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_CONTROL provControl
;
40 } WINE_PROVIDERSTORE
, *PWINE_PROVIDERSTORE
;
42 static void WINAPI
CRYPT_ProvCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
44 PWINE_PROVIDERSTORE store
= (PWINE_PROVIDERSTORE
)hCertStore
;
46 TRACE("(%p, %08x)\n", store
, dwFlags
);
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
);
55 static BOOL
CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store
, void *cert
,
56 void *toReplace
, const void **ppStoreContext
)
58 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
61 TRACE("(%p, %p, %p, %p)\n", store
, cert
, toReplace
, ppStoreContext
);
64 ret
= ps
->memStore
->certs
.addContext(ps
->memStore
, cert
, toReplace
,
69 if (ps
->provWriteCert
)
70 ret
= ps
->provWriteCert(ps
->hStoreProv
, (PCCERT_CONTEXT
)cert
,
71 CERT_STORE_PROV_WRITE_ADD_FLAG
);
73 ret
= ps
->memStore
->certs
.addContext(ps
->memStore
, cert
, NULL
,
76 /* dirty trick: replace the returned context's hCertStore with
80 (*(PCERT_CONTEXT
*)ppStoreContext
)->hCertStore
= store
;
84 static void *CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store
, void *pPrev
)
86 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
89 ret
= ps
->memStore
->certs
.enumContext(ps
->memStore
, pPrev
);
92 /* same dirty trick: replace the returned context's hCertStore with
95 ((PCERT_CONTEXT
)ret
)->hCertStore
= store
;
100 static BOOL
CRYPT_ProvDeleteCert(PWINECRYPT_CERTSTORE store
, void *cert
)
102 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
105 TRACE("(%p, %p)\n", store
, cert
);
107 if (ps
->provDeleteCert
)
108 ret
= ps
->provDeleteCert(ps
->hStoreProv
, cert
, 0);
110 ret
= ps
->memStore
->certs
.deleteContext(ps
->memStore
, cert
);
114 static BOOL
CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store
, void *crl
,
115 void *toReplace
, const void **ppStoreContext
)
117 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
120 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
123 ret
= ps
->memStore
->crls
.addContext(ps
->memStore
, crl
, toReplace
,
127 if (ps
->hdr
.dwOpenFlags
& CERT_STORE_READONLY_FLAG
)
129 SetLastError(ERROR_ACCESS_DENIED
);
135 if (ps
->provWriteCrl
)
136 ret
= ps
->provWriteCrl(ps
->hStoreProv
, (PCCRL_CONTEXT
)crl
,
137 CERT_STORE_PROV_WRITE_ADD_FLAG
);
139 ret
= ps
->memStore
->crls
.addContext(ps
->memStore
, crl
, NULL
,
143 /* dirty trick: replace the returned context's hCertStore with
147 (*(PCRL_CONTEXT
*)ppStoreContext
)->hCertStore
= store
;
151 static void *CRYPT_ProvEnumCRL(PWINECRYPT_CERTSTORE store
, void *pPrev
)
153 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
156 ret
= ps
->memStore
->crls
.enumContext(ps
->memStore
, pPrev
);
159 /* same dirty trick: replace the returned context's hCertStore with
162 ((PCRL_CONTEXT
)ret
)->hCertStore
= store
;
167 static BOOL
CRYPT_ProvDeleteCRL(PWINECRYPT_CERTSTORE store
, void *crl
)
169 PWINE_PROVIDERSTORE ps
= (PWINE_PROVIDERSTORE
)store
;
172 TRACE("(%p, %p)\n", store
, crl
);
174 if (ps
->provDeleteCrl
)
175 ret
= ps
->provDeleteCrl(ps
->hStoreProv
, crl
, 0);
177 ret
= ps
->memStore
->crls
.deleteContext(ps
->memStore
, crl
);
181 static BOOL WINAPI
CRYPT_ProvControl(HCERTSTORE hCertStore
, DWORD dwFlags
,
182 DWORD dwCtrlType
, void const *pvCtrlPara
)
184 PWINE_PROVIDERSTORE store
= (PWINE_PROVIDERSTORE
)hCertStore
;
187 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
190 if (store
->provControl
)
191 ret
= store
->provControl(store
->hStoreProv
, dwFlags
, dwCtrlType
,
196 PWINECRYPT_CERTSTORE
CRYPT_ProvCreateStore(DWORD dwFlags
,
197 PWINECRYPT_CERTSTORE memStore
, const CERT_STORE_PROV_INFO
*pProvInfo
)
199 PWINE_PROVIDERSTORE ret
= CryptMemAlloc(sizeof(WINE_PROVIDERSTORE
));
203 CRYPT_InitStore(&ret
->hdr
, dwFlags
, StoreTypeProvider
);
204 ret
->dwStoreProvFlags
= pProvInfo
->dwStoreProvFlags
;
205 if (ret
->dwStoreProvFlags
& CERT_STORE_PROV_EXTERNAL_FLAG
)
207 CertCloseStore(memStore
, 0);
208 ret
->memStore
= NULL
;
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
];
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
];
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
];
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
];
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
];
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
];
255 ret
->provControl
= NULL
;
257 return (PWINECRYPT_CERTSTORE
)ret
;
260 PWINECRYPT_CERTSTORE
CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider
,
261 DWORD dwEncodingType
, HCRYPTPROV hCryptProv
, DWORD dwFlags
, const void *pvPara
)
263 static HCRYPTOIDFUNCSET set
= NULL
;
264 PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc
;
265 HCRYPTOIDFUNCADDR hFunc
;
266 PWINECRYPT_CERTSTORE ret
= NULL
;
269 set
= CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC
, 0);
270 CryptGetOIDFunctionAddress(set
, dwEncodingType
, lpszStoreProvider
, 0,
271 (void **)&provOpenFunc
, &hFunc
);
274 CERT_STORE_PROV_INFO provInfo
= { 0 };
276 provInfo
.cbSize
= sizeof(provInfo
);
277 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
278 provOpenFunc(lpszStoreProvider
, dwEncodingType
, hCryptProv
,
279 dwFlags
, pvPara
, NULL
, &provInfo
);
284 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
285 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
288 if (provOpenFunc(lpszStoreProvider
, dwEncodingType
, hCryptProv
,
289 dwFlags
, pvPara
, memStore
, &provInfo
))
290 ret
= CRYPT_ProvCreateStore(dwFlags
, memStore
, &provInfo
);
292 CertCloseStore(memStore
, 0);
295 CryptFreeOIDFunctionAddress(hFunc
, 0);
298 SetLastError(ERROR_FILE_NOT_FOUND
);