Jacek Caban : crypt32: Moved chain engine handle handling to separated function and improved error handling.
Alexandre Julliard
julliard at winehq.org
Tue Mar 4 14:08:51 CST 2014
Module: wine
Branch: master
Commit: 786c0c2d58284d51cc67443e27c88a0737be060c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=786c0c2d58284d51cc67443e27c88a0737be060c
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Mar 4 13:18:21 2014 +0100
crypt32: Moved chain engine handle handling to separated function and improved error handling.
---
dlls/crypt32/chain.c | 173 ++++++++++++++++++++--------------------
dlls/crypt32/crypt32_private.h | 3 +-
2 files changed, 89 insertions(+), 87 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 427db63..ffca677 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -33,8 +33,6 @@ WINE_DECLARE_DEBUG_CHANNEL(chain);
#define DEFAULT_CYCLE_MODULUS 7
-static HCERTCHAINENGINE CRYPT_defaultChainEngine;
-
/* This represents a subset of a certificate chain engine: it doesn't include
* the "hOther" store described by MSDN, because I'm not sure how that's used.
* It also doesn't include the "hTrust" store, because I don't yet implement
@@ -114,45 +112,88 @@ static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store)
return ret;
}
-HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root,
- PCERT_CHAIN_ENGINE_CONFIG pConfig)
+HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, const CERT_CHAIN_ENGINE_CONFIG *config)
{
+ CertificateChainEngine *engine;
+ HCERTSTORE worldStores[4];
+
static const WCHAR caW[] = { 'C','A',0 };
static const WCHAR myW[] = { 'M','y',0 };
static const WCHAR trustW[] = { 'T','r','u','s','t',0 };
- CertificateChainEngine *engine =
- CryptMemAlloc(sizeof(CertificateChainEngine));
-
- if (engine)
- {
- HCERTSTORE worldStores[4];
-
- engine->ref = 1;
- 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);
- CRYPT_AddStoresToCollection(engine->hWorld,
- sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
- CRYPT_AddStoresToCollection(engine->hWorld,
- pConfig->cAdditionalStore, pConfig->rghAdditionalStore);
- CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]),
- worldStores);
- engine->dwFlags = pConfig->dwFlags;
- engine->dwUrlRetrievalTimeout = pConfig->dwUrlRetrievalTimeout;
- engine->MaximumCachedCertificates =
- pConfig->MaximumCachedCertificates;
- if (pConfig->CycleDetectionModulus)
- engine->CycleDetectionModulus = pConfig->CycleDetectionModulus;
+
+ if(!root) {
+ if(config->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) && config->hExclusiveRoot)
+ root = CertDuplicateStore(config->hExclusiveRoot);
+ else if (config->hRestrictedRoot)
+ root = CertDuplicateStore(config->hRestrictedRoot);
else
- engine->CycleDetectionModulus = DEFAULT_CYCLE_MODULUS;
+ root = CertOpenSystemStoreW(0, rootW);
+ if(!root)
+ return NULL;
+ }
+
+ engine = CryptMemAlloc(sizeof(CertificateChainEngine));
+ if(!engine) {
+ CertCloseStore(root, 0);
+ return NULL;
}
+
+ engine->ref = 1;
+ 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);
+
+ CRYPT_AddStoresToCollection(engine->hWorld, sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
+ CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
+ CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
+
+ engine->dwFlags = config->dwFlags;
+ engine->dwUrlRetrievalTimeout = config->dwUrlRetrievalTimeout;
+ engine->MaximumCachedCertificates = config->MaximumCachedCertificates;
+ if(config->CycleDetectionModulus)
+ engine->CycleDetectionModulus = config->CycleDetectionModulus;
+ else
+ engine->CycleDetectionModulus = DEFAULT_CYCLE_MODULUS;
+
return engine;
}
+static CertificateChainEngine *default_cu_engine;
+
+static CertificateChainEngine *get_chain_engine(HCERTCHAINENGINE handle, BOOL allow_default)
+{
+ const CERT_CHAIN_ENGINE_CONFIG config = { sizeof(config) };
+
+ if(handle == HCCE_CURRENT_USER) {
+ if(!allow_default)
+ return NULL;
+
+ if(!default_cu_engine) {
+ handle = CRYPT_CreateChainEngine(NULL, &config);
+ InterlockedCompareExchangePointer((void**)&default_cu_engine, handle, NULL);
+ if(default_cu_engine != handle)
+ CertFreeCertificateChainEngine(handle);
+ }
+
+ return default_cu_engine;
+ }
+
+ return (CertificateChainEngine*)handle;
+}
+
+static void free_chain_engine(CertificateChainEngine *engine)
+{
+ if(!engine || InterlockedDecrement(&engine->ref))
+ return;
+
+ CertCloseStore(engine->hWorld, 0);
+ CertCloseStore(engine->hRoot, 0);
+ CryptMemFree(engine);
+}
+
typedef struct _CERT_CHAIN_ENGINE_CONFIG_NO_EXCLUSIVE_ROOT
{
DWORD cbSize;
@@ -180,66 +221,26 @@ BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig,
SetLastError(E_INVALIDARG);
return FALSE;
}
- *phChainEngine = NULL;
ret = CRYPT_CheckRestrictedRoot(pConfig->hRestrictedRoot);
- if (ret)
+ if (!ret)
{
- HCERTSTORE root;
- HCERTCHAINENGINE engine;
-
- if (pConfig->cbSize >= sizeof(CERT_CHAIN_ENGINE_CONFIG) &&
- pConfig->hExclusiveRoot)
- root = CertDuplicateStore(pConfig->hExclusiveRoot);
- else if (pConfig->hRestrictedRoot)
- root = CertDuplicateStore(pConfig->hRestrictedRoot);
- else
- root = CertOpenSystemStoreW(0, rootW);
- engine = CRYPT_CreateChainEngine(root, pConfig);
- if (engine)
- {
- *phChainEngine = engine;
- ret = TRUE;
- }
- else
- ret = FALSE;
+ *phChainEngine = NULL;
+ return FALSE;
}
- return ret;
-}
-
-VOID WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
-{
- CertificateChainEngine *engine = (CertificateChainEngine*)hChainEngine;
-
- TRACE("(%p)\n", hChainEngine);
- if (engine && InterlockedDecrement(&engine->ref) == 0)
- {
- CertCloseStore(engine->hWorld, 0);
- CertCloseStore(engine->hRoot, 0);
- CryptMemFree(engine);
- }
+ *phChainEngine = CRYPT_CreateChainEngine(NULL, pConfig);
+ return *phChainEngine != NULL;
}
-static HCERTCHAINENGINE CRYPT_GetDefaultChainEngine(void)
+void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
{
- if (!CRYPT_defaultChainEngine)
- {
- CERT_CHAIN_ENGINE_CONFIG config = { 0 };
- HCERTCHAINENGINE engine;
-
- config.cbSize = sizeof(config);
- CertCreateCertificateChainEngine(&config, &engine);
- InterlockedCompareExchangePointer(&CRYPT_defaultChainEngine, engine,
- NULL);
- if (CRYPT_defaultChainEngine != engine)
- CertFreeCertificateChainEngine(engine);
- }
- return CRYPT_defaultChainEngine;
+ TRACE("(%p)\n", hChainEngine);
+ free_chain_engine(get_chain_engine(hChainEngine, FALSE));
}
void default_chain_engine_free(void)
{
- CertFreeCertificateChainEngine(CRYPT_defaultChainEngine);
+ free_chain_engine(default_cu_engine);
}
typedef struct _CertificateChain
@@ -2867,14 +2868,18 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved,
PCCERT_CHAIN_CONTEXT* ppChainContext)
{
- CertificateChainEngine *engine = (CertificateChainEngine*)hChainEngine;
+ CertificateChainEngine *engine;
BOOL ret;
CertificateChain *chain = NULL;
- TRACE("(%p, %p, %s, %p, %p, %08x, %p, %p)\n", engine, pCertContext,
+ TRACE("(%p, %p, %s, %p, %p, %08x, %p, %p)\n", hChainEngine, pCertContext,
debugstr_filetime(pTime), hAdditionalStore, pChainPara, dwFlags,
pvReserved, ppChainContext);
+ engine = get_chain_engine(hChainEngine, TRUE);
+ if (!engine)
+ return FALSE;
+
if (ppChainContext)
*ppChainContext = NULL;
if (!pChainPara)
@@ -2888,8 +2893,6 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine,
return FALSE;
}
- if (!engine)
- engine = CRYPT_GetDefaultChainEngine();
if (TRACE_ON(chain))
dump_chain_para(pChainPara);
/* FIXME: what about HCCE_LOCAL_MACHINE? */
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 53e0834..b582a78 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -342,8 +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 root,
- PCERT_CHAIN_ENGINE_CONFIG pConfig) DECLSPEC_HIDDEN;
+HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE, const CERT_CHAIN_ENGINE_CONFIG*) DECLSPEC_HIDDEN;
/* Helper function for store reading functions and
* CertAddSerializedElementToStore. Returns a context of the appropriate type
More information about the wine-cvs
mailing list