crypt32: Don't store the crypto provider when it isn't needed.
[wine/wine-kai.git] / dlls / crypt32 / filestore.c
blobafe4327f8c414b7a8a2e21c21633f8d2fd3d4f4f
1 /*
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
18 #include <stdarg.h>
19 #include "windef.h"
20 #include "winbase.h"
21 #include "wincrypt.h"
22 #include "winnls.h"
23 #include "wine/debug.h"
24 #include "crypt32_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
28 typedef struct _WINE_FILESTOREINFO
30 DWORD dwOpenFlags;
31 HCERTSTORE memStore;
32 HANDLE file;
33 BOOL dirty;
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);
41 if (store->dirty)
42 CRYPT_WriteSerializedFile(store->file, store->memStore);
43 CertCloseStore(store->memStore, dwFlags);
44 CloseHandle(store->file);
45 CryptMemFree(store);
48 static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
49 PCCERT_CONTEXT cert, DWORD dwFlags)
51 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
53 TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
54 store->dirty = TRUE;
55 return TRUE;
58 static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
59 PCCERT_CONTEXT pCertContext, DWORD dwFlags)
61 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
63 TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
64 store->dirty = TRUE;
65 return TRUE;
68 static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
69 PCCRL_CONTEXT crl, DWORD dwFlags)
71 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
73 TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
74 store->dirty = TRUE;
75 return TRUE;
78 static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
79 PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
81 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
83 TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
84 store->dirty = TRUE;
85 return TRUE;
88 static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
89 DWORD dwCtrlType, void const *pvCtrlPara)
91 PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
92 BOOL ret;
94 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
95 pvCtrlPara);
97 switch (dwCtrlType)
99 case CERT_STORE_CTRL_RESYNC:
100 CRYPT_EmptyStore(store->memStore);
101 CRYPT_ReadSerializedFile(store->file, store);
102 ret = TRUE;
103 break;
104 case CERT_STORE_CTRL_COMMIT:
105 if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
107 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
108 ret = FALSE;
110 else if (store->dirty)
111 ret = CRYPT_WriteSerializedFile(store->file, store->memStore);
112 else
113 ret = TRUE;
114 break;
115 default:
116 FIXME("%d: stub\n", dwCtrlType);
117 ret = FALSE;
119 return ret;
122 static void *fileProvFuncs[] = {
123 CRYPT_FileCloseStore,
124 NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
125 CRYPT_FileWriteCert,
126 CRYPT_FileDeleteCert,
127 NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
128 NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
129 CRYPT_FileWriteCRL,
130 CRYPT_FileDeleteCRL,
131 NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
132 NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
133 NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
134 NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
135 NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
136 CRYPT_FileControl,
139 PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
140 const void *pvPara)
142 PWINECRYPT_CERTSTORE store = NULL;
143 HANDLE file = (HANDLE)pvPara;
145 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
147 if (!pvPara)
149 SetLastError(ERROR_INVALID_HANDLE);
150 return NULL;
152 if (dwFlags & CERT_STORE_DELETE_FLAG)
154 SetLastError(E_INVALIDARG);
155 return NULL;
157 if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
158 (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
160 SetLastError(E_INVALIDARG);
161 return NULL;
164 if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
165 GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ?
166 GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0))
168 PWINECRYPT_CERTSTORE memStore;
170 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
171 CERT_STORE_CREATE_NEW_FLAG, NULL);
172 if (memStore)
174 if (CRYPT_ReadSerializedFile(file, memStore))
176 PWINE_FILESTOREINFO info = CryptMemAlloc(
177 sizeof(WINE_FILESTOREINFO));
179 if (info)
181 CERT_STORE_PROV_INFO provInfo = { 0 };
183 info->dwOpenFlags = dwFlags;
184 info->memStore = memStore;
185 info->file = file;
186 info->dirty = FALSE;
187 provInfo.cbSize = sizeof(provInfo);
188 provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
189 sizeof(fileProvFuncs[0]);
190 provInfo.rgpvStoreProvFunc = fileProvFuncs;
191 provInfo.hStoreProv = info;
192 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
193 /* File store doesn't need crypto provider, so close it */
194 if (hCryptProv &&
195 !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
196 CryptReleaseContext(hCryptProv, 0);
201 TRACE("returning %p\n", store);
202 return store;
205 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
206 DWORD dwFlags, const void *pvPara)
208 HCERTSTORE store = 0;
209 LPCWSTR fileName = (LPCWSTR)pvPara;
210 DWORD access, create;
211 HANDLE file;
213 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));
215 if (!fileName)
217 SetLastError(ERROR_PATH_NOT_FOUND);
218 return NULL;
221 access = GENERIC_READ;
222 if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
223 access |= GENERIC_WRITE;
224 if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
225 create = CREATE_NEW;
226 else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
227 create = OPEN_EXISTING;
228 else
229 create = OPEN_ALWAYS;
230 file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
231 FILE_ATTRIBUTE_NORMAL, NULL);
232 if (file != INVALID_HANDLE_VALUE)
234 /* FIXME: need to check whether it's a serialized store; if not, fall
235 * back to a PKCS#7 signed message, then to a single serialized cert.
237 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, hCryptProv, dwFlags,
238 file);
239 CloseHandle(file);
241 return (PWINECRYPT_CERTSTORE)store;
244 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
245 DWORD dwFlags, const void *pvPara)
247 int len;
248 PWINECRYPT_CERTSTORE ret = NULL;
250 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
251 debugstr_a((LPCSTR)pvPara));
253 if (!pvPara)
255 SetLastError(ERROR_FILE_NOT_FOUND);
256 return NULL;
258 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
259 if (len)
261 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
263 if (storeName)
265 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
266 ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName);
267 CryptMemFree(storeName);
270 return ret;