UTF-8 resource files must explicitly say so with a pragma.
[wine.git] / dlls / crypt32 / store.c
blob37247a5e57664b4ffbf45285e0133dec25c7ebb7
1 /*
2 * Copyright 2002 Mike McCormack for CodeWeavers
3 * Copyright 2004-2006 Juan Lang
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.
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.
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
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.
26 #include "config.h"
27 #include "wine/port.h"
29 #include <assert.h>
30 #include <stdarg.h>
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winnls.h"
34 #include "winreg.h"
35 #include "winuser.h"
36 #include "wincrypt.h"
37 #include "wine/debug.h"
38 #include "wine/list.h"
39 #include "wine/exception.h"
40 #include "crypt32_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
44 static const WINE_CONTEXT_INTERFACE gCertInterface = {
45 (CreateContextFunc)CertCreateCertificateContext,
46 (AddContextToStoreFunc)CertAddCertificateContextToStore,
47 (AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore,
48 (DuplicateContextFunc)CertDuplicateCertificateContext,
49 (EnumContextsInStoreFunc)CertEnumCertificatesInStore,
50 (EnumPropertiesFunc)CertEnumCertificateContextProperties,
51 (GetContextPropertyFunc)CertGetCertificateContextProperty,
52 (SetContextPropertyFunc)CertSetCertificateContextProperty,
53 (SerializeElementFunc)CertSerializeCertificateStoreElement,
54 (FreeContextFunc)CertFreeCertificateContext,
55 (DeleteContextFunc)CertDeleteCertificateFromStore,
57 PCWINE_CONTEXT_INTERFACE pCertInterface = &gCertInterface;
59 static const WINE_CONTEXT_INTERFACE gCRLInterface = {
60 (CreateContextFunc)CertCreateCRLContext,
61 (AddContextToStoreFunc)CertAddCRLContextToStore,
62 (AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
63 (DuplicateContextFunc)CertDuplicateCRLContext,
64 (EnumContextsInStoreFunc)CertEnumCRLsInStore,
65 (EnumPropertiesFunc)CertEnumCRLContextProperties,
66 (GetContextPropertyFunc)CertGetCRLContextProperty,
67 (SetContextPropertyFunc)CertSetCRLContextProperty,
68 (SerializeElementFunc)CertSerializeCRLStoreElement,
69 (FreeContextFunc)CertFreeCRLContext,
70 (DeleteContextFunc)CertDeleteCRLFromStore,
72 PCWINE_CONTEXT_INTERFACE pCRLInterface = &gCRLInterface;
74 static const WINE_CONTEXT_INTERFACE gCTLInterface = {
75 (CreateContextFunc)CertCreateCTLContext,
76 (AddContextToStoreFunc)CertAddCTLContextToStore,
77 (AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
78 (DuplicateContextFunc)CertDuplicateCTLContext,
79 (EnumContextsInStoreFunc)CertEnumCTLsInStore,
80 (EnumPropertiesFunc)CertEnumCTLContextProperties,
81 (GetContextPropertyFunc)CertGetCTLContextProperty,
82 (SetContextPropertyFunc)CertSetCTLContextProperty,
83 (SerializeElementFunc)CertSerializeCTLStoreElement,
84 (FreeContextFunc)CertFreeCTLContext,
85 (DeleteContextFunc)CertDeleteCTLFromStore,
87 PCWINE_CONTEXT_INTERFACE pCTLInterface = &gCTLInterface;
89 typedef struct _WINE_MEMSTORE
91 WINECRYPT_CERTSTORE hdr;
92 struct ContextList *certs;
93 struct ContextList *crls;
94 } WINE_MEMSTORE, *PWINE_MEMSTORE;
96 void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
97 CertStoreType type)
99 store->ref = 1;
100 store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
101 store->type = type;
102 store->dwOpenFlags = dwFlags;
103 store->properties = NULL;
106 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
108 if (store->properties)
109 ContextPropertyList_Free(store->properties);
110 CryptMemFree(store);
113 BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
114 DWORD unk1)
116 static BOOL warned = FALSE;
117 const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
118 pCRLInterface, pCTLInterface };
119 DWORD i;
121 TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
122 if (!warned)
124 FIXME("semi-stub\n");
125 warned = TRUE;
128 /* Poor-man's resync: empty first store, then add everything from second
129 * store to it.
131 for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
133 const void *context;
135 do {
136 context = interfaces[i]->enumContextsInStore(store1, NULL);
137 if (context)
138 interfaces[i]->deleteFromStore(context);
139 } while (context);
140 do {
141 context = interfaces[i]->enumContextsInStore(store2, context);
142 if (context)
143 interfaces[i]->addContextToStore(store1, context,
144 CERT_STORE_ADD_ALWAYS, NULL);
145 } while (context);
147 return TRUE;
150 static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
151 void *toReplace, const void **ppStoreContext)
153 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
154 PCERT_CONTEXT context;
156 TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
158 context = (PCERT_CONTEXT)ContextList_Add(ms->certs, cert, toReplace);
159 if (context)
161 context->hCertStore = store;
162 if (ppStoreContext)
163 *ppStoreContext = CertDuplicateCertificateContext(context);
165 return context ? TRUE : FALSE;
168 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
170 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
171 void *ret;
173 TRACE("(%p, %p)\n", store, pPrev);
175 ret = ContextList_Enum(ms->certs, pPrev);
176 if (!ret)
177 SetLastError(CRYPT_E_NOT_FOUND);
179 TRACE("returning %p\n", ret);
180 return ret;
183 static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
185 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
187 ContextList_Delete(ms->certs, pCertContext);
188 return TRUE;
191 static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
192 void *toReplace, const void **ppStoreContext)
194 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
195 PCRL_CONTEXT context;
197 TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
199 context = (PCRL_CONTEXT)ContextList_Add(ms->crls, crl, toReplace);
200 if (context)
202 context->hCertStore = store;
203 if (ppStoreContext)
204 *ppStoreContext = CertDuplicateCRLContext(context);
206 return context ? TRUE : FALSE;
209 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
211 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
212 void *ret;
214 TRACE("(%p, %p)\n", store, pPrev);
216 ret = ContextList_Enum(ms->crls, pPrev);
217 if (!ret)
218 SetLastError(CRYPT_E_NOT_FOUND);
220 TRACE("returning %p\n", ret);
221 return ret;
224 static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
226 WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
228 ContextList_Delete(ms->crls, pCrlContext);
229 return TRUE;
232 static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
234 WINE_MEMSTORE *store = (WINE_MEMSTORE *)hCertStore;
236 TRACE("(%p, %08x)\n", store, dwFlags);
237 if (dwFlags)
238 FIXME("Unimplemented flags: %08x\n", dwFlags);
240 ContextList_Free(store->certs);
241 ContextList_Free(store->crls);
242 CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
245 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
246 DWORD dwFlags, const void *pvPara)
248 PWINE_MEMSTORE store;
250 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
252 if (dwFlags & CERT_STORE_DELETE_FLAG)
254 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
255 store = NULL;
257 else
259 store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
260 if (store)
262 memset(store, 0, sizeof(WINE_MEMSTORE));
263 CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
264 store->hdr.closeStore = CRYPT_MemCloseStore;
265 store->hdr.certs.addContext = CRYPT_MemAddCert;
266 store->hdr.certs.enumContext = CRYPT_MemEnumCert;
267 store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
268 store->hdr.crls.addContext = CRYPT_MemAddCrl;
269 store->hdr.crls.enumContext = CRYPT_MemEnumCrl;
270 store->hdr.crls.deleteContext = CRYPT_MemDeleteCrl;
271 store->hdr.control = NULL;
272 store->certs = ContextList_Create(pCertInterface,
273 sizeof(CERT_CONTEXT));
274 store->crls = ContextList_Create(pCRLInterface,
275 sizeof(CRL_CONTEXT));
276 /* Mem store doesn't need crypto provider, so close it */
277 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
278 CryptReleaseContext(hCryptProv, 0);
281 return (PWINECRYPT_CERTSTORE)store;
284 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
285 DWORD dwFlags, const void *pvPara)
287 static const WCHAR rootW[] = { 'R','o','o','t',0 };
288 static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
289 LPCWSTR storeName = (LPCWSTR)pvPara;
290 LPWSTR storePath;
291 PWINECRYPT_CERTSTORE store = NULL;
292 HKEY root;
293 LPCWSTR base;
294 BOOL ret;
296 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
297 debugstr_w((LPCWSTR)pvPara));
299 if (!pvPara)
301 SetLastError(E_INVALIDARG);
302 return NULL;
304 if (!lstrcmpiW(storeName, rootW))
305 return CRYPT_RootOpenStore(hCryptProv, dwFlags);
307 ret = TRUE;
308 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
310 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
311 root = HKEY_LOCAL_MACHINE;
312 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
313 break;
314 case CERT_SYSTEM_STORE_CURRENT_USER:
315 root = HKEY_CURRENT_USER;
316 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
317 break;
318 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
319 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
320 * SystemCertificates
322 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
323 debugstr_w(storeName));
324 return NULL;
325 case CERT_SYSTEM_STORE_SERVICES:
326 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
327 * SystemCertificates
329 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
330 debugstr_w(storeName));
331 return NULL;
332 case CERT_SYSTEM_STORE_USERS:
333 /* hku\user sid\Software\Microsoft\SystemCertificates */
334 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
335 debugstr_w(storeName));
336 return NULL;
337 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
338 root = HKEY_CURRENT_USER;
339 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
340 break;
341 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
342 root = HKEY_LOCAL_MACHINE;
343 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
344 break;
345 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
346 /* hklm\Software\Microsoft\EnterpriseCertificates */
347 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
348 debugstr_w(storeName));
349 return NULL;
350 default:
351 SetLastError(E_INVALIDARG);
352 return NULL;
355 storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
356 sizeof(WCHAR));
357 if (storePath)
359 LONG rc;
360 HKEY key;
361 REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
362 KEY_ALL_ACCESS;
364 wsprintfW(storePath, fmt, base, storeName);
365 if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
366 rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
367 else
369 DWORD disp;
371 rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
372 &key, &disp);
373 if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
374 disp == REG_OPENED_EXISTING_KEY)
376 RegCloseKey(key);
377 rc = ERROR_FILE_EXISTS;
380 if (!rc)
382 store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
383 RegCloseKey(key);
385 else
386 SetLastError(rc);
387 CryptMemFree(storePath);
389 return store;
392 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
393 DWORD dwFlags, const void *pvPara)
395 int len;
396 PWINECRYPT_CERTSTORE ret = NULL;
398 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
399 debugstr_a((LPCSTR)pvPara));
401 if (!pvPara)
403 SetLastError(ERROR_FILE_NOT_FOUND);
404 return NULL;
406 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
407 if (len)
409 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
411 if (storeName)
413 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
414 ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
415 CryptMemFree(storeName);
418 return ret;
421 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
422 DWORD dwFlags, const void *pvPara)
424 HCERTSTORE store = 0;
425 BOOL ret;
427 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
428 debugstr_w((LPCWSTR)pvPara));
430 if (!pvPara)
432 SetLastError(ERROR_FILE_NOT_FOUND);
433 return NULL;
435 /* This returns a different error than system registry stores if the
436 * location is invalid.
438 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
440 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
441 case CERT_SYSTEM_STORE_CURRENT_USER:
442 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
443 case CERT_SYSTEM_STORE_SERVICES:
444 case CERT_SYSTEM_STORE_USERS:
445 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
446 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
447 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
448 ret = TRUE;
449 break;
450 default:
451 SetLastError(ERROR_FILE_NOT_FOUND);
452 ret = FALSE;
454 if (ret)
456 HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
457 0, 0, dwFlags, pvPara);
459 if (regStore)
461 store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
462 CERT_STORE_CREATE_NEW_FLAG, NULL);
463 CertAddStoreToCollection(store, regStore,
464 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
465 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
466 CertCloseStore(regStore, 0);
467 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
468 * stores.
470 if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
471 CERT_SYSTEM_STORE_CURRENT_USER)
473 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
474 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
475 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
476 0, dwFlags, pvPara);
477 if (regStore)
479 CertAddStoreToCollection(store, regStore,
480 dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
481 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
482 CertCloseStore(regStore, 0);
485 /* System store doesn't need crypto provider, so close it */
486 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
487 CryptReleaseContext(hCryptProv, 0);
490 return (PWINECRYPT_CERTSTORE)store;
493 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
494 DWORD dwFlags, const void *pvPara)
496 int len;
497 PWINECRYPT_CERTSTORE ret = NULL;
499 TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
500 debugstr_a((LPCSTR)pvPara));
502 if (!pvPara)
504 SetLastError(ERROR_FILE_NOT_FOUND);
505 return NULL;
507 len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
508 if (len)
510 LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
512 if (storeName)
514 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
515 ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
516 CryptMemFree(storeName);
519 return ret;
522 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
524 HCRYPTMSG msg = hCertStore;
526 TRACE("(%p, %08x)\n", msg, dwFlags);
527 CryptMsgClose(msg);
530 static void *msgProvFuncs[] = {
531 CRYPT_MsgCloseStore,
534 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
535 DWORD dwFlags, const void *pvPara)
537 PWINECRYPT_CERTSTORE store = NULL;
538 HCRYPTMSG msg = (HCRYPTMSG)pvPara;
539 PWINECRYPT_CERTSTORE memStore;
541 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
543 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
544 CERT_STORE_CREATE_NEW_FLAG, NULL);
545 if (memStore)
547 BOOL ret;
548 DWORD size, count, i;
550 size = sizeof(count);
551 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
552 for (i = 0; ret && i < count; i++)
554 size = 0;
555 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
556 if (ret)
558 LPBYTE buf = CryptMemAlloc(size);
560 if (buf)
562 ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
563 if (ret)
564 ret = CertAddEncodedCertificateToStore(memStore,
565 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
566 NULL);
567 CryptMemFree(buf);
571 size = sizeof(count);
572 ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
573 for (i = 0; ret && i < count; i++)
575 size = 0;
576 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
577 if (ret)
579 LPBYTE buf = CryptMemAlloc(size);
581 if (buf)
583 ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
584 if (ret)
585 ret = CertAddEncodedCRLToStore(memStore,
586 X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
587 NULL);
588 CryptMemFree(buf);
592 if (ret)
594 CERT_STORE_PROV_INFO provInfo = { 0 };
596 provInfo.cbSize = sizeof(provInfo);
597 provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
598 sizeof(msgProvFuncs[0]);
599 provInfo.rgpvStoreProvFunc = msgProvFuncs;
600 provInfo.hStoreProv = CryptMsgDuplicate(msg);
601 store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
602 /* Msg store doesn't need crypto provider, so close it */
603 if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
604 CryptReleaseContext(hCryptProv, 0);
606 else
607 CertCloseStore(memStore, 0);
609 TRACE("returning %p\n", store);
610 return store;
613 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
614 DWORD dwFlags, const void *pvPara)
616 HCRYPTMSG msg;
617 PWINECRYPT_CERTSTORE store = NULL;
618 const CRYPT_DATA_BLOB *data = (const CRYPT_DATA_BLOB *)pvPara;
619 BOOL ret;
620 DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
621 CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
623 TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
625 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
626 hCryptProv, NULL, NULL);
627 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
628 if (!ret)
630 CryptMsgClose(msg);
631 msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
632 hCryptProv, NULL, NULL);
633 ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
634 if (ret)
636 DWORD type, size = sizeof(type);
638 /* Only signed messages are allowed, check type */
639 ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
640 if (ret && type != CMSG_SIGNED)
642 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
643 ret = FALSE;
647 if (ret)
648 store = CRYPT_MsgOpenStore(0, dwFlags, msg);
649 CryptMsgClose(msg);
650 TRACE("returning %p\n", store);
651 return store;
654 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
655 DWORD dwFlags, const void *pvPara)
657 if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
658 FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
659 else
660 FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
661 debugstr_w((LPCWSTR)pvPara));
662 return NULL;
665 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
666 DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
667 const void* pvPara)
669 WINECRYPT_CERTSTORE *hcs;
670 StoreOpenFunc openFunc = NULL;
672 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
673 dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
675 if (!HIWORD(lpszStoreProvider))
677 switch (LOWORD(lpszStoreProvider))
679 case (int)CERT_STORE_PROV_MSG:
680 openFunc = CRYPT_MsgOpenStore;
681 break;
682 case (int)CERT_STORE_PROV_MEMORY:
683 openFunc = CRYPT_MemOpenStore;
684 break;
685 case (int)CERT_STORE_PROV_FILE:
686 openFunc = CRYPT_FileOpenStore;
687 break;
688 case (int)CERT_STORE_PROV_PKCS7:
689 openFunc = CRYPT_PKCSOpenStore;
690 break;
691 case (int)CERT_STORE_PROV_REG:
692 openFunc = CRYPT_RegOpenStore;
693 break;
694 case (int)CERT_STORE_PROV_FILENAME_A:
695 openFunc = CRYPT_FileNameOpenStoreA;
696 break;
697 case (int)CERT_STORE_PROV_FILENAME_W:
698 openFunc = CRYPT_FileNameOpenStoreW;
699 break;
700 case (int)CERT_STORE_PROV_COLLECTION:
701 openFunc = CRYPT_CollectionOpenStore;
702 break;
703 case (int)CERT_STORE_PROV_SYSTEM_A:
704 openFunc = CRYPT_SysOpenStoreA;
705 break;
706 case (int)CERT_STORE_PROV_SYSTEM_W:
707 openFunc = CRYPT_SysOpenStoreW;
708 break;
709 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_A:
710 openFunc = CRYPT_SysRegOpenStoreA;
711 break;
712 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_W:
713 openFunc = CRYPT_SysRegOpenStoreW;
714 break;
715 case (int)CERT_STORE_PROV_PHYSICAL_W:
716 openFunc = CRYPT_PhysOpenStoreW;
717 break;
718 default:
719 if (LOWORD(lpszStoreProvider))
720 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
723 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
724 openFunc = CRYPT_MemOpenStore;
725 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
726 openFunc = CRYPT_FileOpenStore;
727 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
728 openFunc = CRYPT_SysOpenStoreW;
729 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
730 openFunc = CRYPT_CollectionOpenStore;
731 else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
732 openFunc = CRYPT_SysRegOpenStoreW;
733 else
735 FIXME("unimplemented type %s\n", lpszStoreProvider);
736 openFunc = NULL;
739 if (!openFunc)
740 hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
741 hCryptProv, dwFlags, pvPara);
742 else
743 hcs = openFunc(hCryptProv, dwFlags, pvPara);
744 return (HCERTSTORE)hcs;
747 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
748 LPCSTR szSubSystemProtocol)
750 if (!szSubSystemProtocol)
752 SetLastError(E_INVALIDARG);
753 return 0;
755 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
756 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
759 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
760 LPCWSTR szSubSystemProtocol)
762 if (!szSubSystemProtocol)
764 SetLastError(E_INVALIDARG);
765 return 0;
767 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
768 CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
771 #define CertContext_CopyProperties(to, from) \
772 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
774 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
775 PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
776 PCCERT_CONTEXT *ppStoreContext)
778 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
779 BOOL ret = TRUE;
780 PCCERT_CONTEXT toAdd = NULL, existing = NULL;
782 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
783 dwAddDisposition, ppStoreContext);
785 /* Weird case to pass a test */
786 if (dwAddDisposition == 0)
788 SetLastError(STATUS_ACCESS_VIOLATION);
789 return FALSE;
791 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
793 BYTE hashToAdd[20];
794 DWORD size = sizeof(hashToAdd);
796 ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
797 hashToAdd, &size);
798 if (ret)
800 CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
802 existing = CertFindCertificateInStore(hCertStore,
803 pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
804 NULL);
808 switch (dwAddDisposition)
810 case CERT_STORE_ADD_ALWAYS:
811 toAdd = CertDuplicateCertificateContext(pCertContext);
812 break;
813 case CERT_STORE_ADD_NEW:
814 if (existing)
816 TRACE("found matching certificate, not adding\n");
817 SetLastError(CRYPT_E_EXISTS);
818 ret = FALSE;
820 else
821 toAdd = CertDuplicateCertificateContext(pCertContext);
822 break;
823 case CERT_STORE_ADD_REPLACE_EXISTING:
824 toAdd = CertDuplicateCertificateContext(pCertContext);
825 break;
826 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
827 toAdd = CertDuplicateCertificateContext(pCertContext);
828 if (existing)
829 CertContext_CopyProperties(toAdd, existing);
830 break;
831 case CERT_STORE_ADD_USE_EXISTING:
832 if (existing)
834 CertContext_CopyProperties(existing, pCertContext);
835 *ppStoreContext = CertDuplicateCertificateContext(existing);
837 else
838 toAdd = CertDuplicateCertificateContext(pCertContext);
839 break;
840 case CERT_STORE_ADD_NEWER:
841 if (existing)
843 if (CompareFileTime(&existing->pCertInfo->NotBefore,
844 &pCertContext->pCertInfo->NotBefore) >= 0)
846 TRACE("existing certificate is newer, not adding\n");
847 SetLastError(CRYPT_E_EXISTS);
848 ret = FALSE;
850 else
851 toAdd = CertDuplicateCertificateContext(pCertContext);
853 else
854 toAdd = CertDuplicateCertificateContext(pCertContext);
855 break;
856 default:
857 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
858 ret = FALSE;
861 if (toAdd)
863 if (store)
864 ret = store->certs.addContext(store, (void *)toAdd,
865 (void *)existing, (const void **)ppStoreContext);
866 else if (ppStoreContext)
867 *ppStoreContext = CertDuplicateCertificateContext(toAdd);
868 CertFreeCertificateContext(toAdd);
870 CertFreeCertificateContext(existing);
872 TRACE("returning %d\n", ret);
873 return ret;
876 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
877 PCCERT_CONTEXT pPrev)
879 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
880 PCCERT_CONTEXT ret;
882 TRACE("(%p, %p)\n", hCertStore, pPrev);
883 if (!hCertStore)
884 ret = NULL;
885 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
886 ret = NULL;
887 else
888 ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
889 return ret;
892 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
894 BOOL ret;
896 TRACE("(%p)\n", pCertContext);
898 if (!pCertContext)
899 ret = TRUE;
900 else if (!pCertContext->hCertStore)
902 ret = TRUE;
903 CertFreeCertificateContext(pCertContext);
905 else
907 PWINECRYPT_CERTSTORE hcs =
908 (PWINECRYPT_CERTSTORE)pCertContext->hCertStore;
910 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
911 ret = FALSE;
912 else
913 ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
914 CertFreeCertificateContext(pCertContext);
916 return ret;
919 #define CrlContext_CopyProperties(to, from) \
920 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
922 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
923 PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
924 PCCRL_CONTEXT* ppStoreContext)
926 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
927 BOOL ret = TRUE;
928 PCCRL_CONTEXT toAdd = NULL, existing = NULL;
930 TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
931 dwAddDisposition, ppStoreContext);
933 /* Weird case to pass a test */
934 if (dwAddDisposition == 0)
936 SetLastError(STATUS_ACCESS_VIOLATION);
937 return FALSE;
939 if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
941 existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
942 pCrlContext, NULL);
945 switch (dwAddDisposition)
947 case CERT_STORE_ADD_ALWAYS:
948 toAdd = CertDuplicateCRLContext(pCrlContext);
949 break;
950 case CERT_STORE_ADD_NEW:
951 if (existing)
953 TRACE("found matching CRL, not adding\n");
954 SetLastError(CRYPT_E_EXISTS);
955 ret = FALSE;
957 else
958 toAdd = CertDuplicateCRLContext(pCrlContext);
959 break;
960 case CERT_STORE_ADD_NEWER:
961 if (existing)
963 LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
964 &pCrlContext->pCrlInfo->ThisUpdate);
966 if (newer < 0)
967 toAdd = CertDuplicateCRLContext(pCrlContext);
968 else
970 TRACE("existing CRL is newer, not adding\n");
971 SetLastError(CRYPT_E_EXISTS);
972 ret = FALSE;
975 else
976 toAdd = CertDuplicateCRLContext(pCrlContext);
977 break;
978 case CERT_STORE_ADD_REPLACE_EXISTING:
979 toAdd = CertDuplicateCRLContext(pCrlContext);
980 break;
981 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
982 toAdd = CertDuplicateCRLContext(pCrlContext);
983 if (existing)
984 CrlContext_CopyProperties(toAdd, existing);
985 break;
986 case CERT_STORE_ADD_USE_EXISTING:
987 if (existing)
988 CrlContext_CopyProperties(existing, pCrlContext);
989 break;
990 default:
991 FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
992 ret = FALSE;
995 if (toAdd)
997 if (store)
998 ret = store->crls.addContext(store, (void *)toAdd,
999 (void *)existing, (const void **)ppStoreContext);
1000 else if (ppStoreContext)
1001 *ppStoreContext = CertDuplicateCRLContext(toAdd);
1002 CertFreeCRLContext(toAdd);
1004 CertFreeCRLContext(existing);
1006 TRACE("returning %d\n", ret);
1007 return ret;
1010 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
1012 BOOL ret;
1014 TRACE("(%p)\n", pCrlContext);
1016 if (!pCrlContext)
1017 ret = TRUE;
1018 else if (!pCrlContext->hCertStore)
1020 ret = TRUE;
1021 CertFreeCRLContext(pCrlContext);
1023 else
1025 PWINECRYPT_CERTSTORE hcs =
1026 (PWINECRYPT_CERTSTORE)pCrlContext->hCertStore;
1028 if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1029 ret = FALSE;
1030 else
1031 ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
1032 CertFreeCRLContext(pCrlContext);
1034 return ret;
1037 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
1038 PCCRL_CONTEXT pPrev)
1040 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1041 PCCRL_CONTEXT ret;
1043 TRACE("(%p, %p)\n", hCertStore, pPrev);
1044 if (!hCertStore)
1045 ret = NULL;
1046 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1047 ret = NULL;
1048 else
1049 ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
1050 return ret;
1053 PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwCertEncodingType,
1054 const BYTE* pbCtlEncoded, DWORD cbCtlEncoded)
1056 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType, pbCtlEncoded,
1057 cbCtlEncoded);
1058 return NULL;
1061 BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore,
1062 DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded,
1063 DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
1065 FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore,
1066 dwMsgAndCertEncodingType, pbCtlEncoded, cbCtlEncoded, dwAddDisposition,
1067 ppCtlContext);
1068 return FALSE;
1071 BOOL WINAPI CertAddCTLContextToStore(HCERTSTORE hCertStore,
1072 PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition,
1073 PCCTL_CONTEXT* ppStoreContext)
1075 FIXME("(%p, %p, %08x, %p): stub\n", hCertStore, pCtlContext,
1076 dwAddDisposition, ppStoreContext);
1077 return TRUE;
1080 PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext)
1082 FIXME("(%p): stub\n", pCtlContext );
1083 return pCtlContext;
1086 BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCtlContext)
1088 FIXME("(%p): stub\n", pCtlContext );
1089 return TRUE;
1092 BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext)
1094 FIXME("(%p): stub\n", pCtlContext);
1095 return TRUE;
1098 PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(HCERTSTORE hCertStore,
1099 PCCTL_CONTEXT pPrev)
1101 FIXME("(%p, %p): stub\n", hCertStore, pPrev);
1102 return NULL;
1105 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
1107 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1109 TRACE("(%p)\n", hCertStore);
1111 if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
1112 InterlockedIncrement(&hcs->ref);
1113 return hCertStore;
1116 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
1118 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *) hCertStore;
1120 TRACE("(%p, %08x)\n", hCertStore, dwFlags);
1122 if( ! hCertStore )
1123 return TRUE;
1125 if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
1126 return FALSE;
1128 if (InterlockedDecrement(&hcs->ref) == 0)
1130 TRACE("%p's ref count is 0, freeing\n", hcs);
1131 hcs->dwMagic = 0;
1132 hcs->closeStore(hcs, dwFlags);
1134 else
1135 TRACE("%p's ref count is %d\n", hcs, hcs->ref);
1136 return TRUE;
1139 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
1140 DWORD dwCtrlType, void const *pvCtrlPara)
1142 WINECRYPT_CERTSTORE *hcs = (WINECRYPT_CERTSTORE *)hCertStore;
1143 BOOL ret;
1145 TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
1146 pvCtrlPara);
1148 if (!hcs)
1149 ret = FALSE;
1150 else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
1151 ret = FALSE;
1152 else
1154 if (hcs->control)
1155 ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
1156 else
1157 ret = TRUE;
1159 return ret;
1162 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1163 void *pvData, DWORD *pcbData)
1165 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1166 BOOL ret = FALSE;
1168 TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
1170 switch (dwPropId)
1172 case CERT_ACCESS_STATE_PROP_ID:
1173 if (!pvData)
1175 *pcbData = sizeof(DWORD);
1176 ret = TRUE;
1178 else if (*pcbData < sizeof(DWORD))
1180 SetLastError(ERROR_MORE_DATA);
1181 *pcbData = sizeof(DWORD);
1183 else
1185 DWORD state = 0;
1187 if (store->type != StoreTypeMem &&
1188 !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
1189 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1190 *(DWORD *)pvData = state;
1191 ret = TRUE;
1193 break;
1194 default:
1195 if (store->properties)
1197 CRYPT_DATA_BLOB blob;
1199 ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
1200 &blob);
1201 if (ret)
1203 if (!pvData)
1204 *pcbData = blob.cbData;
1205 else if (*pcbData < blob.cbData)
1207 SetLastError(ERROR_MORE_DATA);
1208 *pcbData = blob.cbData;
1209 ret = FALSE;
1211 else
1213 memcpy(pvData, blob.pbData, blob.cbData);
1214 *pcbData = blob.cbData;
1217 else
1218 SetLastError(CRYPT_E_NOT_FOUND);
1220 else
1221 SetLastError(CRYPT_E_NOT_FOUND);
1223 return ret;
1226 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
1227 DWORD dwFlags, const void *pvData)
1229 PWINECRYPT_CERTSTORE store = (PWINECRYPT_CERTSTORE)hCertStore;
1230 BOOL ret = FALSE;
1232 TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
1234 if (!store->properties)
1235 store->properties = ContextPropertyList_Create();
1236 switch (dwPropId)
1238 case CERT_ACCESS_STATE_PROP_ID:
1239 SetLastError(E_INVALIDARG);
1240 break;
1241 default:
1242 if (pvData)
1244 const CRYPT_DATA_BLOB *blob = (const CRYPT_DATA_BLOB *)pvData;
1246 ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
1247 blob->pbData, blob->cbData);
1249 else
1251 ContextPropertyList_RemoveProperty(store->properties, dwPropId);
1252 ret = TRUE;
1255 return ret;
1258 DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext,
1259 DWORD dwPropId)
1261 FIXME("(%p, %d): stub\n", pCTLContext, dwPropId);
1262 return 0;
1265 BOOL WINAPI CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1266 DWORD dwPropId, void *pvData, DWORD *pcbData)
1268 FIXME("(%p, %d, %p, %p): stub\n", pCTLContext, dwPropId, pvData, pcbData);
1269 return FALSE;
1272 BOOL WINAPI CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext,
1273 DWORD dwPropId, DWORD dwFlags, const void *pvData)
1275 FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext, dwPropId, dwFlags,
1276 pvData);
1277 return FALSE;
1280 static LONG CRYPT_OpenParentStore(DWORD dwFlags,
1281 void *pvSystemStoreLocationPara, HKEY *key)
1283 HKEY root;
1284 LPCWSTR base;
1286 TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
1288 switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
1290 case CERT_SYSTEM_STORE_LOCAL_MACHINE:
1291 root = HKEY_LOCAL_MACHINE;
1292 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1293 break;
1294 case CERT_SYSTEM_STORE_CURRENT_USER:
1295 root = HKEY_CURRENT_USER;
1296 base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
1297 break;
1298 case CERT_SYSTEM_STORE_CURRENT_SERVICE:
1299 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1300 * SystemCertificates
1302 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1303 return ERROR_FILE_NOT_FOUND;
1304 case CERT_SYSTEM_STORE_SERVICES:
1305 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1306 * SystemCertificates
1308 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1309 return ERROR_FILE_NOT_FOUND;
1310 case CERT_SYSTEM_STORE_USERS:
1311 /* hku\user sid\Software\Microsoft\SystemCertificates */
1312 FIXME("CERT_SYSTEM_STORE_USERS\n");
1313 return ERROR_FILE_NOT_FOUND;
1314 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
1315 root = HKEY_CURRENT_USER;
1316 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1317 break;
1318 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
1319 root = HKEY_LOCAL_MACHINE;
1320 base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
1321 break;
1322 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
1323 /* hklm\Software\Microsoft\EnterpriseCertificates */
1324 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1325 return ERROR_FILE_NOT_FOUND;
1326 default:
1327 return ERROR_FILE_NOT_FOUND;
1330 return RegOpenKeyExW(root, base, 0, KEY_READ, key);
1333 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
1334 void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
1336 BOOL ret = FALSE;
1337 LONG rc;
1338 HKEY key;
1340 TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
1341 pfnEnum);
1343 rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
1344 if (!rc)
1346 DWORD index = 0;
1347 CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
1349 ret = TRUE;
1350 do {
1351 WCHAR name[MAX_PATH];
1352 DWORD size = sizeof(name) / sizeof(name[0]);
1354 rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
1355 NULL);
1356 if (!rc)
1357 ret = pfnEnum(name, 0, &info, NULL, pvArg);
1358 } while (ret && !rc);
1359 if (ret && rc != ERROR_NO_MORE_ITEMS)
1360 SetLastError(rc);
1362 else
1363 SetLastError(rc);
1364 return ret;