From 2f112cf5ee3957aabf8209672a7c60f4cc1dc113 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 22 Sep 2009 12:04:56 +0200 Subject: [PATCH] crypt32: CertGetCertificateChain does not validate the size of the CERT_CHAIN_PARA structure. --- dlls/crypt32/chain.c | 7 +----- dlls/crypt32/tests/chain.c | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index b22cb5b0cc4..fa9fdf0f34a 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -1567,12 +1567,7 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, SetLastError(ERROR_INVALID_DATA); return FALSE; } - if (pChainPara->cbSize != sizeof(CERT_CHAIN_PARA_NO_EXTRA_FIELDS) && - pChainPara->cbSize != sizeof(CERT_CHAIN_PARA)) - { - SetLastError(E_INVALIDARG); - return FALSE; - } + if (!hChainEngine) hChainEngine = CRYPT_GetDefaultChainEngine(); /* FIXME: what about HCCE_LOCAL_MACHINE? */ diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c index 8b4d36fbc46..a2f537cc673 100644 --- a/dlls/crypt32/tests/chain.c +++ b/dlls/crypt32/tests/chain.c @@ -1680,6 +1680,15 @@ static void testGetCertChain(void) ok(GetLastError() == ERROR_INVALID_DATA || GetLastError() == CRYPT_E_ASN1_BADTAG /* Vista */, "Expected ERROR_INVALID_DATA or CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError()); + + para.cbSize = 0; + SetLastError(0xdeadbeef); + ret = pCertGetCertificateChain(NULL, cert, NULL, NULL, ¶, 0, NULL, + &chain); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_DATA, + "Expected ERROR_INVALID_DATA, got %u\n", GetLastError()); + CertFreeCertificateContext(cert); for (i = 0; i < sizeof(chainCheck) / sizeof(chainCheck[0]); i++) @@ -1707,6 +1716,41 @@ static void testGetCertChain(void) } } +static void test_CERT_CHAIN_PARA_cbSize(void) +{ + BOOL ret; + PCCERT_CONTEXT cert; + CERT_CHAIN_PARA para = { 0 }; + PCCERT_CHAIN_CONTEXT chain; + HCERTSTORE store; + DWORD i; + + store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + + ret = CertAddEncodedCertificateToStore(store, + X509_ASN_ENCODING, chain0_0, sizeof(chain0_0), + CERT_STORE_ADD_ALWAYS, NULL); + ret = CertAddEncodedCertificateToStore(store, + X509_ASN_ENCODING, chain0_1, sizeof(chain0_1), + CERT_STORE_ADD_ALWAYS, &cert); + + for (i = 0; i < sizeof(CERT_CHAIN_PARA) + 2; i++) + { + FILETIME fileTime; + + SystemTimeToFileTime(&oct2007, &fileTime); + + para.cbSize = i; + ret = pCertGetCertificateChain(NULL, cert, &fileTime, + NULL, ¶, 0, NULL, &chain); + ok(ret, "CertGetCertificateChain failed %u\n", GetLastError()); + pCertFreeCertificateChain(chain); + } + + CertCloseStore(store, 0); +} + typedef struct _ChainPolicyCheck { CONST_BLOB_ARRAY certs; @@ -2016,5 +2060,6 @@ START_TEST(chain) { testVerifyCertChainPolicy(); testGetCertChain(); + test_CERT_CHAIN_PARA_cbSize(); } }