2 * Copyright 2004-2007 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
22 #include "wine/debug.h"
23 #include "wine/list.h"
24 #include "crypt32_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
28 typedef struct _WINE_PROVIDERSTORE
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_WRITE_CTL provWriteCtl
;
40 PFN_CERT_STORE_PROV_DELETE_CTL provDeleteCtl
;
41 PFN_CERT_STORE_PROV_CONTROL provControl
;
42 } WINE_PROVIDERSTORE
, *PWINE_PROVIDERSTORE
;
44 static void WINAPI
CRYPT_ProvCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
46 PWINE_PROVIDERSTORE store
= (PWINE_PROVIDERSTORE
)hCertStore
;
48 TRACE("(%p, %08x)\n", store
, dwFlags
);
50 if (store
->provCloseStore
)
51 store
->provCloseStore(store
->hStoreProv
, dwFlags
);
52 if (!(store
->dwStoreProvFlags
& CERT_STORE_PROV_EXTERNAL_FLAG
))
53 CertCloseStore(store
->memStore
, dwFlags
);
54 CRYPT_FreeStore((PWINECRYPT_CERTSTORE
)store
);
57 static BOOL
CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store
, void *cert
,
58 void *toReplace
, const void **ppStoreContext
)
60 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
63 TRACE("(%p, %p, %p, %p)\n", store
, cert
, toReplace
, ppStoreContext
);
66 ret
= ps
->memStore
->certs
.addContext(ps
->memStore
, cert
, toReplace
,
71 if (ps
->provWriteCert
)
72 ret
= ps
->provWriteCert(ps
->hStoreProv
, (PCCERT_CONTEXT
)cert
,
73 CERT_STORE_PROV_WRITE_ADD_FLAG
);
75 ret
= ps
->memStore
->certs
.addContext(ps
->memStore
, cert
, NULL
,
78 /* dirty trick: replace the returned context's hCertStore with
81 if (ret
&& ppStoreContext
)
82 (*(PCERT_CONTEXT
*)ppStoreContext
)->hCertStore
= store
;
86 static void *CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store
, void *pPrev
)
88 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
91 ret
= ps
->memStore
->certs
.enumContext(ps
->memStore
, pPrev
);
94 /* same dirty trick: replace the returned context's hCertStore with
97 ((PCERT_CONTEXT
)ret
)->hCertStore
= store
;
102 static BOOL
CRYPT_ProvDeleteCert(PWINECRYPT_CERTSTORE store
, void *cert
)
104 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
107 TRACE("(%p, %p)\n", store
, cert
);
109 if (ps
->provDeleteCert
)
110 ret
= ps
->provDeleteCert(ps
->hStoreProv
, cert
, 0);
112 ret
= ps
->memStore
->certs
.deleteContext(ps
->memStore
, cert
);
116 static BOOL
CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store
, void *crl
,
117 void *toReplace
, const void **ppStoreContext
)
119 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
122 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
125 ret
= ps
->memStore
->crls
.addContext(ps
->memStore
, crl
, toReplace
,
129 if (ps
->hdr
.dwOpenFlags
& CERT_STORE_READONLY_FLAG
)
131 SetLastError(ERROR_ACCESS_DENIED
);
137 if (ps
->provWriteCrl
)
138 ret
= ps
->provWriteCrl(ps
->hStoreProv
, (PCCRL_CONTEXT
)crl
,
139 CERT_STORE_PROV_WRITE_ADD_FLAG
);
141 ret
= ps
->memStore
->crls
.addContext(ps
->memStore
, crl
, NULL
,
145 /* dirty trick: replace the returned context's hCertStore with
148 if (ret
&& ppStoreContext
)
149 (*(PCRL_CONTEXT
*)ppStoreContext
)->hCertStore
= store
;
153 static void *CRYPT_ProvEnumCRL(PWINECRYPT_CERTSTORE store
, void *pPrev
)
155 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
158 ret
= ps
->memStore
->crls
.enumContext(ps
->memStore
, pPrev
);
161 /* same dirty trick: replace the returned context's hCertStore with
164 ((PCRL_CONTEXT
)ret
)->hCertStore
= store
;
169 static BOOL
CRYPT_ProvDeleteCRL(PWINECRYPT_CERTSTORE store
, void *crl
)
171 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
174 TRACE("(%p, %p)\n", store
, crl
);
176 if (ps
->provDeleteCrl
)
177 ret
= ps
->provDeleteCrl(ps
->hStoreProv
, crl
, 0);
179 ret
= ps
->memStore
->crls
.deleteContext(ps
->memStore
, crl
);
183 static BOOL
CRYPT_ProvAddCTL(PWINECRYPT_CERTSTORE store
, void *ctl
,
184 void *toReplace
, const void **ppStoreContext
)
186 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
189 TRACE("(%p, %p, %p, %p)\n", store
, ctl
, toReplace
, ppStoreContext
);
192 ret
= ps
->memStore
->ctls
.addContext(ps
->memStore
, ctl
, toReplace
,
196 if (ps
->hdr
.dwOpenFlags
& CERT_STORE_READONLY_FLAG
)
198 SetLastError(ERROR_ACCESS_DENIED
);
204 if (ps
->provWriteCtl
)
205 ret
= ps
->provWriteCtl(ps
->hStoreProv
, (PCCTL_CONTEXT
)ctl
,
206 CERT_STORE_PROV_WRITE_ADD_FLAG
);
208 ret
= ps
->memStore
->ctls
.addContext(ps
->memStore
, ctl
, NULL
,
212 /* dirty trick: replace the returned context's hCertStore with
215 if (ret
&& ppStoreContext
)
216 (*(PCTL_CONTEXT
*)ppStoreContext
)->hCertStore
= store
;
220 static void *CRYPT_ProvEnumCTL(PWINECRYPT_CERTSTORE store
, void *pPrev
)
222 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
225 ret
= ps
->memStore
->ctls
.enumContext(ps
->memStore
, pPrev
);
228 /* same dirty trick: replace the returned context's hCertStore with
231 ((PCTL_CONTEXT
)ret
)->hCertStore
= store
;
236 static BOOL
CRYPT_ProvDeleteCTL(PWINECRYPT_CERTSTORE store
, void *ctl
)
238 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
241 TRACE("(%p, %p)\n", store
, ctl
);
243 if (ps
->provDeleteCtl
)
244 ret
= ps
->provDeleteCtl(ps
->hStoreProv
, ctl
, 0);
246 ret
= ps
->memStore
->ctls
.deleteContext(ps
->memStore
, ctl
);
250 static BOOL WINAPI
CRYPT_ProvControl(HCERTSTORE hCertStore
, DWORD dwFlags
,
251 DWORD dwCtrlType
, void const *pvCtrlPara
)
253 PWINE_PROVIDERSTORE store
= (PWINE_PROVIDERSTORE
)hCertStore
;
256 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
259 if (store
->provControl
)
260 ret
= store
->provControl(store
->hStoreProv
, dwFlags
, dwCtrlType
,
265 PWINECRYPT_CERTSTORE
CRYPT_ProvCreateStore(DWORD dwFlags
,
266 PWINECRYPT_CERTSTORE memStore
, const CERT_STORE_PROV_INFO
*pProvInfo
)
268 PWINE_PROVIDERSTORE ret
= CryptMemAlloc(sizeof(WINE_PROVIDERSTORE
));
272 CRYPT_InitStore(&ret
->hdr
, dwFlags
, StoreTypeProvider
);
273 ret
->dwStoreProvFlags
= pProvInfo
->dwStoreProvFlags
;
274 if (ret
->dwStoreProvFlags
& CERT_STORE_PROV_EXTERNAL_FLAG
)
276 CertCloseStore(memStore
, 0);
277 ret
->memStore
= NULL
;
280 ret
->memStore
= memStore
;
281 ret
->hStoreProv
= pProvInfo
->hStoreProv
;
282 ret
->hdr
.closeStore
= CRYPT_ProvCloseStore
;
283 ret
->hdr
.certs
.addContext
= CRYPT_ProvAddCert
;
284 ret
->hdr
.certs
.enumContext
= CRYPT_ProvEnumCert
;
285 ret
->hdr
.certs
.deleteContext
= CRYPT_ProvDeleteCert
;
286 ret
->hdr
.crls
.addContext
= CRYPT_ProvAddCRL
;
287 ret
->hdr
.crls
.enumContext
= CRYPT_ProvEnumCRL
;
288 ret
->hdr
.crls
.deleteContext
= CRYPT_ProvDeleteCRL
;
289 ret
->hdr
.ctls
.addContext
= CRYPT_ProvAddCTL
;
290 ret
->hdr
.ctls
.enumContext
= CRYPT_ProvEnumCTL
;
291 ret
->hdr
.ctls
.deleteContext
= CRYPT_ProvDeleteCTL
;
292 ret
->hdr
.control
= CRYPT_ProvControl
;
293 if (pProvInfo
->cStoreProvFunc
> CERT_STORE_PROV_CLOSE_FUNC
)
294 ret
->provCloseStore
=
295 pProvInfo
->rgpvStoreProvFunc
[CERT_STORE_PROV_CLOSE_FUNC
];
297 ret
->provCloseStore
= NULL
;
298 if (pProvInfo
->cStoreProvFunc
>
299 CERT_STORE_PROV_WRITE_CERT_FUNC
)
300 ret
->provWriteCert
= pProvInfo
->rgpvStoreProvFunc
[
301 CERT_STORE_PROV_WRITE_CERT_FUNC
];
303 ret
->provWriteCert
= NULL
;
304 if (pProvInfo
->cStoreProvFunc
>
305 CERT_STORE_PROV_DELETE_CERT_FUNC
)
306 ret
->provDeleteCert
= pProvInfo
->rgpvStoreProvFunc
[
307 CERT_STORE_PROV_DELETE_CERT_FUNC
];
309 ret
->provDeleteCert
= NULL
;
310 if (pProvInfo
->cStoreProvFunc
>
311 CERT_STORE_PROV_WRITE_CRL_FUNC
)
312 ret
->provWriteCrl
= pProvInfo
->rgpvStoreProvFunc
[
313 CERT_STORE_PROV_WRITE_CRL_FUNC
];
315 ret
->provWriteCrl
= NULL
;
316 if (pProvInfo
->cStoreProvFunc
>
317 CERT_STORE_PROV_DELETE_CRL_FUNC
)
318 ret
->provDeleteCrl
= pProvInfo
->rgpvStoreProvFunc
[
319 CERT_STORE_PROV_DELETE_CRL_FUNC
];
321 ret
->provDeleteCrl
= NULL
;
322 if (pProvInfo
->cStoreProvFunc
>
323 CERT_STORE_PROV_WRITE_CTL_FUNC
)
324 ret
->provWriteCtl
= pProvInfo
->rgpvStoreProvFunc
[
325 CERT_STORE_PROV_WRITE_CTL_FUNC
];
327 ret
->provWriteCtl
= NULL
;
328 if (pProvInfo
->cStoreProvFunc
>
329 CERT_STORE_PROV_DELETE_CTL_FUNC
)
330 ret
->provDeleteCtl
= pProvInfo
->rgpvStoreProvFunc
[
331 CERT_STORE_PROV_DELETE_CTL_FUNC
];
333 ret
->provDeleteCtl
= NULL
;
334 if (pProvInfo
->cStoreProvFunc
>
335 CERT_STORE_PROV_CONTROL_FUNC
)
336 ret
->provControl
= pProvInfo
->rgpvStoreProvFunc
[
337 CERT_STORE_PROV_CONTROL_FUNC
];
339 ret
->provControl
= NULL
;
341 return (PWINECRYPT_CERTSTORE
)ret
;
344 PWINECRYPT_CERTSTORE
CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider
,
345 DWORD dwEncodingType
, HCRYPTPROV hCryptProv
, DWORD dwFlags
, const void *pvPara
)
347 static HCRYPTOIDFUNCSET set
= NULL
;
348 PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc
;
349 HCRYPTOIDFUNCADDR hFunc
;
350 PWINECRYPT_CERTSTORE ret
= NULL
;
353 set
= CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC
, 0);
354 CryptGetOIDFunctionAddress(set
, dwEncodingType
, lpszStoreProvider
, 0,
355 (void **)&provOpenFunc
, &hFunc
);
358 CERT_STORE_PROV_INFO provInfo
= { 0 };
360 provInfo
.cbSize
= sizeof(provInfo
);
361 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
362 provOpenFunc(lpszStoreProvider
, dwEncodingType
, hCryptProv
,
363 dwFlags
, pvPara
, NULL
, &provInfo
);
368 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
369 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
372 if (provOpenFunc(lpszStoreProvider
, dwEncodingType
, hCryptProv
,
373 dwFlags
, pvPara
, memStore
, &provInfo
))
374 ret
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
376 CertCloseStore(memStore
, 0);
379 CryptFreeOIDFunctionAddress(hFunc
, 0);
382 SetLastError(ERROR_FILE_NOT_FOUND
);