~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/crypt32/filestore.c

Version: ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  * Copyright 2004-2007 Juan Lang
  3  *
  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.
  8  *
  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.
 13  *
 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
 17  */
 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 "wine/unicode.h"
 25 #include "crypt32_private.h"
 26 
 27 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 28 
 29 typedef struct _WINE_FILESTOREINFO
 30 {
 31     DWORD      dwOpenFlags;
 32     HCERTSTORE memStore;
 33     HANDLE     file;
 34     DWORD      type;
 35     BOOL       dirty;
 36 } WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
 37 
 38 static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
 39 {
 40     PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
 41 
 42     TRACE("(%p, %08x)\n", store, dwFlags);
 43     if (store->dirty)
 44         CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 45          store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
 46     CertCloseStore(store->memStore, dwFlags);
 47     CloseHandle(store->file);
 48     CryptMemFree(store);
 49 }
 50 
 51 static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
 52  PCCERT_CONTEXT cert, DWORD dwFlags)
 53 {
 54     PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
 55 
 56     TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
 57     store->dirty = TRUE;
 58     return TRUE;
 59 }
 60 
 61 static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
 62  PCCERT_CONTEXT pCertContext, DWORD dwFlags)
 63 {
 64     PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
 65 
 66     TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
 67     store->dirty = TRUE;
 68     return TRUE;
 69 }
 70 
 71 static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
 72  PCCRL_CONTEXT crl, DWORD dwFlags)
 73 {
 74     PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
 75 
 76     TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
 77     store->dirty = TRUE;
 78     return TRUE;
 79 }
 80 
 81 static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
 82  PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
 83 {
 84     PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
 85 
 86     TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
 87     store->dirty = TRUE;
 88     return TRUE;
 89 }
 90 
 91 static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
 92 {
 93     BOOL ret = TRUE;
 94 
 95     blob->cbData = GetFileSize(file, NULL);
 96     if (blob->cbData)
 97     {
 98         blob->pbData = CryptMemAlloc(blob->cbData);
 99         if (blob->pbData)
100         {
101             DWORD read;
102 
103             ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
104         }
105     }
106     return ret;
107 }
108 
109 static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
110  DWORD dwCtrlType, void const *pvCtrlPara)
111 {
112     PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
113     BOOL ret;
114 
115     TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
116      pvCtrlPara);
117 
118     switch (dwCtrlType)
119     {
120     case CERT_STORE_CTRL_RESYNC:
121         store->dirty = FALSE;
122         if (store->type == CERT_STORE_SAVE_AS_STORE)
123         {
124             HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
125              CERT_STORE_CREATE_NEW_FLAG, NULL);
126 
127             /* FIXME: if I could translate a handle to a path, I could use
128              * CryptQueryObject instead, but there's no API to do so yet.
129              */
130             ret = CRYPT_ReadSerializedStoreFromFile(store->file, memStore);
131             if (ret)
132                 I_CertUpdateStore(store->memStore, memStore, 0, 0);
133             CertCloseStore(memStore, 0);
134         }
135         else if (store->type == CERT_STORE_SAVE_AS_PKCS7)
136         {
137             CERT_BLOB blob = { 0, NULL };
138 
139             ret = CRYPT_ReadBlobFromFile(store->file, &blob);
140             if (ret)
141             {
142                 HCERTSTORE messageStore;
143 
144                 ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
145                  CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
146                  CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL,
147                  &messageStore, NULL, NULL);
148                 I_CertUpdateStore(store->memStore, messageStore, 0, 0);
149                 CertCloseStore(messageStore, 0);
150                 CryptMemFree(blob.pbData);
151             }
152         }
153         else
154         {
155             WARN("unknown type %d\n", store->type);
156             ret = FALSE;
157         }
158         break;
159     case CERT_STORE_CTRL_COMMIT:
160         if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
161         {
162             SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
163             ret = FALSE;
164         }
165         else if (store->dirty)
166             ret = CertSaveStore(store->memStore,
167              X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
168              store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
169         else
170             ret = TRUE;
171         break;
172     default:
173         FIXME("%d: stub\n", dwCtrlType);
174         ret = FALSE;
175     }
176     return ret;
177 }
178 
179 static void *fileProvFuncs[] = {
180     CRYPT_FileCloseStore,
181     NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
182     CRYPT_FileWriteCert,
183     CRYPT_FileDeleteCert,
184     NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
185     NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
186     CRYPT_FileWriteCRL,
187     CRYPT_FileDeleteCRL,
188     NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
189     NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
190     NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
191     NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
192     NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
193     CRYPT_FileControl,
194 };
195 
196 static PWINECRYPT_CERTSTORE CRYPT_CreateFileStore(DWORD dwFlags,
197  HCERTSTORE memStore, HANDLE file, DWORD type)
198 {
199     PWINECRYPT_CERTSTORE store = NULL;
200     PWINE_FILESTOREINFO info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
201 
202     if (info)
203     {
204         CERT_STORE_PROV_INFO provInfo = { 0 };
205 
206         info->dwOpenFlags = dwFlags;
207         info->memStore = memStore;
208         info->file = file;
209         info->type = type;
210         info->dirty = FALSE;
211         provInfo.cbSize = sizeof(provInfo);
212         provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
213          sizeof(fileProvFuncs[0]);
214         provInfo.rgpvStoreProvFunc = fileProvFuncs;
215         provInfo.hStoreProv = info;
216         store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
217     }
218     return store;
219 }
220 
221 PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
222  const void *pvPara)
223 {
224     PWINECRYPT_CERTSTORE store = NULL;
225     HANDLE file = (HANDLE)pvPara;
226 
227     TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
228 
229     if (!pvPara)
230     {
231         SetLastError(ERROR_INVALID_HANDLE);
232         return NULL;
233     }
234     if (dwFlags & CERT_STORE_DELETE_FLAG)
235     {
236         SetLastError(E_INVALIDARG);
237         return NULL;
238     }
239     if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
240      (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
241     {
242         SetLastError(E_INVALIDARG);
243         return NULL;
244     }
245 
246     if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
247      GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ?
248      GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0))
249     {
250         HCERTSTORE memStore;
251 
252         memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
253          CERT_STORE_CREATE_NEW_FLAG, NULL);
254         if (memStore)
255         {
256             if (CRYPT_ReadSerializedStoreFromFile(file, memStore))
257             {
258                 store = CRYPT_CreateFileStore(dwFlags, memStore, file,
259                  CERT_STORE_SAVE_AS_STORE);
260                 /* File store doesn't need crypto provider, so close it */
261                 if (hCryptProv &&
262                  !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
263                     CryptReleaseContext(hCryptProv, 0);
264             }
265         }
266     }
267     TRACE("returning %p\n", store);
268     return store;
269 }
270 
271 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
272  DWORD dwFlags, const void *pvPara)
273 {
274     HCERTSTORE store = 0;
275     LPCWSTR fileName = (LPCWSTR)pvPara;
276     DWORD access, create;
277     HANDLE file;
278 
279     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));
280 
281     if (!fileName)
282     {
283         SetLastError(ERROR_PATH_NOT_FOUND);
284         return NULL;
285     }
286     if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
287      (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
288     {
289         SetLastError(E_INVALIDARG);
290         return NULL;
291     }
292 
293     access = GENERIC_READ;
294     if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
295         access |= GENERIC_WRITE;
296     if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
297         create = CREATE_NEW;
298     else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
299         create = OPEN_EXISTING;
300     else
301         create = OPEN_ALWAYS;
302     file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
303      FILE_ATTRIBUTE_NORMAL, NULL);
304     if (file != INVALID_HANDLE_VALUE)
305     {
306         HCERTSTORE memStore = NULL;
307         DWORD size = GetFileSize(file, NULL), type = 0;
308 
309         /* If the file isn't empty, try to get the type from the file itself */
310         if (size)
311         {
312             DWORD contentType;
313             BOOL ret;
314 
315             /* Close the file so CryptQueryObject can succeed.. */
316             CloseHandle(file);
317             ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName,
318              CERT_QUERY_CONTENT_FLAG_CERT |
319              CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
320              CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
321              CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL,
322              &memStore, NULL, NULL);
323             if (ret)
324             {
325                 if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
326                     type = CERT_STORE_SAVE_AS_PKCS7;
327                 else
328                     type = CERT_STORE_SAVE_AS_STORE;
329                 /* and reopen the file. */
330                 file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL,
331                  create, FILE_ATTRIBUTE_NORMAL, NULL);
332             }
333         }
334         else
335         {
336             static const WCHAR spc[] = { 's','p','c',0 };
337             static const WCHAR p7c[] = { 'p','7','c',0 };
338             LPCWSTR ext = strrchrW(fileName, '.');
339 
340             if (ext)
341             {
342                 ext++;
343                 if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c))
344                     type = CERT_STORE_SAVE_AS_PKCS7;
345             }
346             if (!type)
347                 type = CERT_STORE_SAVE_AS_STORE;
348             memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
349              CERT_STORE_CREATE_NEW_FLAG, NULL);
350         }
351         if (memStore)
352         {
353             store = CRYPT_CreateFileStore(dwFlags, memStore, file, type);
354             /* File store doesn't need crypto provider, so close it */
355             if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
356                 CryptReleaseContext(hCryptProv, 0);
357         }
358     }
359     return (PWINECRYPT_CERTSTORE)store;
360 }
361 
362 PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
363  DWORD dwFlags, const void *pvPara)
364 {
365     int len;
366     PWINECRYPT_CERTSTORE ret = NULL;
367 
368     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
369      debugstr_a((LPCSTR)pvPara));
370 
371     if (!pvPara)
372     {
373         SetLastError(ERROR_FILE_NOT_FOUND);
374         return NULL;
375     }
376     len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
377     if (len)
378     {
379         LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
380 
381         if (storeName)
382         {
383             MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
384             ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName);
385             CryptMemFree(storeName);
386         }
387     }
388     return ret;
389 }
390 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.