crypt32: Support base64-encoded context objects in CryptQueryObject.

This commit is contained in:
Juan Lang 2008-12-11 15:42:06 -08:00 committed by Alexandre Julliard
parent 33f0655e2a
commit 626a6fe15d
2 changed files with 74 additions and 32 deletions

View File

@ -61,15 +61,46 @@ static BOOL CRYPT_ReadBlobFromFile(LPCWSTR fileName, PCERT_BLOB blob)
return ret; return ret;
} }
static BOOL CRYPT_QueryContextBlob(const CERT_BLOB *blob,
DWORD dwExpectedContentTypeFlags, HCERTSTORE store,
DWORD *contentType, const void **ppvContext)
{
BOOL ret = FALSE;
if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT)
{
ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING,
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
if (ret && contentType)
*contentType = CERT_QUERY_CONTENT_CERT;
}
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL))
{
ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
if (ret && contentType)
*contentType = CERT_QUERY_CONTENT_CRL;
}
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
{
ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
if (ret && contentType)
*contentType = CERT_QUERY_CONTENT_CTL;
}
return ret;
}
static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject, static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject,
DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType, DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
DWORD *pdwContentType, HCERTSTORE *phCertStore, const void **ppvContext) DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
HCERTSTORE *phCertStore, const void **ppvContext)
{ {
CERT_BLOB fileBlob; CERT_BLOB fileBlob;
const CERT_BLOB *blob; const CERT_BLOB *blob;
HCERTSTORE store; HCERTSTORE store;
DWORD contentType;
BOOL ret; BOOL ret;
DWORD formatType = 0;
switch (dwObjectType) switch (dwObjectType)
{ {
@ -91,36 +122,54 @@ static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject,
if (!ret) if (!ret)
return FALSE; return FALSE;
ret = FALSE;
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL); CERT_STORE_CREATE_NEW_FLAG, NULL);
if (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY)
{
ret = CRYPT_QueryContextBlob(blob, dwExpectedContentTypeFlags, store,
pdwContentType, ppvContext);
if (ret)
formatType = CERT_QUERY_FORMAT_BINARY;
}
if (!ret &&
(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)
{
ret = CRYPT_QueryContextBlob(&decoded,
dwExpectedContentTypeFlags, store, pdwContentType,
ppvContext);
if (ret)
formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
}
CryptMemFree(decoded.pbData);
}
else
ret = FALSE; ret = FALSE;
if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT)
{
ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING,
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
if (ret)
contentType = CERT_QUERY_CONTENT_CERT;
} }
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL))
{
ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
if (ret)
contentType = CERT_QUERY_CONTENT_CRL;
}
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
{
ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
if (ret)
contentType = CERT_QUERY_CONTENT_CTL;
} }
if (ret) if (ret)
{ {
if (pdwMsgAndCertEncodingType) if (pdwMsgAndCertEncodingType)
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING; *pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
if (pdwContentType) if (pdwFormatType)
*pdwContentType = contentType; *pdwFormatType = formatType;
if (phCertStore) if (phCertStore)
*phCertStore = CertDuplicateStore(store); *phCertStore = CertDuplicateStore(store);
} }
@ -509,15 +558,9 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
if (dwExpectedContentTypeFlags & unimplementedTypes) if (dwExpectedContentTypeFlags & unimplementedTypes)
WARN("unimplemented for types %08x\n", WARN("unimplemented for types %08x\n",
dwExpectedContentTypeFlags & unimplementedTypes); dwExpectedContentTypeFlags & unimplementedTypes);
if (!(dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY))
{
FIXME("unimplemented for anything but binary\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
if (pdwFormatType) if (pdwFormatType)
*pdwFormatType = CERT_QUERY_FORMAT_BINARY; *pdwFormatType = CERT_QUERY_FORMAT_BINARY;
if (phCertStore) if (phCertStore)
*phCertStore = NULL; *phCertStore = NULL;
if (phMsg) if (phMsg)
@ -531,8 +574,9 @@ BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL)) (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
{ {
ret = CRYPT_QueryContextObject(dwObjectType, pvObject, ret = CRYPT_QueryContextObject(dwObjectType, pvObject,
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
phCertStore, ppvContext); pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
ppvContext);
} }
if (!ret && if (!ret &&
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE)) (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE))

View File

@ -152,7 +152,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());
/* The same base64-encoded cert, restricting the format types */ /* The same base64-encoded cert, restricting the format types */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
@ -165,7 +164,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_BASE64_ENCODED, 0, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED, 0,
NULL, NULL, 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());
/* The same cert, base64-encoded but as a wide character string */ /* The same cert, base64-encoded but as a wide character string */
blob.pbData = (BYTE *)bigCertBase64W; blob.pbData = (BYTE *)bigCertBase64W;