[PATCH] crypt32: Add support for PFX objects in CryptQueryObject.

Hans Leidekker hans at codeweavers.com
Fri Feb 1 08:30:31 CST 2019


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/crypt32/object.c      | 53 ++++++++++++++++++++++++++++++++++++--
 dlls/crypt32/tests/store.c | 34 ++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/dlls/crypt32/object.c b/dlls/crypt32/object.c
index 3dc28af0e9..1993a0a879 100644
--- a/dlls/crypt32/object.c
+++ b/dlls/crypt32/object.c
@@ -696,6 +696,48 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
     return ret;
 }
 
+static BOOL CRYPT_QueryPFXObject(DWORD dwObjectType, const void *pvObject,
+ DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
+ DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
+ HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
+{
+    CRYPT_DATA_BLOB blob = {0}, *ptr;
+    BOOL ret;
+
+    TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject,
+     dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
+     pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
+     phMsg);
+
+    switch (dwObjectType)
+    {
+    case CERT_QUERY_OBJECT_FILE:
+        if (!CRYPT_ReadBlobFromFile(pvObject, &blob)) return FALSE;
+        ptr = &blob;
+        break;
+
+    case CERT_QUERY_OBJECT_BLOB:
+        ptr = (CRYPT_DATA_BLOB *)pvObject;
+        break;
+
+    default:
+        return FALSE;
+    }
+
+    ret = PFXIsPFXBlob(ptr);
+    if (ret)
+    {
+        if (pdwMsgAndCertEncodingType) *pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
+        if (pdwContentType) *pdwContentType = CERT_QUERY_CONTENT_PFX;
+        if (pdwFormatType) *pdwFormatType = CERT_QUERY_FORMAT_BINARY;
+        if (phCertStore) *phCertStore = NULL;
+        if (phMsg) *phMsg = NULL;
+    }
+
+    CryptMemFree(blob.pbData);
+    return ret;
+}
+
 BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
  DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
  DWORD dwFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
@@ -703,8 +745,7 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
  const void **ppvContext)
 {
     static const DWORD unimplementedTypes =
-     CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_PFX |
-     CERT_QUERY_CONTENT_FLAG_CERT_PAIR;
+     CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_CERT_PAIR;
     BOOL ret = TRUE;
 
     TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n",
@@ -779,6 +820,14 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
          dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
          phCertStore, phMsg);
     }
+    if (!ret &&
+     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PFX))
+    {
+        ret = CRYPT_QueryPFXObject(dwObjectType, pvObject,
+         dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
+         pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
+         phCertStore, phMsg);
+    }
     if (!ret)
         SetLastError(CRYPT_E_NO_MATCH);
     TRACE("returning %d\n", ret);
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index b13fee6cd1..f3fb420140 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -3326,6 +3326,39 @@ static void test_PFXImportCertStore(void)
     CertCloseStore( store, 0 );
 }
 
+static void test_CryptQueryObject(void)
+{
+    CRYPT_DATA_BLOB pfx;
+    DWORD encoding_type, content_type, format_type;
+    HCERTSTORE store;
+    HCRYPTMSG msg;
+    const void *ctx;
+    BOOL ret;
+
+    SetLastError( 0xdeadbeef );
+    ret = CryptQueryObject( CERT_QUERY_OBJECT_BLOB, NULL, CERT_QUERY_CONTENT_FLAG_ALL,
+                            CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, NULL, NULL, NULL );
+    ok( !ret, "success\n" );
+    ok( GetLastError() == E_INVALIDARG, "got %u\n", GetLastError() );
+
+    pfx.pbData = (BYTE *)pfxdata;
+    pfx.cbData = sizeof(pfxdata);
+    encoding_type = content_type = format_type = 0xdeadbeef;
+    store = (HCERTSTORE *)0xdeadbeef;
+    msg = (HCRYPTMSG *)0xdeadbeef;
+    ctx = (void *)0xdeadbeef;
+    ret = CryptQueryObject( CERT_QUERY_OBJECT_BLOB, &pfx, CERT_QUERY_CONTENT_FLAG_ALL,
+                            CERT_QUERY_FORMAT_FLAG_BINARY, 0, &encoding_type, &content_type, &format_type,
+                            &store, &msg, &ctx );
+    ok( ret, "got %u\n", GetLastError() );
+    ok( encoding_type == X509_ASN_ENCODING, "got %08x\n", encoding_type );
+    ok( content_type == CERT_QUERY_CONTENT_PFX, "got %08x\n", content_type );
+    ok( format_type == CERT_QUERY_FORMAT_BINARY, "got %08x\n", format_type );
+    ok( store == NULL, "got %p\n", store );
+    ok( msg == NULL, "got %p\n", msg );
+    ok( ctx == NULL, "got %p\n", ctx );
+}
+
 START_TEST(store)
 {
     /* various combinations of CertOpenStore */
@@ -3357,4 +3390,5 @@ START_TEST(store)
 
     test_I_UpdateStore();
     test_PFXImportCertStore();
+    test_CryptQueryObject();
 }
-- 
2.20.1




More information about the wine-devel mailing list