Juan Lang : crypt32: Implement key context property, with tests.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jul 11 06:10:38 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: 4b8845ae12f944980971440f3f48d1a4701a64e4
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=4b8845ae12f944980971440f3f48d1a4701a64e4

Author: Juan Lang <juan_lang at yahoo.com>
Date:   Mon Jul 10 09:10:36 2006 -0700

crypt32: Implement key context property, with tests.

---

 dlls/crypt32/cert.c       |  109 ++++++++++++++++++++++++++++++++++++++++-----
 dlls/crypt32/tests/cert.c |   73 +++++++++++++++++++++++++++---
 2 files changed, 163 insertions(+), 19 deletions(-)

diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index eabea82..3af7fa1 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -307,6 +307,40 @@ BOOL WINAPI CertGetCertificateContextPro
             ret = TRUE;
         }
         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;
+        DWORD size = sizeof(keyContext);
+
+        ret = CertContext_GetProperty((void *)pCertContext,
+         CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
+        if (ret)
+        {
+            if (!pvData)
+            {
+                *pcbData = sizeof(HCRYPTPROV);
+                ret = TRUE;
+            }
+            else if (*pcbData < sizeof(HCRYPTPROV))
+            {
+                SetLastError(ERROR_MORE_DATA);
+                *pcbData = sizeof(HCRYPTPROV);
+                ret = FALSE;
+            }
+            else
+            {
+                *(HCRYPTPROV *)pvData = keyContext.hCryptProv;
+                ret = TRUE;
+            }
+        }
+        break;
+    }
     case CERT_KEY_PROV_INFO_PROP_ID:
         ret = CertContext_GetProperty((void *)pCertContext, dwPropId, pvData,
          pcbData);
@@ -397,11 +431,6 @@ static BOOL WINAPI CertContext_SetProper
 
     if (!properties)
         ret = FALSE;
-    else if (!pvData)
-    {
-        ContextPropertyList_RemoveProperty(properties, dwPropId);
-        ret = TRUE;
-    }
     else
     {
         switch (dwPropId)
@@ -424,20 +453,76 @@ static BOOL WINAPI CertContext_SetProper
         case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
         case CERT_RENEWAL_PROP_ID:
         {
-            PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
+            if (pvData)
+            {
+                PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData;
 
-            ret = ContextPropertyList_SetProperty(properties, dwPropId,
-             blob->pbData, blob->cbData);
+                ret = ContextPropertyList_SetProperty(properties, dwPropId,
+                 blob->pbData, blob->cbData);
+            }
+            else
+            {
+                ContextPropertyList_RemoveProperty(properties, dwPropId);
+                ret = TRUE;
+            }
             break;
         }
         case CERT_DATE_STAMP_PROP_ID:
-            ret = ContextPropertyList_SetProperty(properties, dwPropId,
-             (LPBYTE)pvData, sizeof(FILETIME));
+            if (pvData)
+                ret = ContextPropertyList_SetProperty(properties, dwPropId,
+                 (LPBYTE)pvData, sizeof(FILETIME));
+            else
+            {
+                ContextPropertyList_RemoveProperty(properties, dwPropId);
+                ret = TRUE;
+            }
+            break;
+        case CERT_KEY_CONTEXT_PROP_ID:
+        {
+            if (pvData)
+            {
+                PCERT_KEY_CONTEXT keyContext = (PCERT_KEY_CONTEXT)pvData;
+
+                ret = ContextPropertyList_SetProperty(properties, dwPropId,
+                 (const BYTE *)keyContext, keyContext->cbSize);
+            }
+            else
+            {
+                ContextPropertyList_RemoveProperty(properties, dwPropId);
+                ret = TRUE;
+            }
             break;
+        }
         case CERT_KEY_PROV_INFO_PROP_ID:
-            ret = CertContext_SetKeyProvInfoProperty(properties,
-             (PCRYPT_KEY_PROV_INFO)pvData);
+            if (pvData)
+                ret = CertContext_SetKeyProvInfoProperty(properties,
+                 (PCRYPT_KEY_PROV_INFO)pvData);
+            else
+            {
+                ContextPropertyList_RemoveProperty(properties, dwPropId);
+                ret = TRUE;
+            }
+            break;
+        case CERT_KEY_PROV_HANDLE_PROP_ID:
+        {
+            CERT_KEY_CONTEXT keyContext;
+            DWORD size = sizeof(keyContext);
+
+            ret = CertContext_GetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
+             &keyContext, &size);
+            if (ret)
+            {
+                if (!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
+                    CryptReleaseContext(keyContext.hCryptProv, 0);
+                if (pvData)
+                    keyContext.hCryptProv = *(HCRYPTPROV *)pvData;
+                else
+                    keyContext.hCryptProv = 0;
+                ret = CertContext_SetProperty(context, CERT_KEY_CONTEXT_PROP_ID,
+                 0, &keyContext);
+            }
             break;
+        }
         default:
             FIXME("%ld: stub\n", dwPropId);
             ret = FALSE;
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index 917236d..b03d61e 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -310,6 +310,9 @@ static void checkHash(const BYTE *data, 
      propID);
 }
 
