2006-04-16 19:15:04 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2002 Mike McCormack for CodeWeavers
|
|
|
|
* Copyright 2004-2006 Juan Lang
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2006-07-06 10:19:03 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2006-04-16 19:15:04 +00:00
|
|
|
*
|
|
|
|
* FIXME:
|
|
|
|
* - The concept of physical stores and locations isn't implemented. (This
|
|
|
|
* doesn't mean registry stores et al aren't implemented. See the PSDK for
|
|
|
|
* registering and enumerating physical stores and locations.)
|
|
|
|
* - Many flags, options and whatnot are unimplemented.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "crypt32_private.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
|
|
|
|
|
|
|
static const WINE_CONTEXT_INTERFACE gCertInterface = {
|
|
|
|
(CreateContextFunc)CertCreateCertificateContext,
|
|
|
|
(AddContextToStoreFunc)CertAddCertificateContextToStore,
|
|
|
|
(AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore,
|
|
|
|
(EnumContextsInStoreFunc)CertEnumCertificatesInStore,
|
2006-07-06 10:19:03 +00:00
|
|
|
(EnumPropertiesFunc)CertEnumCertificateContextProperties,
|
2006-04-16 19:15:04 +00:00
|
|
|
(GetContextPropertyFunc)CertGetCertificateContextProperty,
|
|
|
|
(SetContextPropertyFunc)CertSetCertificateContextProperty,
|
|
|
|
(SerializeElementFunc)CertSerializeCertificateStoreElement,
|
2008-05-10 18:43:43 +00:00
|
|
|
(DeleteContextFunc)CertDeleteCertificateFromStore,
|
|
|
|
};
|
2014-04-22 15:10:43 +00:00
|
|
|
const WINE_CONTEXT_INTERFACE *pCertInterface = &gCertInterface;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static const WINE_CONTEXT_INTERFACE gCRLInterface = {
|
|
|
|
(CreateContextFunc)CertCreateCRLContext,
|
|
|
|
(AddContextToStoreFunc)CertAddCRLContextToStore,
|
|
|
|
(AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
|
|
|
|
(EnumContextsInStoreFunc)CertEnumCRLsInStore,
|
|
|
|
(EnumPropertiesFunc)CertEnumCRLContextProperties,
|
|
|
|
(GetContextPropertyFunc)CertGetCRLContextProperty,
|
|
|
|
(SetContextPropertyFunc)CertSetCRLContextProperty,
|
|
|
|
(SerializeElementFunc)CertSerializeCRLStoreElement,
|
|
|
|
(DeleteContextFunc)CertDeleteCRLFromStore,
|
|
|
|
};
|
2014-04-22 15:10:43 +00:00
|
|
|
const WINE_CONTEXT_INTERFACE *pCRLInterface = &gCRLInterface;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static const WINE_CONTEXT_INTERFACE gCTLInterface = {
|
|
|
|
(CreateContextFunc)CertCreateCTLContext,
|
|
|
|
(AddContextToStoreFunc)CertAddCTLContextToStore,
|
|
|
|
(AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
|
|
|
|
(EnumContextsInStoreFunc)CertEnumCTLsInStore,
|
|
|
|
(EnumPropertiesFunc)CertEnumCTLContextProperties,
|
|
|
|
(GetContextPropertyFunc)CertGetCTLContextProperty,
|
|
|
|
(SetContextPropertyFunc)CertSetCTLContextProperty,
|
|
|
|
(SerializeElementFunc)CertSerializeCTLStoreElement,
|
|
|
|
(DeleteContextFunc)CertDeleteCTLFromStore,
|
|
|
|
};
|
2014-04-22 15:10:43 +00:00
|
|
|
const WINE_CONTEXT_INTERFACE *pCTLInterface = &gCTLInterface;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
typedef struct _WINE_MEMSTORE
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINECRYPT_CERTSTORE hdr;
|
2014-04-22 15:10:43 +00:00
|
|
|
CRITICAL_SECTION cs;
|
|
|
|
struct list certs;
|
|
|
|
struct list crls;
|
|
|
|
struct list ctls;
|
|
|
|
} WINE_MEMSTORE;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags, CertStoreType type, const store_vtbl_t *vtbl)
|
2008-05-10 18:43:43 +00:00
|
|
|
{
|
|
|
|
store->ref = 1;
|
|
|
|
store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
|
|
|
|
store->type = type;
|
|
|
|
store->dwOpenFlags = dwFlags;
|
2014-04-22 15:10:43 +00:00
|
|
|
store->vtbl = vtbl;
|
2008-05-10 18:43:43 +00:00
|
|
|
store->properties = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
void CRYPT_FreeStore(WINECRYPT_CERTSTORE *store)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
if (store->properties)
|
|
|
|
ContextPropertyList_Free(store->properties);
|
2014-04-22 15:10:43 +00:00
|
|
|
store->dwMagic = 0;
|
2008-05-10 18:43:43 +00:00
|
|
|
CryptMemFree(store);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
|
|
|
|
DWORD unk1)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
static BOOL warned = FALSE;
|
|
|
|
const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
|
|
|
|
pCRLInterface, pCTLInterface };
|
|
|
|
DWORD i;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
|
|
|
|
if (!warned)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
FIXME("semi-stub\n");
|
|
|
|
warned = TRUE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
/* Poor-man's resync: empty first store, then add everything from second
|
|
|
|
* store to it.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
|
|
|
|
{
|
|
|
|
const void *context;
|
|
|
|
|
|
|
|
do {
|
|
|
|
context = interfaces[i]->enumContextsInStore(store1, NULL);
|
|
|
|
if (context)
|
|
|
|
interfaces[i]->deleteFromStore(context);
|
|
|
|
} while (context);
|
|
|
|
do {
|
|
|
|
context = interfaces[i]->enumContextsInStore(store2, context);
|
|
|
|
if (context)
|
|
|
|
interfaces[i]->addContextToStore(store1, context,
|
|
|
|
CERT_STORE_ADD_ALWAYS, NULL);
|
|
|
|
} while (context);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
return TRUE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static BOOL MemStore_addContext(WINE_MEMSTORE *store, struct list *list, context_t *orig_context,
|
|
|
|
context_t *existing, context_t **ret_context, BOOL use_link)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
context_t *context;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
context = orig_context->vtbl->clone(orig_context, &store->hdr, use_link);
|
|
|
|
if (!context)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
TRACE("adding %p\n", context);
|
|
|
|
EnterCriticalSection(&store->cs);
|
|
|
|
if (existing) {
|
|
|
|
context->u.entry.prev = existing->u.entry.prev;
|
|
|
|
context->u.entry.next = existing->u.entry.next;
|
|
|
|
context->u.entry.prev->next = &context->u.entry;
|
|
|
|
context->u.entry.next->prev = &context->u.entry;
|
|
|
|
list_init(&existing->u.entry);
|
|
|
|
if(!existing->ref)
|
|
|
|
Context_Release(existing);
|
|
|
|
}else {
|
|
|
|
list_add_head(list, &context->u.entry);
|
|
|
|
}
|
|
|
|
LeaveCriticalSection(&store->cs);
|
|
|
|
|
|
|
|
if(ret_context)
|
|
|
|
*ret_context = context;
|
|
|
|
else
|
|
|
|
Context_Release(context);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static context_t *MemStore_enumContext(WINE_MEMSTORE *store, struct list *list, context_t *prev)
|
|
|
|
{
|
|
|
|
struct list *next;
|
|
|
|
context_t *ret;
|
|
|
|
|
|
|
|
EnterCriticalSection(&store->cs);
|
|
|
|
if (prev) {
|
|
|
|
next = list_next(list, &prev->u.entry);
|
|
|
|
Context_Release(prev);
|
|
|
|
}else {
|
|
|
|
next = list_next(list, list);
|
|
|
|
}
|
|
|
|
LeaveCriticalSection(&store->cs);
|
|
|
|
|
|
|
|
if (!next) {
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
ret = LIST_ENTRY(next, context_t, u.entry);
|
|
|
|
Context_AddRef(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL MemStore_deleteContext(WINE_MEMSTORE *store, context_t *context)
|
|
|
|
{
|
|
|
|
BOOL in_list = FALSE;
|
|
|
|
|
|
|
|
EnterCriticalSection(&store->cs);
|
|
|
|
if (!list_empty(&context->u.entry)) {
|
|
|
|
list_remove(&context->u.entry);
|
|
|
|
list_init(&context->u.entry);
|
|
|
|
in_list = TRUE;
|
|
|
|
}
|
|
|
|
LeaveCriticalSection(&store->cs);
|
|
|
|
|
|
|
|
if(in_list && !context->ref)
|
|
|
|
Context_Free(context);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_contexts(struct list *list)
|
|
|
|
{
|
|
|
|
context_t *context, *next;
|
|
|
|
|
|
|
|
LIST_FOR_EACH_ENTRY_SAFE(context, next, list, context_t, u.entry)
|
2008-05-10 18:43:43 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("freeing %p\n", context);
|
|
|
|
list_remove(&context->u.entry);
|
|
|
|
Context_Free(context);
|
2008-05-10 18:43:43 +00:00
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static void MemStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
|
|
|
|
{
|
|
|
|
/* Free the context only if it's not in a list. Otherwise it may be reused later. */
|
|
|
|
if(list_empty(&context->u.entry))
|
|
|
|
Context_Free(context);
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL MemStore_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
|
|
|
|
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
|
|
|
|
return MemStore_addContext(ms, &ms->certs, cert, toReplace, ppStoreContext, use_link);
|
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static context_t *MemStore_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
|
|
|
|
{
|
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("(%p, %p)\n", store, prev);
|
|
|
|
|
|
|
|
return MemStore_enumContext(ms, &ms->certs, prev);
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static BOOL MemStore_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("(%p, %p)\n", store, context);
|
|
|
|
|
|
|
|
return MemStore_deleteContext(ms, context);
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static BOOL MemStore_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
|
|
|
|
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
2006-07-06 10:19:03 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
|
2006-07-06 10:19:03 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
return MemStore_addContext(ms, &ms->crls, crl, toReplace, ppStoreContext, use_link);
|
2006-07-06 10:19:03 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static context_t *MemStore_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("(%p, %p)\n", store, prev);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
return MemStore_enumContext(ms, &ms->crls, prev);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static BOOL MemStore_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("(%p, %p)\n", store, context);
|
|
|
|
|
|
|
|
return MemStore_deleteContext(ms, context);
|
2008-05-10 18:43:43 +00:00
|
|
|
}
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static BOOL MemStore_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
|
|
|
|
context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
|
2008-09-14 11:32:55 +00:00
|
|
|
{
|
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
return MemStore_addContext(ms, &ms->ctls, ctl, toReplace, ppStoreContext, use_link);
|
2008-09-14 11:32:55 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static context_t *MemStore_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
|
2008-09-14 11:32:55 +00:00
|
|
|
{
|
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("(%p, %p)\n", store, prev);
|
2008-09-14 11:32:55 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
return MemStore_enumContext(ms, &ms->ctls, prev);
|
2008-09-14 11:32:55 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static BOOL MemStore_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
|
2008-09-14 11:32:55 +00:00
|
|
|
{
|
|
|
|
WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
TRACE("(%p, %p)\n", store, context);
|
|
|
|
|
|
|
|
return MemStore_deleteContext(ms, context);
|
2009-11-15 22:58:08 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static void MemStore_addref(WINECRYPT_CERTSTORE *store)
|
2009-11-15 22:58:08 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
LONG ref = InterlockedIncrement(&store->ref);
|
|
|
|
TRACE("ref = %d\n", ref);
|
2008-09-14 11:32:55 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static DWORD MemStore_release(WINECRYPT_CERTSTORE *cert_store, DWORD flags)
|
2008-05-10 18:43:43 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINE_MEMSTORE *store = (WINE_MEMSTORE*)cert_store;
|
|
|
|
LONG ref;
|
|
|
|
|
|
|
|
if(flags & ~CERT_CLOSE_STORE_CHECK_FLAG)
|
|
|
|
FIXME("Unimplemented flags %x\n", flags);
|
|
|
|
|
|
|
|
ref = InterlockedDecrement(&store->hdr.ref);
|
|
|
|
TRACE("(%p) ref=%d\n", store, ref);
|
|
|
|
if(ref)
|
|
|
|
return (flags & CERT_CLOSE_STORE_CHECK_FLAG) ? CRYPT_E_PENDING_CLOSE : ERROR_SUCCESS;
|
|
|
|
|
|
|
|
free_contexts(&store->certs);
|
|
|
|
free_contexts(&store->crls);
|
|
|
|
free_contexts(&store->ctls);
|
|
|
|
store->cs.DebugInfo->Spare[0] = 0;
|
|
|
|
DeleteCriticalSection(&store->cs);
|
|
|
|
CRYPT_FreeStore(&store->hdr);
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static BOOL MemStore_control(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
|
|
|
DWORD dwCtrlType, void const *pvCtrlPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static const store_vtbl_t MemStoreVtbl = {
|
|
|
|
MemStore_addref,
|
|
|
|
MemStore_release,
|
|
|
|
MemStore_releaseContext,
|
|
|
|
MemStore_control,
|
|
|
|
{
|
|
|
|
MemStore_addCert,
|
|
|
|
MemStore_enumCert,
|
|
|
|
MemStore_deleteCert
|
|
|
|
}, {
|
|
|
|
MemStore_addCRL,
|
|
|
|
MemStore_enumCRL,
|
|
|
|
MemStore_deleteCRL
|
|
|
|
}, {
|
|
|
|
MemStore_addCTL,
|
|
|
|
MemStore_enumCTL,
|
|
|
|
MemStore_deleteCTL
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINE_MEMSTORE *store;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
store = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
|
|
|
|
if (store)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
memset(store, 0, sizeof(WINE_MEMSTORE));
|
2014-04-22 15:10:43 +00:00
|
|
|
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem, &MemStoreVtbl);
|
|
|
|
InitializeCriticalSection(&store->cs);
|
|
|
|
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs");
|
|
|
|
list_init(&store->certs);
|
|
|
|
list_init(&store->crls);
|
|
|
|
list_init(&store->ctls);
|
2008-05-10 18:43:43 +00:00
|
|
|
/* Mem store doesn't need crypto provider, so close it */
|
|
|
|
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
|
|
|
CryptReleaseContext(hCryptProv, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
}
|
2014-04-22 15:10:43 +00:00
|
|
|
return (WINECRYPT_CERTSTORE*)store;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 14:28:46 +00:00
|
|
|
static const WCHAR rootW[] = { 'R','o','o','t',0 };
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
|
2009-01-31 14:28:46 +00:00
|
|
|
LPCWSTR storeName = pvPara;
|
2006-04-16 19:15:04 +00:00
|
|
|
LPWSTR storePath;
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *store = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
HKEY root;
|
|
|
|
LPCWSTR base;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_w(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
|
|
|
{
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
2016-11-22 17:05:59 +00:00
|
|
|
/* If the HKLM\Root certs are requested, expressing system certs into the registry */
|
|
|
|
if (!lstrcmpiW(storeName, rootW))
|
|
|
|
CRYPT_ImportSystemRootCertsToReg();
|
2006-04-16 19:15:04 +00:00
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_SERVICE:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
case CERT_SYSTEM_STORE_SERVICES:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
case CERT_SYSTEM_STORE_USERS:
|
|
|
|
/* hku\user sid\Software\Microsoft\SystemCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
|
|
|
|
/* hklm\Software\Microsoft\EnterpriseCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
|
|
|
|
debugstr_w(storeName));
|
|
|
|
return NULL;
|
|
|
|
default:
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
|
|
|
|
sizeof(WCHAR));
|
|
|
|
if (storePath)
|
|
|
|
{
|
|
|
|
LONG rc;
|
|
|
|
HKEY key;
|
|
|
|
REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
|
|
|
|
KEY_ALL_ACCESS;
|
|
|
|
|
|
|
|
wsprintfW(storePath, fmt, base, storeName);
|
|
|
|
if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
|
|
|
|
rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DWORD disp;
|
|
|
|
|
|
|
|
rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
|
|
|
|
&key, &disp);
|
|
|
|
if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
|
|
|
|
disp == REG_OPENED_EXISTING_KEY)
|
|
|
|
{
|
|
|
|
RegCloseKey(key);
|
|
|
|
rc = ERROR_FILE_EXISTS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!rc)
|
|
|
|
{
|
|
|
|
store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
|
|
|
|
RegCloseKey(key);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(rc);
|
|
|
|
CryptMemFree(storePath);
|
|
|
|
}
|
|
|
|
return store;
|
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
int len;
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *ret = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_a(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-31 14:28:46 +00:00
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
|
|
|
|
|
|
|
|
if (storeName)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
|
2006-04-16 19:15:04 +00:00
|
|
|
ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
|
|
|
|
CryptMemFree(storeName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
HCERTSTORE store = 0;
|
|
|
|
BOOL ret;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_w(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* This returns a different error than system registry stores if the
|
|
|
|
* location is invalid.
|
|
|
|
*/
|
|
|
|
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
|
|
|
{
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER:
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_SERVICE:
|
|
|
|
case CERT_SYSTEM_STORE_SERVICES:
|
|
|
|
case CERT_SYSTEM_STORE_USERS:
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
|
|
|
|
ret = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
|
2008-05-10 18:43:43 +00:00
|
|
|
0, 0, dwFlags, pvPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (regStore)
|
|
|
|
{
|
|
|
|
store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
|
|
|
|
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
|
|
|
CertAddStoreToCollection(store, regStore,
|
|
|
|
dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
|
|
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
|
|
|
|
CertCloseStore(regStore, 0);
|
|
|
|
/* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
|
|
|
|
* stores.
|
|
|
|
*/
|
|
|
|
if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
|
|
|
|
CERT_SYSTEM_STORE_CURRENT_USER)
|
|
|
|
{
|
|
|
|
dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
|
|
|
|
dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
|
|
|
|
regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
|
2008-05-10 18:43:43 +00:00
|
|
|
0, dwFlags, pvPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
if (regStore)
|
|
|
|
{
|
|
|
|
CertAddStoreToCollection(store, regStore,
|
|
|
|
dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
|
|
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
|
|
|
|
CertCloseStore(regStore, 0);
|
|
|
|
}
|
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
/* System store doesn't need crypto provider, so close it */
|
|
|
|
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
|
|
|
CryptReleaseContext(hCryptProv, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
}
|
2009-01-31 14:28:46 +00:00
|
|
|
return store;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
int len;
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *ret = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_a(pvPara));
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if (!pvPara)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-31 14:28:46 +00:00
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
|
2006-04-16 19:15:04 +00:00
|
|
|
if (len)
|
|
|
|
{
|
|
|
|
LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
|
|
|
|
|
|
|
|
if (storeName)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
|
2008-05-10 18:43:43 +00:00
|
|
|
ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
|
|
|
|
CryptMemFree(storeName);
|
|
|
|
}
|
2007-04-26 13:37:57 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|
|
|
{
|
|
|
|
HCRYPTMSG msg = hCertStore;
|
|
|
|
|
|
|
|
TRACE("(%p, %08x)\n", msg, dwFlags);
|
|
|
|
CryptMsgClose(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *msgProvFuncs[] = {
|
|
|
|
CRYPT_MsgCloseStore,
|
2007-04-26 13:37:57 +00:00
|
|
|
};
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
|
2007-04-26 13:37:57 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *store = NULL;
|
2008-05-10 18:43:43 +00:00
|
|
|
HCRYPTMSG msg = (HCRYPTMSG)pvPara;
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *memStore;
|
2007-04-26 13:37:57 +00:00
|
|
|
|
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
|
|
|
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
|
|
|
if (memStore)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret;
|
|
|
|
DWORD size, count, i;
|
2007-04-26 13:37:57 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
size = sizeof(count);
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
|
|
|
|
for (i = 0; ret && i < count; i++)
|
|
|
|
{
|
|
|
|
size = 0;
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
LPBYTE buf = CryptMemAlloc(size);
|
2007-04-26 13:37:57 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
if (buf)
|
|
|
|
{
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
|
|
|
|
if (ret)
|
|
|
|
ret = CertAddEncodedCertificateToStore(memStore,
|
|
|
|
X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
|
|
|
|
NULL);
|
|
|
|
CryptMemFree(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size = sizeof(count);
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
|
|
|
|
for (i = 0; ret && i < count; i++)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
size = 0;
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
|
|
|
|
if (ret)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
LPBYTE buf = CryptMemAlloc(size);
|
2007-04-26 13:37:57 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
if (buf)
|
2007-04-26 13:37:57 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
|
|
|
|
if (ret)
|
|
|
|
ret = CertAddEncodedCRLToStore(memStore,
|
|
|
|
X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
|
|
|
|
NULL);
|
|
|
|
CryptMemFree(buf);
|
2007-04-26 13:37:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
CERT_STORE_PROV_INFO provInfo = { 0 };
|
|
|
|
|
|
|
|
provInfo.cbSize = sizeof(provInfo);
|
|
|
|
provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
|
|
|
|
sizeof(msgProvFuncs[0]);
|
|
|
|
provInfo.rgpvStoreProvFunc = msgProvFuncs;
|
|
|
|
provInfo.hStoreProv = CryptMsgDuplicate(msg);
|
|
|
|
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
|
|
|
/* Msg store doesn't need crypto provider, so close it */
|
|
|
|
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
|
|
|
CryptReleaseContext(hCryptProv, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
CertCloseStore(memStore, 0);
|
2007-04-26 13:37:57 +00:00
|
|
|
}
|
|
|
|
TRACE("returning %p\n", store);
|
|
|
|
return store;
|
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
|
2006-07-21 11:13:18 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
HCRYPTMSG msg;
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *store = NULL;
|
2009-01-31 14:28:46 +00:00
|
|
|
const CRYPT_DATA_BLOB *data = pvPara;
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret;
|
|
|
|
DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
|
|
|
|
CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
|
2006-07-21 11:13:18 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
2006-07-21 11:13:18 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
|
|
|
|
hCryptProv, NULL, NULL);
|
|
|
|
ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
|
|
|
|
if (!ret)
|
2006-07-21 11:13:18 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
CryptMsgClose(msg);
|
|
|
|
msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
|
|
|
|
hCryptProv, NULL, NULL);
|
|
|
|
ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
|
|
|
|
if (ret)
|
2006-07-21 11:13:18 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
DWORD type, size = sizeof(type);
|
|
|
|
|
|
|
|
/* Only signed messages are allowed, check type */
|
|
|
|
ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
|
|
|
|
if (ret && type != CMSG_SIGNED)
|
|
|
|
{
|
|
|
|
SetLastError(CRYPT_E_INVALID_MSG_TYPE);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
2006-07-21 11:13:18 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
if (ret)
|
|
|
|
store = CRYPT_MsgOpenStore(0, dwFlags, msg);
|
|
|
|
CryptMsgClose(msg);
|
|
|
|
TRACE("returning %p\n", store);
|
|
|
|
return store;
|
2006-07-21 11:13:18 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
HCERTSTORE store;
|
|
|
|
const CRYPT_DATA_BLOB *data = pvPara;
|
|
|
|
|
|
|
|
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
|
|
|
|
|
|
|
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
|
|
|
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
|
|
|
if (store)
|
|
|
|
{
|
|
|
|
if (!CRYPT_ReadSerializedStoreFromBlob(data, store))
|
|
|
|
{
|
|
|
|
CertCloseStore(store, 0);
|
|
|
|
store = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TRACE("returning %p\n", store);
|
2014-04-22 15:10:43 +00:00
|
|
|
return (WINECRYPT_CERTSTORE*)store;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static WINECRYPT_CERTSTORE *CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
|
2006-07-21 11:13:18 +00:00
|
|
|
DWORD dwFlags, const void *pvPara)
|
|
|
|
{
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
2007-04-26 13:37:57 +00:00
|
|
|
FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
|
2006-07-21 11:13:18 +00:00
|
|
|
else
|
2007-04-26 13:37:57 +00:00
|
|
|
FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
|
2009-01-31 14:28:46 +00:00
|
|
|
debugstr_w(pvPara));
|
2006-07-21 11:13:18 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-04-16 19:15:04 +00:00
|
|
|
HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
|
2008-05-10 18:43:43 +00:00
|
|
|
DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
|
2006-04-16 19:15:04 +00:00
|
|
|
const void* pvPara)
|
|
|
|
{
|
|
|
|
WINECRYPT_CERTSTORE *hcs;
|
|
|
|
StoreOpenFunc openFunc = NULL;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
|
2006-04-16 19:15:04 +00:00
|
|
|
dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
|
|
|
|
|
2010-03-03 20:55:13 +00:00
|
|
|
if (IS_INTOID(lpszStoreProvider))
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
|
|
|
switch (LOWORD(lpszStoreProvider))
|
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_MSG):
|
|
|
|
openFunc = CRYPT_MsgOpenStore;
|
|
|
|
break;
|
|
|
|
case LOWORD(CERT_STORE_PROV_MEMORY):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_MemOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_FILE):
|
2007-04-26 13:37:57 +00:00
|
|
|
openFunc = CRYPT_FileOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_PKCS7):
|
|
|
|
openFunc = CRYPT_PKCSOpenStore;
|
|
|
|
break;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SERIALIZED):
|
|
|
|
openFunc = CRYPT_SerializedOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_REG):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_RegOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_FILENAME_A):
|
2006-07-21 11:13:18 +00:00
|
|
|
openFunc = CRYPT_FileNameOpenStoreA;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_FILENAME_W):
|
2006-07-21 11:13:18 +00:00
|
|
|
openFunc = CRYPT_FileNameOpenStoreW;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_COLLECTION):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_CollectionOpenStore;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_A):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysOpenStoreA;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_W):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysOpenStoreW;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysRegOpenStoreA;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
|
2006-04-16 19:15:04 +00:00
|
|
|
openFunc = CRYPT_SysRegOpenStoreW;
|
|
|
|
break;
|
2008-05-10 18:43:43 +00:00
|
|
|
case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
|
2006-07-21 11:13:18 +00:00
|
|
|
openFunc = CRYPT_PhysOpenStoreW;
|
|
|
|
break;
|
2006-04-16 19:15:04 +00:00
|
|
|
default:
|
|
|
|
if (LOWORD(lpszStoreProvider))
|
|
|
|
FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
|
|
|
|
openFunc = CRYPT_MemOpenStore;
|
2007-04-26 13:37:57 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
|
|
|
|
openFunc = CRYPT_FileOpenStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
|
|
|
|
openFunc = CRYPT_SysOpenStoreW;
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_PKCS7))
|
|
|
|
openFunc = CRYPT_PKCSOpenStore;
|
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SERIALIZED))
|
|
|
|
openFunc = CRYPT_SerializedOpenStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
|
|
|
|
openFunc = CRYPT_CollectionOpenStore;
|
|
|
|
else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
|
|
|
|
openFunc = CRYPT_SysRegOpenStoreW;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FIXME("unimplemented type %s\n", lpszStoreProvider);
|
|
|
|
openFunc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!openFunc)
|
|
|
|
hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
|
|
|
|
hCryptProv, dwFlags, pvPara);
|
|
|
|
else
|
|
|
|
hcs = openFunc(hCryptProv, dwFlags, pvPara);
|
2009-01-31 14:28:46 +00:00
|
|
|
return hcs;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
LPCSTR szSubSystemProtocol)
|
|
|
|
{
|
|
|
|
if (!szSubSystemProtocol)
|
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
|
|
|
|
CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
|
2006-04-16 19:15:04 +00:00
|
|
|
LPCWSTR szSubSystemProtocol)
|
|
|
|
{
|
|
|
|
if (!szSubSystemProtocol)
|
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(E_INVALIDARG);
|
2006-04-16 19:15:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
|
|
|
|
CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
|
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
cert_t *prev = pPrev ? cert_from_ptr(pPrev) : NULL, *ret;
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("(%p, %p)\n", hCertStore, pPrev);
|
|
|
|
if (!hCertStore)
|
|
|
|
ret = NULL;
|
|
|
|
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
ret = NULL;
|
|
|
|
else
|
2014-04-22 15:10:43 +00:00
|
|
|
ret = (cert_t*)hcs->vtbl->certs.enumContext(hcs, prev ? &prev->base : NULL);
|
|
|
|
return ret ? &ret->ctx : NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("(%p)\n", pCertContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
if (!pCertContext)
|
2014-04-22 15:10:43 +00:00
|
|
|
return TRUE;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
hcs = pCertContext->hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return hcs->vtbl->certs.delete(hcs, &cert_from_ptr(pCertContext)->base);
|
|
|
|
}
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
|
|
|
|
PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
|
|
|
|
PCCRL_CONTEXT* ppStoreContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *store = hCertStore;
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL ret = TRUE;
|
|
|
|
PCCRL_CONTEXT toAdd = NULL, existing = NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
|
2006-04-16 19:15:04 +00:00
|
|
|
dwAddDisposition, ppStoreContext);
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
/* Weird case to pass a test */
|
|
|
|
if (dwAddDisposition == 0)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
SetLastError(STATUS_ACCESS_VIOLATION);
|
2006-04-16 19:15:04 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
|
|
|
|
pCrlContext, NULL);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
switch (dwAddDisposition)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
case CERT_STORE_ADD_ALWAYS:
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_NEW:
|
|
|
|
if (existing)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("found matching CRL, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
else
|
2006-07-06 10:19:03 +00:00
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_NEWER:
|
|
|
|
if (existing)
|
|
|
|
{
|
|
|
|
LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
|
|
|
|
&pCrlContext->pCrlInfo->ThisUpdate);
|
|
|
|
|
|
|
|
if (newer < 0)
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TRACE("existing CRL is newer, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
2009-01-19 16:16:15 +00:00
|
|
|
case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
|
|
|
|
if (existing)
|
|
|
|
{
|
|
|
|
LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
|
|
|
|
&pCrlContext->pCrlInfo->ThisUpdate);
|
|
|
|
|
|
|
|
if (newer < 0)
|
|
|
|
{
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
2014-04-22 15:10:43 +00:00
|
|
|
Context_CopyProperties(toAdd, existing);
|
2009-01-19 16:16:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TRACE("existing CRL is newer, not adding\n");
|
|
|
|
SetLastError(CRYPT_E_EXISTS);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
2006-07-06 10:19:03 +00:00
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING:
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
|
|
|
if (existing)
|
2014-04-22 15:10:43 +00:00
|
|
|
Context_CopyProperties(toAdd, existing);
|
2006-07-06 10:19:03 +00:00
|
|
|
break;
|
|
|
|
case CERT_STORE_ADD_USE_EXISTING:
|
|
|
|
if (existing)
|
2010-01-03 11:59:38 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
Context_CopyProperties(existing, pCrlContext);
|
2010-01-03 11:59:38 +00:00
|
|
|
if (ppStoreContext)
|
|
|
|
*ppStoreContext = CertDuplicateCRLContext(existing);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
toAdd = CertDuplicateCRLContext(pCrlContext);
|
2006-07-06 10:19:03 +00:00
|
|
|
break;
|
|
|
|
default:
|
2007-04-26 13:37:57 +00:00
|
|
|
FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
|
2006-07-06 10:19:03 +00:00
|
|
|
ret = FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
if (toAdd)
|
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
if (store) {
|
|
|
|
context_t *ret_context;
|
|
|
|
ret = store->vtbl->crls.addContext(store, context_from_ptr(toAdd),
|
|
|
|
existing ? context_from_ptr(existing) : NULL, ppStoreContext ? &ret_context : NULL, FALSE);
|
|
|
|
if (ret && ppStoreContext)
|
|
|
|
*ppStoreContext = context_ptr(ret_context);
|
|
|
|
}else if (ppStoreContext) {
|
2006-07-06 10:19:03 +00:00
|
|
|
*ppStoreContext = CertDuplicateCRLContext(toAdd);
|
2014-04-22 15:10:43 +00:00
|
|
|
}
|
2006-07-06 10:19:03 +00:00
|
|
|
CertFreeCRLContext(toAdd);
|
|
|
|
}
|
2014-04-22 15:10:43 +00:00
|
|
|
if (existing)
|
|
|
|
CertFreeCRLContext(existing);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("returning %d\n", ret);
|
2006-04-16 19:15:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs;
|
2006-04-16 19:15:04 +00:00
|
|
|
BOOL ret;
|
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
TRACE("(%p)\n", pCrlContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2006-07-06 10:19:03 +00:00
|
|
|
if (!pCrlContext)
|
2014-04-22 15:10:43 +00:00
|
|
|
return TRUE;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
hcs = pCrlContext->hCertStore;
|
|
|
|
|
|
|
|
if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
ret = hcs->vtbl->crls.delete(hcs, &crl_from_ptr(pCrlContext)->base);
|
|
|
|
if (ret)
|
|
|
|
ret = CertFreeCRLContext(pCrlContext);
|
2006-04-16 19:15:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, PCCRL_CONTEXT pPrev)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
crl_t *ret, *prev = pPrev ? crl_from_ptr(pPrev) : NULL;
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-07-06 10:19:03 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", hCertStore, pPrev);
|
|
|
|
if (!hCertStore)
|
|
|
|
ret = NULL;
|
|
|
|
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
ret = NULL;
|
|
|
|
else
|
2014-04-22 15:10:43 +00:00
|
|
|
ret = (crl_t*)hcs->vtbl->crls.enumContext(hcs, prev ? &prev->base : NULL);
|
|
|
|
return ret ? &ret->ctx : NULL;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
TRACE("(%p)\n", hCertStore);
|
|
|
|
|
|
|
|
if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
|
2014-04-22 15:10:43 +00:00
|
|
|
hcs->vtbl->addref(hcs);
|
2006-04-16 19:15:04 +00:00
|
|
|
return hCertStore;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2014-04-22 15:10:43 +00:00
|
|
|
DWORD res;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%p, %08x)\n", hCertStore, dwFlags);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
|
|
|
if( ! hCertStore )
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
|
|
|
|
return FALSE;
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
res = hcs->vtbl->release(hcs, dwFlags);
|
|
|
|
if (res != ERROR_SUCCESS) {
|
|
|
|
SetLastError(res);
|
|
|
|
return FALSE;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2014-04-22 15:10:43 +00:00
|
|
|
|
2006-04-16 19:15:04 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
|
|
|
|
DWORD dwCtrlType, void const *pvCtrlPara)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
WINECRYPT_CERTSTORE *hcs = hCertStore;
|
2006-04-16 19:15:04 +00:00
|
|
|
BOOL ret;
|
|
|
|
|
2007-04-26 13:37:57 +00:00
|
|
|
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
2006-04-16 19:15:04 +00:00
|
|
|
pvCtrlPara);
|
|
|
|
|
|
|
|
if (!hcs)
|
|
|
|
ret = FALSE;
|
|
|
|
else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
|
|
|
ret = FALSE;
|
|
|
|
else
|
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
if (hcs->vtbl->control)
|
|
|
|
ret = hcs->vtbl->control(hcs, dwFlags, dwCtrlType, pvCtrlPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
else
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
|
|
|
|
void *pvData, DWORD *pcbData)
|
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *store = hCertStore;
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
|
|
|
TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
|
|
|
|
|
|
|
|
switch (dwPropId)
|
|
|
|
{
|
|
|
|
case CERT_ACCESS_STATE_PROP_ID:
|
|
|
|
if (!pvData)
|
|
|
|
{
|
|
|
|
*pcbData = sizeof(DWORD);
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
else if (*pcbData < sizeof(DWORD))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_MORE_DATA);
|
|
|
|
*pcbData = sizeof(DWORD);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DWORD state = 0;
|
|
|
|
|
|
|
|
if (store->type != StoreTypeMem &&
|
|
|
|
!(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
|
|
|
|
state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
|
|
|
|
*(DWORD *)pvData = state;
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (store->properties)
|
|
|
|
{
|
|
|
|
CRYPT_DATA_BLOB blob;
|
|
|
|
|
|
|
|
ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
|
|
|
|
&blob);
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
if (!pvData)
|
|
|
|
*pcbData = blob.cbData;
|
|
|
|
else if (*pcbData < blob.cbData)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_MORE_DATA);
|
|
|
|
*pcbData = blob.cbData;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(pvData, blob.pbData, blob.cbData);
|
|
|
|
*pcbData = blob.cbData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
|
|
|
|
DWORD dwFlags, const void *pvData)
|
|
|
|
{
|
2014-04-22 15:10:43 +00:00
|
|
|
WINECRYPT_CERTSTORE *store = hCertStore;
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
|
|
|
TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
|
|
|
|
|
|
|
|
if (!store->properties)
|
|
|
|
store->properties = ContextPropertyList_Create();
|
|
|
|
switch (dwPropId)
|
|
|
|
{
|
|
|
|
case CERT_ACCESS_STATE_PROP_ID:
|
|
|
|
SetLastError(E_INVALIDARG);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (pvData)
|
|
|
|
{
|
2009-01-31 14:28:46 +00:00
|
|
|
const CRYPT_DATA_BLOB *blob = pvData;
|
2008-05-10 18:43:43 +00:00
|
|
|
|
|
|
|
ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
|
|
|
|
blob->pbData, blob->cbData);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ContextPropertyList_RemoveProperty(store->properties, dwPropId);
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LONG CRYPT_OpenParentStore(DWORD dwFlags,
|
|
|
|
void *pvSystemStoreLocationPara, HKEY *key)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
HKEY root;
|
|
|
|
LPCWSTR base;
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_SERVICE:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
case CERT_SYSTEM_STORE_SERVICES:
|
|
|
|
/* hklm\Software\Microsoft\Cryptography\Services\servicename\
|
|
|
|
* SystemCertificates
|
|
|
|
*/
|
|
|
|
FIXME("CERT_SYSTEM_STORE_SERVICES\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
case CERT_SYSTEM_STORE_USERS:
|
|
|
|
/* hku\user sid\Software\Microsoft\SystemCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_USERS\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
|
|
|
|
root = HKEY_CURRENT_USER;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
|
|
|
|
root = HKEY_LOCAL_MACHINE;
|
|
|
|
base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
|
|
|
|
break;
|
|
|
|
case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
|
|
|
|
/* hklm\Software\Microsoft\EnterpriseCertificates */
|
|
|
|
FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
default:
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
return RegOpenKeyExW(root, base, 0, KEY_READ, key);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
|
|
|
|
void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
BOOL ret = FALSE;
|
|
|
|
LONG rc;
|
|
|
|
HKEY key;
|
2009-01-31 14:28:46 +00:00
|
|
|
CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
|
|
|
|
pfnEnum);
|
2006-04-16 19:15:04 +00:00
|
|
|
|
2008-05-10 18:43:43 +00:00
|
|
|
rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
|
|
|
|
if (!rc)
|
2006-04-16 19:15:04 +00:00
|
|
|
{
|
2008-05-10 18:43:43 +00:00
|
|
|
DWORD index = 0;
|
|
|
|
|
|
|
|
ret = TRUE;
|
|
|
|
do {
|
|
|
|
WCHAR name[MAX_PATH];
|
|
|
|
DWORD size = sizeof(name) / sizeof(name[0]);
|
|
|
|
|
|
|
|
rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
|
|
|
|
NULL);
|
|
|
|
if (!rc)
|
2008-12-27 11:03:19 +00:00
|
|
|
ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
|
2008-05-10 18:43:43 +00:00
|
|
|
} while (ret && !rc);
|
|
|
|
if (ret && rc != ERROR_NO_MORE_ITEMS)
|
|
|
|
SetLastError(rc);
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2008-05-10 18:43:43 +00:00
|
|
|
else
|
|
|
|
SetLastError(rc);
|
2009-01-31 14:28:46 +00:00
|
|
|
/* Include root store for the local machine location (it isn't in the
|
|
|
|
* registry)
|
|
|
|
*/
|
|
|
|
if (ret && (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
|
|
|
|
CERT_SYSTEM_STORE_LOCAL_MACHINE)
|
|
|
|
ret = pfnEnum(rootW, dwFlags, &info, NULL, pvArg);
|
2008-05-10 18:43:43 +00:00
|
|
|
return ret;
|
2006-04-16 19:15:04 +00:00
|
|
|
}
|
2008-12-27 11:03:19 +00:00
|
|
|
|
|
|
|
BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
|
|
|
|
void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
|
|
|
|
{
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
|
|
|
FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
|
|
|
|
pfnEnum);
|
|
|
|
else
|
2009-01-31 14:28:46 +00:00
|
|
|
FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore),
|
2008-12-27 11:03:19 +00:00
|
|
|
dwFlags, pvArg,
|
|
|
|
pfnEnum);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-01-23 15:45:15 +00:00
|
|
|
|
|
|
|
BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
|
|
|
|
LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved)
|
|
|
|
{
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
|
|
|
FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore, dwFlags,
|
|
|
|
debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
|
|
|
|
else
|
|
|
|
FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore),
|
|
|
|
dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2014-04-22 15:10:43 +00:00
|
|
|
|
2016-11-22 17:05:59 +00:00
|
|
|
BOOL WINAPI CertRegisterSystemStore(const void *pvSystemStore, DWORD dwFlags,
|
|
|
|
PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved)
|
|
|
|
{
|
|
|
|
HCERTSTORE hstore;
|
|
|
|
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG )
|
|
|
|
{
|
|
|
|
FIXME("(%p, %08x, %p, %p): flag not supported\n", pvSystemStore, dwFlags, pStoreInfo, pvReserved);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRACE("(%s, %08x, %p, %p)\n", debugstr_w(pvSystemStore), dwFlags, pStoreInfo, pvReserved);
|
|
|
|
|
|
|
|
hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags, pvSystemStore);
|
|
|
|
if (hstore)
|
|
|
|
{
|
|
|
|
CertCloseStore(hstore, 0);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI CertUnregisterSystemStore(void *pvSystemStore, DWORD dwFlags)
|
|
|
|
{
|
|
|
|
HCERTSTORE hstore;
|
|
|
|
|
|
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
|
|
|
{
|
|
|
|
FIXME("(%p, %08x): flag not supported\n", pvSystemStore, dwFlags);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
TRACE("(%s, %08x)\n", debugstr_w(pvSystemStore), dwFlags);
|
|
|
|
|
|
|
|
hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags | CERT_STORE_OPEN_EXISTING_FLAG, pvSystemStore);
|
|
|
|
if (hstore == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0, dwFlags | CERT_STORE_DELETE_FLAG, pvSystemStore);
|
|
|
|
if (hstore == NULL && GetLastError() == 0)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2014-04-22 15:10:43 +00:00
|
|
|
static void EmptyStore_addref(WINECRYPT_CERTSTORE *store)
|
|
|
|
{
|
|
|
|
TRACE("(%p)\n", store);
|
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD EmptyStore_release(WINECRYPT_CERTSTORE *store, DWORD flags)
|
|
|
|
{
|
|
|
|
TRACE("(%p)\n", store);
|
|
|
|
return E_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void EmptyStore_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
|
|
|
|
{
|
|
|
|
Context_Free(context);
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL EmptyStore_add(WINECRYPT_CERTSTORE *store, context_t *context,
|
|
|
|
context_t *replace, context_t **ret_context, BOOL use_link)
|
|
|
|
{
|
|
|
|
TRACE("(%p, %p, %p, %p)\n", store, context, replace, ret_context);
|
|
|
|
|
|
|
|
/* FIXME: We should clone the context */
|
|
|
|
if(ret_context) {
|
|
|
|
Context_AddRef(context);
|
|
|
|
*ret_context = context;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static context_t *EmptyStore_enum(WINECRYPT_CERTSTORE *store, context_t *prev)
|
|
|
|
{
|
|
|
|
TRACE("(%p, %p)\n", store, prev);
|
|
|
|
|
|
|
|
SetLastError(CRYPT_E_NOT_FOUND);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL EmptyStore_delete(WINECRYPT_CERTSTORE *store, context_t *context)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL EmptyStore_control(WINECRYPT_CERTSTORE *store, DWORD flags, DWORD ctrl_type, void const *ctrl_para)
|
|
|
|
{
|
|
|
|
TRACE("()\n");
|
|
|
|
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const store_vtbl_t EmptyStoreVtbl = {
|
|
|
|
EmptyStore_addref,
|
|
|
|
EmptyStore_release,
|
|
|
|
EmptyStore_releaseContext,
|
|
|
|
EmptyStore_control,
|
|
|
|
{
|
|
|
|
EmptyStore_add,
|
|
|
|
EmptyStore_enum,
|
|
|
|
EmptyStore_delete
|
|
|
|
}, {
|
|
|
|
EmptyStore_add,
|
|
|
|
EmptyStore_enum,
|
|
|
|
EmptyStore_delete
|
|
|
|
}, {
|
|
|
|
EmptyStore_add,
|
|
|
|
EmptyStore_enum,
|
|
|
|
EmptyStore_delete
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
WINECRYPT_CERTSTORE empty_store;
|
|
|
|
|
|
|
|
void init_empty_store(void)
|
|
|
|
{
|
|
|
|
CRYPT_InitStore(&empty_store, CERT_STORE_READONLY_FLAG, StoreTypeEmpty, &EmptyStoreVtbl);
|
|
|
|
}
|