2016-06-30 46 views

回答

1

是的。

使用QueryContextAttributes()SECPKG_ATTR_REMOTE_CERT_CONTEXT和服務器證書返回將有hCertStore成員設置爲包含所有服務器的中間CA證書的證書存儲區。 (見備註在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; 
    } 
}