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