【问题标题】:Extract Certificate Chain from SChannel with C++ and CryptoApi/SChannel使用 C++ 和 CryptoApi/SChannel 从 SChannel 中提取证书链
【发布时间】:2016-06-30 11:08:06
【问题描述】:

是否可以提取远程计算机在 TLS 1.0 握手中发送的证书链?

具有 SECPKG_ATTR_REMOTE_CERT_CONTEXT 值的 API QueryContextAttributes 仅返回结束证书。

是否可以使用某些方法提取所有链证书? 使用 CryptoApi 和 SChannel 的环境 Windows 和 C++。

谢谢!

【问题讨论】:

    标签: c++ windows ssl cryptoapi schannel


    【解决方案1】:

    是的。

    QueryContextAttributes()SECPKG_ATTR_REMOTE_CERT_CONTEXT 一起使用,返回的服务器证书会将hCertStore 成员设置为包含所有服务器中间CA 证书的证书存储。 (请参阅MSDN 的备注。)

    查看下面的代码 sn-p(来源:WebClient.c,Microsoft Platform 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;
        }
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-11
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 2021-07-29
    • 2011-05-02
    相关资源
    最近更新 更多