c++ - 使用 C++ 和 CryptoApi/SChannel 从 SChannel 中提取证书链

标签 c++ windows ssl cryptoapi schannel

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

具有 SECPKG_ATTR_REMOTE_CERT_CONTEXT 值的 API QueryContextAttributes 仅返回最终证书。

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

谢谢!

最佳答案

是的,确实如此。

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

请参阅下面的代码片段(来源: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;
    }
}

关于c++ - 使用 C++ 和 CryptoApi/SChannel 从 SChannel 中提取证书链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38121372/

相关文章:

c++ - 我想制作自己的源代码编辑器,有哪些好的选择?

c++ - 调整 C++ std/boost iostreams 以提供对内存块的循环写入

linux - 测量代码性能时的虚拟机或双启动

asp.net-mvc - ASP.NET MVC : How to implement a wild card SSL for more than one static domain on a single IP?

java - TLSv1 握手失败

c++ - c++中 "this"的类型?

c++ - 人脸识别: Does all the images per person must be the same count?

c++ - 结合使用PCH,PDB和Zi会导致VS2017令人困惑的C2859编译错误

windows - 通过 shell 脚本使用用户名和密码 SSH 到远程 Windows 机器

google-chrome - NET::ERR_CERT_AUTHORITY_INVALID 在我的网站上只有 chrome v.57