是否可以在TLS 1.0握手中提取远程计算机发送的证书链?
带有SECPKG_ATTR_REMOTE_CERT_CONTEXT值的API QueryContextAttributes仅返回结束证书。
是否可以使用某些方法提取所有链证书? 使用CryptoApi和SChannel环境Windows和C ++。
谢谢!
答案 0 :(得分:1)
是的,是的。
将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;
}
}