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
19 #include "crypt32_private.h"
21 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
23 typedef struct _WINE_PROVIDERSTORE
25 WINECRYPT_CERTSTORE hdr
;
26 DWORD dwStoreProvFlags
;
27 WINECRYPT_CERTSTORE
*memStore
;
28 HCERTSTOREPROV hStoreProv
;
29 PFN_CERT_STORE_PROV_CLOSE provCloseStore
;
30 PFN_CERT_STORE_PROV_WRITE_CERT provWriteCert
;
31 PFN_CERT_STORE_PROV_DELETE_CERT provDeleteCert
;
32 PFN_CERT_STORE_PROV_WRITE_CRL provWriteCrl
;
33 PFN_CERT_STORE_PROV_DELETE_CRL provDeleteCrl
;
34 PFN_CERT_STORE_PROV_WRITE_CTL provWriteCtl
;
35 PFN_CERT_STORE_PROV_DELETE_CTL provDeleteCtl
;
36 PFN_CERT_STORE_PROV_CONTROL provControl
;
39 static void ProvStore_addref(WINECRYPT_CERTSTORE
*store
)
41 LONG ref
= InterlockedIncrement(&store
->ref
);
42 TRACE("ref = %d\n", ref
);
45 static DWORD
ProvStore_release(WINECRYPT_CERTSTORE
*cert_store
, DWORD flags
)
47 WINE_PROVIDERSTORE
*store
= (WINE_PROVIDERSTORE
*)cert_store
;
51 FIXME("Unimplemented flags %x\n", flags
);
53 ref
= InterlockedDecrement(&store
->hdr
.ref
);
54 TRACE("(%p) ref=%d\n", store
, ref
);
59 if (store
->provCloseStore
)
60 store
->provCloseStore(store
->hStoreProv
, flags
);
61 if (!(store
->dwStoreProvFlags
& CERT_STORE_PROV_EXTERNAL_FLAG
))
62 store
->memStore
->vtbl
->release(store
->memStore
, flags
);
63 CRYPT_FreeStore(&store
->hdr
);
67 static void ProvStore_releaseContext(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
69 /* As long as we don't have contexts properly stored (and hack around hCertStore
70 in add* and enum* functions), this function should never be called. */
74 static BOOL
ProvStore_addCert(WINECRYPT_CERTSTORE
*store
, context_t
*cert
,
75 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
77 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
80 TRACE("(%p, %p, %p, %p)\n", store
, cert
, toReplace
, ppStoreContext
);
83 ret
= ps
->memStore
->vtbl
->certs
.addContext(ps
->memStore
, cert
, toReplace
,
84 ppStoreContext
, TRUE
);
88 if (ps
->provWriteCert
)
89 ret
= ps
->provWriteCert(ps
->hStoreProv
, context_ptr(cert
), CERT_STORE_PROV_WRITE_ADD_FLAG
);
91 ret
= ps
->memStore
->vtbl
->certs
.addContext(ps
->memStore
, cert
, NULL
,
92 ppStoreContext
, TRUE
);
94 /* dirty trick: replace the returned context's hCertStore with
97 if (ret
&& ppStoreContext
)
98 (*(cert_t
**)ppStoreContext
)->ctx
.hCertStore
= store
;
102 static context_t
*ProvStore_enumCert(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
104 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
107 ret
= (cert_t
*)ps
->memStore
->vtbl
->certs
.enumContext(ps
->memStore
, prev
);
111 /* same dirty trick: replace the returned context's hCertStore with
114 ret
->ctx
.hCertStore
= store
;
118 static BOOL
ProvStore_deleteCert(WINECRYPT_CERTSTORE
*store
, context_t
*context
)
120 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
123 TRACE("(%p, %p)\n", store
, context
);
125 if (ps
->provDeleteCert
)
126 ret
= ps
->provDeleteCert(ps
->hStoreProv
, context_ptr(context
), 0);
128 ret
= ps
->memStore
->vtbl
->certs
.delete(ps
->memStore
, context
);
132 static BOOL
ProvStore_addCRL(WINECRYPT_CERTSTORE
*store
, context_t
*crl
,
133 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
135 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
138 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
141 ret
= ps
->memStore
->vtbl
->crls
.addContext(ps
->memStore
, crl
, toReplace
,
142 ppStoreContext
, TRUE
);
145 if (ps
->hdr
.dwOpenFlags
& CERT_STORE_READONLY_FLAG
)
147 SetLastError(ERROR_ACCESS_DENIED
);
153 if (ps
->provWriteCrl
)
154 ret
= ps
->provWriteCrl(ps
->hStoreProv
, context_ptr(crl
),
155 CERT_STORE_PROV_WRITE_ADD_FLAG
);
157 ret
= ps
->memStore
->vtbl
->crls
.addContext(ps
->memStore
, crl
, NULL
,
158 ppStoreContext
, TRUE
);
161 /* dirty trick: replace the returned context's hCertStore with
164 if (ret
&& ppStoreContext
)
165 (*(crl_t
**)ppStoreContext
)->ctx
.hCertStore
= store
;
169 static context_t
*ProvStore_enumCRL(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
171 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
174 ret
= (crl_t
*)ps
->memStore
->vtbl
->crls
.enumContext(ps
->memStore
, prev
);
178 /* same dirty trick: replace the returned context's hCertStore with
181 ret
->ctx
.hCertStore
= store
;
185 static BOOL
ProvStore_deleteCRL(WINECRYPT_CERTSTORE
*store
, context_t
*crl
)
187 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
190 TRACE("(%p, %p)\n", store
, crl
);
192 if (ps
->provDeleteCrl
)
193 ret
= ps
->provDeleteCrl(ps
->hStoreProv
, context_ptr(crl
), 0);
195 ret
= ps
->memStore
->vtbl
->crls
.delete(ps
->memStore
, crl
);
199 static BOOL
ProvStore_addCTL(WINECRYPT_CERTSTORE
*store
, context_t
*ctl
,
200 context_t
*toReplace
, context_t
**ppStoreContext
, BOOL use_link
)
202 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
205 TRACE("(%p, %p, %p, %p)\n", store
, ctl
, toReplace
, ppStoreContext
);
208 ret
= ps
->memStore
->vtbl
->ctls
.addContext(ps
->memStore
, ctl
, toReplace
,
209 ppStoreContext
, TRUE
);
212 if (ps
->hdr
.dwOpenFlags
& CERT_STORE_READONLY_FLAG
)
214 SetLastError(ERROR_ACCESS_DENIED
);
220 if (ps
->provWriteCtl
)
221 ret
= ps
->provWriteCtl(ps
->hStoreProv
, context_ptr(ctl
),
222 CERT_STORE_PROV_WRITE_ADD_FLAG
);
224 ret
= ps
->memStore
->vtbl
->ctls
.addContext(ps
->memStore
, ctl
, NULL
,
225 ppStoreContext
, TRUE
);
228 /* dirty trick: replace the returned context's hCertStore with
231 if (ret
&& ppStoreContext
)
232 (*(ctl_t
**)ppStoreContext
)->ctx
.hCertStore
= store
;
236 static context_t
*ProvStore_enumCTL(WINECRYPT_CERTSTORE
*store
, context_t
*prev
)
238 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
241 ret
= (ctl_t
*)ps
->memStore
->vtbl
->ctls
.enumContext(ps
->memStore
, prev
);
245 /* same dirty trick: replace the returned context's hCertStore with
248 ret
->ctx
.hCertStore
= store
;
252 static BOOL
ProvStore_deleteCTL(WINECRYPT_CERTSTORE
*store
, context_t
*ctl
)
254 WINE_PROVIDERSTORE
*ps
= (WINE_PROVIDERSTORE
*)store
;
257 TRACE("(%p, %p)\n", store
, ctl
);
259 if (ps
->provDeleteCtl
)
260 ret
= ps
->provDeleteCtl(ps
->hStoreProv
, context_ptr(ctl
), 0);
262 ret
= ps
->memStore
->vtbl
->ctls
.delete(ps
->memStore
, ctl
);
266 static BOOL
ProvStore_control(WINECRYPT_CERTSTORE
*cert_store
, DWORD dwFlags
, DWORD dwCtrlType
, void const *pvCtrlPara
)
268 WINE_PROVIDERSTORE
*store
= (WINE_PROVIDERSTORE
*)cert_store
;
271 TRACE("(%p, %08x, %d, %p)\n", store
, dwFlags
, dwCtrlType
,
274 if (store
->provControl
)
275 ret
= store
->provControl(store
->hStoreProv
, dwFlags
, dwCtrlType
,
280 static const store_vtbl_t ProvStoreVtbl
= {
283 ProvStore_releaseContext
,
300 WINECRYPT_CERTSTORE
*CRYPT_ProvCreateStore(DWORD dwFlags
,
301 WINECRYPT_CERTSTORE
*memStore
, const CERT_STORE_PROV_INFO
*pProvInfo
)
303 WINE_PROVIDERSTORE
*ret
= CryptMemAlloc(sizeof(WINE_PROVIDERSTORE
));
307 CRYPT_InitStore(&ret
->hdr
, dwFlags
, StoreTypeProvider
, &ProvStoreVtbl
);
308 ret
->dwStoreProvFlags
= pProvInfo
->dwStoreProvFlags
;
309 if (ret
->dwStoreProvFlags
& CERT_STORE_PROV_EXTERNAL_FLAG
)
311 CertCloseStore(memStore
, 0);
312 ret
->memStore
= NULL
;
315 ret
->memStore
= memStore
;
316 ret
->hStoreProv
= pProvInfo
->hStoreProv
;
317 if (pProvInfo
->cStoreProvFunc
> CERT_STORE_PROV_CLOSE_FUNC
)
318 ret
->provCloseStore
=
319 pProvInfo
->rgpvStoreProvFunc
[CERT_STORE_PROV_CLOSE_FUNC
];
321 ret
->provCloseStore
= NULL
;
322 if (pProvInfo
->cStoreProvFunc
>
323 CERT_STORE_PROV_WRITE_CERT_FUNC
)
324 ret
->provWriteCert
= pProvInfo
->rgpvStoreProvFunc
[
325 CERT_STORE_PROV_WRITE_CERT_FUNC
];
327 ret
->provWriteCert
= NULL
;
328 if (pProvInfo
->cStoreProvFunc
>
329 CERT_STORE_PROV_DELETE_CERT_FUNC
)
330 ret
->provDeleteCert
= pProvInfo
->rgpvStoreProvFunc
[
331 CERT_STORE_PROV_DELETE_CERT_FUNC
];
333 ret
->provDeleteCert
= NULL
;
334 if (pProvInfo
->cStoreProvFunc
>
335 CERT_STORE_PROV_WRITE_CRL_FUNC
)
336 ret
->provWriteCrl
= pProvInfo
->rgpvStoreProvFunc
[
337 CERT_STORE_PROV_WRITE_CRL_FUNC
];
339 ret
->provWriteCrl
= NULL
;
340 if (pProvInfo
->cStoreProvFunc
>
341 CERT_STORE_PROV_DELETE_CRL_FUNC
)
342 ret
->provDeleteCrl
= pProvInfo
->rgpvStoreProvFunc
[
343 CERT_STORE_PROV_DELETE_CRL_FUNC
];
345 ret
->provDeleteCrl
= NULL
;
346 if (pProvInfo
->cStoreProvFunc
>
347 CERT_STORE_PROV_WRITE_CTL_FUNC
)
348 ret
->provWriteCtl
= pProvInfo
->rgpvStoreProvFunc
[
349 CERT_STORE_PROV_WRITE_CTL_FUNC
];
351 ret
->provWriteCtl
= NULL
;
352 if (pProvInfo
->cStoreProvFunc
>
353 CERT_STORE_PROV_DELETE_CTL_FUNC
)
354 ret
->provDeleteCtl
= pProvInfo
->rgpvStoreProvFunc
[
355 CERT_STORE_PROV_DELETE_CTL_FUNC
];
357 ret
->provDeleteCtl
= NULL
;
358 if (pProvInfo
->cStoreProvFunc
>
359 CERT_STORE_PROV_CONTROL_FUNC
)
360 ret
->provControl
= pProvInfo
->rgpvStoreProvFunc
[
361 CERT_STORE_PROV_CONTROL_FUNC
];
363 ret
->provControl
= NULL
;
365 return (WINECRYPT_CERTSTORE
*)ret
;
368 WINECRYPT_CERTSTORE
*CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider
,
369 DWORD dwEncodingType
, HCRYPTPROV hCryptProv
, DWORD dwFlags
, const void *pvPara
)
371 static HCRYPTOIDFUNCSET set
= NULL
;
372 PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc
;
373 HCRYPTOIDFUNCADDR hFunc
;
374 WINECRYPT_CERTSTORE
*ret
= NULL
;
377 set
= CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC
, 0);
378 CryptGetOIDFunctionAddress(set
, dwEncodingType
, lpszStoreProvider
, 0,
379 (void **)&provOpenFunc
, &hFunc
);
382 CERT_STORE_PROV_INFO provInfo
= { 0 };
384 provInfo
.cbSize
= sizeof(provInfo
);
385 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
386 provOpenFunc(lpszStoreProvider
, dwEncodingType
, hCryptProv
,
387 dwFlags
, pvPara
, NULL
, &provInfo
);
392 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
393 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
396 if (provOpenFunc(lpszStoreProvider
, dwEncodingType
, hCryptProv
,
397 dwFlags
, pvPara
, memStore
, &provInfo
))
398 ret
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
400 CertCloseStore(memStore
, 0);
403 CryptFreeOIDFunctionAddress(hFunc
, 0);
406 SetLastError(ERROR_FILE_NOT_FOUND
);