+static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
+ 'm','p',0 };
+
 static void testCertProperties(void)
 {
     PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
@@ -323,6 +326,8 @@ static void testCertProperties(void)
         BOOL ret;
         BYTE hash[20] = { 0 }, hashProperty[20];
         CRYPT_DATA_BLOB blob;
+        CERT_KEY_CONTEXT keyContext;
+        HCRYPTPROV csp;
 
         /* This crashes
         propID = CertEnumCertificateContextProperties(NULL, 0);
@@ -425,14 +430,71 @@ static void testCertProperties(void)
          context->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
          CALG_MD5, context, CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID);
 
-        /* Odd: this doesn't fail on other certificates, so there must be
-         * something weird about this cert that causes it to fail.
-         */
+        /* Test key identifiers and handles and such */
         size = 0;
         ret = CertGetCertificateContextProperty(context,
          CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
-        todo_wine ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+        ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+         "Expected ERROR_INVALID_DATA, got %08lx\n", GetLastError());
+        size = sizeof(CERT_KEY_CONTEXT);
+        ret = CertGetCertificateContextProperty(context,
+         CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
+        ok(!ret && GetLastError() == ERROR_INVALID_DATA,
+         "Expected ERROR_INVALID_DATA, got %08lx\n", GetLastError());
+        ret = CertGetCertificateContextProperty(context,
+         CERT_KEY_IDENTIFIER_PROP_ID, &keyContext, &size);
+        ok(!ret && GetLastError() == ERROR_INVALID_DATA,
          "Expected ERROR_INVALID_DATA, got %08lx\n", GetLastError());
+        /* Key context with an invalid size */
+        keyContext.cbSize = 0;
+        ret = CertSetCertificateContextProperty(context,
+         CERT_KEY_IDENTIFIER_PROP_ID, 0, &keyContext);
+        ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
+         GetLastError());
+        size = sizeof(keyContext);
+        ret = CertGetCertificateContextProperty(context,
+         CERT_KEY_IDENTIFIER_PROP_ID, &keyContext, &size);
+        ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
+         GetLastError());
+        keyContext.cbSize = sizeof(keyContext);
+        keyContext.hCryptProv = 0;
+        keyContext.dwKeySpec = AT_SIGNATURE;
+        /* Crash
+        ret = CertSetCertificateContextProperty(context,
+         CERT_KEY_IDENTIFIER_PROP_ID, 0, &keyContext);
+        ret = CertSetCertificateContextProperty(context,
+         CERT_KEY_IDENTIFIER_PROP_ID, CERT_STORE_NO_CRYPT_RELEASE_FLAG,
+         &keyContext);
+         */
+        ret = CryptAcquireContextW(&csp, cspNameW,
+         MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET);
+        ok(ret, "CryptAcquireContextW failed: %08lx\n", GetLastError());
+        keyContext.hCryptProv = csp;
+        ret = CertSetCertificateContextProperty(context,
+         CERT_KEY_CONTEXT_PROP_ID, 0, &keyContext);
+        ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
+         GetLastError());
+        /* Now that that's set, the key prov handle property is also gettable.
+         */
+        size = sizeof(DWORD);
+        ret = CertGetCertificateContextProperty(context,
+         CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
+        ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08lx\n",
+         GetLastError());
+        /* Remove the key prov handle property.. */
+        ret = CertSetCertificateContextProperty(context,
+         CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
+        ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
+         GetLastError());
+        /* and the key context's CSP is set to NULL. */
+        size = sizeof(keyContext);
+        ret = CertGetCertificateContextProperty(context,
+         CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
+        ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
+         GetLastError());
+        ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
+
+        CryptReleaseContext(csp, 0);
 
         CertFreeCertificateContext(context);
     }
@@ -799,9 +861,6 @@ static void testCryptHashCert(void)
     ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
 }
 
-static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
- 'm','p',0 };
-
 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
  const BYTE *sig, unsigned int sigLen)
 {




More information about the wine-cvs mailing list