wintrust: Check authority key identifer extension to determine if a certificate is self-signed.

This commit is contained in:
Juan Lang 2009-12-17 08:54:54 -08:00 committed by Alexandre Julliard
parent 048594854a
commit 2fbe80ad89

View file

@ -77,11 +77,118 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
*/
BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert )
{
PCERT_EXTENSION ext;
DWORD size;
BOOL ret;
TRACE("%p\n", cert);
ret = CertCompareCertificateName(cert->dwCertEncodingType,
&cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
{
CERT_AUTHORITY_KEY_ID2_INFO *info;
ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
&info, &size);
if (ret)
{
if (info->AuthorityCertIssuer.cAltEntry &&
info->AuthorityCertSerialNumber.cbData)
{
PCERT_ALT_NAME_ENTRY directoryName = NULL;
DWORD i;
for (i = 0; !directoryName &&
i < info->AuthorityCertIssuer.cAltEntry; i++)
if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice
== CERT_ALT_NAME_DIRECTORY_NAME)
directoryName =
&info->AuthorityCertIssuer.rgAltEntry[i];
if (directoryName)
{
ret = CertCompareCertificateName(cert->dwCertEncodingType,
&directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
&& CertCompareIntegerBlob(&info->AuthorityCertSerialNumber,
&cert->pCertInfo->SerialNumber);
}
else
{
FIXME("no supported name type in authority key id2\n");
ret = FALSE;
}
}
else if (info->KeyId.cbData)
{
ret = CertGetCertificateContextProperty(cert,
CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
if (ret && size == info->KeyId.cbData)
{
LPBYTE buf = CryptMemAlloc(size);
if (buf)
{
CertGetCertificateContextProperty(cert,
CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
ret = !memcmp(buf, info->KeyId.pbData, size);
CryptMemFree(buf);
}
else
ret = FALSE;
}
else
ret = FALSE;
}
LocalFree(info);
}
}
else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER,
cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
{
CERT_AUTHORITY_KEY_ID_INFO *info;
ret = CryptDecodeObjectEx(cert->dwCertEncodingType,
X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
&info, &size);
if (ret)
{
if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
{
ret = CertCompareCertificateName(cert->dwCertEncodingType,
&info->CertIssuer, &cert->pCertInfo->Issuer) &&
CertCompareIntegerBlob(&info->CertSerialNumber,
&cert->pCertInfo->SerialNumber);
}
else if (info->KeyId.cbData)
{
ret = CertGetCertificateContextProperty(cert,
CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
if (ret && size == info->KeyId.cbData)
{
LPBYTE buf = CryptMemAlloc(size);
if (buf)
{
CertGetCertificateContextProperty(cert,
CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
ret = !memcmp(buf, info->KeyId.pbData, size);
CryptMemFree(buf);
}
else
ret = FALSE;
}
else
ret = FALSE;
}
else
ret = FALSE;
LocalFree(info);
}
}
else
ret = CertCompareCertificateName(cert->dwCertEncodingType,
&cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
return ret;
}