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
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.
27 #include "wine/port.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 typedef struct _WINE_FILESTOREINFO
103 } WINE_FILESTOREINFO
, *PWINE_FILESTOREINFO
;
105 typedef struct _WINE_MSGSTOREINFO
108 HCRYPTPROV cryptProv
;
111 } WINE_MSGSTOREINFO
, *PWINE_MSGSTOREINFO
;
113 void CRYPT_InitStore(WINECRYPT_CERTSTORE
*store
, HCRYPTPROV hCryptProv
,
114 DWORD dwFlags
, CertStoreType type
)
117 store
->dwMagic
= WINE_CRYPTCERTSTORE_MAGIC
;
121 hCryptProv
= CRYPT_GetDefaultProvider();
122 dwFlags
|= CERT_STORE_NO_CRYPT_RELEASE_FLAG
;
124 store
->cryptProv
= hCryptProv
;
125 store
->dwOpenFlags
= dwFlags
;
126 store
->properties
= NULL
;
129 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store
)
131 if (store
->properties
)
132 ContextPropertyList_Free(store
->properties
);
136 static BOOL
CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store
, void *cert
,
137 void *toReplace
, const void **ppStoreContext
)
139 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
140 PCERT_CONTEXT context
;
142 TRACE("(%p, %p, %p, %p)\n", store
, cert
, toReplace
, ppStoreContext
);
144 context
= (PCERT_CONTEXT
)ContextList_Add(ms
->certs
, cert
, toReplace
);
147 context
->hCertStore
= store
;
149 *ppStoreContext
= CertDuplicateCertificateContext(context
);
151 return context
? TRUE
: FALSE
;
154 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store
, void *pPrev
)
156 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
159 TRACE("(%p, %p)\n", store
, pPrev
);
161 ret
= ContextList_Enum(ms
->certs
, pPrev
);
163 SetLastError(CRYPT_E_NOT_FOUND
);
165 TRACE("returning %p\n", ret
);
169 static BOOL
CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store
, void *pCertContext
)
171 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
173 ContextList_Delete(ms
->certs
, pCertContext
);
177 static BOOL
CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store
, void *crl
,
178 void *toReplace
, const void **ppStoreContext
)
180 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
181 PCRL_CONTEXT context
;
183 TRACE("(%p, %p, %p, %p)\n", store
, crl
, toReplace
, ppStoreContext
);
185 context
= (PCRL_CONTEXT
)ContextList_Add(ms
->crls
, crl
, toReplace
);
188 context
->hCertStore
= store
;
190 *ppStoreContext
= CertDuplicateCRLContext(context
);
192 return context
? TRUE
: FALSE
;
195 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store
, void *pPrev
)
197 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
200 TRACE("(%p, %p)\n", store
, pPrev
);
202 ret
= ContextList_Enum(ms
->crls
, pPrev
);
204 SetLastError(CRYPT_E_NOT_FOUND
);
206 TRACE("returning %p\n", ret
);
210 static BOOL
CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store
, void *pCrlContext
)
212 WINE_MEMSTORE
*ms
= (WINE_MEMSTORE
*)store
;
214 ContextList_Delete(ms
->crls
, pCrlContext
);
218 void CRYPT_EmptyStore(HCERTSTORE store
)
224 cert
= CertEnumCertificatesInStore(store
, NULL
);
226 CertDeleteCertificateFromStore(cert
);
229 crl
= CertEnumCRLsInStore(store
, NULL
);
231 CertDeleteCRLFromStore(crl
);
235 static void WINAPI
CRYPT_MemCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
237 WINE_MEMSTORE
*store
= (WINE_MEMSTORE
*)hCertStore
;
239 TRACE("(%p, %08x)\n", store
, dwFlags
);
241 FIXME("Unimplemented flags: %08x\n", dwFlags
);
243 ContextList_Free(store
->certs
);
244 ContextList_Free(store
->crls
);
245 CRYPT_FreeStore((PWINECRYPT_CERTSTORE
)store
);
248 static WINECRYPT_CERTSTORE
*CRYPT_MemOpenStore(HCRYPTPROV hCryptProv
,
249 DWORD dwFlags
, const void *pvPara
)
251 PWINE_MEMSTORE store
;
253 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
255 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
257 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
262 store
= CryptMemAlloc(sizeof(WINE_MEMSTORE
));
265 memset(store
, 0, sizeof(WINE_MEMSTORE
));
266 CRYPT_InitStore(&store
->hdr
, hCryptProv
, dwFlags
, StoreTypeMem
);
267 store
->hdr
.closeStore
= CRYPT_MemCloseStore
;
268 store
->hdr
.certs
.addContext
= CRYPT_MemAddCert
;
269 store
->hdr
.certs
.enumContext
= CRYPT_MemEnumCert
;
270 store
->hdr
.certs
.deleteContext
= CRYPT_MemDeleteCert
;
271 store
->hdr
.crls
.addContext
= CRYPT_MemAddCrl
;
272 store
->hdr
.crls
.enumContext
= CRYPT_MemEnumCrl
;
273 store
->hdr
.crls
.deleteContext
= CRYPT_MemDeleteCrl
;
274 store
->hdr
.control
= NULL
;
275 store
->certs
= ContextList_Create(pCertInterface
,
276 sizeof(CERT_CONTEXT
));
277 store
->crls
= ContextList_Create(pCRLInterface
,
278 sizeof(CRL_CONTEXT
));
281 return (PWINECRYPT_CERTSTORE
)store
;
284 /* FIXME: this isn't complete for the Root store, in which the top-level
285 * self-signed CA certs reside. Adding a cert to the Root store should present
286 * the user with a dialog indicating the consequences of doing so, and asking
287 * the user to confirm whether the cert should be added.
289 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv
,
290 DWORD dwFlags
, const void *pvPara
)
292 static const WCHAR fmt
[] = { '%','s','\\','%','s',0 };
293 LPCWSTR storeName
= (LPCWSTR
)pvPara
;
295 PWINECRYPT_CERTSTORE store
= NULL
;
300 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
301 debugstr_w((LPCWSTR
)pvPara
));
305 SetLastError(E_INVALIDARG
);
310 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
312 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
313 root
= HKEY_LOCAL_MACHINE
;
314 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
316 case CERT_SYSTEM_STORE_CURRENT_USER
:
317 root
= HKEY_CURRENT_USER
;
318 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
320 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
321 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
324 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
325 debugstr_w(storeName
));
327 case CERT_SYSTEM_STORE_SERVICES
:
328 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
331 FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
332 debugstr_w(storeName
));
334 case CERT_SYSTEM_STORE_USERS
:
335 /* hku\user sid\Software\Microsoft\SystemCertificates */
336 FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
337 debugstr_w(storeName
));
339 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
340 root
= HKEY_CURRENT_USER
;
341 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
343 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
344 root
= HKEY_LOCAL_MACHINE
;
345 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
347 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
348 /* hklm\Software\Microsoft\EnterpriseCertificates */
349 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
350 debugstr_w(storeName
));
353 SetLastError(E_INVALIDARG
);
357 storePath
= CryptMemAlloc((lstrlenW(base
) + lstrlenW(storeName
) + 2) *
363 REGSAM sam
= dwFlags
& CERT_STORE_READONLY_FLAG
? KEY_READ
:
366 wsprintfW(storePath
, fmt
, base
, storeName
);
367 if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
368 rc
= RegOpenKeyExW(root
, storePath
, 0, sam
, &key
);
373 rc
= RegCreateKeyExW(root
, storePath
, 0, NULL
, 0, sam
, NULL
,
375 if (!rc
&& dwFlags
& CERT_STORE_CREATE_NEW_FLAG
&&
376 disp
== REG_OPENED_EXISTING_KEY
)
379 rc
= ERROR_FILE_EXISTS
;
384 store
= CRYPT_RegOpenStore(hCryptProv
, dwFlags
, key
);
389 CryptMemFree(storePath
);
394 static PWINECRYPT_CERTSTORE
CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv
,
395 DWORD dwFlags
, const void *pvPara
)
398 PWINECRYPT_CERTSTORE ret
= NULL
;
400 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
401 debugstr_a((LPCSTR
)pvPara
));
405 SetLastError(ERROR_FILE_NOT_FOUND
);
408 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
411 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
415 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
416 ret
= CRYPT_SysRegOpenStoreW(hCryptProv
, dwFlags
, storeName
);
417 CryptMemFree(storeName
);
423 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv
,
424 DWORD dwFlags
, const void *pvPara
)
426 HCERTSTORE store
= 0;
429 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
430 debugstr_w((LPCWSTR
)pvPara
));
434 SetLastError(ERROR_FILE_NOT_FOUND
);
437 /* This returns a different error than system registry stores if the
438 * location is invalid.
440 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
442 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
443 case CERT_SYSTEM_STORE_CURRENT_USER
:
444 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
445 case CERT_SYSTEM_STORE_SERVICES
:
446 case CERT_SYSTEM_STORE_USERS
:
447 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
448 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
449 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
453 SetLastError(ERROR_FILE_NOT_FOUND
);
458 HCERTSTORE regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
,
459 0, hCryptProv
, dwFlags
, pvPara
);
463 store
= CertOpenStore(CERT_STORE_PROV_COLLECTION
, 0, 0,
464 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
465 CertAddStoreToCollection(store
, regStore
,
466 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
467 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
468 CertCloseStore(regStore
, 0);
469 /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
472 if ((dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
) ==
473 CERT_SYSTEM_STORE_CURRENT_USER
)
475 dwFlags
&= ~CERT_SYSTEM_STORE_CURRENT_USER
;
476 dwFlags
|= CERT_SYSTEM_STORE_LOCAL_MACHINE
;
477 regStore
= CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W
, 0,
478 hCryptProv
, dwFlags
, pvPara
);
481 CertAddStoreToCollection(store
, regStore
,
482 dwFlags
& CERT_STORE_READONLY_FLAG
? 0 :
483 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG
, 0);
484 CertCloseStore(regStore
, 0);
489 return (PWINECRYPT_CERTSTORE
)store
;
492 static PWINECRYPT_CERTSTORE
CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv
,
493 DWORD dwFlags
, const void *pvPara
)
496 PWINECRYPT_CERTSTORE ret
= NULL
;
498 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
499 debugstr_a((LPCSTR
)pvPara
));
503 SetLastError(ERROR_FILE_NOT_FOUND
);
506 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
509 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
513 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
514 ret
= CRYPT_SysOpenStoreW(hCryptProv
, dwFlags
, storeName
);
515 CryptMemFree(storeName
);
521 static void WINAPI
CRYPT_FileCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
523 PWINE_FILESTOREINFO store
= (PWINE_FILESTOREINFO
)hCertStore
;
525 TRACE("(%p, %08x)\n", store
, dwFlags
);
527 CRYPT_WriteSerializedFile(store
->file
, store
->memStore
);
528 CertCloseStore(store
->memStore
, dwFlags
);
529 CloseHandle(store
->file
);
533 static BOOL WINAPI
CRYPT_FileWriteCert(HCERTSTORE hCertStore
,
534 PCCERT_CONTEXT cert
, DWORD dwFlags
)
536 PWINE_FILESTOREINFO store
= (PWINE_FILESTOREINFO
)hCertStore
;
538 TRACE("(%p, %p, %d)\n", hCertStore
, cert
, dwFlags
);
543 static BOOL WINAPI
CRYPT_FileDeleteCert(HCERTSTORE hCertStore
,
544 PCCERT_CONTEXT pCertContext
, DWORD dwFlags
)
546 PWINE_FILESTOREINFO store
= (PWINE_FILESTOREINFO
)hCertStore
;
548 TRACE("(%p, %p, %08x)\n", hCertStore
, pCertContext
, dwFlags
);
553 static BOOL WINAPI
CRYPT_FileWriteCRL(HCERTSTORE hCertStore
,
554 PCCRL_CONTEXT crl
, DWORD dwFlags
)
556 PWINE_FILESTOREINFO store
= (PWINE_FILESTOREINFO
)hCertStore
;
558 TRACE("(%p, %p, %d)\n", hCertStore
, crl
, dwFlags
);
563 static BOOL WINAPI
CRYPT_FileDeleteCRL(HCERTSTORE hCertStore
,
564 PCCRL_CONTEXT pCrlContext
, DWORD dwFlags
)
566 PWINE_FILESTOREINFO store
= (PWINE_FILESTOREINFO
)hCertStore
;
568 TRACE("(%p, %p, %08x)\n", hCertStore
, pCrlContext
, dwFlags
);
573 static BOOL WINAPI
CRYPT_FileControl(HCERTSTORE hCertStore
, DWORD dwFlags
,
574 DWORD dwCtrlType
, void const *pvCtrlPara
)
576 PWINE_FILESTOREINFO store
= (PWINE_FILESTOREINFO
)hCertStore
;
579 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
584 case CERT_STORE_CTRL_RESYNC
:
585 CRYPT_EmptyStore(store
->memStore
);
586 CRYPT_ReadSerializedFile(store
->file
, store
);
589 case CERT_STORE_CTRL_COMMIT
:
590 if (!(store
->dwOpenFlags
& CERT_FILE_STORE_COMMIT_ENABLE_FLAG
))
592 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
595 else if (store
->dirty
)
596 ret
= CRYPT_WriteSerializedFile(store
->file
, store
->memStore
);
601 FIXME("%d: stub\n", dwCtrlType
);
607 static void *fileProvFuncs
[] = {
608 CRYPT_FileCloseStore
,
609 NULL
, /* CERT_STORE_PROV_READ_CERT_FUNC */
611 CRYPT_FileDeleteCert
,
612 NULL
, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
613 NULL
, /* CERT_STORE_PROV_READ_CRL_FUNC */
616 NULL
, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
617 NULL
, /* CERT_STORE_PROV_READ_CTL_FUNC */
618 NULL
, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
619 NULL
, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
620 NULL
, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
624 static PWINECRYPT_CERTSTORE
CRYPT_FileOpenStore(HCRYPTPROV hCryptProv
,
625 DWORD dwFlags
, const void *pvPara
)
627 PWINECRYPT_CERTSTORE store
= NULL
;
628 HANDLE file
= (HANDLE
)pvPara
;
630 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
634 SetLastError(ERROR_INVALID_HANDLE
);
637 if (dwFlags
& CERT_STORE_DELETE_FLAG
)
639 SetLastError(E_INVALIDARG
);
642 if ((dwFlags
& CERT_STORE_READONLY_FLAG
) &&
643 (dwFlags
& CERT_FILE_STORE_COMMIT_ENABLE_FLAG
))
645 SetLastError(E_INVALIDARG
);
649 if (DuplicateHandle(GetCurrentProcess(), (HANDLE
)pvPara
,
650 GetCurrentProcess(), &file
, dwFlags
& CERT_STORE_READONLY_FLAG
?
651 GENERIC_READ
: GENERIC_READ
| GENERIC_WRITE
, TRUE
, 0))
653 PWINECRYPT_CERTSTORE memStore
;
655 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, hCryptProv
,
656 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
659 if (CRYPT_ReadSerializedFile(file
, memStore
))
661 PWINE_FILESTOREINFO info
= CryptMemAlloc(
662 sizeof(WINE_FILESTOREINFO
));
666 CERT_STORE_PROV_INFO provInfo
= { 0 };
668 info
->dwOpenFlags
= dwFlags
;
669 info
->cryptProv
= hCryptProv
;
670 info
->memStore
= memStore
;
673 provInfo
.cbSize
= sizeof(provInfo
);
674 provInfo
.cStoreProvFunc
= sizeof(fileProvFuncs
) /
675 sizeof(fileProvFuncs
[0]);
676 provInfo
.rgpvStoreProvFunc
= fileProvFuncs
;
677 provInfo
.hStoreProv
= info
;
678 store
= CRYPT_ProvCreateStore(hCryptProv
, dwFlags
, memStore
,
684 TRACE("returning %p\n", store
);
688 static PWINECRYPT_CERTSTORE
CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv
,
689 DWORD dwFlags
, const void *pvPara
)
691 HCERTSTORE store
= 0;
692 LPCWSTR fileName
= (LPCWSTR
)pvPara
;
693 DWORD access
, create
;
696 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
, debugstr_w(fileName
));
700 SetLastError(ERROR_PATH_NOT_FOUND
);
704 access
= GENERIC_READ
;
705 if (dwFlags
& CERT_FILE_STORE_COMMIT_ENABLE_FLAG
)
706 access
|= GENERIC_WRITE
;
707 if (dwFlags
& CERT_STORE_CREATE_NEW_FLAG
)
709 else if (dwFlags
& CERT_STORE_OPEN_EXISTING_FLAG
)
710 create
= OPEN_EXISTING
;
712 create
= OPEN_ALWAYS
;
713 file
= CreateFileW(fileName
, access
, FILE_SHARE_READ
, NULL
, create
,
714 FILE_ATTRIBUTE_NORMAL
, NULL
);
715 if (file
!= INVALID_HANDLE_VALUE
)
717 /* FIXME: need to check whether it's a serialized store; if not, fall
718 * back to a PKCS#7 signed message, then to a single serialized cert.
720 store
= CertOpenStore(CERT_STORE_PROV_FILE
, 0, hCryptProv
, dwFlags
,
724 return (PWINECRYPT_CERTSTORE
)store
;
727 static PWINECRYPT_CERTSTORE
CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv
,
728 DWORD dwFlags
, const void *pvPara
)
731 PWINECRYPT_CERTSTORE ret
= NULL
;
733 TRACE("(%ld, %08x, %s)\n", hCryptProv
, dwFlags
,
734 debugstr_a((LPCSTR
)pvPara
));
738 SetLastError(ERROR_FILE_NOT_FOUND
);
741 len
= MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, NULL
, 0);
744 LPWSTR storeName
= CryptMemAlloc(len
* sizeof(WCHAR
));
748 MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)pvPara
, -1, storeName
, len
);
749 ret
= CRYPT_FileNameOpenStoreW(hCryptProv
, dwFlags
, storeName
);
750 CryptMemFree(storeName
);
756 static void WINAPI
CRYPT_MsgCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
758 PWINE_MSGSTOREINFO store
= (PWINE_MSGSTOREINFO
)hCertStore
;
760 TRACE("(%p, %08x)\n", store
, dwFlags
);
761 CertCloseStore(store
->memStore
, dwFlags
);
762 CryptMsgClose(store
->msg
);
766 static void *msgProvFuncs
[] = {
768 NULL
, /* CERT_STORE_PROV_READ_CERT_FUNC */
769 NULL
, /* CERT_STORE_PROV_WRITE_CERT_FUNC */
770 NULL
, /* CERT_STORE_PROV_DELETE_CERT_FUNC */
771 NULL
, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
772 NULL
, /* CERT_STORE_PROV_READ_CRL_FUNC */
773 NULL
, /* CERT_STORE_PROV_WRITE_CRL_FUNC */
774 NULL
, /* CERT_STORE_PROV_DELETE_CRL_FUNC */
775 NULL
, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
776 NULL
, /* CERT_STORE_PROV_READ_CTL_FUNC */
777 NULL
, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
778 NULL
, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
779 NULL
, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
780 NULL
, /* CERT_STORE_PROV_CONTROL_FUNC */
783 static PWINECRYPT_CERTSTORE
CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv
,
784 DWORD dwFlags
, const void *pvPara
)
786 PWINECRYPT_CERTSTORE store
= NULL
;
787 HCRYPTMSG msg
= (HCRYPTMSG
)pvPara
;
788 PWINECRYPT_CERTSTORE memStore
;
790 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
792 memStore
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, hCryptProv
,
793 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
797 DWORD size
, count
, i
;
799 size
= sizeof(count
);
800 ret
= CryptMsgGetParam(msg
, CMSG_CERT_COUNT_PARAM
, 0, &count
, &size
);
801 for (i
= 0; ret
&& i
< count
; i
++)
804 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, NULL
, &size
);
807 LPBYTE buf
= CryptMemAlloc(size
);
811 ret
= CryptMsgGetParam(msg
, CMSG_CERT_PARAM
, i
, buf
, &size
);
813 ret
= CertAddEncodedCertificateToStore(memStore
,
814 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
820 size
= sizeof(count
);
821 ret
= CryptMsgGetParam(msg
, CMSG_CRL_COUNT_PARAM
, 0, &count
, &size
);
822 for (i
= 0; ret
&& i
< count
; i
++)
825 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, NULL
, &size
);
828 LPBYTE buf
= CryptMemAlloc(size
);
832 ret
= CryptMsgGetParam(msg
, CMSG_CRL_PARAM
, i
, buf
, &size
);
834 ret
= CertAddEncodedCRLToStore(memStore
,
835 X509_ASN_ENCODING
, buf
, size
, CERT_STORE_ADD_ALWAYS
,
843 PWINE_MSGSTOREINFO info
= CryptMemAlloc(sizeof(WINE_MSGSTOREINFO
));
847 CERT_STORE_PROV_INFO provInfo
= { 0 };
849 info
->dwOpenFlags
= dwFlags
;
850 info
->cryptProv
= hCryptProv
;
851 info
->memStore
= memStore
;
852 info
->msg
= CryptMsgDuplicate(msg
);
853 provInfo
.cbSize
= sizeof(provInfo
);
854 provInfo
.cStoreProvFunc
= sizeof(msgProvFuncs
) /
855 sizeof(msgProvFuncs
[0]);
856 provInfo
.rgpvStoreProvFunc
= msgProvFuncs
;
857 provInfo
.hStoreProv
= info
;
858 store
= CRYPT_ProvCreateStore(hCryptProv
, dwFlags
, memStore
,
862 CertCloseStore(memStore
, 0);
865 CertCloseStore(memStore
, 0);
867 TRACE("returning %p\n", store
);
871 static PWINECRYPT_CERTSTORE
CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv
,
872 DWORD dwFlags
, const void *pvPara
)
875 PWINECRYPT_CERTSTORE store
= NULL
;
876 const CRYPT_DATA_BLOB
*data
= (const CRYPT_DATA_BLOB
*)pvPara
;
879 TRACE("(%ld, %08x, %p)\n", hCryptProv
, dwFlags
, pvPara
);
881 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, CMSG_SIGNED
, 0, NULL
,
883 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
887 msg
= CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING
, 0, 0, 0, NULL
, NULL
);
888 ret
= CryptMsgUpdate(msg
, data
->pbData
, data
->cbData
, TRUE
);
891 DWORD type
, size
= sizeof(type
);
893 /* Only signed messages are allowed, check type */
894 ret
= CryptMsgGetParam(msg
, CMSG_TYPE_PARAM
, 0, &type
, &size
);
895 if (ret
&& type
!= CMSG_SIGNED
)
897 SetLastError(CRYPT_E_INVALID_MSG_TYPE
);
903 store
= CRYPT_MsgOpenStore(hCryptProv
, dwFlags
, msg
);
905 TRACE("returning %p\n", store
);
909 static PWINECRYPT_CERTSTORE
CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv
,
910 DWORD dwFlags
, const void *pvPara
)
912 if (dwFlags
& CERT_SYSTEM_STORE_RELOCATE_FLAG
)
913 FIXME("(%ld, %08x, %p): stub\n", hCryptProv
, dwFlags
, pvPara
);
915 FIXME("(%ld, %08x, %s): stub\n", hCryptProv
, dwFlags
,
916 debugstr_w((LPCWSTR
)pvPara
));
920 HCERTSTORE WINAPI
CertOpenStore(LPCSTR lpszStoreProvider
,
921 DWORD dwMsgAndCertEncodingType
, HCRYPTPROV_LEGACY hCryptProv
, DWORD dwFlags
,
924 WINECRYPT_CERTSTORE
*hcs
;
925 StoreOpenFunc openFunc
= NULL
;
927 TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider
),
928 dwMsgAndCertEncodingType
, hCryptProv
, dwFlags
, pvPara
);
930 if (!HIWORD(lpszStoreProvider
))
932 switch (LOWORD(lpszStoreProvider
))
934 case (int)CERT_STORE_PROV_MSG
:
935 openFunc
= CRYPT_MsgOpenStore
;
937 case (int)CERT_STORE_PROV_MEMORY
:
938 openFunc
= CRYPT_MemOpenStore
;
940 case (int)CERT_STORE_PROV_FILE
:
941 openFunc
= CRYPT_FileOpenStore
;
943 case (int)CERT_STORE_PROV_PKCS7
:
944 openFunc
= CRYPT_PKCSOpenStore
;
946 case (int)CERT_STORE_PROV_REG
:
947 openFunc
= CRYPT_RegOpenStore
;
949 case (int)CERT_STORE_PROV_FILENAME_A
:
950 openFunc
= CRYPT_FileNameOpenStoreA
;
952 case (int)CERT_STORE_PROV_FILENAME_W
:
953 openFunc
= CRYPT_FileNameOpenStoreW
;
955 case (int)CERT_STORE_PROV_COLLECTION
:
956 openFunc
= CRYPT_CollectionOpenStore
;
958 case (int)CERT_STORE_PROV_SYSTEM_A
:
959 openFunc
= CRYPT_SysOpenStoreA
;
961 case (int)CERT_STORE_PROV_SYSTEM_W
:
962 openFunc
= CRYPT_SysOpenStoreW
;
964 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_A
:
965 openFunc
= CRYPT_SysRegOpenStoreA
;
967 case (int)CERT_STORE_PROV_SYSTEM_REGISTRY_W
:
968 openFunc
= CRYPT_SysRegOpenStoreW
;
970 case (int)CERT_STORE_PROV_PHYSICAL_W
:
971 openFunc
= CRYPT_PhysOpenStoreW
;
974 if (LOWORD(lpszStoreProvider
))
975 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider
));
978 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_MEMORY
))
979 openFunc
= CRYPT_MemOpenStore
;
980 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_FILENAME_W
))
981 openFunc
= CRYPT_FileOpenStore
;
982 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM
))
983 openFunc
= CRYPT_SysOpenStoreW
;
984 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_COLLECTION
))
985 openFunc
= CRYPT_CollectionOpenStore
;
986 else if (!strcasecmp(lpszStoreProvider
, sz_CERT_STORE_PROV_SYSTEM_REGISTRY
))
987 openFunc
= CRYPT_SysRegOpenStoreW
;
990 FIXME("unimplemented type %s\n", lpszStoreProvider
);
995 hcs
= CRYPT_ProvOpenStore(lpszStoreProvider
, dwMsgAndCertEncodingType
,
996 hCryptProv
, dwFlags
, pvPara
);
998 hcs
= openFunc(hCryptProv
, dwFlags
, pvPara
);
999 return (HCERTSTORE
)hcs
;
1002 HCERTSTORE WINAPI
CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv
,
1003 LPCSTR szSubSystemProtocol
)
1005 if (!szSubSystemProtocol
)
1007 SetLastError(E_INVALIDARG
);
1010 return CertOpenStore(CERT_STORE_PROV_SYSTEM_A
, 0, hProv
,
1011 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
1014 HCERTSTORE WINAPI
CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv
,
1015 LPCWSTR szSubSystemProtocol
)
1017 if (!szSubSystemProtocol
)
1019 SetLastError(E_INVALIDARG
);
1022 return CertOpenStore(CERT_STORE_PROV_SYSTEM_W
, 0, hProv
,
1023 CERT_SYSTEM_STORE_CURRENT_USER
, szSubSystemProtocol
);
1026 BOOL WINAPI
CertSaveStore(HCERTSTORE hCertStore
, DWORD dwMsgAndCertEncodingType
,
1027 DWORD dwSaveAs
, DWORD dwSaveTo
, void* pvSaveToPara
, DWORD dwFlags
)
1029 FIXME("(%p,%d,%d,%d,%p,%08x) stub!\n", hCertStore
,
1030 dwMsgAndCertEncodingType
, dwSaveAs
, dwSaveTo
, pvSaveToPara
, dwFlags
);
1034 #define CertContext_CopyProperties(to, from) \
1035 Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
1037 BOOL WINAPI
CertAddCertificateContextToStore(HCERTSTORE hCertStore
,
1038 PCCERT_CONTEXT pCertContext
, DWORD dwAddDisposition
,
1039 PCCERT_CONTEXT
*ppStoreContext
)
1041 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1043 PCCERT_CONTEXT toAdd
= NULL
, existing
= NULL
;
1045 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCertContext
,
1046 dwAddDisposition
, ppStoreContext
);
1048 /* Weird case to pass a test */
1049 if (dwAddDisposition
== 0)
1051 SetLastError(STATUS_ACCESS_VIOLATION
);
1054 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
1057 DWORD size
= sizeof(hashToAdd
);
1059 ret
= CertGetCertificateContextProperty(pCertContext
, CERT_HASH_PROP_ID
,
1063 CRYPT_HASH_BLOB blob
= { sizeof(hashToAdd
), hashToAdd
};
1065 existing
= CertFindCertificateInStore(hCertStore
,
1066 pCertContext
->dwCertEncodingType
, 0, CERT_FIND_SHA1_HASH
, &blob
,
1071 switch (dwAddDisposition
)
1073 case CERT_STORE_ADD_ALWAYS
:
1074 toAdd
= CertDuplicateCertificateContext(pCertContext
);
1076 case CERT_STORE_ADD_NEW
:
1079 TRACE("found matching certificate, not adding\n");
1080 SetLastError(CRYPT_E_EXISTS
);
1084 toAdd
= CertDuplicateCertificateContext(pCertContext
);
1086 case CERT_STORE_ADD_REPLACE_EXISTING
:
1087 toAdd
= CertDuplicateCertificateContext(pCertContext
);
1089 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
1090 toAdd
= CertDuplicateCertificateContext(pCertContext
);
1092 CertContext_CopyProperties(toAdd
, existing
);
1094 case CERT_STORE_ADD_USE_EXISTING
:
1097 CertContext_CopyProperties(existing
, pCertContext
);
1098 *ppStoreContext
= CertDuplicateCertificateContext(existing
);
1101 toAdd
= CertDuplicateCertificateContext(pCertContext
);
1104 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
1111 ret
= store
->certs
.addContext(store
, (void *)toAdd
,
1112 (void *)existing
, (const void **)ppStoreContext
);
1113 else if (ppStoreContext
)
1114 *ppStoreContext
= CertDuplicateCertificateContext(toAdd
);
1115 CertFreeCertificateContext(toAdd
);
1117 CertFreeCertificateContext(existing
);
1119 TRACE("returning %d\n", ret
);
1123 PCCERT_CONTEXT WINAPI
CertEnumCertificatesInStore(HCERTSTORE hCertStore
,
1124 PCCERT_CONTEXT pPrev
)
1126 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1129 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1132 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1135 ret
= (PCCERT_CONTEXT
)hcs
->certs
.enumContext(hcs
, (void *)pPrev
);
1139 BOOL WINAPI
CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext
)
1143 TRACE("(%p)\n", pCertContext
);
1147 else if (!pCertContext
->hCertStore
)
1150 CertFreeCertificateContext(pCertContext
);
1154 PWINECRYPT_CERTSTORE hcs
=
1155 (PWINECRYPT_CERTSTORE
)pCertContext
->hCertStore
;
1157 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1160 ret
= hcs
->certs
.deleteContext(hcs
, (void *)pCertContext
);
1161 CertFreeCertificateContext(pCertContext
);
1166 #define CrlContext_CopyProperties(to, from) \
1167 Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
1169 BOOL WINAPI
CertAddCRLContextToStore(HCERTSTORE hCertStore
,
1170 PCCRL_CONTEXT pCrlContext
, DWORD dwAddDisposition
,
1171 PCCRL_CONTEXT
* ppStoreContext
)
1173 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1175 PCCRL_CONTEXT toAdd
= NULL
, existing
= NULL
;
1177 TRACE("(%p, %p, %08x, %p)\n", hCertStore
, pCrlContext
,
1178 dwAddDisposition
, ppStoreContext
);
1180 /* Weird case to pass a test */
1181 if (dwAddDisposition
== 0)
1183 SetLastError(STATUS_ACCESS_VIOLATION
);
1186 if (dwAddDisposition
!= CERT_STORE_ADD_ALWAYS
)
1188 existing
= CertFindCRLInStore(hCertStore
, 0, 0, CRL_FIND_EXISTING
,
1192 switch (dwAddDisposition
)
1194 case CERT_STORE_ADD_ALWAYS
:
1195 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1197 case CERT_STORE_ADD_NEW
:
1200 TRACE("found matching CRL, not adding\n");
1201 SetLastError(CRYPT_E_EXISTS
);
1205 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1207 case CERT_STORE_ADD_NEWER
:
1210 LONG newer
= CompareFileTime(&existing
->pCrlInfo
->ThisUpdate
,
1211 &pCrlContext
->pCrlInfo
->ThisUpdate
);
1214 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1217 TRACE("existing CRL is newer, not adding\n");
1218 SetLastError(CRYPT_E_EXISTS
);
1223 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1225 case CERT_STORE_ADD_REPLACE_EXISTING
:
1226 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1228 case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
:
1229 toAdd
= CertDuplicateCRLContext(pCrlContext
);
1231 CrlContext_CopyProperties(toAdd
, existing
);
1233 case CERT_STORE_ADD_USE_EXISTING
:
1235 CrlContext_CopyProperties(existing
, pCrlContext
);
1238 FIXME("Unimplemented add disposition %d\n", dwAddDisposition
);
1245 ret
= store
->crls
.addContext(store
, (void *)toAdd
,
1246 (void *)existing
, (const void **)ppStoreContext
);
1247 else if (ppStoreContext
)
1248 *ppStoreContext
= CertDuplicateCRLContext(toAdd
);
1249 CertFreeCRLContext(toAdd
);
1251 CertFreeCRLContext(existing
);
1253 TRACE("returning %d\n", ret
);
1257 BOOL WINAPI
CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext
)
1261 TRACE("(%p)\n", pCrlContext
);
1265 else if (!pCrlContext
->hCertStore
)
1268 CertFreeCRLContext(pCrlContext
);
1272 PWINECRYPT_CERTSTORE hcs
=
1273 (PWINECRYPT_CERTSTORE
)pCrlContext
->hCertStore
;
1275 if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1278 ret
= hcs
->crls
.deleteContext(hcs
, (void *)pCrlContext
);
1279 CertFreeCRLContext(pCrlContext
);
1284 PCCRL_CONTEXT WINAPI
CertEnumCRLsInStore(HCERTSTORE hCertStore
,
1285 PCCRL_CONTEXT pPrev
)
1287 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1290 TRACE("(%p, %p)\n", hCertStore
, pPrev
);
1293 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1296 ret
= (PCCRL_CONTEXT
)hcs
->crls
.enumContext(hcs
, (void *)pPrev
);
1300 PCCTL_CONTEXT WINAPI
CertCreateCTLContext(DWORD dwCertEncodingType
,
1301 const BYTE
* pbCtlEncoded
, DWORD cbCtlEncoded
)
1303 FIXME("(%08x, %p, %08x): stub\n", dwCertEncodingType
, pbCtlEncoded
,
1308 BOOL WINAPI
CertAddEncodedCTLToStore(HCERTSTORE hCertStore
,
1309 DWORD dwMsgAndCertEncodingType
, const BYTE
*pbCtlEncoded
, DWORD cbCtlEncoded
,
1310 DWORD dwAddDisposition
, PCCTL_CONTEXT
*ppCtlContext
)
1312 FIXME("(%p, %08x, %p, %d, %08x, %p): stub\n", hCertStore
,
1313 dwMsgAndCertEncodingType
, pbCtlEncoded
, cbCtlEncoded
, dwAddDisposition
,
1318 BOOL WINAPI
CertAddCTLContextToStore(HCERTSTORE hCertStore
,
1319 PCCTL_CONTEXT pCtlContext
, DWORD dwAddDisposition
,
1320 PCCTL_CONTEXT
* ppStoreContext
)
1322 FIXME("(%p, %p, %08x, %p): stub\n", hCertStore
, pCtlContext
,
1323 dwAddDisposition
, ppStoreContext
);
1327 PCCTL_CONTEXT WINAPI
CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext
)
1329 FIXME("(%p): stub\n", pCtlContext
);
1333 BOOL WINAPI
CertFreeCTLContext(PCCTL_CONTEXT pCtlContext
)
1335 FIXME("(%p): stub\n", pCtlContext
);
1339 BOOL WINAPI
CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext
)
1341 FIXME("(%p): stub\n", pCtlContext
);
1345 PCCTL_CONTEXT WINAPI
CertEnumCTLsInStore(HCERTSTORE hCertStore
,
1346 PCCTL_CONTEXT pPrev
)
1348 FIXME("(%p, %p): stub\n", hCertStore
, pPrev
);
1352 HCERTSTORE WINAPI
CertDuplicateStore(HCERTSTORE hCertStore
)
1354 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1356 TRACE("(%p)\n", hCertStore
);
1358 if (hcs
&& hcs
->dwMagic
== WINE_CRYPTCERTSTORE_MAGIC
)
1359 InterlockedIncrement(&hcs
->ref
);
1363 BOOL WINAPI
CertCloseStore(HCERTSTORE hCertStore
, DWORD dwFlags
)
1365 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*) hCertStore
;
1367 TRACE("(%p, %08x)\n", hCertStore
, dwFlags
);
1372 if ( hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1375 if (InterlockedDecrement(&hcs
->ref
) == 0)
1377 TRACE("%p's ref count is 0, freeing\n", hcs
);
1379 if (!(hcs
->dwOpenFlags
& CERT_STORE_NO_CRYPT_RELEASE_FLAG
))
1380 CryptReleaseContext(hcs
->cryptProv
, 0);
1381 hcs
->closeStore(hcs
, dwFlags
);
1384 TRACE("%p's ref count is %d\n", hcs
, hcs
->ref
);
1388 BOOL WINAPI
CertControlStore(HCERTSTORE hCertStore
, DWORD dwFlags
,
1389 DWORD dwCtrlType
, void const *pvCtrlPara
)
1391 WINECRYPT_CERTSTORE
*hcs
= (WINECRYPT_CERTSTORE
*)hCertStore
;
1394 TRACE("(%p, %08x, %d, %p)\n", hCertStore
, dwFlags
, dwCtrlType
,
1399 else if (hcs
->dwMagic
!= WINE_CRYPTCERTSTORE_MAGIC
)
1404 ret
= hcs
->control(hCertStore
, dwFlags
, dwCtrlType
, pvCtrlPara
);
1411 BOOL WINAPI
CertGetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1412 void *pvData
, DWORD
*pcbData
)
1414 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1417 TRACE("(%p, %d, %p, %p)\n", hCertStore
, dwPropId
, pvData
, pcbData
);
1421 case CERT_ACCESS_STATE_PROP_ID
:
1424 *pcbData
= sizeof(DWORD
);
1427 else if (*pcbData
< sizeof(DWORD
))
1429 SetLastError(ERROR_MORE_DATA
);
1430 *pcbData
= sizeof(DWORD
);
1436 if (store
->type
!= StoreTypeMem
&&
1437 !(store
->dwOpenFlags
& CERT_STORE_READONLY_FLAG
))
1438 state
|= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
;
1439 *(DWORD
*)pvData
= state
;
1444 if (store
->properties
)
1446 CRYPT_DATA_BLOB blob
;
1448 ret
= ContextPropertyList_FindProperty(store
->properties
, dwPropId
,
1453 *pcbData
= blob
.cbData
;
1454 else if (*pcbData
< blob
.cbData
)
1456 SetLastError(ERROR_MORE_DATA
);
1457 *pcbData
= blob
.cbData
;
1462 memcpy(pvData
, blob
.pbData
, blob
.cbData
);
1463 *pcbData
= blob
.cbData
;
1467 SetLastError(CRYPT_E_NOT_FOUND
);
1470 SetLastError(CRYPT_E_NOT_FOUND
);
1475 BOOL WINAPI
CertSetStoreProperty(HCERTSTORE hCertStore
, DWORD dwPropId
,
1476 DWORD dwFlags
, const void *pvData
)
1478 PWINECRYPT_CERTSTORE store
= (PWINECRYPT_CERTSTORE
)hCertStore
;
1481 TRACE("(%p, %d, %08x, %p)\n", hCertStore
, dwPropId
, dwFlags
, pvData
);
1483 if (!store
->properties
)
1484 store
->properties
= ContextPropertyList_Create();
1487 case CERT_ACCESS_STATE_PROP_ID
:
1488 SetLastError(E_INVALIDARG
);
1493 const CRYPT_DATA_BLOB
*blob
= (const CRYPT_DATA_BLOB
*)pvData
;
1495 ret
= ContextPropertyList_SetProperty(store
->properties
, dwPropId
,
1496 blob
->pbData
, blob
->cbData
);
1500 ContextPropertyList_RemoveProperty(store
->properties
, dwPropId
);
1507 DWORD WINAPI
CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext
,
1510 FIXME("(%p, %d): stub\n", pCTLContext
, dwPropId
);
1514 BOOL WINAPI
CertGetCTLContextProperty(PCCTL_CONTEXT pCTLContext
,
1515 DWORD dwPropId
, void *pvData
, DWORD
*pcbData
)
1517 FIXME("(%p, %d, %p, %p): stub\n", pCTLContext
, dwPropId
, pvData
, pcbData
);
1521 BOOL WINAPI
CertSetCTLContextProperty(PCCTL_CONTEXT pCTLContext
,
1522 DWORD dwPropId
, DWORD dwFlags
, const void *pvData
)
1524 FIXME("(%p, %d, %08x, %p): stub\n", pCTLContext
, dwPropId
, dwFlags
,
1529 static LONG
CRYPT_OpenParentStore(DWORD dwFlags
,
1530 void *pvSystemStoreLocationPara
, HKEY
*key
)
1535 TRACE("(%08x, %p)\n", dwFlags
, pvSystemStoreLocationPara
);
1537 switch (dwFlags
& CERT_SYSTEM_STORE_LOCATION_MASK
)
1539 case CERT_SYSTEM_STORE_LOCAL_MACHINE
:
1540 root
= HKEY_LOCAL_MACHINE
;
1541 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1543 case CERT_SYSTEM_STORE_CURRENT_USER
:
1544 root
= HKEY_CURRENT_USER
;
1545 base
= CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH
;
1547 case CERT_SYSTEM_STORE_CURRENT_SERVICE
:
1548 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1549 * SystemCertificates
1551 FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
1552 return ERROR_FILE_NOT_FOUND
;
1553 case CERT_SYSTEM_STORE_SERVICES
:
1554 /* hklm\Software\Microsoft\Cryptography\Services\servicename\
1555 * SystemCertificates
1557 FIXME("CERT_SYSTEM_STORE_SERVICES\n");
1558 return ERROR_FILE_NOT_FOUND
;
1559 case CERT_SYSTEM_STORE_USERS
:
1560 /* hku\user sid\Software\Microsoft\SystemCertificates */
1561 FIXME("CERT_SYSTEM_STORE_USERS\n");
1562 return ERROR_FILE_NOT_FOUND
;
1563 case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
:
1564 root
= HKEY_CURRENT_USER
;
1565 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1567 case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
:
1568 root
= HKEY_LOCAL_MACHINE
;
1569 base
= CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH
;
1571 case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
:
1572 /* hklm\Software\Microsoft\EnterpriseCertificates */
1573 FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
1574 return ERROR_FILE_NOT_FOUND
;
1576 return ERROR_FILE_NOT_FOUND
;
1579 return RegOpenKeyExW(root
, base
, 0, KEY_READ
, key
);
1582 BOOL WINAPI
CertEnumSystemStore(DWORD dwFlags
, void *pvSystemStoreLocationPara
,
1583 void *pvArg
, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
)
1589 TRACE("(%08x, %p, %p, %p)\n", dwFlags
, pvSystemStoreLocationPara
, pvArg
,
1592 rc
= CRYPT_OpenParentStore(dwFlags
, pvArg
, &key
);
1596 CERT_SYSTEM_STORE_INFO info
= { sizeof(info
) };
1600 WCHAR name
[MAX_PATH
];
1601 DWORD size
= sizeof(name
) / sizeof(name
[0]);
1603 rc
= RegEnumKeyExW(key
, index
++, name
, &size
, NULL
, NULL
, NULL
,
1606 ret
= pfnEnum(name
, 0, &info
, NULL
, pvArg
);
1607 } while (ret
&& !rc
);
1608 if (ret
&& rc
!= ERROR_NO_MORE_ITEMS
)