2016-06-30 7 views
0

TLS 1.0ハンドシェイクでリモートコンピュータから送信された証明書チェーンを抽出することはできますか?C++とCryptoApi/SChannelのSChannelから証明書チェーンを抽出する

値がSECPKG_ATTR_REMOTE_CERT_CONTEXTのAPI QueryContextAttributesは、終了証明書のみを返します。

いくつかの方法ですべてのチェーン証明書を抽出できますか。 環境CryptoApiとSChannelを使用するWindowsとC++。

ありがとうございます!

答えて

1

はい、そうです。

SECPKG_ATTR_REMOTE_CERT_CONTEXTQueryContextAttributes()を使用し、返されるサーバー証明書は、すべてのサーバーの中間CA証明書を含む証明書ストアにhCertStoreメンバを設定します。 (MSDNでの発言を参照してください。)

は、以下のコードを参照してください(出典:WebClient.c、MicrosoftプラットフォームSDK)あなたは連鎖解析できる方法:

static 
void 
DisplayCertChain(
    PCCERT_CONTEXT pServerCert, 
    BOOL   fLocal) 
{ 
    CHAR szName[1000]; 
    PCCERT_CONTEXT pCurrentCert; 
    PCCERT_CONTEXT pIssuerCert; 
    DWORD dwVerificationFlags; 

    printf("\n"); 

    // display leaf name 
    if(!CertNameToStr(pServerCert->dwCertEncodingType, 
         &pServerCert->pCertInfo->Subject, 
         CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, 
         szName, sizeof(szName))) 
    { 
     printf("**** Error 0x%x building subject name\n", GetLastError()); 
    } 
    if(fLocal) 
    { 
     printf("Client subject: %s\n", szName); 
    } 
    else 
    { 
     printf("Server subject: %s\n", szName); 
    } 
    if(!CertNameToStr(pServerCert->dwCertEncodingType, 
         &pServerCert->pCertInfo->Issuer, 
         CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, 
         szName, sizeof(szName))) 
    { 
     printf("**** Error 0x%x building issuer name\n", GetLastError()); 
    } 
    if(fLocal) 
    { 
     printf("Client issuer: %s\n", szName); 
    } 
    else 
    { 
     printf("Server issuer: %s\n\n", szName); 
    } 


    // display certificate chain 
    pCurrentCert = pServerCert; 
    while(pCurrentCert != NULL) 
    { 
     dwVerificationFlags = 0; 
     pIssuerCert = CertGetIssuerCertificateFromStore(pServerCert->hCertStore, 
                 pCurrentCert, 
                 NULL, 
                 &dwVerificationFlags); 
     if(pIssuerCert == NULL) 
     { 
      if(pCurrentCert != pServerCert) 
      { 
       CertFreeCertificateContext(pCurrentCert); 
      } 
      break; 
     } 

     if(!CertNameToStr(pIssuerCert->dwCertEncodingType, 
          &pIssuerCert->pCertInfo->Subject, 
          CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, 
          szName, sizeof(szName))) 
     { 
      printf("**** Error 0x%x building subject name\n", GetLastError()); 
     } 
     printf("CA subject: %s\n", szName); 
     if(!CertNameToStr(pIssuerCert->dwCertEncodingType, 
          &pIssuerCert->pCertInfo->Issuer, 
          CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, 
          szName, sizeof(szName))) 
     { 
      printf("**** Error 0x%x building issuer name\n", GetLastError()); 
     } 
     printf("CA issuer: %s\n\n", szName); 

     if(pCurrentCert != pServerCert) 
     { 
      CertFreeCertificateContext(pCurrentCert); 
     } 
     pCurrentCert = pIssuerCert; 
     pIssuerCert = NULL; 
    } 
} 
関連する問題