Juan Lang : crypt32: Only decode authority key ID in subject cert once when looking for issuer.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Sep 12 07:50:37 CDT 2007


Module: wine
Branch: master
Commit: 5c8254886f087a22e3648a87f6494184941b74ae
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5c8254886f087a22e3648a87f6494184941b74ae

Author: Juan Lang <juan.lang at gmail.com>
Date:   Tue Sep 11 12:47:51 2007 -0700

crypt32: Only decode authority key ID in subject cert once when looking for issuer.

---

 dlls/crypt32/chain.c |  102 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 98 insertions(+), 4 deletions(-)

diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index bd26cb1..f34f04a 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -17,6 +17,7 @@
  *
  */
 #include <stdarg.h>
+#define NONAMELESSUNION
 #include "windef.h"
 #include "winbase.h"
 #include "wincrypt.h"
@@ -514,11 +515,104 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine,
 static PCCERT_CONTEXT CRYPT_GetIssuer(HCERTSTORE store, PCCERT_CONTEXT subject,
  PCCERT_CONTEXT prevIssuer)
 {
-    PCCERT_CONTEXT issuer;
-    DWORD flags = 0;
+    PCCERT_CONTEXT issuer = NULL;
+    PCERT_EXTENSION ext;
+    DWORD size;
 
-    issuer = CertGetIssuerCertificateFromStore(store, subject, prevIssuer,
-     &flags);
+    if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER,
+     subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
+    {
+        CERT_AUTHORITY_KEY_ID_INFO *info;
+        BOOL ret;
+
+        ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
+         X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData,
+         CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
+         &info, &size);
+        if (ret)
+        {
+            CERT_ID id;
+
+            if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
+            {
+                id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
+                memcpy(&id.u.IssuerSerialNumber.Issuer, &info->CertIssuer,
+                 sizeof(CERT_NAME_BLOB));
+                memcpy(&id.u.IssuerSerialNumber.SerialNumber,
+                 &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB));
+                issuer = CertFindCertificateInStore(store,
+                 subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
+                 prevIssuer);
+            }
+            else if (info->KeyId.cbData)
+            {
+                id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
+                memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
+                issuer = CertFindCertificateInStore(store,
+                 subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
+                 prevIssuer);
+            }
+            LocalFree(info);
+        }
+    }
+    else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
+     subject->pCertInfo->cExtension, subject->pCertInfo->rgExtension)))
+    {
+        CERT_AUTHORITY_KEY_ID2_INFO *info;
+        BOOL ret;
+
+        ret = CryptDecodeObjectEx(subject->dwCertEncodingType,
+         X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData,
+         CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL,
+         &info, &size);
+        if (ret)
+        {
+            CERT_ID id;
+
+            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)
+                {
+                    id.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
+                    memcpy(&id.u.IssuerSerialNumber.Issuer,
+                     &directoryName->u.DirectoryName, sizeof(CERT_NAME_BLOB));
+                    memcpy(&id.u.IssuerSerialNumber.SerialNumber,
+                     &info->AuthorityCertSerialNumber,
+                     sizeof(CRYPT_INTEGER_BLOB));
+                    issuer = CertFindCertificateInStore(store,
+                     subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
+                     prevIssuer);
+                }
+                else
+                    FIXME("no supported name type in authority key id2\n");
+            }
+            else if (info->KeyId.cbData)
+            {
+                id.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
+                memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB));
+                issuer = CertFindCertificateInStore(store,
+                 subject->dwCertEncodingType, 0, CERT_FIND_CERT_ID, &id,
+                 prevIssuer);
+            }
+            LocalFree(info);
+        }
+    }
+    else
+    {
+        issuer = CertFindCertificateInStore(store,
+         subject->dwCertEncodingType, 0, CERT_FIND_SUBJECT_NAME,
+         &subject->pCertInfo->Issuer, prevIssuer);
+    }
     return issuer;
 }
 




More information about the wine-cvs mailing list