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
23 #include "wine/debug.h"
24 #include "crypt32_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
28 typedef struct _WINE_FILESTOREINFO
34 } WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
36 static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
38 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
40 TRACE("(%p, %08x)\n", store, dwFlags);
42 CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
43 CERT_STORE_SAVE_AS_STORE, CERT_STORE_SAVE_TO_FILE, store->file, 0);
44 CertCloseStore(store->memStore, dwFlags);
45 CloseHandle(store->file);
49 static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
50 PCCERT_CONTEXT cert, DWORD dwFlags)
52 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
54 TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
59 static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
60 PCCERT_CONTEXT pCertContext, DWORD dwFlags)
62 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
64 TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
69 static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
70 PCCRL_CONTEXT crl, DWORD dwFlags)
72 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
74 TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
79 static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
80 PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
82 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
84 TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
89 static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
90 DWORD dwCtrlType, void const *pvCtrlPara)
92 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
95 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
100 case CERT_STORE_CTRL_RESYNC:
101 CRYPT_EmptyStore(store->memStore);
102 store->dirty = FALSE;
103 ret = CRYPT_ReadSerializedStoreFromFile(store->file, store->memStore);
105 case CERT_STORE_CTRL_COMMIT:
106 if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
108 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
111 else if (store->dirty)
112 ret = CertSaveStore(store->memStore,
113 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
114 CERT_STORE_SAVE_AS_STORE, CERT_STORE_SAVE_TO_FILE, store->file, 0);
119 FIXME("%d: stub\n", dwCtrlType);
125 static void *fileProvFuncs[] = {
126 CRYPT_FileCloseStore,
127 NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
129 CRYPT_FileDeleteCert,
130 NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
131 NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
134 NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
135 NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
136 NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
137 NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
138 NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
142 static PWINECRYPT_CERTSTORE CRYPT_CreateFileStore(DWORD dwFlags,
143 HCERTSTORE memStore, HANDLE file)
145 PWINECRYPT_CERTSTORE store = NULL;
146 PWINE_FILESTOREINFO info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
150 CERT_STORE_PROV_INFO provInfo = { 0 };
152 info->dwOpenFlags = dwFlags;
153 info->memStore = memStore;
156 provInfo.cbSize = sizeof(provInfo);
157 provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
158 sizeof(fileProvFuncs[0]);
159 provInfo.rgpvStoreProvFunc = fileProvFuncs;
160 provInfo.hStoreProv = info;
161 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
166 PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
169 PWINECRYPT_CERTSTORE store = NULL;
170 HANDLE file = (HANDLE)pvPara;
172 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
176 SetLastError(ERROR_INVALID_HANDLE);
179 if (dwFlags & CERT_STORE_DELETE_FLAG)
181 SetLastError(E_INVALIDARG);
184 if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
185 (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
187 SetLastError(E_INVALIDARG);
191 if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
192 GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ?
193 GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0))
197 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
198 CERT_STORE_CREATE_NEW_FLAG, NULL);
201 if (CRYPT_ReadSerializedStoreFromFile(file, memStore))
203 store = CRYPT_CreateFileStore(dwFlags, memStore, file);
204 /* File store doesn't need crypto provider, so close it */
206 !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
207 CryptReleaseContext(hCryptProv, 0);
211 TRACE("returning %p\n", store);
215 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
216 DWORD dwFlags, const void *pvPara)
218 HCERTSTORE store = 0;
219 LPCWSTR fileName = (LPCWSTR)pvPara;
220 DWORD access, create;
223 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));
227 SetLastError(ERROR_PATH_NOT_FOUND);
230 if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
231 (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
233 SetLastError(E_INVALIDARG);
237 access = GENERIC_READ;
238 if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
239 access |= GENERIC_WRITE;
240 if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
242 else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
243 create = OPEN_EXISTING;
245 create = OPEN_ALWAYS;
246 file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
247 FILE_ATTRIBUTE_NORMAL, NULL);
248 if (file != INVALID_HANDLE_VALUE)
252 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
253 CERT_STORE_CREATE_NEW_FLAG, NULL);
256 if (CRYPT_ReadSerializedStoreFromFile(file, memStore))
258 store = CRYPT_CreateFileStore(dwFlags, memStore, file);
259 /* File store doesn't need crypto provider, so close it */
261 !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
262 CryptReleaseContext(hCryptProv, 0);
266 /* FIXME: fall back to a PKCS#7 signed message, then to a
267 * single serialized cert.
272 return (PWINECRYPT_CERTSTORE)store;
275 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
276 DWORD dwFlags, const void *pvPara)
279 PWINECRYPT_CERTSTORE ret = NULL;
281 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
282 debugstr_a((LPCSTR)pvPara));
286 SetLastError(ERROR_FILE_NOT_FOUND);
289 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
292 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
296 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
297 ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName);
298 CryptMemFree(storeName);