windows — Извлечение цепочки сертификатов из SChannel с C ++ и CryptoApi / SChannel

Можно ли извлечь цепочку сертификатов, отправленную удаленным компьютером в TLS 1.0 Handshake?

API QueryContextAttributes со значением SECPKG_ATTR_REMOTE_CERT_CONTEXT возвращает только конечный сертификат.

Можно ли извлечь все цепные сертификаты, используя несколько методов?
Среды Windows и C ++ используют CryptoApi и SChannel.

Спасибо!

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;
}
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]