crypt32(5/6): Test and fix getting a certificate context's key identifier property

Juan Lang juan.lang at gmail.com
Thu Aug 2 14:34:43 CDT 2007


--Juan
-------------- next part --------------
From d2e13b3a7e35aebdd630be0b2ca13ea9d4efcb8e Mon Sep 17 00:00:00 2001
From: Juan Lang <juanlang at juan.corp.google.com>
Date: Thu, 2 Aug 2007 12:29:49 -0700
Subject: [PATCH] Test and fix getting a certificate context's key identifier property
---
 dlls/crypt32/cert.c       |   33 +++++++++++++++++++----
 dlls/crypt32/tests/cert.c |   64 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index a74e5e4..f3d5809 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -242,6 +242,33 @@ static BOOL WINAPI CertContext_GetProper
             FIXME("CERT_SIGNATURE_HASH_PROP_ID unimplemented\n");
             SetLastError(CRYPT_E_NOT_FOUND);
             break;
+        case CERT_KEY_IDENTIFIER_PROP_ID:
+        {
+            PCERT_EXTENSION ext = CertFindExtension(
+             szOID_SUBJECT_KEY_IDENTIFIER, pCertContext->pCertInfo->cExtension,
+             pCertContext->pCertInfo->rgExtension);
+
+            if (ext)
+            {
+                CRYPT_DATA_BLOB *value;
+                DWORD size;
+
+                ret = CryptDecodeObjectEx(X509_ASN_ENCODING,
+                 szOID_SUBJECT_KEY_IDENTIFIER, ext->Value.pbData,
+                 ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &value,
+                 &size);
+                if (ret)
+                {
+                    ret = CertContext_CopyParam(pvData, pcbData, value->pbData,
+                     value->cbData);
+                    CertContext_SetProperty(context, dwPropId, 0, value);
+                    LocalFree(value);
+                }
+            }
+            else
+                SetLastError(ERROR_INVALID_DATA);
+            break;
+        }
         default:
             SetLastError(CRYPT_E_NOT_FOUND);
         }
@@ -300,12 +327,6 @@ BOOL WINAPI CertGetCertificateContextPro
             ret = CertContext_CopyParam(pvData, pcbData, &state, sizeof(state));
         }
         break;
-    case CERT_KEY_IDENTIFIER_PROP_ID:
-        ret = CertContext_GetProperty((void *)pCertContext, dwPropId,
-         pvData, pcbData);
-        if (!ret)
-            SetLastError(ERROR_INVALID_DATA);
-        break;
     case CERT_KEY_PROV_HANDLE_PROP_ID:
     {
         CERT_KEY_CONTEXT keyContext;
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index 4231a1e..ab668ae 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -324,6 +324,30 @@ static void checkHash(const BYTE *data, 
 }
 
 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
+static const BYTE v1CertWithPubKey[] = {
+0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
+0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
+0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
+0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
+0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
+0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
+0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
+0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
+0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
+0x01,0x01 };
+static const BYTE v1CertWithSubjectKeyId[] = {
+0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
+0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
+0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
+0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
+0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
+0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
+0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
+0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
+0x4c,0x61,0x6e,0x67,0x00 };
+static const BYTE subjectKeyId[] = {
+0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
 
 static void testCertProperties(void)
 {
@@ -493,6 +517,46 @@ static void testCertProperties(void)
      GetLastError());
     ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
 
+    /* According to MSDN the subject key id can be stored as a property,
+     * as a subject key extension, or as the SHA1 hash of the public key,
+     * but this cert has none of them:
+     */
+    ret = CertGetCertificateContextProperty(context,
+     CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
+    ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+     "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
+    CertFreeCertificateContext(context);
+    /* This cert does have a public key, but its subject key identifier still
+     * isn't available: */
+    context = CertCreateCertificateContext(X509_ASN_ENCODING,
+     v1CertWithPubKey, sizeof(v1CertWithPubKey));
+    ret = CertGetCertificateContextProperty(context,
+     CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
+    ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+     "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
+    CertFreeCertificateContext(context);
+    /* This cert with a subject key extension can have its key identifier
+     * property retrieved:
+     */
+    context = CertCreateCertificateContext(X509_ASN_ENCODING,
+     v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
+    ret = CertGetCertificateContextProperty(context,
+     CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
+    ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
+    if (ret)
+    {
+        LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
+
+        if (buf)
+        {
+            ret = CertGetCertificateContextProperty(context,
+             CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
+            ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
+             GetLastError());
+            ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
+            HeapFree(GetProcessHeap(), 0, buf);
+        }
+    }
     CertFreeCertificateContext(context);
 }
 
-- 
1.4.1


More information about the wine-patches mailing list