Juan Lang : wintrust: Check authority key identifer extension to determine if a certificate is self-signed .
Alexandre Julliard
julliard at winehq.org
Fri Dec 18 10:49:07 CST 2009
Module: wine
Branch: master
Commit: 2fbe80ad8936537c80685ba584b79e600f6b6085
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2fbe80ad8936537c80685ba584b79e600f6b6085
Author: Juan Lang <juan.lang at gmail.com>
Date: Thu Dec 17 08:54:54 2009 -0800
wintrust: Check authority key identifer extension to determine if a certificate is self-signed.
---
dlls/wintrust/wintrust_main.c | 111 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/dlls/wintrust/wintrust_main.c b/dlls/wintrust/wintrust_main.c
index c61f6e0..1c87b6e 100644
--- a/dlls/wintrust/wintrust_main.c
+++ b/dlls/wintrust/wintrust_main.c
@@ -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;
}
More information about the wine-cvs
mailing list