crypt32: Support wide character base64-encoded PKCS messages in CryptQueryObject.
authorJuan Lang <juan.lang@gmail.com>
Fri, 12 Dec 2008 01:02:13 +0000 (17:02 -0800)
committerAlexandre Julliard <julliard@winehq.org>
Fri, 12 Dec 2008 10:40:15 +0000 (11:40 +0100)
dlls/crypt32/object.c
dlls/crypt32/tests/object.c

index b55b441f8c84ce5f5eb734405ad8afe5ad4294f2..202f45806552978c6a38cfb1a8ad897394abbbee 100644 (file)
@@ -517,6 +517,46 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
             else
                 ret = FALSE;
         }
+        if (!ret && !(blob->cbData % sizeof(WCHAR)))
+        {
+            CRYPT_DATA_BLOB decoded;
+            LPWSTR str = (LPWSTR)blob->pbData;
+            DWORD strLen = blob->cbData / sizeof(WCHAR);
+
+            /* Try again, assuming the input string is UTF-16 base64 */
+            while (strLen && !str[strLen - 1])
+                strLen--;
+            ret = CryptStringToBinaryW(str, strLen, CRYPT_STRING_BASE64_ANY,
+             NULL, &decoded.cbData, NULL, NULL);
+            if (ret)
+            {
+                decoded.pbData = CryptMemAlloc(decoded.cbData);
+                if (decoded.pbData)
+                {
+                    ret = CryptStringToBinaryW(str, strLen,
+                     CRYPT_STRING_BASE64_ANY, decoded.pbData, &decoded.cbData,
+                     NULL, NULL);
+                    if (ret)
+                    {
+                        /* Try it first as a signed message */
+                        if (dwExpectedContentTypeFlags &
+                         CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
+                            ret = CRYPT_QuerySignedMessage(&decoded,
+                             pdwMsgAndCertEncodingType, pdwContentType, &msg);
+                        /* Failing that, try as an unsigned message */
+                        if (!ret && (dwExpectedContentTypeFlags &
+                         CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
+                            ret = CRYPT_QueryUnsignedMessage(&decoded,
+                             pdwMsgAndCertEncodingType, pdwContentType, &msg);
+                        if (ret)
+                            formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
+                    }
+                    CryptMemFree(decoded.pbData);
+                }
+                else
+                    ret = FALSE;
+            }
+        }
     }
     if (ret)
     {
index e658dd6286c68b39caeb9a7b5fa1bf1091ae7cb0..911fc9f7c913f51ea949076c2bc855127ea98389 100644 (file)
@@ -202,7 +202,6 @@ static void test_query_object(void)
     ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
      CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
      NULL, NULL, NULL, NULL);
-    todo_wine
     ok(ret, "CryptQueryObject failed: %08x\n", GetLastError());
     SetLastError(0xdeadbeef);
     ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
@@ -214,7 +213,6 @@ static void test_query_object(void)
     ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
      CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED, 0,
      NULL, NULL, NULL, NULL, NULL, NULL);
-    todo_wine
     ok(ret, "CryptQueryObject failed: %08x\n", GetLastError());
 }