Signed-off-by: Hans Leidekker hans@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(); }
Hans Leidekker hans@codeweavers.com wrote:
- 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;
- }
Is it worth a FIXME for an unhandled case?
On Fri, 2019-02-01 at 22:50 +0800, Dmitry Timoshkov wrote:
Hans Leidekker hans@codeweavers.com wrote:
- 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;
- }
Is it worth a FIXME for an unhandled case?
I decided against that because these are the only 2 supported types according to MSDN. And since this API is deprecated I don't expect new values to be added.