是否可以在TLS 1.0握手中提取远程计算机发送的证书链?
具有SECPKG_ATTR_REMOTE_CERT_CONTEXT值的API SECPKG_ATTR_REMOTE_CERT_CONTEXT只返回结束证书。
是否可以使用某些方法提取所有链证书?环境Windows和C++使用CryptoApi和SChannel。
谢谢!
发布于 2016-08-23 09:54:24
是的,是这样的。
将QueryContextAttributes()与SECPKG_ATTR_REMOTE_CERT_CONTEXT一起使用,返回的服务器证书将将hCertStore成员设置为包含所有服务器中间CA证书的证书存储区。(见MSDN的备注)
请参阅下面的代码片段(源代码: WebClient.c,),您可以如何解析这个链:
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;
}
}https://stackoverflow.com/questions/38121372
复制相似问题