source: trunk/src/crypt32/store.c@ 22012

Last change on this file since 22012 was 21354, checked in by rlwalsh, 16 years ago

eliminate VACPP warning & info msgs - see Ticket #1

File size: 40.7 KB
Line 
1/*
2 * Copyright 2002 Mike McCormack for CodeWeavers
3 * Copyright 2004-2006 Juan Lang
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 * FIXME:
20 * - The concept of physical stores and locations isn't implemented. (This
21 * doesn't mean registry stores et al aren't implemented. See the PSDK for
22 * registering and enumerating physical stores and locations.)
23 * - Many flags, options and whatnot are unimplemented.
24 */
25
26#include "config.h"
27#include "wine/port.h"
28
29#include <assert.h>
30#include <stdarg.h>
31#include <string.h>
32#include "windef.h"
33#include "winbase.h"
34#include "winnls.h"
35#include "winreg.h"
36#include "winuser.h"
37#include "wincrypt.h"
38#include "wine/debug.h"
39#include "wine/list.h"
40#include "wine/exception.h"
41#include "crypt32_private.h"
42
43WINE_DEFAULT_DEBUG_CHANNEL(crypt);
44
45static const WINE_CONTEXT_INTERFACE gCertInterface = {
46 (CreateContextFunc)CertCreateCertificateContext,
47 (AddContextToStoreFunc)CertAddCertificateContextToStore,
48 (AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore,
49 (DuplicateContextFunc)CertDuplicateCertificateContext,
50 (EnumContextsInStoreFunc)CertEnumCertificatesInStore,
51 (EnumPropertiesFunc)CertEnumCertificateContextProperties,
52 (GetContextPropertyFunc)CertGetCertificateContextProperty,
53 (SetContextPropertyFunc)CertSetCertificateContextProperty,
54 (SerializeElementFunc)CertSerializeCertificateStoreElement,
55 (FreeContextFunc)CertFreeCertificateContext,
56 (DeleteContextFunc)CertDeleteCertificateFromStore,
57};
58PCWINE_CONTEXT_INTERFACE pCertInterface = &gCertInterface;
59
60static const WINE_CONTEXT_INTERFACE gCRLInterface = {
61 (CreateContextFunc)CertCreateCRLContext,
62 (AddContextToStoreFunc)CertAddCRLContextToStore,
63 (AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
64 (DuplicateContextFunc)CertDuplicateCRLContext,
65 (EnumContextsInStoreFunc)CertEnumCRLsInStore,
66 (EnumPropertiesFunc)CertEnumCRLContextProperties,
67 (GetContextPropertyFunc)CertGetCRLContextProperty,
68 (SetContextPropertyFunc)CertSetCRLContextProperty,
69 (SerializeElementFunc)CertSerializeCRLStoreElement,
70 (FreeContextFunc)CertFreeCRLContext,
71 (DeleteContextFunc)CertDeleteCRLFromStore,
72};
73PCWINE_CONTEXT_INTERFACE pCRLInterface = &gCRLInterface;
74
75static const WINE_CONTEXT_INTERFACE gCTLInterface = {
76 (CreateContextFunc)CertCreateCTLContext,
77 (AddContextToStoreFunc)CertAddCTLContextToStore,
78 (AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
79 (DuplicateContextFunc)CertDuplicateCTLContext,
80 (EnumContextsInStoreFunc)CertEnumCTLsInStore,
81 (EnumPropertiesFunc)CertEnumCTLContextProperties,
82 (GetContextPropertyFunc)CertGetCTLContextProperty,
83 (SetContextPropertyFunc)CertSetCTLContextProperty,
84 (SerializeElementFunc)CertSerializeCTLStoreElement,
85 (FreeContextFunc)CertFreeCTLContext,
86 (DeleteContextFunc)CertDeleteCTLFromStore,
87};
88PCWINE_CONTEXT_INTERFACE pCTLInterface = &gCTLInterface;
89
90typedef struct _WINE_MEMSTORE
91{
92 WINECRYPT_CERTSTORE hdr;
93 struct ContextList *certs;
94 struct ContextList *crls;
95 struct ContextList *ctls;
96} WINE_MEMSTORE, *PWINE_MEMSTORE;
97
98void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
99 CertStoreType type)
100{
101 store->ref = 1;
102 store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
103 store->type = type;
104 store->dwOpenFlags = dwFlags;
105 store->properties = NULL;
106}
107
108void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
109{
110 if (store->properties)
111 ContextPropertyList_Free(store->properties);
112 CryptMemFree(store);
113}
114
115BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
116 DWORD unk1)
117{
118 static BOOL warned = FALSE;
119 const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
120 pCRLInterface, pCTLInterface };
121 DWORD i;
122
123 TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
124 if (!warned)
125 {
126 FIXME("semi-stub\n");
127 warned = TRUE;
128 }
129
130 /* Poor-man's resync: empty first store, then add everything from second
131 * store to it.
132 */
133 for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
134 {
135 const void *context;
136
137 do {
138 context = interfaces[i]->enumContextsInStore(store1, NULL);
139 if (context)
140 interfaces[i]->deleteFromStore(context);
141 } while (context);
142 do {
143 context = interfaces[i]->enumContextsInStore(store2, context);
144 if (context)
145 interfaces[i]->addContextToStore(store1, context,
146 CERT_STORE_ADD_ALWAYS, NULL);
147 } while (context);
148 }
149 return TRUE;
150}
151
152static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
153 void *toReplace, const void **ppStoreContext)
154{
155 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
156 PCERT_CONTEXT context;
157
158 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
159
160 context = ContextList_Add(ms->certs, cert, toReplace);
161 if (context)
162 {
163 context->hCertStore = store;
164 if (ppStoreContext)
165 *ppStoreContext = CertDuplicateCertificateContext(context);
166 }
167 return context ? TRUE : FALSE;
168}
169
170static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
171{
172 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
173 void *ret;
174
175 TRACE("(%p, %p)\n", store, pPrev);
176
177 ret = ContextList_Enum(ms->certs, pPrev);
178 if (!ret)
179 SetLastError(CRYPT_E_NOT_FOUND);
180
181 TRACE("returning %p\n", ret);
182 return ret;
183}
184
185static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
186{
187 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
188
189 ContextList_Delete(ms->certs, pCertContext);
190 return TRUE;
191}
192
193static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
194 void *toReplace, const void **ppStoreContext)
195{
196 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
197 PCRL_CONTEXT context;
198
199 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
200
201 context = ContextList_Add(ms->crls, crl, toReplace);
202 if (context)
203 {
204 context->hCertStore = store;
205 if (ppStoreContext)
206 *ppStoreContext = CertDuplicateCRLContext(context);
207 }
208 return context ? TRUE : FALSE;
209}
210
211static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
212{
213 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
214 void *ret;
215
216 TRACE("(%p, %p)\n", store, pPrev);
217
218 ret = ContextList_Enum(ms->crls, pPrev);
219 if (!ret)
220 SetLastError(CRYPT_E_NOT_FOUND);
221
222 TRACE("returning %p\n", ret);
223 return ret;
224}
225
226static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
227{
228 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
229
230 ContextList_Delete(ms->crls, pCrlContext);
231 return TRUE;
232}
233
234static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
235 void *toReplace, const void **ppStoreContext)
236{
237 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
238 PCTL_CONTEXT context;
239
240 TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
241
242 context = ContextList_Add(ms->ctls, ctl, toReplace);
243 if (context)
244 {
245 context->hCertStore = store;
246 if (ppStoreContext)
247 *ppStoreContext = CertDuplicateCTLContext(context);
248 }
249 return context ? TRUE : FALSE;
250}
251
252static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev)
253{
254 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
255 void *ret;
256
257 TRACE("(%p, %p)\n", store, pPrev);
258
259 ret = ContextList_Enum(ms->ctls, pPrev);
260 if (!ret)
261 SetLastError(CRYPT_E_NOT_FOUND);
262
263 TRACE("returning %p\n", ret);
264 return ret;
265}
266
267static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
268{
269 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
270
271 ContextList_Delete(ms->ctls, pCtlContext);
272 return TRUE;
273}
274
275static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
276{
277 WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
278
279 TRACE("(%p, %08x)\n", store, dwFlags);
280 if (dwFlags)
281 FIXME("Unimplemented flags: %08x\n", dwFlags);
282
283 ContextList_Free(store->certs);
284 ContextList_Free(store->crls);
285 ContextList_Free(store->ctls);
286 CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
287}
288
289static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
290 DWORD dwFlags, const void *pvPara)
291{
292 PWINE_MEMSTORE store;
293
294 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
295
296 if (dwFlags & CERT_STORE_DELETE_FLAG)
297 {
298 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
299 store = NULL;
300 }
301 else
302 {
303 store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
304 if (store)
305 {
306 memset(store, 0, sizeof(WINE_MEMSTORE));
307 CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
308 store->hdr.closeStore = CRYPT_MemCloseStore;
309 store->hdr.certs.addContext = CRYPT_MemAddCert;
310 store->hdr.certs.enumContext = CRYPT_MemEnumCert;
311 store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
312 store->hdr.crls.addContext = CRYPT_MemAddCrl;
313 store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
314 store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
315 store->hdr.ctls.addContext = CRYPT_MemAddCtl;
316 store->hdr.ctls.enumContext = CRYPT_MemEnumCtl;
317 store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl;
318 store->hdr.control = NULL;
319 store->certs = ContextList_Create(pCertInterface,
320 sizeof(CERT_CONTEXT));
321 store->crls = ContextList_Create(pCRLInterface,
322 sizeof(CRL_CONTEXT));
323 store->ctls = ContextList_Create(pCTLInterface,
324 sizeof(CTL_CONTEXT));
325 /* Mem store doesn't need crypto provider, so close it */
326 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
327 CryptReleaseContext(hCryptProv, 0);
328 }
329 }
330 return (PWINECRYPT_CERTSTORE)store;
331}
332
333static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
334 DWORD dwFlags, const void *pvPara)
335{
336 static const WCHAR rootW[] = { 'R','o','o','t',0 };
337 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
338 LPCWSTR storeName = (LPCWSTR)pvPara;
339 LPWSTR storePath;
340 PWINECRYPT_CERTSTORE store = NULL;
341 HKEY root;
342 LPCWSTR base;
343
344 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
345 debugstr_w((LPCWSTR)pvPara));
346
347 if (!pvPara)
348 {
349 SetLastError(E_INVALIDARG);
350 return NULL;
351 }
352 if (!lstrcmpiW(storeName, rootW))
353 return CRYPT_RootOpenStore(hCryptProv, dwFlags);
354
355 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
356 {
357 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
358 root = HKEY_LOCAL_MACHINE;
359 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
360 break;
361 case CERT_SYSTEM_STORE_CURRENT_USER:
362 root = HKEY_CURRENT_USER;
363 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
364 break;
365 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
366 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
367 * SystemCertificates
368 */
369 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
370 debugstr_w(storeName));
371 return NULL;
372 case CERT_SYSTEM_STORE_SERVICES:
373 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
374 * SystemCertificates
375 */
376 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
377 debugstr_w(storeName));
378 return NULL;
379 case CERT_SYSTEM_STORE_USERS:
380 /* hku\user sid\Software\Microsoft\SystemCertificates */
381 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
382 debugstr_w(storeName));
383 return NULL;
384 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
385 root = HKEY_CURRENT_USER;
386 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
387 break;
388 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
389 root = HKEY_LOCAL_MACHINE;
390 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
391 break;
392 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
393 /* hklm\Software\Microsoft\EnterpriseCertificates */
394 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
395 debugstr_w(storeName));
396 return NULL;
397 default:
398 SetLastError(E_INVALIDARG);
399 return NULL;
400 }
401
402 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
403 sizeof(WCHAR));
404 if (storePath)
405 {
406 LONG rc;
407 HKEY key;
408 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
409 KEY_ALL_ACCESS;
410
411 wsprintfW(storePath, fmt, base, storeName);
412 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
413 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
414 else
415 {
416 DWORD disp;
417
418 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
419 &key, &disp);
420 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
421 disp == REG_OPENED_EXISTING_KEY)
422 {
423 RegCloseKey(key);
424 rc = ERROR_FILE_EXISTS;
425 }
426 }
427 if (!rc)
428 {
429 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, (const void*)key);
430 RegCloseKey(key);
431 }
432 else
433 SetLastError(rc);
434 CryptMemFree(storePath);
435 }
436 return store;
437}
438
439static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
440 DWORD dwFlags, const void *pvPara)
441{
442 int len;
443 PWINECRYPT_CERTSTORE ret = NULL;
444
445 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
446 debugstr_a((LPCSTR)pvPara));
447
448 if (!pvPara)
449 {
450 SetLastError(ERROR_FILE_NOT_FOUND);
451 return NULL;
452 }
453 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
454 if (len)
455 {
456 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
457
458 if (storeName)
459 {
460 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
461 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
462 CryptMemFree(storeName);
463 }
464 }
465 return ret;
466}
467
468static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
469 DWORD dwFlags, const void *pvPara)
470{
471 HCERTSTORE store = 0;
472 BOOL ret;
473
474 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
475 debugstr_w((LPCWSTR)pvPara));
476
477 if (!pvPara)
478 {
479 SetLastError(ERROR_FILE_NOT_FOUND);
480 return NULL;
481 }
482 /* This returns a different error than system registry stores if the
483 * location is invalid.
484 */
485 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
486 {
487 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
488 case CERT_SYSTEM_STORE_CURRENT_USER:
489 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
490 case CERT_SYSTEM_STORE_SERVICES:
491 case CERT_SYSTEM_STORE_USERS:
492 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
493 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
494 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
495 ret = TRUE;
496 break;
497 default:
498 SetLastError(ERROR_FILE_NOT_FOUND);
499 ret = FALSE;
500 }
501 if (ret)
502 {
503 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
504 0, 0, dwFlags, pvPara);
505
506 if (regStore)
507 {
508 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
509 CERT_STORE_CREATE_NEW_FLAG, NULL);
510 CertAddStoreToCollection(store, regStore,
511 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
512 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
513 CertCloseStore(regStore, 0);
514 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
515 * stores.
516 */
517 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
518 CERT_SYSTEM_STORE_CURRENT_USER)
519 {
520 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
521 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
522 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
523 0, dwFlags, pvPara);
524 if (regStore)
525 {
526 CertAddStoreToCollection(store, regStore,
527 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
528 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
529 CertCloseStore(regStore, 0);
530 }
531 }
532 /* System store doesn't need crypto provider, so close it */
533 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
534 CryptReleaseContext(hCryptProv, 0);
535 }
536 }
537 return (PWINECRYPT_CERTSTORE)store;
538}
539
540static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
541 DWORD dwFlags, const void *pvPara)
542{
543 int len;
544 PWINECRYPT_CERTSTORE ret = NULL;
545
546 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
547 debugstr_a((LPCSTR)pvPara));
548
549 if (!pvPara)
550 {
551 SetLastError(ERROR_FILE_NOT_FOUND);
552 return NULL;
553 }
554 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
555 if (len)
556 {
557 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
558
559 if (storeName)
560 {
561 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
562 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
563 CryptMemFree(storeName);
564 }
565 }
566 return ret;
567}
568
569static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
570{
571 HCRYPTMSG msg = hCertStore;
572
573 TRACE("(%p, %08x)\n", msg, dwFlags);
574 CryptMsgClose(msg);
575}
576
577static void *msgProvFuncs[] = {
578 (void*)CRYPT_MsgCloseStore,
579};
580
581static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
582 DWORD dwFlags, const void *pvPara)
583{
584 PWINECRYPT_CERTSTORE store = NULL;
585 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
586 PWINECRYPT_CERTSTORE memStore;
587
588 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
589
590 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
591 CERT_STORE_CREATE_NEW_FLAG, NULL);
592 if (memStore)
593 {
594 BOOL ret;
595 DWORD size, count, i;
596
597 size = sizeof(count);
598 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
599 for (i = 0; ret && i < count; i++)
600 {
601 size = 0;
602 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
603 if (ret)
604 {
605 LPBYTE buf = CryptMemAlloc(size);
606
607 if (buf)
608 {
609 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
610 if (ret)
611 ret = CertAddEncodedCertificateToStore(memStore,
612 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
613 NULL);
614 CryptMemFree(buf);
615 }
616 }
617 }
618 size = sizeof(count);
619 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
620 for (i = 0; ret && i < count; i++)
621 {
622 size = 0;
623 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
624 if (ret)
625 {
626 LPBYTE buf = CryptMemAlloc(size);
627
628 if (buf)
629 {
630 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
631 if (ret)
632 ret = CertAddEncodedCRLToStore(memStore,
633 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
634 NULL);
635 CryptMemFree(buf);
636 }
637 }
638 }
639 if (ret)
640 {
641 CERT_STORE_PROV_INFO provInfo = { 0 };
642
643 provInfo.cbSize = sizeof(provInfo);
644 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
645 sizeof(msgProvFuncs[0]);
646 provInfo.rgpvStoreProvFunc = msgProvFuncs;
647 provInfo.hStoreProv = CryptMsgDuplicate(msg);
648 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
649 /* Msg store doesn't need crypto provider, so close it */
650 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
651 CryptReleaseContext(hCryptProv, 0);
652 }
653 else
654 CertCloseStore(memStore, 0);
655 }
656 TRACE("returning %p\n", store);
657 return store;
658}
659
660static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
661 DWORD dwFlags, const void *pvPara)
662{
663 HCRYPTMSG msg;
664 PWINECRYPT_CERTSTORE store = NULL;
665 const CRYPT_DATA_BLOB *data = (const CRYPT_DATA_BLOB *)pvPara;
666 BOOL ret;
667 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
668 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
669
670 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
671
672 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
673 hCryptProv, NULL, NULL);
674 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
675 if (!ret)
676 {
677 CryptMsgClose(msg);
678 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
679 hCryptProv, NULL, NULL);
680 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
681 if (ret)
682 {
683 DWORD type, size = sizeof(type);
684
685 /* Only signed messages are allowed, check type */
686 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
687 if (ret && type != CMSG_SIGNED)
688 {
689 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
690 ret = FALSE;
691 }
692 }
693 }
694 if (ret)
695 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
696 CryptMsgClose(msg);
697 TRACE("returning %p\n", store);
698 return store;
699}
700
701static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
702 DWORD dwFlags, const void *pvPara)
703{
704 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
705 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
706 else
707 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
708 debugstr_w((LPCWSTR)pvPara));
709 return NULL;
710}
711
712HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
713 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
714 const void* pvPara)
715{
716 WINECRYPT_CERTSTORE *hcs;
717 StoreOpenFunc openFunc = NULL;
718
719 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
720 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
721
722 if (!HIWORD(lpszStoreProvider))
723 {
724 switch (LOWORD(lpszStoreProvider))
725 {
726 case LOWORD(CERT_STORE_PROV_MSG):
727 openFunc = CRYPT_MsgOpenStore;
728 break;
729 case LOWORD(CERT_STORE_PROV_MEMORY):
730 openFunc = CRYPT_MemOpenStore;
731 break;
732 case LOWORD(CERT_STORE_PROV_FILE):
733 openFunc = CRYPT_FileOpenStore;
734 break;
735 case LOWORD(CERT_STORE_PROV_PKCS7):
736 openFunc = CRYPT_PKCSOpenStore;
737 break;
738 case LOWORD(CERT_STORE_PROV_REG):
739 openFunc = CRYPT_RegOpenStore;
740 break;
741 case LOWORD(CERT_STORE_PROV_FILENAME_A):
742 openFunc = CRYPT_FileNameOpenStoreA;
743 break;
744 case LOWORD(CERT_STORE_PROV_FILENAME_W):
745 openFunc = CRYPT_FileNameOpenStoreW;
746 break;
747 case LOWORD(CERT_STORE_PROV_COLLECTION):
748 openFunc = CRYPT_CollectionOpenStore;
749 break;
750 case LOWORD(CERT_STORE_PROV_SYSTEM_A):
751 openFunc = CRYPT_SysOpenStoreA;
752 break;
753 case LOWORD(CERT_STORE_PROV_SYSTEM_W):
754 openFunc = CRYPT_SysOpenStoreW;
755 break;
756 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
757 openFunc = CRYPT_SysRegOpenStoreA;
758 break;
759 case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
760 openFunc = CRYPT_SysRegOpenStoreW;
761 break;
762 case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
763 openFunc = CRYPT_PhysOpenStoreW;
764 break;
765 default:
766 if (LOWORD(lpszStoreProvider))
767 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
768 }
769 }
770 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
771 openFunc = CRYPT_MemOpenStore;
772 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
773 openFunc = CRYPT_FileOpenStore;
774 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
775 openFunc = CRYPT_SysOpenStoreW;
776 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
777 openFunc = CRYPT_CollectionOpenStore;
778 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
779 openFunc = CRYPT_SysRegOpenStoreW;
780 else
781 {
782 FIXME("unimplemented type %s\n", lpszStoreProvider);
783 openFunc = NULL;
784 }
785
786 if (!openFunc)
787 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
788 hCryptProv, dwFlags, pvPara);
789 else
790 hcs = openFunc(hCryptProv, dwFlags, pvPara);
791 return (HCERTSTORE)hcs;
792}
793
794HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
795 LPCSTR szSubSystemProtocol)
796{
797 if (!szSubSystemProtocol)
798 {
799 SetLastError(E_INVALIDARG);
800 return 0;
801 }
802 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
803 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
804}
805
806HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
807 LPCWSTR szSubSystemProtocol)
808{
809 if (!szSubSystemProtocol)
810 {
811 SetLastError(E_INVALIDARG);
812 return 0;
813 }
814 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
815 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
816}
817
818#define CertContext_CopyProperties(to, from) \
819 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
820
821BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
822 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
823 PCCERT_CONTEXT *ppStoreContext)
824{
825 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
826 BOOL ret = TRUE;
827 PCCERT_CONTEXT toAdd = NULL, existing = NULL;
828
829 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
830 dwAddDisposition, ppStoreContext);
831
832 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
833 {
834 BYTE hashToAdd[20];
835 DWORD size = sizeof(hashToAdd);
836
837 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
838 hashToAdd, &size);
839 if (ret)
840 {
841 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
842
843 existing = CertFindCertificateInStore(hCertStore,
844 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
845 NULL);
846 }
847 }
848
849 switch (dwAddDisposition)
850 {
851 case CERT_STORE_ADD_ALWAYS:
852 toAdd = CertDuplicateCertificateContext(pCertContext);
853 break;
854 case CERT_STORE_ADD_NEW:
855 if (existing)
856 {
857 TRACE("found matching certificate, not adding\n");
858 SetLastError(CRYPT_E_EXISTS);
859 ret = FALSE;
860 }
861 else
862 toAdd = CertDuplicateCertificateContext(pCertContext);
863 break;
864 case CERT_STORE_ADD_REPLACE_EXISTING:
865 toAdd = CertDuplicateCertificateContext(pCertContext);
866 break;
867 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
868 toAdd = CertDuplicateCertificateContext(pCertContext);
869 if (existing)
870 CertContext_CopyProperties(toAdd, existing);
871 break;
872 case CERT_STORE_ADD_USE_EXISTING:
873 if (existing)
874 {
875 CertContext_CopyProperties(existing, pCertContext);
876 *ppStoreContext = CertDuplicateCertificateContext(existing);
877 }
878 else
879 toAdd = CertDuplicateCertificateContext(pCertContext);
880 break;
881 case CERT_STORE_ADD_NEWER:
882 if (existing)
883 {
884 if (CompareFileTime(&existing->pCertInfo->NotBefore,
885 &pCertContext->pCertInfo->NotBefore) >= 0)
886 {
887 TRACE("existing certificate is newer, not adding\n");
888 SetLastError(CRYPT_E_EXISTS);
889 ret = FALSE;
890 }
891 else
892 toAdd = CertDuplicateCertificateContext(pCertContext);
893 }
894 else
895 toAdd = CertDuplicateCertificateContext(pCertContext);
896 break;
897 default:
898 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
899 SetLastError(E_INVALIDARG);
900 ret = FALSE;
901 }
902
903 if (toAdd)
904 {
905 if (store)
906 ret = store->certs.addContext(store, (void *)toAdd,
907 (void *)existing, (const void **)ppStoreContext);
908 else if (ppStoreContext)
909 *ppStoreContext = CertDuplicateCertificateContext(toAdd);
910 CertFreeCertificateContext(toAdd);
911 }
912 CertFreeCertificateContext(existing);
913
914 TRACE("returning %d\n", ret);
915 return ret;
916}
917
918PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
919 PCCERT_CONTEXT pPrev)
920{
921 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
922 PCCERT_CONTEXT ret;
923
924 TRACE("(%p, %p)\n", hCertStore, pPrev);
925 if (!hCertStore)
926 ret = NULL;
927 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
928 ret = NULL;
929 else
930 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
931 return ret;
932}
933
934BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
935{
936 BOOL ret;
937
938 TRACE("(%p)\n", pCertContext);
939
940 if (!pCertContext)
941 ret = TRUE;
942 else if (!pCertContext->hCertStore)
943 {
944 ret = TRUE;
945 CertFreeCertificateContext(pCertContext);
946 }
947 else
948 {
949 PWINECRYPT_CERTSTORE hcs =
950 (PWINECRYPT_CERTSTORE)pCertContext->hCertStore;
951
952 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
953 ret = FALSE;
954 else
955 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
956 CertFreeCertificateContext(pCertContext);
957 }
958 return ret;
959}
960
961#define CrlContext_CopyProperties(to, from) \
962 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
963
964BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
965 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
966 PCCRL_CONTEXT* ppStoreContext)
967{
968 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
969 BOOL ret = TRUE;
970 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
971
972 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
973 dwAddDisposition, ppStoreContext);
974
975 /* Weird case to pass a test */
976 if (dwAddDisposition == 0)
977 {
978 SetLastError(STATUS_ACCESS_VIOLATION);
979 return FALSE;
980 }
981 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
982 {
983 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
984 pCrlContext, NULL);
985 }
986
987 switch (dwAddDisposition)
988 {
989 case CERT_STORE_ADD_ALWAYS:
990 toAdd = CertDuplicateCRLContext(pCrlContext);
991 break;
992 case CERT_STORE_ADD_NEW:
993 if (existing)
994 {
995 TRACE("found matching CRL, not adding\n");
996 SetLastError(CRYPT_E_EXISTS);
997 ret = FALSE;
998 }
999 else
1000 toAdd = CertDuplicateCRLContext(pCrlContext);
1001 break;
1002 case CERT_STORE_ADD_NEWER:
1003 if (existing)
1004 {
1005 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
1006 &pCrlContext->pCrlInfo->ThisUpdate);
1007
1008 if (newer < 0)
1009 toAdd = CertDuplicateCRLContext(pCrlContext);
1010 else
1011 {
1012 TRACE("existing CRL is newer, not adding\n");
1013 SetLastError(CRYPT_E_EXISTS);
1014 ret = FALSE;
1015 }
1016 }
1017 else
1018 toAdd = CertDuplicateCRLContext(pCrlContext);
1019 break;
1020 case CERT_STORE_ADD_REPLACE_EXISTING:
1021 toAdd = CertDuplicateCRLContext(pCrlContext);
1022 break;
1023 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
1024 toAdd = CertDuplicateCRLContext(pCrlContext);
1025 if (existing)
1026 CrlContext_CopyProperties(toAdd, existing);
1027 break;
1028 case CERT_STORE_ADD_USE_EXISTING:
1029 if (existing)
1030 CrlContext_CopyProperties(existing, pCrlContext);
1031 break;
1032 default:
1033 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
1034 ret = FALSE;
1035 }
1036
1037 if (toAdd)
1038 {
1039 if (store)
1040 ret = store->crls.addContext(store, (void *)toAdd,
1041 (void *)existing, (const void **)ppStoreContext);
1042 else if (ppStoreContext)
1043 *ppStoreContext = CertDuplicateCRLContext(toAdd);
1044 CertFreeCRLContext(toAdd);
1045 }
1046 CertFreeCRLContext(existing);
1047
1048 TRACE("returning %d\n", ret);
1049 return ret;
1050}
1051
1052BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1053{
1054 BOOL ret;
1055
1056 TRACE("(%p)\n", pCrlContext);
1057
1058 if (!pCrlContext)
1059 ret = TRUE;
1060 else if (!pCrlContext->hCertStore)
1061 {
1062 ret = TRUE;
1063 CertFreeCRLContext(pCrlContext);
1064 }
1065 else
1066 {
1067 PWINECRYPT_CERTSTORE hcs =
1068 (PWINECRYPT_CERTSTORE)pCrlContext->hCertStore;
1069
1070 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1071 ret = FALSE;
1072 else
1073 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
1074 CertFreeCRLContext(pCrlContext);
1075 }
1076 return ret;
1077}
1078
1079PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
1080 PCCRL_CONTEXT pPrev)
1081{
1082 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1083 PCCRL_CONTEXT ret;
1084
1085 TRACE("(%p, %p)\n", hCertStore, pPrev);
1086 if (!hCertStore)
1087 ret = NULL;
1088 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1089 ret = NULL;
1090 else
1091 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
1092 return ret;
1093}
1094
1095HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1096{
1097 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1098
1099 TRACE("(%p)\n", hCertStore);
1100
1101 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1102 InterlockedIncrement(&hcs->ref);
1103 return hCertStore;
1104}
1105
1106BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1107{
1108 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
1109
1110 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1111
1112 if( ! hCertStore )
1113 return TRUE;
1114
1115 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1116 return FALSE;
1117
1118 if (InterlockedDecrement(&hcs->ref) == 0)
1119 {
1120 TRACE("%p's ref count is 0, freeing\n", hcs);
1121 hcs->dwMagic = 0;
1122 hcs->closeStore(hcs, dwFlags);
1123 }
1124 else
1125 TRACE("%p's ref count is %d\n", hcs, hcs->ref);
1126 return TRUE;
1127}
1128
1129BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1130 DWORD dwCtrlType, void const *pvCtrlPara)
1131{
1132 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1133 BOOL ret;
1134
1135 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1136 pvCtrlPara);
1137
1138 if (!hcs)
1139 ret = FALSE;
1140 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1141 ret = FALSE;
1142 else
1143 {
1144 if (hcs->control)
1145 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
1146 else
1147 ret = TRUE;
1148 }
1149 return ret;
1150}
1151
1152BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1153 void *pvData, DWORD *pcbData)
1154{
1155 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1156 BOOL ret = FALSE;
1157
1158 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1159
1160 switch (dwPropId)
1161 {
1162 case CERT_ACCESS_STATE_PROP_ID:
1163 if (!pvData)
1164 {
1165 *pcbData = sizeof(DWORD);
1166 ret = TRUE;
1167 }
1168 else if (*pcbData < sizeof(DWORD))
1169 {
1170 SetLastError(ERROR_MORE_DATA);
1171 *pcbData = sizeof(DWORD);
1172 }
1173 else
1174 {
1175 DWORD state = 0;
1176
1177 if (store->type != StoreTypeMem &&
1178 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1179 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1180 *(DWORD *)pvData = state;
1181 ret = TRUE;
1182 }
1183 break;
1184 default:
1185 if (store->properties)
1186 {
1187 CRYPT_DATA_BLOB blob;
1188
1189 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1190 &blob);
1191 if (ret)
1192 {
1193 if (!pvData)
1194 *pcbData = blob.cbData;
1195 else if (*pcbData < blob.cbData)
1196 {
1197 SetLastError(ERROR_MORE_DATA);
1198 *pcbData = blob.cbData;
1199 ret = FALSE;
1200 }
1201 else
1202 {
1203 memcpy(pvData, blob.pbData, blob.cbData);
1204 *pcbData = blob.cbData;
1205 }
1206 }
1207 else
1208 SetLastError(CRYPT_E_NOT_FOUND);
1209 }
1210 else
1211 SetLastError(CRYPT_E_NOT_FOUND);
1212 }
1213 return ret;
1214}
1215
1216BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1217 DWORD dwFlags, const void *pvData)
1218{
1219 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1220 BOOL ret = FALSE;
1221
1222 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1223
1224 if (!store->properties)
1225 store->properties = ContextPropertyList_Create();
1226 switch (dwPropId)
1227 {
1228 case CERT_ACCESS_STATE_PROP_ID:
1229 SetLastError(E_INVALIDARG);
1230 break;
1231 default:
1232 if (pvData)
1233 {
1234 const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
1235
1236 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1237 blob->pbData, blob->cbData);
1238 }
1239 else
1240 {
1241 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1242 ret = TRUE;
1243 }
1244 }
1245 return ret;
1246}
1247
1248static LONG CRYPT_OpenParentStore(DWORD dwFlags,
1249 void *pvSystemStoreLocationPara, HKEY *key)
1250{
1251 HKEY root;
1252 LPCWSTR base;
1253
1254 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
1255
1256 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
1257 {
1258 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
1259 root = HKEY_LOCAL_MACHINE;
1260 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1261 break;
1262 case CERT_SYSTEM_STORE_CURRENT_USER:
1263 root = HKEY_CURRENT_USER;
1264 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1265 break;
1266 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
1267 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1268 * SystemCertificates
1269 */
1270 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1271 return ERROR_FILE_NOT_FOUND;
1272 case CERT_SYSTEM_STORE_SERVICES:
1273 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1274 * SystemCertificates
1275 */
1276 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1277 return ERROR_FILE_NOT_FOUND;
1278 case CERT_SYSTEM_STORE_USERS:
1279 /* hku\user sid\Software\Microsoft\SystemCertificates */
1280 FIXME("CERT_SYSTEM_STORE_USERS\n");
1281 return ERROR_FILE_NOT_FOUND;
1282 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
1283 root = HKEY_CURRENT_USER;
1284 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1285 break;
1286 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
1287 root = HKEY_LOCAL_MACHINE;
1288 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1289 break;
1290 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
1291 /* hklm\Software\Microsoft\EnterpriseCertificates */
1292 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1293 return ERROR_FILE_NOT_FOUND;
1294 default:
1295 return ERROR_FILE_NOT_FOUND;
1296 }
1297
1298 return RegOpenKeyExW(root, base, 0, KEY_READ, key);
1299}
1300
1301BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
1302 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
1303{
1304 BOOL ret = FALSE;
1305 LONG rc;
1306 HKEY key;
1307
1308 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
1309 pfnEnum);
1310
1311 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
1312 if (!rc)
1313 {
1314 DWORD index = 0;
1315 CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
1316
1317 ret = TRUE;
1318 do {
1319 WCHAR name[MAX_PATH];
1320 DWORD size = sizeof(name) / sizeof(name[0]);
1321
1322 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
1323 NULL);
1324 if (!rc)
1325 ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
1326 } while (ret && !rc);
1327 if (ret && rc != ERROR_NO_MORE_ITEMS)
1328 SetLastError(rc);
1329 }
1330 else
1331 SetLastError(rc);
1332 return ret;
1333}
1334
1335BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
1336 void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
1337{
1338 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
1339 FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
1340 pfnEnum);
1341 else
1342 FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w((LPCWSTR)pvSystemStore),
1343 dwFlags, pvArg,
1344 pfnEnum);
1345 return FALSE;
1346}
Note: See TracBrowser for help on using the repository browser.