From ca2e1c164fcd892dfbeaa865914f97ce3ae3c1a5 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 4 Mar 2014 13:18:53 +0100 Subject: [PATCH] crypt32: Added support for HCCE_LOCAL_MACHINE. --- dlls/crypt32/chain.c | 31 +++++++++++++++++++++++-------- dlls/crypt32/crypt32_private.h | 2 +- dlls/crypt32/rootstore.c | 2 +- dlls/crypt32/tests/chain.c | 7 +++++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index ffca677d305..9e319d32114 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -112,7 +112,7 @@ static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store) return ret; } -HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, const CERT_CHAIN_ENGINE_CONFIG *config) +HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, DWORD system_store, const CERT_CHAIN_ENGINE_CONFIG *config) { CertificateChainEngine *engine; HCERTSTORE worldStores[4]; @@ -127,7 +127,7 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, const CERT_CHAIN_ENGIN else if (config->hRestrictedRoot) root = CertDuplicateStore(config->hRestrictedRoot); else - root = CertOpenSystemStoreW(0, rootW); + root = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, rootW); if(!root) return NULL; } @@ -142,9 +142,9 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, const CERT_CHAIN_ENGIN engine->hRoot = root; engine->hWorld = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); worldStores[0] = CertDuplicateStore(engine->hRoot); - worldStores[1] = CertOpenSystemStoreW(0, caW); - worldStores[2] = CertOpenSystemStoreW(0, myW); - worldStores[3] = CertOpenSystemStoreW(0, trustW); + worldStores[1] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, caW); + worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, myW); + worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, trustW); CRYPT_AddStoresToCollection(engine->hWorld, sizeof(worldStores) / sizeof(worldStores[0]), worldStores); CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore); @@ -161,7 +161,7 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, const CERT_CHAIN_ENGIN return engine; } -static CertificateChainEngine *default_cu_engine; +static CertificateChainEngine *default_cu_engine, *default_lm_engine; static CertificateChainEngine *get_chain_engine(HCERTCHAINENGINE handle, BOOL allow_default) { @@ -172,7 +172,7 @@ static CertificateChainEngine *get_chain_engine(HCERTCHAINENGINE handle, BOOL al return NULL; if(!default_cu_engine) { - handle = CRYPT_CreateChainEngine(NULL, &config); + handle = CRYPT_CreateChainEngine(NULL, CERT_SYSTEM_STORE_CURRENT_USER, &config); InterlockedCompareExchangePointer((void**)&default_cu_engine, handle, NULL); if(default_cu_engine != handle) CertFreeCertificateChainEngine(handle); @@ -181,6 +181,20 @@ static CertificateChainEngine *get_chain_engine(HCERTCHAINENGINE handle, BOOL al return default_cu_engine; } + if(handle == HCCE_LOCAL_MACHINE) { + if(!allow_default) + return NULL; + + if(!default_cu_engine) { + handle = CRYPT_CreateChainEngine(NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, &config); + InterlockedCompareExchangePointer((void**)&default_lm_engine, handle, NULL); + if(default_lm_engine != handle) + CertFreeCertificateChainEngine(handle); + } + + return default_cu_engine; + } + return (CertificateChainEngine*)handle; } @@ -228,7 +242,7 @@ BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig, return FALSE; } - *phChainEngine = CRYPT_CreateChainEngine(NULL, pConfig); + *phChainEngine = CRYPT_CreateChainEngine(NULL, CERT_SYSTEM_STORE_CURRENT_USER, pConfig); return *phChainEngine != NULL; } @@ -241,6 +255,7 @@ void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine) void default_chain_engine_free(void) { free_chain_engine(default_cu_engine); + free_chain_engine(default_lm_engine); } typedef struct _CertificateChain diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h index b582a787283..02bd902fa44 100644 --- a/dlls/crypt32/crypt32_private.h +++ b/dlls/crypt32/crypt32_private.h @@ -342,7 +342,7 @@ WINECRYPT_CERTSTORE *CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) D * the root store. Instead, it uses root, and assumes the caller has done any * checking necessary. */ -HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE, const CERT_CHAIN_ENGINE_CONFIG*) DECLSPEC_HIDDEN; +HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE, DWORD, const CERT_CHAIN_ENGINE_CONFIG*) DECLSPEC_HIDDEN; /* Helper function for store reading functions and * CertAddSerializedElementToStore. Returns a context of the appropriate type diff --git a/dlls/crypt32/rootstore.c b/dlls/crypt32/rootstore.c index 2c8af686b59..641a2b79efc 100644 --- a/dlls/crypt32/rootstore.c +++ b/dlls/crypt32/rootstore.c @@ -245,7 +245,7 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) TRACE("\n"); CertDuplicateStore(to); - engine = CRYPT_CreateChainEngine(to, &chainEngineConfig); + engine = CRYPT_CreateChainEngine(to, CERT_SYSTEM_STORE_CURRENT_USER, &chainEngineConfig); if (engine) { PCCERT_CONTEXT cert = NULL; diff --git a/dlls/crypt32/tests/chain.c b/dlls/crypt32/tests/chain.c index ec53539e88a..f69fbdc1c66 100644 --- a/dlls/crypt32/tests/chain.c +++ b/dlls/crypt32/tests/chain.c @@ -4041,6 +4041,13 @@ static void testGetCertChain(void) test_name_blob(&simple_chain->rgpElement[2]->pCertContext->pCertInfo->Subject, "US, GeoTrust Inc., GeoTrust Global CA"); pCertFreeCertificateChain(chain); + + /* Test HCCE_LOCAL_MACHINE */ + ret = CertGetCertificateChain(HCCE_LOCAL_MACHINE, cert, &fileTime, store, ¶, 0, NULL, &chain); + ok(ret, "CertGetCertificateChain failed: %u\n", GetLastError()); + pCertFreeCertificateChain(chain); + + CertFreeCertificateContext(cert); CertCloseStore(store, 0); }