Juan Lang : crypt32: Support base64-encoded PKCS messages in CryptQueryObject.
Alexandre Julliard
julliard at winehq.org
Fri Dec 12 07:04:10 CST 2008
Module: wine
Branch: master
Commit: 909a81839b74bac9c1fad49272f0b956195ede2b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=909a81839b74bac9c1fad49272f0b956195ede2b
Author: Juan Lang <juan.lang at gmail.com>
Date: Thu Dec 11 16:36:46 2008 -0800
crypt32: Support base64-encoded PKCS messages in CryptQueryObject.
---
dlls/crypt32/object.c | 81 ++++++++++++++++++++++++++++++++++++-------
dlls/crypt32/tests/object.c | 1 -
2 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/dlls/crypt32/object.c b/dlls/crypt32/object.c
index 97f71b7..b55b441 100644
--- a/dlls/crypt32/object.c
+++ b/dlls/crypt32/object.c
@@ -428,14 +428,21 @@ static BOOL CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB *blob,
/* Used to decode non-embedded messages */
static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
- DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType,
- DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
+ DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
+ DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
+ HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
CERT_BLOB fileBlob;
const CERT_BLOB *blob;
BOOL ret;
HCRYPTMSG msg = NULL;
DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
+ DWORD formatType = 0;
+
+ TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject,
+ dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
+ pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
+ phMsg);
switch (dwObjectType)
{
@@ -458,17 +465,63 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
return FALSE;
ret = FALSE;
- /* Try it first as a signed message */
- if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
- ret = CRYPT_QuerySignedMessage(blob, pdwMsgAndCertEncodingType,
- pdwContentType, &msg);
- /* Failing that, try as an unsigned message */
+ if (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY)
+ {
+ /* Try it first as a signed message */
+ if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
+ ret = CRYPT_QuerySignedMessage(blob, pdwMsgAndCertEncodingType,
+ pdwContentType, &msg);
+ /* Failing that, try as an unsigned message */
+ if (!ret &&
+ (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
+ ret = CRYPT_QueryUnsignedMessage(blob, pdwMsgAndCertEncodingType,
+ pdwContentType, &msg);
+ if (ret)
+ formatType = CERT_QUERY_FORMAT_BINARY;
+ }
if (!ret &&
- (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
- ret = CRYPT_QueryUnsignedMessage(blob, pdwMsgAndCertEncodingType,
- pdwContentType, &msg);
+ (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED))
+ {
+ CRYPT_DATA_BLOB trimmed = { blob->cbData, blob->pbData };
+ CRYPT_DATA_BLOB decoded;
+
+ while (trimmed.cbData && !trimmed.pbData[trimmed.cbData - 1])
+ trimmed.cbData--;
+ ret = CryptStringToBinaryA((LPSTR)trimmed.pbData, trimmed.cbData,
+ CRYPT_STRING_BASE64_ANY, NULL, &decoded.cbData, NULL, NULL);
+ if (ret)
+ {
+ decoded.pbData = CryptMemAlloc(decoded.cbData);
+ if (decoded.pbData)
+ {
+ ret = CryptStringToBinaryA((LPSTR)trimmed.pbData,
+ trimmed.cbData, 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)
{
+ if (pdwFormatType)
+ *pdwFormatType = formatType;
if (phMsg)
*phMsg = msg;
if (phCertStore)
@@ -536,8 +589,9 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
ret = CRYPT_QueryMessageObject(
CERT_QUERY_OBJECT_BLOB, &blob,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
- pdwMsgAndCertEncodingType, NULL, phCertStore,
- phMsg);
+ CERT_QUERY_FORMAT_FLAG_BINARY,
+ pdwMsgAndCertEncodingType, NULL, NULL,
+ phCertStore, phMsg);
if (ret && pdwContentType)
*pdwContentType =
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED;
@@ -630,7 +684,8 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)))
{
ret = CRYPT_QueryMessageObject(dwObjectType, pvObject,
- dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
+ dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
+ pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
phCertStore, phMsg);
}
if (!ret &&
diff --git a/dlls/crypt32/tests/object.c b/dlls/crypt32/tests/object.c
index b0b95a6..e658dd6 100644
--- a/dlls/crypt32/tests/object.c
+++ b/dlls/crypt32/tests/object.c
@@ -192,7 +192,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());
/* A valid signed message, encoded as a wide character base64 string, can
* be queried successfully.
More information about the wine-cvs
mailing list