Commit 909a8183 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

crypt32: Support base64-encoded PKCS messages in CryptQueryObject.

parent 62cbf426
...@@ -428,14 +428,21 @@ static BOOL CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB *blob, ...@@ -428,14 +428,21 @@ static BOOL CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB *blob,
/* Used to decode non-embedded messages */ /* Used to decode non-embedded messages */
static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject, static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType, DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{ {
CERT_BLOB fileBlob; CERT_BLOB fileBlob;
const CERT_BLOB *blob; const CERT_BLOB *blob;
BOOL ret; BOOL ret;
HCRYPTMSG msg = NULL; HCRYPTMSG msg = NULL;
DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; 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) switch (dwObjectType)
{ {
...@@ -458,17 +465,63 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject, ...@@ -458,17 +465,63 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
return FALSE; return FALSE;
ret = FALSE; ret = FALSE;
/* Try it first as a signed message */ if (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY)
if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) {
ret = CRYPT_QuerySignedMessage(blob, pdwMsgAndCertEncodingType, /* Try it first as a signed message */
pdwContentType, &msg); if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
/* Failing that, try as an unsigned message */ 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 && if (!ret &&
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)) (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED))
ret = CRYPT_QueryUnsignedMessage(blob, pdwMsgAndCertEncodingType, {
pdwContentType, &msg); 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 (ret)
{ {
if (pdwFormatType)
*pdwFormatType = formatType;
if (phMsg) if (phMsg)
*phMsg = msg; *phMsg = msg;
if (phCertStore) if (phCertStore)
...@@ -536,8 +589,9 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType, ...@@ -536,8 +589,9 @@ static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
ret = CRYPT_QueryMessageObject( ret = CRYPT_QueryMessageObject(
CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_OBJECT_BLOB, &blob,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
pdwMsgAndCertEncodingType, NULL, phCertStore, CERT_QUERY_FORMAT_FLAG_BINARY,
phMsg); pdwMsgAndCertEncodingType, NULL, NULL,
phCertStore, phMsg);
if (ret && pdwContentType) if (ret && pdwContentType)
*pdwContentType = *pdwContentType =
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED; CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED;
...@@ -630,7 +684,8 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject, ...@@ -630,7 +684,8 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))) (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)))
{ {
ret = CRYPT_QueryMessageObject(dwObjectType, pvObject, ret = CRYPT_QueryMessageObject(dwObjectType, pvObject,
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
phCertStore, phMsg); phCertStore, phMsg);
} }
if (!ret && if (!ret &&
......
...@@ -192,7 +192,6 @@ static void test_query_object(void) ...@@ -192,7 +192,6 @@ static void test_query_object(void)
ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
todo_wine
ok(ret, "CryptQueryObject failed: %08x\n", GetLastError()); ok(ret, "CryptQueryObject failed: %08x\n", GetLastError());
/* A valid signed message, encoded as a wide character base64 string, can /* A valid signed message, encoded as a wide character base64 string, can
* be queried successfully. * be queried successfully.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment