2 * Copyright 2006 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/debug.h"
24 #include "crypt32_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
28 /* This represents a subset of a certificate chain engine: it doesn't include
29 * the "hOther" store described by MSDN, because I'm not sure how that's used.
30 * It also doesn't include the "hTrust" store, because I don't yet implement
31 * CTLs or complex certificate chains.
33 typedef struct _CertificateChainEngine
39 DWORD dwUrlRetrievalTimeout;
40 DWORD MaximumCachedCertificates;
41 DWORD CycleDetectionModulus;
42 } CertificateChainEngine, *PCertificateChainEngine;
44 static inline void CRYPT_AddStoresToCollection(HCERTSTORE collection,
45 DWORD cStores, HCERTSTORE *stores)
49 for (i = 0; i < cStores; i++)
50 CertAddStoreToCollection(collection, stores[i], 0, 0);
53 static inline void CRYPT_CloseStores(DWORD cStores, HCERTSTORE *stores)
57 for (i = 0; i < cStores; i++)
58 CertCloseStore(stores[i], 0);
61 static const WCHAR rootW[] = { 'R','o','o','t',0 };
63 static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store)
69 HCERTSTORE rootStore = CertOpenSystemStoreW(0, rootW);
70 PCCERT_CONTEXT cert = NULL, check;
75 cert = CertEnumCertificatesInStore(store, cert);
80 ret = CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID,
84 CRYPT_HASH_BLOB blob = { sizeof(hash), hash };
86 check = CertFindCertificateInStore(rootStore,
87 cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
92 CertFreeCertificateContext(check);
95 } while (ret && cert);
97 CertFreeCertificateContext(cert);
98 CertCloseStore(rootStore, 0);
103 BOOL WINAPI CertCreateCertificateChainEngine(PCERT_CHAIN_ENGINE_CONFIG pConfig,
104 HCERTCHAINENGINE *phChainEngine)
106 static const WCHAR caW[] = { 'C','A',0 };
107 static const WCHAR myW[] = { 'M','y',0 };
108 static const WCHAR trustW[] = { 'T','r','u','s','t',0 };
111 TRACE("(%p, %p)\n", pConfig, phChainEngine);
113 if (pConfig->cbSize != sizeof(*pConfig))
115 SetLastError(E_INVALIDARG);
118 *phChainEngine = NULL;
119 ret = CRYPT_CheckRestrictedRoot(pConfig->hRestrictedRoot);
122 PCertificateChainEngine engine =
123 CryptMemAlloc(sizeof(CertificateChainEngine));
127 HCERTSTORE worldStores[4];
130 if (pConfig->hRestrictedRoot)
131 engine->hRoot = CertDuplicateStore(pConfig->hRestrictedRoot);
133 engine->hRoot = CertOpenSystemStoreW(0, rootW);
134 engine->hWorld = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
135 CERT_STORE_CREATE_NEW_FLAG, NULL);
136 worldStores[0] = CertDuplicateStore(engine->hRoot);
137 worldStores[1] = CertOpenSystemStoreW(0, caW);
138 worldStores[2] = CertOpenSystemStoreW(0, myW);
139 worldStores[3] = CertOpenSystemStoreW(0, trustW);
140 CRYPT_AddStoresToCollection(engine->hWorld,
141 sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
142 CRYPT_AddStoresToCollection(engine->hWorld,
143 pConfig->cAdditionalStore, pConfig->rghAdditionalStore);
144 CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]),
146 engine->dwFlags = pConfig->dwFlags;
147 engine->dwUrlRetrievalTimeout = pConfig->dwUrlRetrievalTimeout;
148 engine->MaximumCachedCertificates =
149 pConfig->MaximumCachedCertificates;
150 engine->CycleDetectionModulus = pConfig->CycleDetectionModulus;
151 *phChainEngine = (HCERTCHAINENGINE)engine;
160 void WINAPI CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine)
162 PCertificateChainEngine engine = (PCertificateChainEngine)hChainEngine;
164 TRACE("(%p)\n", hChainEngine);
166 if (engine && InterlockedDecrement(&engine->ref) == 0)
168 CertCloseStore(engine->hWorld, 0);
169 CertCloseStore(engine->hRoot, 0);
170 CryptMemFree(engine);