1 /*
2 * Copyright 2004-2007 Juan Lang
3 *
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.
8 *
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.
13 *
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
17 */
18 #include <stdarg.h>
19 #include "windef.h"
20 #include "winbase.h"
21 #include "wincrypt.h"
22 #include "wine/debug.h"
23 #include "wine/list.h"
24 #include "crypt32_private.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
27
28 typedef struct _WINE_PROVIDERSTORE
29 {
30 WINECRYPT_CERTSTORE hdr;
31 DWORD dwStoreProvFlags;
32 PWINECRYPT_CERTSTORE memStore;
33 HCERTSTOREPROV hStoreProv;
34 PFN_CERT_STORE_PROV_CLOSE provCloseStore;
35 PFN_CERT_STORE_PROV_WRITE_CERT provWriteCert;
36 PFN_CERT_STORE_PROV_DELETE_CERT provDeleteCert;
37 PFN_CERT_STORE_PROV_WRITE_CRL provWriteCrl;
38 PFN_CERT_STORE_PROV_DELETE_CRL provDeleteCrl;
39 PFN_CERT_STORE_PROV_CONTROL provControl;
40 } WINE_PROVIDERSTORE, *PWINE_PROVIDERSTORE;
41
42 static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
43 {
44 PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
45
46 TRACE("(%p, %08x)\n", store, dwFlags);
47
48 if (store->provCloseStore)
49 store->provCloseStore(store->hStoreProv, dwFlags);
50 if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
51 CertCloseStore(store->memStore, dwFlags);
52 CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
53 }
54
55 static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
56 void *toReplace, const void **ppStoreContext)
57 {
58 PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
59 BOOL ret;
60
61 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
62
63 if (toReplace)
64 ret = ps->memStore->certs.addContext(ps->memStore, cert, toReplace,
65 ppStoreContext);
66 else
67 {
68 ret = TRUE;
69 if (ps->provWriteCert)
70 ret = ps->provWriteCert(ps->hStoreProv, (PCCERT_CONTEXT)cert,
71 CERT_STORE_PROV_WRITE_ADD_FLAG);
72 if (ret)
73 ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL,
74 ppStoreContext);
75 }
76 /* dirty trick: replace the returned context's hCertStore with
77 * store.
78 */
79 if (ppStoreContext)
80 (*(PCERT_CONTEXT *)ppStoreContext)->hCertStore = store;
81 return ret;
82 }
83
84 static void *CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
85 {
86 PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
87 void *ret;
88
89 ret = ps->memStore->certs.enumContext(ps->memStore, pPrev);
90 if (ret)
91 {
92 /* same dirty trick: replace the returned context's hCertStore with
93 * store.
94 */
95 ((PCERT_CONTEXT)ret)->hCertStore = store;
96 }
97 return ret;
98 }
99
100 static BOOL CRYPT_ProvDeleteCert(PWINECRYPT_CERTSTORE store, void *cert)
101 {
102 PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
103 BOOL ret = TRUE;
104
105 TRACE("(%p, %p)\n", store, cert);
106
107 if (ps->provDeleteCert)
108 ret = ps->provDeleteCert(ps->hStoreProv, cert, 0);
109 if (ret)
110 ret = ps->memStore->certs.deleteContext(ps->memStore, cert);
111 return ret;
112 }
113
114 static BOOL CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
115 void *toReplace, const void **ppStoreContext)
116 {
117 PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
118 BOOL ret;
119
120 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
121
122 if (toReplace)
123 ret = ps->memStore->crls.addContext(ps->memStore, crl, toReplace,
124 ppStoreContext);
125 else
126 {
127 if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
128 {
129 SetLastError(ERROR_ACCESS_DENIED);
130 ret = FALSE;
131 }
132 else
133 {
134 ret = TRUE;
135 if (ps->provWriteCrl)
136 ret = ps->provWriteCrl(ps->hStoreProv, (PCCRL_CONTEXT)crl,
137 CERT_STORE_PROV_WRITE_ADD_FLAG);
138 if (ret)
139 ret = ps->memStore->crls.addContext(ps->memStore, crl, NULL,
140 ppStoreContext);
141 }
142 }
143 /* dirty trick: replace the returned context's hCertStore with
144 * store.
145 */
146 if (ppStoreContext)
147 (*(PCRL_CONTEXT *)ppStoreContext)->hCertStore = store;
148 return ret;
149 }
150
151 static void *CRYPT_ProvEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
152 {
153 PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
154 void *ret;
155
156 ret = ps->memStore->crls.enumContext(ps->memStore, pPrev);
157 if (ret)
158 {
159 /* same dirty trick: replace the returned context's hCertStore with
160 * store.
161 */
162 ((PCRL_CONTEXT)ret)->hCertStore = store;
163 }
164 return ret;
165 }
166
167 static BOOL CRYPT_ProvDeleteCRL(PWINECRYPT_CERTSTORE store, void *crl)
168 {
169 PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
170 BOOL ret = TRUE;
171
172 TRACE("(%p, %p)\n", store, crl);
173
174 if (ps->provDeleteCrl)
175 ret = ps->provDeleteCrl(ps->hStoreProv, crl, 0);
176 if (ret)
177 ret = ps->memStore->crls.deleteContext(ps->memStore, crl);
178 return ret;
179 }
180
181 static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
182 DWORD dwCtrlType, void const *pvCtrlPara)
183 {
184 PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
185 BOOL ret = TRUE;
186
187 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
188 pvCtrlPara);
189
190 if (store->provControl)
191 ret = store->provControl(store->hStoreProv, dwFlags, dwCtrlType,
192 pvCtrlPara);
193 return ret;
194 }
195
196 PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
197 PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo)
198 {
199 PWINE_PROVIDERSTORE ret = CryptMemAlloc(sizeof(WINE_PROVIDERSTORE));
200
201 if (ret)
202 {
203 CRYPT_InitStore(&ret->hdr, dwFlags, StoreTypeProvider);
204 ret->dwStoreProvFlags = pProvInfo->dwStoreProvFlags;
205 if (ret->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG)
206 {
207 CertCloseStore(memStore, 0);
208 ret->memStore = NULL;
209 }
210 else
211 ret->memStore = memStore;
212 ret->hStoreProv = pProvInfo->hStoreProv;
213 ret->hdr.closeStore = CRYPT_ProvCloseStore;
214 ret->hdr.certs.addContext = CRYPT_ProvAddCert;
215 ret->hdr.certs.enumContext = CRYPT_ProvEnumCert;
216 ret->hdr.certs.deleteContext = CRYPT_ProvDeleteCert;
217 ret->hdr.crls.addContext = CRYPT_ProvAddCRL;
218 ret->hdr.crls.enumContext = CRYPT_ProvEnumCRL;
219 ret->hdr.crls.deleteContext = CRYPT_ProvDeleteCRL;
220 ret->hdr.control = CRYPT_ProvControl;
221 if (pProvInfo->cStoreProvFunc > CERT_STORE_PROV_CLOSE_FUNC)
222 ret->provCloseStore =
223 pProvInfo->rgpvStoreProvFunc[CERT_STORE_PROV_CLOSE_FUNC];
224 else
225 ret->provCloseStore = NULL;
226 if (pProvInfo->cStoreProvFunc >
227 CERT_STORE_PROV_WRITE_CERT_FUNC)
228 ret->provWriteCert = pProvInfo->rgpvStoreProvFunc[
229 CERT_STORE_PROV_WRITE_CERT_FUNC];
230 else
231 ret->provWriteCert = NULL;
232 if (pProvInfo->cStoreProvFunc >
233 CERT_STORE_PROV_DELETE_CERT_FUNC)
234 ret->provDeleteCert = pProvInfo->rgpvStoreProvFunc[
235 CERT_STORE_PROV_DELETE_CERT_FUNC];
236 else
237 ret->provDeleteCert = NULL;
238 if (pProvInfo->cStoreProvFunc >
239 CERT_STORE_PROV_WRITE_CRL_FUNC)
240 ret->provWriteCrl = pProvInfo->rgpvStoreProvFunc[
241 CERT_STORE_PROV_WRITE_CRL_FUNC];
242 else
243 ret->provWriteCert = NULL;
244 if (pProvInfo->cStoreProvFunc >
245 CERT_STORE_PROV_DELETE_CRL_FUNC)
246 ret->provDeleteCrl = pProvInfo->rgpvStoreProvFunc[
247 CERT_STORE_PROV_DELETE_CRL_FUNC];
248 else
249 ret->provDeleteCert = NULL;
250 if (pProvInfo->cStoreProvFunc >
251 CERT_STORE_PROV_CONTROL_FUNC)
252 ret->provControl = pProvInfo->rgpvStoreProvFunc[
253 CERT_STORE_PROV_CONTROL_FUNC];
254 else
255 ret->provControl = NULL;
256 }
257 return (PWINECRYPT_CERTSTORE)ret;
258 }
259
260 PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
261 DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
262 {
263 static HCRYPTOIDFUNCSET set = NULL;
264 PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc;
265 HCRYPTOIDFUNCADDR hFunc;
266 PWINECRYPT_CERTSTORE ret = NULL;
267
268 if (!set)
269 set = CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC, 0);
270 CryptGetOIDFunctionAddress(set, dwEncodingType, lpszStoreProvider, 0,
271 (void **)&provOpenFunc, &hFunc);
272 if (provOpenFunc)
273 {
274 CERT_STORE_PROV_INFO provInfo = { 0 };
275
276 provInfo.cbSize = sizeof(provInfo);
277 if (dwFlags & CERT_STORE_DELETE_FLAG)
278 provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
279 dwFlags, pvPara, NULL, &provInfo);
280 else
281 {
282 HCERTSTORE memStore;
283
284 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
285 CERT_STORE_CREATE_NEW_FLAG, NULL);
286 if (memStore)
287 {
288 if (provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
289 dwFlags, pvPara, memStore, &provInfo))
290 ret = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
291 else
292 CertCloseStore(memStore, 0);
293 }
294 }
295 CryptFreeOIDFunctionAddress(hFunc, 0);
296 }
297 else
298 SetLastError(ERROR_FILE_NOT_FOUND);
299 return ret;
300 }
301
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.