Juan Lang : crypt32: Implement message stores.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jul 30 08:55:41 CDT 2007


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Jul 27 10:59:49 2007 -0700

crypt32: Implement message stores.

---

 dlls/crypt32/store.c       |  166 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/crypt32/tests/store.c |    6 --
 2 files changed, 166 insertions(+), 6 deletions(-)

diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index b2be152..2bebb5d 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -175,6 +175,14 @@ typedef struct _WINE_FILESTOREINFO
     BOOL                 dirty;
 } WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
 
+typedef struct _WINE_MSGSTOREINFO
+{
+    DWORD                dwOpenFlags;
+    HCRYPTPROV           cryptProv;
+    PWINECRYPT_CERTSTORE memStore;
+    HCRYPTMSG            msg;
+} WINE_MSGSTOREINFO, *PWINE_MSGSTOREINFO;
+
 typedef struct _WINE_STORE_LIST_ENTRY
 {
     PWINECRYPT_CERTSTORE store;
@@ -1920,6 +1928,158 @@ static PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
     return ret;
 }
 
+static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
+{
+    PWINE_MSGSTOREINFO store = (PWINE_MSGSTOREINFO)hCertStore;
+
+    TRACE("(%p, %08x)\n", store, dwFlags);
+    CertCloseStore(store->memStore, dwFlags);
+    CryptMsgClose(store->msg);
+    CryptMemFree(store);
+}
+
+static void *msgProvFuncs[] = {
+    CRYPT_MsgCloseStore,
+    NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
+    NULL, /* CERT_STORE_PROV_WRITE_CERT_FUNC */
+    NULL, /* CERT_STORE_PROV_DELETE_CERT_FUNC */
+    NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
+    NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
+    NULL, /* CERT_STORE_PROV_WRITE_CRL_FUNC */
+    NULL, /* CERT_STORE_PROV_DELETE_CRL_FUNC */
+    NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
+    NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
+    NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
+    NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
+    NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
+    NULL, /* CERT_STORE_PROV_CONTROL_FUNC */
+};
+
+static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
+ DWORD dwFlags, const void *pvPara)
+{
+    PWINECRYPT_CERTSTORE store = NULL;
+    HCRYPTMSG msg = (HCRYPTMSG)pvPara;
+    PWINECRYPT_CERTSTORE memStore;
+
+    TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
+
+    memStore = CRYPT_MemOpenStore(hCryptProv, dwFlags, NULL);
+    if (memStore)
+    {
+        BOOL ret;
+        DWORD size, count, i;
+
+        size = sizeof(count);
+        ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
+        for (i = 0; ret && i < count; i++)
+        {
+            size = 0;
+            ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
+            if (ret)
+            {
+                LPBYTE buf = CryptMemAlloc(size);
+
+                if (buf)
+                {
+                    ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
+                    if (ret)
+                        ret = CertAddEncodedCertificateToStore(memStore,
+                         X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
+                         NULL);
+                    CryptMemFree(buf);
+                }
+            }
+        }
+        size = sizeof(count);
+        ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
+        for (i = 0; ret && i < count; i++)
+        {
+            size = 0;
+            ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
+            if (ret)
+            {
+                LPBYTE buf = CryptMemAlloc(size);
+
+                if (buf)
+                {
+                    ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
+                    if (ret)
+                        ret = CertAddEncodedCRLToStore(memStore,
+                         X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
+                         NULL);
+                    CryptMemFree(buf);
+                }
+            }
+        }
+        if (ret)
+        {
+            PWINE_MSGSTOREINFO info = CryptMemAlloc(sizeof(WINE_MSGSTOREINFO));
+
+            if (info)
+            {
+                CERT_STORE_PROV_INFO provInfo = { 0 };
+
+                info->dwOpenFlags = dwFlags;
+                info->cryptProv = hCryptProv;
+                info->memStore = memStore;
+                info->msg = CryptMsgDuplicate(msg);
+                provInfo.cbSize = sizeof(provInfo);
+                provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
+                 sizeof(msgProvFuncs[0]);
+                provInfo.rgpvStoreProvFunc = msgProvFuncs;
+                provInfo.hStoreProv = info;
+                store = CRYPT_ProvCreateStore(hCryptProv, dwFlags, memStore,
+                 &provInfo);
+            }
+            else
+                CertCloseStore(memStore, 0);
+        }
+        else
+            CertCloseStore(memStore, 0);
+    }
+    TRACE("returning %p\n", store);
+    return store;
+}
+
+static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
+ DWORD dwFlags, const void *pvPara)
+{
+    HCRYPTMSG msg;
+    PWINECRYPT_CERTSTORE store = NULL;
+    const CRYPT_DATA_BLOB *data = (const CRYPT_DATA_BLOB *)pvPara;
+    BOOL ret;
+
+    TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
+
+    msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, CMSG_SIGNED, 0, NULL,
+     NULL);
+    ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
+    if (!ret)
+    {
+        CryptMsgClose(msg);
+        msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL, NULL);
+        ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
+        if (ret)
+        {
+            DWORD type, size = sizeof(type);
+
+            /* Only signed messages are allowed, check type */
+            ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
+            if (ret && type != CMSG_SIGNED)
+            {
+                SetLastError(CRYPT_E_INVALID_MSG_TYPE);
+                ret = FALSE;
+            }
+        }
+    }
+    if (ret)
+        store = CRYPT_MsgOpenStore(hCryptProv, dwFlags, msg);
+    CryptMsgClose(msg);
+    TRACE("returning %p\n", store);
+    return store;
+}
+
 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
  DWORD dwFlags, const void *pvPara)
 {
@@ -1945,12 +2105,18 @@ HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
     {
         switch (LOWORD(lpszStoreProvider))
         {
+        case (int)CERT_STORE_PROV_MSG:
+            openFunc = CRYPT_MsgOpenStore;
+            break;
         case (int)CERT_STORE_PROV_MEMORY:
             openFunc = CRYPT_MemOpenStore;
             break;
         case (int)CERT_STORE_PROV_FILE:
             openFunc = CRYPT_FileOpenStore;
             break;
+        case (int)CERT_STORE_PROV_PKCS7:
+            openFunc = CRYPT_PKCSOpenStore;
+            break;
         case (int)CERT_STORE_PROV_REG:
             openFunc = CRYPT_RegOpenStore;
             break;
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index 96b62f0..450352f 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -1398,12 +1398,10 @@ static void testMessageStore(void)
      */
     SetLastError(0xdeadbeef);
     store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, msg);
-    todo_wine
     ok(!store && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
     CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
     store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, msg);
-    todo_wine
     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
     if (store)
     {
@@ -1452,7 +1450,6 @@ static void testMessageStore(void)
     store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, NULL);
      */
     store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob);
-    todo_wine
     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
     if (store)
     {
@@ -1479,7 +1476,6 @@ static void testMessageStore(void)
     /* Encoding appears to be ignored */
     store = CertOpenStore(CERT_STORE_PROV_PKCS7, X509_ASN_ENCODING, 0, 0,
      &blob);
-    todo_wine
     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
     if (store)
         CertCloseStore(store, 0);
@@ -1488,14 +1484,12 @@ static void testMessageStore(void)
     blob.pbData = (LPBYTE)hashContent;
     SetLastError(0xdeadbeef);
     store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob);
-    todo_wine
     ok(!store && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
      "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
     blob.cbData = sizeof(hashBareContent);
     blob.pbData = (LPBYTE)hashBareContent;
     SetLastError(0xdeadbeef);
     store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob);
-    todo_wine
     ok(!store && GetLastError() == CRYPT_E_ASN1_BADTAG,
      "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
 }




More information about the wine-cvs mailing list