mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
Samuel Serapión (samdwise51 AT gmail DOT com):
- Winesync of crypt32 The function import_certs_from_dir had to be killed, because it uses UNIX-only functions. (see "crypt32_ros.diff") - This gets MSN Messenger a bit more to work svn path=/trunk/; revision=33417
This commit is contained in:
parent
7e4da4bd18
commit
b1c2a48e3b
35 changed files with 12733 additions and 3345 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
480
reactos/dll/win32/crypt32/collectionstore.c
Normal file
480
reactos/dll/win32/crypt32/collectionstore.c
Normal file
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_STORE_LIST_ENTRY
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store;
|
||||
DWORD dwUpdateFlags;
|
||||
DWORD dwPriority;
|
||||
struct list entry;
|
||||
} WINE_STORE_LIST_ENTRY, *PWINE_STORE_LIST_ENTRY;
|
||||
|
||||
typedef struct _WINE_COLLECTIONSTORE
|
||||
{
|
||||
WINECRYPT_CERTSTORE hdr;
|
||||
CRITICAL_SECTION cs;
|
||||
struct list stores;
|
||||
} WINE_COLLECTIONSTORE, *PWINE_COLLECTIONSTORE;
|
||||
|
||||
static void WINAPI CRYPT_CollectionCloseStore(HCERTSTORE store, DWORD dwFlags)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
PWINE_STORE_LIST_ENTRY entry, next;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY,
|
||||
entry)
|
||||
{
|
||||
TRACE("closing %p\n", entry);
|
||||
CertCloseStore((HCERTSTORE)entry->store, dwFlags);
|
||||
CryptMemFree(entry);
|
||||
}
|
||||
cs->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&cs->cs);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionCreateContextFromChild(PWINE_COLLECTIONSTORE store,
|
||||
PWINE_STORE_LIST_ENTRY storeEntry, void *child, size_t contextSize,
|
||||
BOOL addRef)
|
||||
{
|
||||
void *ret = Context_CreateLinkContext(contextSize, child,
|
||||
sizeof(PWINE_STORE_LIST_ENTRY), addRef);
|
||||
|
||||
if (ret)
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(ret, contextSize)
|
||||
= storeEntry;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddContext(PWINE_COLLECTIONSTORE store,
|
||||
unsigned int contextFuncsOffset, void *context, void *toReplace, unsigned int contextSize,
|
||||
void **pChildContext)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = NULL;
|
||||
|
||||
TRACE("(%p, %d, %p, %p, %d)\n", store, contextFuncsOffset, context,
|
||||
toReplace, contextSize);
|
||||
|
||||
ret = FALSE;
|
||||
if (toReplace)
|
||||
{
|
||||
void *existingLinked = Context_GetLinkedContext(toReplace, contextSize);
|
||||
PCONTEXT_FUNCS contextFuncs;
|
||||
|
||||
storeEntry = *(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(toReplace,
|
||||
contextSize);
|
||||
contextFuncs = (PCONTEXT_FUNCS)((LPBYTE)storeEntry->store +
|
||||
contextFuncsOffset);
|
||||
ret = contextFuncs->addContext(storeEntry->store, context,
|
||||
existingLinked, childContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY entry, next;
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores,
|
||||
WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
|
||||
{
|
||||
PCONTEXT_FUNCS contextFuncs = (PCONTEXT_FUNCS)(
|
||||
(LPBYTE)entry->store + contextFuncsOffset);
|
||||
|
||||
storeEntry = entry;
|
||||
ret = contextFuncs->addContext(entry->store, context, NULL,
|
||||
(const void **)&childContext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
if (!storeEntry)
|
||||
SetLastError(E_ACCESSDENIED);
|
||||
}
|
||||
*pChildContext = childContext;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Advances a collection enumeration by one context, if possible, where
|
||||
* advancing means:
|
||||
* - calling the current store's enumeration function once, and returning
|
||||
* the enumerated context if one is returned
|
||||
* - moving to the next store if the current store has no more items, and
|
||||
* recursively calling itself to get the next item.
|
||||
* Returns NULL if the collection contains no more items or on error.
|
||||
* Assumes the collection store's lock is held.
|
||||
*/
|
||||
static void *CRYPT_CollectionAdvanceEnum(PWINE_COLLECTIONSTORE store,
|
||||
PWINE_STORE_LIST_ENTRY storeEntry, PCONTEXT_FUNCS contextFuncs,
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface, void *pPrev, size_t contextSize)
|
||||
{
|
||||
void *ret, *child;
|
||||
struct list *storeNext = list_next(&store->stores, &storeEntry->entry);
|
||||
|
||||
TRACE("(%p, %p, %p)\n", store, storeEntry, pPrev);
|
||||
|
||||
if (pPrev)
|
||||
{
|
||||
/* Ref-counting funny business: "duplicate" (addref) the child, because
|
||||
* the free(pPrev) below can cause the ref count to become negative.
|
||||
*/
|
||||
child = Context_GetLinkedContext(pPrev, contextSize);
|
||||
contextInterface->duplicate(child);
|
||||
child = contextFuncs->enumContext(storeEntry->store, child);
|
||||
contextInterface->free(pPrev);
|
||||
pPrev = NULL;
|
||||
}
|
||||
else
|
||||
child = contextFuncs->enumContext(storeEntry->store, NULL);
|
||||
if (child)
|
||||
ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child,
|
||||
contextSize, FALSE);
|
||||
else
|
||||
{
|
||||
if (storeNext)
|
||||
{
|
||||
/* We always want the same function pointers (from certs, crls)
|
||||
* in the next store, so use the same offset into the next store.
|
||||
*/
|
||||
size_t offset = (LPBYTE)contextFuncs - (LPBYTE)storeEntry->store;
|
||||
PWINE_STORE_LIST_ENTRY storeNextEntry =
|
||||
LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
|
||||
PCONTEXT_FUNCS storeNextContexts =
|
||||
(PCONTEXT_FUNCS)((LPBYTE)storeNextEntry->store + offset);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
|
||||
storeNextContexts, contextInterface, NULL, contextSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, certs),
|
||||
cert, toReplace, sizeof(CERT_CONTEXT), &childContext);
|
||||
if (ppStoreContext && childContext)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
|
||||
Context_GetExtra(childContext, sizeof(CERT_CONTEXT));
|
||||
PCERT_CONTEXT context =
|
||||
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
|
||||
sizeof(CERT_CONTEXT), TRUE);
|
||||
|
||||
if (context)
|
||||
context->hCertStore = store;
|
||||
*ppStoreContext = context;
|
||||
}
|
||||
CertFreeCertificateContext((PCCERT_CONTEXT)childContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
|
||||
EnterCriticalSection(&cs->cs);
|
||||
if (pPrev)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry =
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
|
||||
sizeof(CERT_CONTEXT));
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->certs, pCertInterface, pPrev,
|
||||
sizeof(CERT_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list_empty(&cs->stores))
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY, entry);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->certs, pCertInterface, NULL,
|
||||
sizeof(CERT_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs->cs);
|
||||
if (ret)
|
||||
((PCERT_CONTEXT)ret)->hCertStore = store;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store,
|
||||
void *pCertContext)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pCertContext);
|
||||
|
||||
ret = CertDeleteCertificateFromStore((PCCERT_CONTEXT)
|
||||
Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
BOOL ret;
|
||||
void *childContext = NULL;
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
|
||||
ret = CRYPT_CollectionAddContext(cs, offsetof(WINECRYPT_CERTSTORE, crls),
|
||||
crl, toReplace, sizeof(CRL_CONTEXT), &childContext);
|
||||
if (ppStoreContext && childContext)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = *(PWINE_STORE_LIST_ENTRY *)
|
||||
Context_GetExtra(childContext, sizeof(CRL_CONTEXT));
|
||||
PCRL_CONTEXT context =
|
||||
CRYPT_CollectionCreateContextFromChild(cs, storeEntry, childContext,
|
||||
sizeof(CRL_CONTEXT), TRUE);
|
||||
|
||||
if (context)
|
||||
context->hCertStore = store;
|
||||
*ppStoreContext = context;
|
||||
}
|
||||
CertFreeCRLContext((PCCRL_CONTEXT)childContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_CollectionEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE cs = (PWINE_COLLECTIONSTORE)store;
|
||||
void *ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pPrev);
|
||||
|
||||
EnterCriticalSection(&cs->cs);
|
||||
if (pPrev)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry =
|
||||
*(PWINE_STORE_LIST_ENTRY *)Context_GetExtra(pPrev,
|
||||
sizeof(CRL_CONTEXT));
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->crls, pCRLInterface, pPrev, sizeof(CRL_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list_empty(&cs->stores))
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY storeEntry = LIST_ENTRY(cs->stores.next,
|
||||
WINE_STORE_LIST_ENTRY, entry);
|
||||
|
||||
ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
|
||||
&storeEntry->store->crls, pCRLInterface, NULL,
|
||||
sizeof(CRL_CONTEXT));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_NOT_FOUND);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&cs->cs);
|
||||
if (ret)
|
||||
((PCRL_CONTEXT)ret)->hCertStore = store;
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store,
|
||||
void *pCrlContext)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p)\n", store, pCrlContext);
|
||||
|
||||
ret = CertDeleteCRLFromStore((PCCRL_CONTEXT)
|
||||
Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE store;
|
||||
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
store = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
|
||||
if (store)
|
||||
{
|
||||
memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
|
||||
CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection);
|
||||
store->hdr.closeStore = CRYPT_CollectionCloseStore;
|
||||
store->hdr.certs.addContext = CRYPT_CollectionAddCert;
|
||||
store->hdr.certs.enumContext = CRYPT_CollectionEnumCert;
|
||||
store->hdr.certs.deleteContext = CRYPT_CollectionDeleteCert;
|
||||
store->hdr.crls.addContext = CRYPT_CollectionAddCRL;
|
||||
store->hdr.crls.enumContext = CRYPT_CollectionEnumCRL;
|
||||
store->hdr.crls.deleteContext = CRYPT_CollectionDeleteCRL;
|
||||
InitializeCriticalSection(&store->cs);
|
||||
store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
|
||||
list_init(&store->stores);
|
||||
}
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)store;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
|
||||
HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
|
||||
WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
|
||||
PWINE_STORE_LIST_ENTRY entry;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
|
||||
dwUpdateFlags, dwPriority);
|
||||
|
||||
if (!collection || !sibling)
|
||||
return TRUE;
|
||||
if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
if (collection->hdr.type != StoreTypeCollection)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
entry = CryptMemAlloc(sizeof(WINE_STORE_LIST_ENTRY));
|
||||
if (entry)
|
||||
{
|
||||
InterlockedIncrement(&sibling->ref);
|
||||
TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
|
||||
entry->store = sibling;
|
||||
entry->dwUpdateFlags = dwUpdateFlags;
|
||||
entry->dwPriority = dwPriority;
|
||||
list_init(&entry->entry);
|
||||
TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
|
||||
EnterCriticalSection(&collection->cs);
|
||||
if (dwPriority)
|
||||
{
|
||||
PWINE_STORE_LIST_ENTRY cursor;
|
||||
BOOL added = FALSE;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
|
||||
WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (cursor->dwPriority < dwPriority)
|
||||
{
|
||||
list_add_before(&cursor->entry, &entry->entry);
|
||||
added = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!added)
|
||||
list_add_tail(&collection->stores, &entry->entry);
|
||||
}
|
||||
else
|
||||
list_add_tail(&collection->stores, &entry->entry);
|
||||
LeaveCriticalSection(&collection->cs);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
|
||||
HCERTSTORE hSiblingStore)
|
||||
{
|
||||
PWINE_COLLECTIONSTORE collection = (PWINE_COLLECTIONSTORE)hCollectionStore;
|
||||
WINECRYPT_CERTSTORE *sibling = (WINECRYPT_CERTSTORE *)hSiblingStore;
|
||||
PWINE_STORE_LIST_ENTRY store, next;
|
||||
|
||||
TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);
|
||||
|
||||
if (!collection || !sibling)
|
||||
return;
|
||||
if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return;
|
||||
}
|
||||
if (collection->hdr.type != StoreTypeCollection)
|
||||
return;
|
||||
if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return;
|
||||
}
|
||||
EnterCriticalSection(&collection->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(store, next, &collection->stores,
|
||||
WINE_STORE_LIST_ENTRY, entry)
|
||||
{
|
||||
if (store->store == sibling)
|
||||
{
|
||||
list_remove(&store->entry);
|
||||
CertCloseStore(store->store, 0);
|
||||
CryptMemFree(store);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&collection->cs);
|
||||
}
|
|
@ -71,6 +71,7 @@ void *Context_CreateDataContext(size_t contextSize)
|
|||
ret = NULL;
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -96,6 +97,7 @@ void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned
|
|||
InterlockedIncrement(&linkedBase->ref);
|
||||
TRACE("%p's ref count is %d\n", context, linkContext->ref);
|
||||
}
|
||||
TRACE("returning %p\n", context);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -123,7 +125,7 @@ void *Context_GetLinkedContext(void *context, size_t contextSize)
|
|||
contextSize);
|
||||
}
|
||||
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(void *context, size_t contextSize)
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize)
|
||||
{
|
||||
PBASE_CONTEXT ptr = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
|
||||
|
||||
|
@ -242,7 +244,7 @@ void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace)
|
|||
list->contextInterface->free(toReplace);
|
||||
}
|
||||
else
|
||||
list_add_tail(&list->contexts, entry);
|
||||
list_add_head(&list->contexts, entry);
|
||||
LeaveCriticalSection(&list->cs);
|
||||
}
|
||||
return context;
|
||||
|
|
|
@ -266,10 +266,10 @@ DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData);
|
||||
static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData);
|
||||
|
||||
static BOOL CRLContext_GetHashProp(void *context, DWORD dwPropId,
|
||||
static BOOL CRLContext_GetHashProp(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
|
||||
DWORD *pcbData)
|
||||
{
|
||||
|
@ -284,10 +284,9 @@ static BOOL CRLContext_GetHashProp(void *context, DWORD dwPropId,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
static BOOL CRLContext_GetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
void *pvData, DWORD *pcbData)
|
||||
{
|
||||
PCCRL_CONTEXT pCRLContext = (PCCRL_CONTEXT)context;
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
Context_GetProperties(context, sizeof(CRL_CONTEXT));
|
||||
BOOL ret;
|
||||
|
@ -302,20 +301,17 @@ static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
|
|||
if (ret)
|
||||
{
|
||||
if (!pvData)
|
||||
{
|
||||
*pcbData = blob.cbData;
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (*pcbData < blob.cbData)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
*pcbData = blob.cbData;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pvData, blob.pbData, blob.cbData);
|
||||
*pcbData = blob.cbData;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -325,12 +321,12 @@ static BOOL WINAPI CRLContext_GetProperty(void *context, DWORD dwPropId,
|
|||
{
|
||||
case CERT_SHA1_HASH_PROP_ID:
|
||||
ret = CRLContext_GetHashProp(context, dwPropId, CALG_SHA1,
|
||||
pCRLContext->pbCrlEncoded, pCRLContext->cbCrlEncoded, pvData,
|
||||
context->pbCrlEncoded, context->cbCrlEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
case CERT_MD5_HASH_PROP_ID:
|
||||
ret = CRLContext_GetHashProp(context, dwPropId, CALG_MD5,
|
||||
pCRLContext->pbCrlEncoded, pCRLContext->cbCrlEncoded, pvData,
|
||||
context->pbCrlEncoded, context->cbCrlEncoded, pvData,
|
||||
pcbData);
|
||||
break;
|
||||
default:
|
||||
|
@ -371,19 +367,22 @@ BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
|
|||
}
|
||||
else
|
||||
{
|
||||
*(DWORD *)pvData =
|
||||
CertStore_GetAccessState(pCRLContext->hCertStore);
|
||||
if (pCRLContext->hCertStore)
|
||||
ret = CertGetStoreProperty(pCRLContext->hCertStore, dwPropId,
|
||||
pvData, pcbData);
|
||||
else
|
||||
*(DWORD *)pvData = 0;
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = CRLContext_GetProperty((void *)pCRLContext, dwPropId, pvData,
|
||||
ret = CRLContext_GetProperty(pCRLContext, dwPropId, pvData,
|
||||
pcbData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRLContext_SetProperty(void *context, DWORD dwPropId,
|
||||
static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId,
|
||||
DWORD dwFlags, const void *pvData)
|
||||
{
|
||||
PCONTEXT_PROPERTY_LIST properties =
|
||||
|
@ -460,8 +459,7 @@ BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext,
|
|||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
ret = CRLContext_SetProperty((void *)pCRLContext, dwPropId, dwFlags,
|
||||
pvData);
|
||||
ret = CRLContext_SetProperty(pCRLContext, dwPropId, dwFlags, pvData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -519,10 +517,7 @@ LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify,
|
|||
|
||||
if (!pTimeToVerify)
|
||||
{
|
||||
SYSTEMTIME sysTime;
|
||||
|
||||
GetSystemTime(&sysTime);
|
||||
SystemTimeToFileTime(&sysTime, &fileTime);
|
||||
GetSystemTimeAsFileTime(&fileTime);
|
||||
pTimeToVerify = &fileTime;
|
||||
}
|
||||
if ((ret = CompareFileTime(pTimeToVerify, &pCrlInfo->ThisUpdate)) >= 0)
|
||||
|
|
|
@ -5,28 +5,36 @@
|
|||
<define name="__WINESRC__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x501</define>
|
||||
<define name="_WIN32_WINNT">0x600</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<library>wine</library>
|
||||
<library>user32</library>
|
||||
<library>advapi32</library>
|
||||
<library>kernel32</library>
|
||||
<library>ntdll</library>
|
||||
<library>imagehlp</library>
|
||||
<file>base64.c</file>
|
||||
<file>cert.c</file>
|
||||
<file>chain.c</file>
|
||||
<file>crl.c</file>
|
||||
<file>collectionstore.c</file>
|
||||
<file>context.c</file>
|
||||
<file>crl.c</file>
|
||||
<file>decode.c</file>
|
||||
<file>encode.c</file>
|
||||
<file>filestore.c</file>
|
||||
<file>main.c</file>
|
||||
<file>msg.c</file>
|
||||
<file>object.c</file>
|
||||
<file>oid.c</file>
|
||||
<file>proplist.c</file>
|
||||
<file>protectdata.c</file>
|
||||
<file>provstore.c</file>
|
||||
<file>regstore.c</file>
|
||||
<file>rootstore.c</file>
|
||||
<file>serialize.c</file>
|
||||
<file>sip.c</file>
|
||||
<file>store.c</file>
|
||||
<file>str.c</file>
|
||||
<file>main.c</file>
|
||||
<file>crypt32.rc</file>
|
||||
<file>crypt32.spec</file>
|
||||
</module>
|
||||
|
|
|
@ -17,21 +17,17 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "CryptoAPI Library\0"
|
||||
#define REACTOS_STR_INTERNAL_NAME "crypt32\0"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "crypt32.dll\0"
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "cryptres.h"
|
||||
|
||||
#include <reactos/version.rc>
|
||||
#include "version.rc"
|
||||
|
||||
#include "crypt32_De.rc"
|
||||
#include "crypt32_En.rc"
|
||||
#include "crypt32_Fr.rc"
|
||||
#include "crypt32_Ko.rc"
|
||||
#include "crypt32_Nl.rc"
|
||||
#include "crypt32_No.rc"
|
||||
#include "crypt32_Sv.rc"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
@ stdcall CertDeleteCertificateFromStore(ptr)
|
||||
@ stdcall CertDuplicateCRLContext(ptr)
|
||||
@ stdcall CertDuplicateCTLContext(ptr)
|
||||
@ stdcall CertDuplicateCertificateChain(ptr)
|
||||
@ stdcall CertDuplicateCertificateContext(ptr)
|
||||
@ stdcall CertDuplicateStore(ptr)
|
||||
@ stdcall CertEnumCRLContextProperties(ptr long)
|
||||
|
@ -34,6 +35,7 @@
|
|||
@ stdcall CertEnumCTLsInStore(ptr ptr)
|
||||
@ stdcall CertEnumCertificateContextProperties(ptr long)
|
||||
@ stdcall CertEnumCertificatesInStore(long ptr)
|
||||
@ stdcall CertEnumSystemStore(long ptr ptr ptr)
|
||||
@ stdcall CertFindAttribute(str long ptr)
|
||||
@ stdcall CertFindCRLInStore(long long long long ptr ptr)
|
||||
@ stub CertFindCTLInStore
|
||||
|
@ -44,13 +46,13 @@
|
|||
@ stub CertFindSubjectInCTL
|
||||
@ stdcall CertFreeCRLContext(ptr)
|
||||
@ stdcall CertFreeCTLContext(ptr)
|
||||
@ stub CertFreeCertificateChain
|
||||
@ stdcall CertFreeCertificateChain(ptr)
|
||||
@ stdcall CertFreeCertificateChainEngine(ptr)
|
||||
@ stdcall CertFreeCertificateContext(ptr)
|
||||
@ stdcall CertGetCRLContextProperty(ptr long ptr ptr)
|
||||
@ stdcall CertGetCRLFromStore(ptr ptr ptr ptr)
|
||||
@ stdcall CertGetCTLContextProperty(ptr long ptr ptr)
|
||||
@ stub CertGetCertificateChain
|
||||
@ stdcall CertGetCertificateChain(ptr ptr ptr ptr ptr long ptr ptr)
|
||||
@ stdcall CertGetCertificateContextProperty(ptr long ptr ptr)
|
||||
@ stdcall CertGetEnhancedKeyUsage(ptr long ptr ptr)
|
||||
@ stub CertGetIntendedKeyUsage
|
||||
|
@ -58,6 +60,7 @@
|
|||
@ stdcall CertGetNameStringA(ptr long long ptr ptr long)
|
||||
@ stdcall CertGetNameStringW(ptr long long ptr ptr long)
|
||||
@ stdcall CertGetPublicKeyLength(long ptr)
|
||||
@ stdcall CertGetStoreProperty(long long ptr ptr)
|
||||
@ stdcall CertGetSubjectCertificateFromStore(ptr long ptr)
|
||||
@ stdcall CertGetValidUsages(long ptr ptr ptr ptr)
|
||||
@ stub CertIsRDNAttrsInCertificateName
|
||||
|
@ -80,12 +83,14 @@
|
|||
@ stdcall CertSetCTLContextProperty(ptr long long ptr)
|
||||
@ stdcall CertSetCertificateContextProperty(ptr long long ptr)
|
||||
@ stdcall CertSetEnhancedKeyUsage(ptr ptr)
|
||||
@ stdcall CertSetStoreProperty(ptr long long ptr)
|
||||
@ stdcall CertStrToNameA(long str long ptr ptr ptr ptr)
|
||||
@ stdcall CertStrToNameW(long wstr long ptr ptr ptr ptr)
|
||||
@ stdcall CertVerifyCertificateChainPolicy(str ptr ptr ptr)
|
||||
@ stdcall CertVerifyCRLRevocation(long ptr long ptr)
|
||||
@ stdcall CertVerifyCRLTimeValidity(ptr ptr)
|
||||
@ stub CertVerifyCTLUsage
|
||||
@ stub CertVerifyRevocation
|
||||
@ stdcall CertVerifyCTLUsage(long long ptr ptr long ptr ptr)
|
||||
@ stdcall CertVerifyRevocation(long long long ptr long ptr ptr)
|
||||
@ stdcall CertVerifySubjectCertificateContext(ptr ptr ptr)
|
||||
@ stdcall CertVerifyTimeValidity(ptr ptr)
|
||||
@ stdcall CertVerifyValidityNesting(ptr ptr)
|
||||
|
@ -112,14 +117,15 @@
|
|||
@ stub CryptExportPKCS8
|
||||
@ stdcall CryptExportPublicKeyInfo(long long long ptr ptr)
|
||||
@ stdcall CryptExportPublicKeyInfoEx(long long long str long ptr ptr ptr)
|
||||
@ stdcall CryptFindLocalizedName(wstr)
|
||||
@ stdcall CryptFindOIDInfo(long ptr long)
|
||||
@ stdcall CryptFormatObject(long long long ptr str ptr long ptr ptr)
|
||||
@ stdcall CryptFreeOIDFunctionAddress(long long)
|
||||
@ stub CryptGetAsyncParam
|
||||
@ stdcall CryptGetDefaultOIDDllList(long long ptr ptr)
|
||||
@ stdcall CryptGetDefaultOIDFunctionAddress(long long wstr long ptr ptr)
|
||||
@ stub CryptGetMessageCertificates
|
||||
@ stub CryptGetMessageSignerCount
|
||||
@ stdcall CryptGetMessageCertificates(long ptr long ptr long)
|
||||
@ stdcall CryptGetMessageSignerCount(long ptr long)
|
||||
@ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr)
|
||||
@ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr)
|
||||
@ stdcall CryptHashCertificate(long long long ptr long ptr ptr)
|
||||
|
@ -136,17 +142,18 @@
|
|||
@ stdcall CryptMemFree(ptr)
|
||||
@ stdcall CryptMemRealloc(ptr long)
|
||||
@ stub CryptMsgCalculateEncodedLength
|
||||
@ stub CryptMsgClose
|
||||
@ stub CryptMsgControl
|
||||
@ stdcall CryptMsgClose(ptr)
|
||||
@ stdcall CryptMsgControl(ptr long long ptr)
|
||||
@ stub CryptMsgCountersign
|
||||
@ stub CryptMsgCountersignEncoded
|
||||
@ stdcall CryptMsgDuplicate(ptr)
|
||||
@ stub CryptMsgEncodeAndSignCTL
|
||||
@ stub CryptMsgGetAndVerifySigner
|
||||
@ stub CryptMsgGetParam
|
||||
@ stub CryptMsgOpenToDecode
|
||||
@ stub CryptMsgOpenToEncode
|
||||
@ stdcall CryptMsgGetParam(ptr long long ptr ptr)
|
||||
@ stdcall CryptMsgOpenToDecode(long long long long ptr ptr)
|
||||
@ stdcall CryptMsgOpenToEncode(long long long ptr str ptr)
|
||||
@ stub CryptMsgSignCTL
|
||||
@ stub CryptMsgUpdate
|
||||
@ stdcall CryptMsgUpdate(ptr ptr long long)
|
||||
@ stub CryptMsgVerifyCountersignatureEncoded
|
||||
@ stdcall CryptProtectData(ptr wstr ptr ptr ptr long ptr)
|
||||
@ stdcall CryptQueryObject(long ptr long long long ptr ptr ptr ptr ptr ptr)
|
||||
|
@ -183,25 +190,29 @@
|
|||
@ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr)
|
||||
@ stub CryptVerifyMessageSignatureWithKey
|
||||
@ stub CryptVerifySignatureU
|
||||
@ stdcall I_CertUpdateStore(ptr ptr long long)
|
||||
@ stdcall I_CryptAllocTls()
|
||||
@ stdcall I_CryptCreateLruCache(ptr ptr)
|
||||
@ stub I_CryptCreateLruEntry
|
||||
@ stdcall I_CryptCreateLruEntry(ptr long long)
|
||||
@ stdcall I_CryptDetachTls(long)
|
||||
@ stdcall I_CryptFindLruEntry(long long)
|
||||
@ stdcall I_CryptFindLruEntryData(long long long)
|
||||
@ stdcall I_CryptFlushLruCache(ptr long long)
|
||||
@ stdcall I_CryptFreeLruCache(ptr long long)
|
||||
@ stdcall I_CryptFreeTls(long long)
|
||||
@ stdcall I_CryptGetAsn1Decoder(long)
|
||||
@ stdcall I_CryptGetAsn1Encoder(long)
|
||||
@ stdcall I_CryptGetDefaultCryptProv(long)
|
||||
@ stub I_CryptGetDefaultCryptProvForEncrypt
|
||||
@ stdcall I_CryptGetOssGlobal(long)
|
||||
@ stdcall I_CryptGetTls(long)
|
||||
@ stub I_CryptInsertLruEntry
|
||||
@ stdcall I_CryptInstallAsn1Module(long long long)
|
||||
@ stdcall I_CryptInstallAsn1Module(ptr long ptr)
|
||||
@ stdcall I_CryptInstallOssGlobal(long long long)
|
||||
@ stdcall I_CryptReadTrustedPublisherDWORDValueFromRegistry(wstr ptr)
|
||||
@ stub I_CryptReleaseLruEntry
|
||||
@ stdcall I_CryptSetTls(long ptr)
|
||||
@ stdcall I_CryptUninstallAsn1Module(ptr)
|
||||
@ stdcall I_CryptUninstallAsn1Module(long)
|
||||
@ stub I_CryptUninstallOssGlobal
|
||||
@ stub PFXExportCertStore
|
||||
@ stub PFXImportCertStore
|
||||
|
|
|
@ -97,7 +97,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_CROSS_CERT_DIST_POINTS "Verteilungspunkte für Kreuzzertifikate"
|
||||
IDS_APPLICATION_POLICIES "Anwendungsrichtlinien"
|
||||
IDS_APPLICATION_POLICY_MAPPINGS "Anwendungsrichtlinienzuordnungen"
|
||||
IDS_APPLICATION_POLICY_CONSTRAINTS "Anweungsungsrichtlinieneinschränkungen"
|
||||
IDS_APPLICATION_POLICY_CONSTRAINTS "Anwendungsungsrichtlinieneinschränkungen"
|
||||
IDS_CMC_DATA "CMC Daten"
|
||||
IDS_CMC_RESPONSE "CMC Antwort"
|
||||
IDS_UNSIGNED_CMC_REQUEST "Unsignierte CMC Antwort"
|
||||
|
@ -164,3 +164,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "Lebensdauersignatur"
|
||||
IDS_ANY_CERT_POLICY "Alle ausgegebenen Richtlinien"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Vertrauenswürdige Stammzertifizierungsstellen"
|
||||
IDS_LOCALIZEDNAME_MY "Persönlich"
|
||||
IDS_LOCALIZEDNAME_CA "Zwischenzertifizierungsstellen"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Andere Personen"
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
|
@ -164,3 +164,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "Lifetime Signing"
|
||||
IDS_ANY_CERT_POLICY "All issuance policies"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Trusted Root Certification Authorities"
|
||||
IDS_LOCALIZEDNAME_MY "Personal"
|
||||
IDS_LOCALIZEDNAME_CA "Intermediate Certification Authorities"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Other People"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* crypt32 dll French resources
|
||||
*
|
||||
* Copyright 2006 Jonathan Ernst
|
||||
* Copyright 2006-2008 Jonathan Ernst
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -22,13 +22,13 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
|
|||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_AUTHORITY_KEY_ID "Authority Key Identifier"
|
||||
IDS_KEY_ATTRIBUTES "Key Attributes"
|
||||
IDS_KEY_USAGE_RESTRICTION "Key Usage Restriction"
|
||||
IDS_AUTHORITY_KEY_ID "Identifiant de l'authorité de la clé"
|
||||
IDS_KEY_ATTRIBUTES "Attributs de la clé"
|
||||
IDS_KEY_USAGE_RESTRICTION "Restrictions de l'utilisation de la clé"
|
||||
IDS_SUBJECT_ALT_NAME "Subject Alternative Name"
|
||||
IDS_ISSUER_ALT_NAME "Issuer Alternative Name"
|
||||
IDS_BASIC_CONSTRAINTS "Basic Constraints"
|
||||
IDS_KEY_USAGE "Key Usage"
|
||||
IDS_KEY_USAGE "Utilisation de la clé"
|
||||
IDS_CERT_POLICIES "Certificate Policies"
|
||||
IDS_SUBJECT_KEY_IDENTIFIER "Subject Key Identifier"
|
||||
IDS_CRL_REASON_CODE "CRL Reason Code"
|
||||
|
@ -49,7 +49,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_SMIME_CAPABILITIES "SMIME Capabilities"
|
||||
IDS_PREFER_SIGNED_DATA "Prefer Signed Data"
|
||||
IDS_CPS "CPS"
|
||||
IDS_USER_NOTICE "User Notice"
|
||||
IDS_USER_NOTICE "Notice utilisateur"
|
||||
IDS_OCSP "On-line Certificate Status Protocol"
|
||||
IDS_CA_ISSUER "Certification Authority Issuer"
|
||||
IDS_CERT_TEMPLATE_NAME "Certification Template Name"
|
||||
|
@ -157,10 +157,18 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_DOCUMENT_SIGNING "Signature de document"
|
||||
IDS_IPSEC_IKE_INTERMEDIATE "IP security IKE intermediate"
|
||||
IDS_FILE_RECOVERY "Récupération de fichier"
|
||||
IDS_ROOT_LIST_SIGNER "Root List Signer"
|
||||
IDS_ROOT_LIST_SIGNER "Signataires de la liste racine"
|
||||
IDS_ANY_APPLICATION_POLICIES "All application policies"
|
||||
IDS_DS_EMAIL_REPLICATION "Directory Service Email Replication"
|
||||
IDS_ENROLLMENT_AGENT "Certificate Request Agent"
|
||||
IDS_LIFETIME_SIGNING "Lifetime Signing"
|
||||
IDS_ANY_CERT_POLICY "All issuance policies"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Autorités de certification de confiance"
|
||||
IDS_LOCALIZEDNAME_MY "Personnel"
|
||||
IDS_LOCALIZEDNAME_CA "Autorités intermédiaires"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Autres personnes"
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
|
||||
LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
|
@ -165,3 +165,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "평생 서명"
|
||||
IDS_ANY_CERT_POLICY "모든 배포 방침"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "신회 할 수 있는 루트 검사증기관"
|
||||
IDS_LOCALIZEDNAME_MY "개인적"
|
||||
IDS_LOCALIZEDNAME_CA "중간 검증 기관ㄴIntermediate Certification Authorities"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "다른 사람"
|
||||
}
|
||||
|
|
174
reactos/dll/win32/crypt32/crypt32_Nl.rc
Normal file
174
reactos/dll/win32/crypt32/crypt32_Nl.rc
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* Dutch crypt32 dll resources
|
||||
*
|
||||
* Copyright (C) 2008 Frans Kool
|
||||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_AUTHORITY_KEY_ID "Autoriteits Sleutel Identificatie nummer"
|
||||
IDS_KEY_ATTRIBUTES "Sleutel Attributen"
|
||||
IDS_KEY_USAGE_RESTRICTION "Sleutel Gebruiksbeperkingen"
|
||||
IDS_SUBJECT_ALT_NAME "Onderwerp's Alternatieve Naam"
|
||||
IDS_ISSUER_ALT_NAME "Verstrekker's Alternatieve Naam"
|
||||
IDS_BASIC_CONSTRAINTS "Basis Beperkingen"
|
||||
IDS_KEY_USAGE "Sleutel Gebruik"
|
||||
IDS_CERT_POLICIES "Certificaat Beleid"
|
||||
IDS_SUBJECT_KEY_IDENTIFIER "Onderwerp's Sleutel Identificatie nummer"
|
||||
IDS_CRL_REASON_CODE "CRL Reden Code"
|
||||
IDS_CRL_DIST_POINTS "CRL Distributie Locaties"
|
||||
IDS_ENHANCED_KEY_USAGE "Uitgebreid Sleutel Gebruik"
|
||||
IDS_AUTHORITY_INFO_ACCESS "Autoriteits Informatie Toegang"
|
||||
IDS_CERT_EXTENSIONS "Certificaat Extensies"
|
||||
IDS_NEXT_UPDATE_LOCATION "Volgende Update Locatie"
|
||||
IDS_YES_OR_NO_TRUST "Wel of Geen Vertrouwen"
|
||||
IDS_EMAIL_ADDRESS "Email Adres"
|
||||
IDS_UNSTRUCTURED_NAME "Ongestructureerde Naam"
|
||||
IDS_CONTENT_TYPE "Inhoud Type"
|
||||
IDS_MESSAGE_DIGEST "Boodschap Samenvatting"
|
||||
IDS_SIGNING_TIME "Tijd van Ondertekening"
|
||||
IDS_COUNTER_SIGN "Counter Sign"
|
||||
IDS_CHALLENGE_PASSWORD "Geheime Vraag Wachtwoord"
|
||||
IDS_UNSTRUCTURED_ADDRESS "Ongestructureerd Adres"
|
||||
IDS_SMIME_CAPABILITIES "SMIME Mogelijkheden"
|
||||
IDS_PREFER_SIGNED_DATA "Prefereer Getekende Data"
|
||||
IDS_CPS "CPS"
|
||||
IDS_USER_NOTICE "Gebruikers Mededeling"
|
||||
IDS_OCSP "On-line Certificaat Status Protocol"
|
||||
IDS_CA_ISSUER "Certificatie Autoriteits Verstrekker"
|
||||
IDS_CERT_TEMPLATE_NAME "Certificatie Template Naam"
|
||||
IDS_CERT_TYPE "Type Certificaat"
|
||||
IDS_CERT_MANIFOLD "Certificaat Verspreider"
|
||||
IDS_NETSCAPE_CERT_TYPE "Netscape Certificaat Type"
|
||||
IDS_NETSCAPE_BASE_URL "Netscape Basis URL"
|
||||
IDS_NETSCAPE_REVOCATION_URL "Netscape Terugroep URL"
|
||||
IDS_NETSCAPE_CA_REVOCATION_URL "Netscape CA Terugroep URL"
|
||||
IDS_NETSCAPE_CERT_RENEWAL_URL "Netscape Cert Verversings URL"
|
||||
IDS_NETSCAPE_CA_POLICY_URL "Netscape CA Beleids URL"
|
||||
IDS_NETSCAPE_SSL_SERVER_NAME "Netscape SSL Server Naam"
|
||||
IDS_NETSCAPE_COMMENT "Netscape Commentaar"
|
||||
IDS_SPC_SP_AGENCY_INFO "SpcSpAgencyInfo"
|
||||
IDS_SPC_FINANCIAL_CRITERIA "SpcFinancialCriteria"
|
||||
IDS_SPC_MINIMAL_CRITERIA "SpcMinimalCriteria"
|
||||
IDS_COUNTRY "Land/Regio"
|
||||
IDS_ORGANIZATION "Organisatie"
|
||||
IDS_ORGANIZATIONAL_UNIT "Organisatie Onderdeel"
|
||||
IDS_COMMON_NAME "Gemeenschappelijke Naam"
|
||||
IDS_LOCALITY "Localiteit"
|
||||
IDS_STATE_OR_PROVINCE "Staat of Provincie"
|
||||
IDS_TITLE "Titel"
|
||||
IDS_GIVEN_NAME "Voornaam"
|
||||
IDS_INITIALS "Initialen"
|
||||
IDS_SUR_NAME "Achternaam"
|
||||
IDS_DOMAIN_COMPONENT "Domein Component"
|
||||
IDS_STREET_ADDRESS "Straat/Adres"
|
||||
IDS_SERIAL_NUMBER "Registratie Nummer"
|
||||
IDS_CA_VERSION "CA Versie"
|
||||
IDS_CROSS_CA_VERSION "Cross CA Versie"
|
||||
IDS_SERIALIZED_SIG_SERIAL_NUMBER "Geautomatiseerde Handtekening Serienummer"
|
||||
IDS_PRINCIPAL_NAME "Hoofd Naam"
|
||||
IDS_WINDOWS_PRODUCT_UPDATE "Windows Produkt Update"
|
||||
IDS_ENROLLMENT_NAME_VALUE_PAIR "Inschrijvingsnaam Waarde Paar"
|
||||
IDS_OS_VERSION "OS Versie"
|
||||
IDS_ENROLLMENT_CSP "Inschrijving CSP"
|
||||
IDS_CRL_NUMBER "CRL Nummer"
|
||||
IDS_DELTA_CRL_INDICATOR "Delta CRL Indicatie"
|
||||
IDS_ISSUING_DIST_POINT "Verstrekkend Distributie Punt"
|
||||
IDS_FRESHEST_CRL "Nieuwste CRL"
|
||||
IDS_NAME_CONSTRAINTS "Beperkingen op Naam"
|
||||
IDS_POLICY_MAPPINGS "Beleids Mappingen"
|
||||
IDS_POLICY_CONSTRAINTS "Beperkingen op Beleid"
|
||||
IDS_CROSS_CERT_DIST_POINTS "Trans-Certificaat Distributie Punten"
|
||||
IDS_APPLICATION_POLICIES "Applicatie Beleid"
|
||||
IDS_APPLICATION_POLICY_MAPPINGS "Applicatie Beleids Mappingen"
|
||||
IDS_APPLICATION_POLICY_CONSTRAINTS "Applicatie Beperkingen op Beleid"
|
||||
IDS_CMC_DATA "CMC Data"
|
||||
IDS_CMC_RESPONSE "CMC Antwoord"
|
||||
IDS_UNSIGNED_CMC_REQUEST "Ongetekend CMC Verzoek"
|
||||
IDS_CMC_STATUS_INFO "CMC Status Informatie"
|
||||
IDS_CMC_EXTENSIONS "CMC Extensies"
|
||||
IDS_CMC_ATTRIBUTES "CMC Attributen"
|
||||
IDS_PKCS_7_DATA "PKCS 7 Data"
|
||||
IDS_PKCS_7_SIGNED "PKCS 7 Ondertekend"
|
||||
IDS_PKCS_7_ENVELOPED "PKCS 7 Omsloten"
|
||||
IDS_PKCS_7_SIGNED_ENVELOPED "PKCS 7 Getekend Omsloten"
|
||||
IDS_PKCS_7_DIGESTED "PKCS 7 Samengevat"
|
||||
IDS_PKCS_7_ENCRYPTED "PKCS 7 Gecodeerd"
|
||||
IDS_PREVIOUS_CA_CERT_HASH "Vorige CA Certificaat Hash"
|
||||
IDS_CRL_VIRTUAL_BASE "Virtueel Basis CRL Nummer"
|
||||
IDS_CRL_NEXT_PUBLISH "Volgende CRL Publicatie"
|
||||
IDS_CA_EXCHANGE "CA Coderings Certificaat"
|
||||
IDS_KEY_RECOVERY_AGENT "Sleutel Herstel Agent"
|
||||
IDS_CERTIFICATE_TEMPLATE "Certificaat Template Information"
|
||||
IDS_ENTERPRISE_ROOT_OID "Ondernemings Basis OID"
|
||||
IDS_RDN_DUMMY_SIGNER "Dummie Tekenaar"
|
||||
IDS_ARCHIVED_KEY_ATTR "Gecodeerde Persoonlijke Sleutel"
|
||||
IDS_CRL_SELF_CDP "Gepubliseerde CRL Locaties"
|
||||
IDS_REQUIRE_CERT_CHAIN_POLICY "Afdwingen Certificaat Keten Beleid"
|
||||
IDS_TRANSACTION_ID "Transactie Nummer"
|
||||
IDS_SENDER_NONCE "Zender Nonce"
|
||||
IDS_RECIPIENT_NONCE "Ontvanger Nonce"
|
||||
IDS_REG_INFO "Registratie Informatie"
|
||||
IDS_GET_CERTIFICATE "Haal Certificaat op"
|
||||
IDS_GET_CRL "Haal CRL op"
|
||||
IDS_REVOKE_REQUEST "Trek Verzoek In"
|
||||
IDS_QUERY_PENDING "Verzoek in behandeling"
|
||||
IDS_SORTED_CTL "Certificaat Vertrouwenslijst"
|
||||
IDS_ARCHIVED_KEY_CERT_HASH "Gearchiveerde Sleutel Certificaat Hash"
|
||||
IDS_PRIVATE_KEY_USAGE_PERIOD "Prive Sleutel Gebruik Periode"
|
||||
IDS_CLIENT_INFORMATION "Cliënt Informatie"
|
||||
IDS_SERVER_AUTHENTICATION "Server Authentificatie"
|
||||
IDS_CLIENT_AUTHENTICATION "Cliënt Authentificatie"
|
||||
IDS_CODE_SIGNING "Code Ondertekenen"
|
||||
IDS_SECURE_EMAIL "Beveiligde Email"
|
||||
IDS_TIME_STAMPING "Tijd Stempel Toekennen"
|
||||
IDS_MICROSOFT_TRUST_LIST_SIGNING "Microsoft Trust Lijst Ondertekenen"
|
||||
IDS_MICROSOFT_TIME_STAMPING "Microsoft Tijd Stempel Toekennen"
|
||||
IDS_IPSEC_END_SYSTEM "IP beveiliging eind systeem"
|
||||
IDS_IPSEC_TUNNEL "IP beveiliging tunnel afsluiting"
|
||||
IDS_IPSEC_USER "IP beveiliging gebruiker"
|
||||
IDS_EFS "Versleutelen Bestand Systeem"
|
||||
IDS_WHQL_CRYPTO "Windows Hardware Driver Verificatie"
|
||||
IDS_NT5_CRYPTO "Windows Systeem Component Verificatie"
|
||||
IDS_OEM_WHQL_CRYPTO "OEM Windows Systeem Component Verificatie"
|
||||
IDS_EMBEDDED_NT_CRYPTO "Ingebed Windows Systeem Componenten Verificatie"
|
||||
IDS_KEY_PACK_LICENSES "Sleutel Verzameling Licenties"
|
||||
IDS_LICENSE_SERVER "Licentie Server Verificatie"
|
||||
IDS_SMART_CARD_LOGON "Smart Card Aanmelden"
|
||||
IDS_DIGITAL_RIGHTS "Digitale Rechten"
|
||||
IDS_QUALIFIED_SUBORDINATION "Gekwalificeerde Ondergeschiktheid"
|
||||
IDS_KEY_RECOVERY "Sleutel Herstellen"
|
||||
IDS_DOCUMENT_SIGNING "Document Ondertekenen"
|
||||
IDS_IPSEC_IKE_INTERMEDIATE "IP beveiliging IKE tussenpersoon"
|
||||
IDS_FILE_RECOVERY "Bestand Herstellen"
|
||||
IDS_ROOT_LIST_SIGNER "Basis Lijst Ondertekenaar"
|
||||
IDS_ANY_APPLICATION_POLICIES "Alle applicaties beleid"
|
||||
IDS_DS_EMAIL_REPLICATION "Directory Service Email Replicatie"
|
||||
IDS_ENROLLMENT_AGENT "Certificaat Verzoek Agent"
|
||||
IDS_LIFETIME_SIGNING "Levensduur Ondertekenen"
|
||||
IDS_ANY_CERT_POLICY "Alle uitgifte beleid"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Vertrouwde Basis Certificatie Autoriteiten"
|
||||
IDS_LOCALIZEDNAME_MY "Persoonlijk"
|
||||
IDS_LOCALIZEDNAME_CA "Certificatie Tussen-Autoriteiten"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Overige Personen"
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
|
||||
LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
|
@ -164,3 +164,11 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_LIFETIME_SIGNING "Livstidsignering"
|
||||
IDS_ANY_CERT_POLICY "Alle framgangsmåter for utsteding"
|
||||
}
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_LOCALIZEDNAME_ROOT "Klarerte rotsertifiseringsinstanser"
|
||||
IDS_LOCALIZEDNAME_MY "Personlig"
|
||||
IDS_LOCALIZEDNAME_CA "Mellomliggende sertifiseringsinstanser"
|
||||
IDS_LOCALIZEDNAME_ADDRESSBOOK "Andre personer"
|
||||
}
|
||||
|
|
169
reactos/dll/win32/crypt32/crypt32_Sv.rc
Normal file
169
reactos/dll/win32/crypt32/crypt32_Sv.rc
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* crypt32 dll resources
|
||||
*
|
||||
* Copyright (C) 2007 Daniel Nylander
|
||||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_AUTHORITY_KEY_ID "Authority Key Identifier"
|
||||
IDS_KEY_ATTRIBUTES "Nyckelattribut"
|
||||
IDS_KEY_USAGE_RESTRICTION "Key Usage Restriction"
|
||||
IDS_SUBJECT_ALT_NAME "Subject Alternative Name"
|
||||
IDS_ISSUER_ALT_NAME "Issuer Alternative Name"
|
||||
IDS_BASIC_CONSTRAINTS "Basic Constraints"
|
||||
IDS_KEY_USAGE "Nyckelanvändning"
|
||||
IDS_CERT_POLICIES "Certificate Policies"
|
||||
IDS_SUBJECT_KEY_IDENTIFIER "Subject Key Identifier"
|
||||
IDS_CRL_REASON_CODE "CRL Reason Code"
|
||||
IDS_CRL_DIST_POINTS "CRL Distribution Points"
|
||||
IDS_ENHANCED_KEY_USAGE "Enhanced Key Usage"
|
||||
IDS_AUTHORITY_INFO_ACCESS "Authority Information Access"
|
||||
IDS_CERT_EXTENSIONS "Certificate Extensions"
|
||||
IDS_NEXT_UPDATE_LOCATION "Next Update Location"
|
||||
IDS_YES_OR_NO_TRUST "Yes or No Trust"
|
||||
IDS_EMAIL_ADDRESS "E-postadress"
|
||||
IDS_UNSTRUCTURED_NAME "Unstructured Name"
|
||||
IDS_CONTENT_TYPE "Innehållstyp"
|
||||
IDS_MESSAGE_DIGEST "Message Digest"
|
||||
IDS_SIGNING_TIME "Signing Time"
|
||||
IDS_COUNTER_SIGN "Counter Sign"
|
||||
IDS_CHALLENGE_PASSWORD "Challenge Password"
|
||||
IDS_UNSTRUCTURED_ADDRESS "Unstructured Address"
|
||||
IDS_SMIME_CAPABILITIES "SMIME Capabilities"
|
||||
IDS_PREFER_SIGNED_DATA "Prefer Signed Data"
|
||||
IDS_CPS "CPS"
|
||||
IDS_USER_NOTICE "User Notice"
|
||||
IDS_OCSP "On-line Certificate Status Protocol"
|
||||
IDS_CA_ISSUER "Certification Authority Issuer"
|
||||
IDS_CERT_TEMPLATE_NAME "Certification Template Name"
|
||||
IDS_CERT_TYPE "Certificate Type"
|
||||
IDS_CERT_MANIFOLD "Certificate Manifold"
|
||||
IDS_NETSCAPE_CERT_TYPE "Netscape Cert Type"
|
||||
IDS_NETSCAPE_BASE_URL "Netscape Base URL"
|
||||
IDS_NETSCAPE_REVOCATION_URL "Netscape Revocation URL"
|
||||
IDS_NETSCAPE_CA_REVOCATION_URL "Netscape CA Revocation URL"
|
||||
IDS_NETSCAPE_CERT_RENEWAL_URL "Netscape Cert Renewal URL"
|
||||
IDS_NETSCAPE_CA_POLICY_URL "Netscape CA Policy URL"
|
||||
IDS_NETSCAPE_SSL_SERVER_NAME "Netscape SSL ServerName"
|
||||
IDS_NETSCAPE_COMMENT "Netscape Comment"
|
||||
IDS_SPC_SP_AGENCY_INFO "SpcSpAgencyInfo"
|
||||
IDS_SPC_FINANCIAL_CRITERIA "SpcFinancialCriteria"
|
||||
IDS_SPC_MINIMAL_CRITERIA "SpcMinimalCriteria"
|
||||
IDS_COUNTRY "Land/Region"
|
||||
IDS_ORGANIZATION "Organisation"
|
||||
IDS_ORGANIZATIONAL_UNIT "Organizational Unit"
|
||||
IDS_COMMON_NAME "Common Name"
|
||||
IDS_LOCALITY "Plats"
|
||||
IDS_STATE_OR_PROVINCE "Län eller region"
|
||||
IDS_TITLE "Titel"
|
||||
IDS_GIVEN_NAME "Förnamn"
|
||||
IDS_INITIALS "Initialer"
|
||||
IDS_SUR_NAME "Efternamn"
|
||||
IDS_DOMAIN_COMPONENT "Domain Component"
|
||||
IDS_STREET_ADDRESS "Postadress"
|
||||
IDS_SERIAL_NUMBER "Serienummer"
|
||||
IDS_CA_VERSION "CA Version"
|
||||
IDS_CROSS_CA_VERSION "Cross CA Version"
|
||||
IDS_SERIALIZED_SIG_SERIAL_NUMBER "Serialized Signature Serial Number"
|
||||
IDS_PRINCIPAL_NAME "Principal Name"
|
||||
IDS_WINDOWS_PRODUCT_UPDATE "Windows Product Update"
|
||||
IDS_ENROLLMENT_NAME_VALUE_PAIR "Enrollment Name Value Pair"
|
||||
IDS_OS_VERSION "OS Version"
|
||||
IDS_ENROLLMENT_CSP "Enrollment CSP"
|
||||
IDS_CRL_NUMBER "CRL Number"
|
||||
IDS_DELTA_CRL_INDICATOR "Delta CRL Indicator"
|
||||
IDS_ISSUING_DIST_POINT "Issuing Distribution Point"
|
||||
IDS_FRESHEST_CRL "Freshest CRL"
|
||||
IDS_NAME_CONSTRAINTS "Name Constraints"
|
||||
IDS_POLICY_MAPPINGS "Policy Mappings"
|
||||
IDS_POLICY_CONSTRAINTS "Policy Constraints"
|
||||
IDS_CROSS_CERT_DIST_POINTS "Cross-Certificate Distribution Points"
|
||||
IDS_APPLICATION_POLICIES "Application Policies"
|
||||
IDS_APPLICATION_POLICY_MAPPINGS "Application Policy Mappings"
|
||||
IDS_APPLICATION_POLICY_CONSTRAINTS "Application Policy Constraints"
|
||||
IDS_CMC_DATA "CMC Data"
|
||||
IDS_CMC_RESPONSE "CMC Response"
|
||||
IDS_UNSIGNED_CMC_REQUEST "Unsigned CMC Request"
|
||||
IDS_CMC_STATUS_INFO "CMC Status Info"
|
||||
IDS_CMC_EXTENSIONS "CMC Extensions"
|
||||
IDS_CMC_ATTRIBUTES "CMC Attributes"
|
||||
IDS_PKCS_7_DATA "PKCS 7 Data"
|
||||
IDS_PKCS_7_SIGNED "PKCS 7 Signed"
|
||||
IDS_PKCS_7_ENVELOPED "PKCS 7 Enveloped"
|
||||
IDS_PKCS_7_SIGNED_ENVELOPED "PKCS 7 Signed Enveloped"
|
||||
IDS_PKCS_7_DIGESTED "PKCS 7 Digested"
|
||||
IDS_PKCS_7_ENCRYPTED "PKCS 7 Encrypted"
|
||||
IDS_PREVIOUS_CA_CERT_HASH "Previous CA Certificate Hash"
|
||||
IDS_CRL_VIRTUAL_BASE "Virtual Base CRL Number"
|
||||
IDS_CRL_NEXT_PUBLISH "Next CRL Publish"
|
||||
IDS_CA_EXCHANGE "CA Encryption Certificate"
|
||||
IDS_KEY_RECOVERY_AGENT "Key Recovery Agent"
|
||||
IDS_CERTIFICATE_TEMPLATE "Certificate Template Information"
|
||||
IDS_ENTERPRISE_ROOT_OID "Enterprise Root OID"
|
||||
IDS_RDN_DUMMY_SIGNER "Dummy Signer"
|
||||
IDS_ARCHIVED_KEY_ATTR "Encrypted Private Key"
|
||||
IDS_CRL_SELF_CDP "Published CRL Locations"
|
||||
IDS_REQUIRE_CERT_CHAIN_POLICY "Enforce Certificate Chain Policy"
|
||||
IDS_TRANSACTION_ID "Transaction Id"
|
||||
IDS_SENDER_NONCE "Sender Nonce"
|
||||
IDS_RECIPIENT_NONCE "Recipient Nonce"
|
||||
IDS_REG_INFO "Reg Info"
|
||||
IDS_GET_CERTIFICATE "Get Certificate"
|
||||
IDS_GET_CRL "Get CRL"
|
||||
IDS_REVOKE_REQUEST "Revoke Request"
|
||||
IDS_QUERY_PENDING "Query Pending"
|
||||
IDS_SORTED_CTL "Certificate Trust List"
|
||||
IDS_ARCHIVED_KEY_CERT_HASH "Archived Key Certificate Hash"
|
||||
IDS_PRIVATE_KEY_USAGE_PERIOD "Private Key Usage Period"
|
||||
IDS_CLIENT_INFORMATION "Client Information"
|
||||
IDS_SERVER_AUTHENTICATION "Server Authentication"
|
||||
IDS_CLIENT_AUTHENTICATION "Client Authentication"
|
||||
IDS_CODE_SIGNING "Code Signing"
|
||||
IDS_SECURE_EMAIL "Säker e-post"
|
||||
IDS_TIME_STAMPING "Time Stamping"
|
||||
IDS_MICROSOFT_TRUST_LIST_SIGNING "Microsoft Trust List Signing"
|
||||
IDS_MICROSOFT_TIME_STAMPING "Microsoft Time Stamping"
|
||||
IDS_IPSEC_END_SYSTEM "IP security end system"
|
||||
IDS_IPSEC_TUNNEL "IP security tunnel termination"
|
||||
IDS_IPSEC_USER "IP security user"
|
||||
IDS_EFS "Encrypting File System"
|
||||
IDS_WHQL_CRYPTO "Windows Hardware Driver Verification"
|
||||
IDS_NT5_CRYPTO "Windows System Component Verification"
|
||||
IDS_OEM_WHQL_CRYPTO "OEM Windows System Component Verification"
|
||||
IDS_EMBEDDED_NT_CRYPTO "Embedded Windows System Component Verification"
|
||||
IDS_KEY_PACK_LICENSES "Key Pack Licenses"
|
||||
IDS_LICENSE_SERVER "License Server Verification"
|
||||
IDS_SMART_CARD_LOGON "Smart Card Logon"
|
||||
IDS_DIGITAL_RIGHTS "Digital Rights"
|
||||
IDS_QUALIFIED_SUBORDINATION "Qualified Subordination"
|
||||
IDS_KEY_RECOVERY "Key Recovery"
|
||||
IDS_DOCUMENT_SIGNING "Document Signing"
|
||||
IDS_IPSEC_IKE_INTERMEDIATE "IP security IKE intermediate"
|
||||
IDS_FILE_RECOVERY "File Recovery"
|
||||
IDS_ROOT_LIST_SIGNER "Root List Signer"
|
||||
IDS_ANY_APPLICATION_POLICIES "All application policies"
|
||||
IDS_DS_EMAIL_REPLICATION "Directory Service Email Replication"
|
||||
IDS_ENROLLMENT_AGENT "Certificate Request Agent"
|
||||
IDS_LIFETIME_SIGNING "Lifetime Signing"
|
||||
IDS_ANY_CERT_POLICY "All issuance policies"
|
||||
}
|
||||
|
||||
#pragma code_page(default)
|
|
@ -38,6 +38,81 @@
|
|||
#define ASN_UNIVERSALSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1c)
|
||||
#define ASN_BMPSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1e)
|
||||
|
||||
BOOL CRYPT_EncodeLen(DWORD len, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
typedef BOOL (WINAPI *CryptEncodeObjectExFunc)(DWORD, LPCSTR, const void *,
|
||||
DWORD, PCRYPT_ENCODE_PARA, BYTE *, DWORD *);
|
||||
|
||||
struct AsnEncodeSequenceItem
|
||||
{
|
||||
const void *pvStructInfo;
|
||||
CryptEncodeObjectExFunc encodeFunc;
|
||||
DWORD size; /* used during encoding, not for your use */
|
||||
};
|
||||
|
||||
BOOL WINAPI CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType,
|
||||
struct AsnEncodeSequenceItem items[], DWORD cItem, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
struct AsnConstructedItem
|
||||
{
|
||||
BYTE tag;
|
||||
const void *pvStructInfo;
|
||||
CryptEncodeObjectExFunc encodeFunc;
|
||||
};
|
||||
|
||||
BOOL WINAPI CRYPT_AsnEncodeConstructed(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
BOOL WINAPI CRYPT_AsnEncodeOid(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
BOOL WINAPI CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType,
|
||||
LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
|
||||
PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
typedef struct _CRYPT_DIGESTED_DATA
|
||||
{
|
||||
DWORD version;
|
||||
CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm;
|
||||
CRYPT_CONTENT_INFO ContentInfo;
|
||||
CRYPT_HASH_BLOB hash;
|
||||
} CRYPT_DIGESTED_DATA;
|
||||
|
||||
BOOL CRYPT_AsnEncodePKCSDigestedData(CRYPT_DIGESTED_DATA *digestedData,
|
||||
void *pvData, DWORD *pcbData);
|
||||
|
||||
typedef struct _CRYPT_SIGNED_INFO
|
||||
{
|
||||
DWORD version;
|
||||
DWORD cCertEncoded;
|
||||
PCERT_BLOB rgCertEncoded;
|
||||
DWORD cCrlEncoded;
|
||||
PCRL_BLOB rgCrlEncoded;
|
||||
CRYPT_CONTENT_INFO content;
|
||||
DWORD cSignerInfo;
|
||||
PCMSG_SIGNER_INFO rgSignerInfo;
|
||||
} CRYPT_SIGNED_INFO;
|
||||
|
||||
BOOL CRYPT_AsnEncodePKCSSignedInfo(CRYPT_SIGNED_INFO *, void *pvData,
|
||||
DWORD *pcbData);
|
||||
|
||||
BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
|
||||
CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo);
|
||||
|
||||
/* Helper function to check *pcbEncoded, set it to the required size, and
|
||||
* optionally to allocate memory. Assumes pbEncoded is not NULL.
|
||||
* If CRYPT_ENCODE_ALLOC_FLAG is set in dwFlags, *pbEncoded will be set to a
|
||||
* pointer to the newly allocated memory.
|
||||
*/
|
||||
BOOL CRYPT_EncodeEnsureSpace(DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
|
||||
BYTE *pbEncoded, DWORD *pcbEncoded, DWORD bytesNeeded);
|
||||
|
||||
BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
|
||||
DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
|
||||
CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData);
|
||||
|
||||
/* The following aren't defined in wincrypt.h, as they're "reserved" */
|
||||
#define CERT_CERT_PROP_ID 32
|
||||
#define CERT_CRL_PROP_ID 33
|
||||
|
@ -50,6 +125,9 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void);
|
|||
|
||||
void crypt_oid_init(HINSTANCE hinst);
|
||||
void crypt_oid_free(void);
|
||||
void crypt_sip_free(void);
|
||||
void root_store_free(void);
|
||||
void default_chain_engine_free(void);
|
||||
|
||||
/* Some typedefs that make it easier to abstract which type of context we're
|
||||
* working with.
|
||||
|
@ -95,6 +173,94 @@ extern PCWINE_CONTEXT_INTERFACE pCertInterface;
|
|||
extern PCWINE_CONTEXT_INTERFACE pCRLInterface;
|
||||
extern PCWINE_CONTEXT_INTERFACE pCTLInterface;
|
||||
|
||||
/* (Internal) certificate store types and functions */
|
||||
struct WINE_CRYPTCERTSTORE;
|
||||
|
||||
typedef struct WINE_CRYPTCERTSTORE * (*StoreOpenFunc)(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
|
||||
/* Called to enumerate the next context in a store. */
|
||||
typedef void * (*EnumFunc)(struct WINE_CRYPTCERTSTORE *store, void *pPrev);
|
||||
|
||||
/* Called to add a context to a store. If toReplace is not NULL,
|
||||
* context replaces toReplace in the store, and access checks should not be
|
||||
* performed. Otherwise context is a new context, and it should only be
|
||||
* added if the store allows it. If ppStoreContext is not NULL, the added
|
||||
* context should be returned in *ppStoreContext.
|
||||
*/
|
||||
typedef BOOL (*AddFunc)(struct WINE_CRYPTCERTSTORE *store, void *context,
|
||||
void *toReplace, const void **ppStoreContext);
|
||||
|
||||
typedef BOOL (*DeleteFunc)(struct WINE_CRYPTCERTSTORE *store, void *context);
|
||||
|
||||
typedef struct _CONTEXT_FUNCS
|
||||
{
|
||||
AddFunc addContext;
|
||||
EnumFunc enumContext;
|
||||
DeleteFunc deleteContext;
|
||||
} CONTEXT_FUNCS, *PCONTEXT_FUNCS;
|
||||
|
||||
typedef enum _CertStoreType {
|
||||
StoreTypeMem,
|
||||
StoreTypeCollection,
|
||||
StoreTypeProvider,
|
||||
} CertStoreType;
|
||||
|
||||
struct _CONTEXT_PROPERTY_LIST;
|
||||
typedef struct _CONTEXT_PROPERTY_LIST *PCONTEXT_PROPERTY_LIST;
|
||||
|
||||
#define WINE_CRYPTCERTSTORE_MAGIC 0x74726563
|
||||
|
||||
/* A cert store is polymorphic through the use of function pointers. A type
|
||||
* is still needed to distinguish collection stores from other types.
|
||||
* On the function pointers:
|
||||
* - closeStore is called when the store's ref count becomes 0
|
||||
* - control is optional, but should be implemented by any store that supports
|
||||
* persistence
|
||||
*/
|
||||
typedef struct WINE_CRYPTCERTSTORE
|
||||
{
|
||||
DWORD dwMagic;
|
||||
LONG ref;
|
||||
DWORD dwOpenFlags;
|
||||
CertStoreType type;
|
||||
PFN_CERT_STORE_PROV_CLOSE closeStore;
|
||||
CONTEXT_FUNCS certs;
|
||||
CONTEXT_FUNCS crls;
|
||||
PFN_CERT_STORE_PROV_CONTROL control; /* optional */
|
||||
PCONTEXT_PROPERTY_LIST properties;
|
||||
} WINECRYPT_CERTSTORE, *PWINECRYPT_CERTSTORE;
|
||||
|
||||
void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
|
||||
CertStoreType type);
|
||||
void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store);
|
||||
BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
|
||||
DWORD unk1);
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo);
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara);
|
||||
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags);
|
||||
|
||||
/* Allocates and initializes a certificate chain engine, but without creating
|
||||
* the root store. Instead, it uses root, and assumes the caller has done any
|
||||
* checking necessary.
|
||||
*/
|
||||
HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root,
|
||||
PCERT_CHAIN_ENGINE_CONFIG pConfig);
|
||||
|
||||
/* Helper function for store reading functions and
|
||||
* CertAddSerializedElementToStore. Returns a context of the appropriate type
|
||||
* if it can, or NULL otherwise. Doesn't validate any of the properties in
|
||||
|
@ -104,15 +270,12 @@ extern PCWINE_CONTEXT_INTERFACE pCTLInterface;
|
|||
const void *CRYPT_ReadSerializedElement(const BYTE *pbElement,
|
||||
DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType);
|
||||
|
||||
/* Writes contexts from the memory store to the file. */
|
||||
BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store);
|
||||
|
||||
/* Reads contexts serialized in the file into the memory store. Returns FALSE
|
||||
* if the file is not of the expected format.
|
||||
*/
|
||||
BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store);
|
||||
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store);
|
||||
|
||||
/* Fixes up the the pointers in info, where info is assumed to be a
|
||||
/* Fixes up the pointers in info, where info is assumed to be a
|
||||
* CRYPT_KEY_PROV_INFO, followed by its container name, provider name, and any
|
||||
* provider parameters, in a contiguous buffer, but where info's pointers are
|
||||
* assumed to be invalid. Upon return, info's pointers point to the
|
||||
|
@ -120,8 +283,6 @@ BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store);
|
|||
*/
|
||||
void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info);
|
||||
|
||||
DWORD CertStore_GetAccessState(HCERTSTORE hCertStore);
|
||||
|
||||
/**
|
||||
* Context functions
|
||||
*/
|
||||
|
@ -153,13 +314,10 @@ void *Context_GetLinkedContext(void *context, size_t contextSize);
|
|||
void Context_CopyProperties(const void *to, const void *from,
|
||||
size_t contextSize);
|
||||
|
||||
struct _CONTEXT_PROPERTY_LIST;
|
||||
typedef struct _CONTEXT_PROPERTY_LIST *PCONTEXT_PROPERTY_LIST;
|
||||
|
||||
/* Returns context's properties, or the linked context's properties if context
|
||||
* is a link context.
|
||||
*/
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(void *context, size_t contextSize);
|
||||
PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize);
|
||||
|
||||
void Context_AddRef(void *context, size_t contextSize);
|
||||
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
Index: crypt32.rc
|
||||
===================================================================
|
||||
--- crypt32.rc (revision 22838)
|
||||
+++ crypt32.rc (working copy)
|
||||
@@ -17,12 +17,18 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
+
|
||||
+#define REACTOS_VERSION_DLL
|
||||
+#define REACTOS_STR_FILE_DESCRIPTION "CryptoAPI Library\0"
|
||||
+#define REACTOS_STR_INTERNAL_NAME "crypt32\0"
|
||||
+#define REACTOS_STR_ORIGINAL_FILENAME "crypt32.dll\0"
|
||||
+
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "cryptres.h"
|
||||
--- D:/Wine-CVS/wine/dlls/crypt32/rootstore.c Sat Feb 16 22:49:56 2008
|
||||
+++ D:/ReactOS-Trunk/reactos/dll/win32/crypt32/rootstore.c Sat May 10 20:30:25 2008
|
||||
@@ -317,7 +317,7 @@
|
||||
DIR *dir;
|
||||
|
||||
-#include "version.rc"
|
||||
+#include <reactos/version.rc>
|
||||
TRACE("(%s, %p)\n", debugstr_a(path), store);
|
||||
-
|
||||
+ /* UNIX functions = bad for reactos
|
||||
dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
@@ -340,6 +340,7 @@
|
||||
CryptMemFree(filebuf);
|
||||
}
|
||||
}
|
||||
+ */
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "crypt32_De.rc"
|
||||
#include "crypt32_En.rc"
|
||||
|
|
|
@ -160,4 +160,9 @@
|
|||
#define IDS_LIFETIME_SIGNING 1139
|
||||
#define IDS_ANY_CERT_POLICY 1140
|
||||
|
||||
#define IDS_LOCALIZEDNAME_ROOT 1141
|
||||
#define IDS_LOCALIZEDNAME_MY 1142
|
||||
#define IDS_LOCALIZEDNAME_CA 1143
|
||||
#define IDS_LOCALIZEDNAME_ADDRESSBOOK 1144
|
||||
|
||||
#endif /* ndef __WINE_CRYPTRES_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
389
reactos/dll/win32/crypt32/filestore.c
Normal file
389
reactos/dll/win32/crypt32/filestore.c
Normal file
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winnls.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_FILESTOREINFO
|
||||
{
|
||||
DWORD dwOpenFlags;
|
||||
HCERTSTORE memStore;
|
||||
HANDLE file;
|
||||
DWORD type;
|
||||
BOOL dirty;
|
||||
} WINE_FILESTOREINFO, *PWINE_FILESTOREINFO;
|
||||
|
||||
static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
if (store->dirty)
|
||||
CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
|
||||
CertCloseStore(store->memStore, dwFlags);
|
||||
CloseHandle(store->file);
|
||||
CryptMemFree(store);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_FileWriteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_FileDeleteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", hCertStore, pCertContext, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_FileWriteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_FileDeleteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", hCertStore, pCrlContext, dwFlags);
|
||||
store->dirty = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
blob->cbData = GetFileSize(file, NULL);
|
||||
if (blob->cbData)
|
||||
{
|
||||
blob->pbData = CryptMemAlloc(blob->cbData);
|
||||
if (blob->pbData)
|
||||
{
|
||||
DWORD read;
|
||||
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_FILESTOREINFO store = (PWINE_FILESTOREINFO)hCertStore;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
|
||||
switch (dwCtrlType)
|
||||
{
|
||||
case CERT_STORE_CTRL_RESYNC:
|
||||
store->dirty = FALSE;
|
||||
if (store->type == CERT_STORE_SAVE_AS_STORE)
|
||||
{
|
||||
HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
/* FIXME: if I could translate a handle to a path, I could use
|
||||
* CryptQueryObject instead, but there's no API to do so yet.
|
||||
*/
|
||||
ret = CRYPT_ReadSerializedStoreFromFile(store->file, memStore);
|
||||
if (ret)
|
||||
I_CertUpdateStore(store->memStore, memStore, 0, 0);
|
||||
CertCloseStore(memStore, 0);
|
||||
}
|
||||
else if (store->type == CERT_STORE_SAVE_AS_PKCS7)
|
||||
{
|
||||
CERT_BLOB blob = { 0, NULL };
|
||||
|
||||
ret = CRYPT_ReadBlobFromFile(store->file, &blob);
|
||||
if (ret)
|
||||
{
|
||||
HCERTSTORE messageStore;
|
||||
|
||||
ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
|
||||
CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL,
|
||||
&messageStore, NULL, NULL);
|
||||
I_CertUpdateStore(store->memStore, messageStore, 0, 0);
|
||||
CertCloseStore(messageStore, 0);
|
||||
CryptMemFree(blob.pbData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("unknown type %d\n", store->type);
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_CTRL_COMMIT:
|
||||
if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (store->dirty)
|
||||
ret = CertSaveStore(store->memStore,
|
||||
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||
store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0);
|
||||
else
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
FIXME("%d: stub\n", dwCtrlType);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *fileProvFuncs[] = {
|
||||
CRYPT_FileCloseStore,
|
||||
NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
|
||||
CRYPT_FileWriteCert,
|
||||
CRYPT_FileDeleteCert,
|
||||
NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
|
||||
CRYPT_FileWriteCRL,
|
||||
CRYPT_FileDeleteCRL,
|
||||
NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
|
||||
CRYPT_FileControl,
|
||||
};
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_CreateFileStore(DWORD dwFlags,
|
||||
HCERTSTORE memStore, HANDLE file, DWORD type)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
PWINE_FILESTOREINFO info = CryptMemAlloc(sizeof(WINE_FILESTOREINFO));
|
||||
|
||||
if (info)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = { 0 };
|
||||
|
||||
info->dwOpenFlags = dwFlags;
|
||||
info->memStore = memStore;
|
||||
info->file = file;
|
||||
info->type = type;
|
||||
info->dirty = FALSE;
|
||||
provInfo.cbSize = sizeof(provInfo);
|
||||
provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
|
||||
sizeof(fileProvFuncs[0]);
|
||||
provInfo.rgpvStoreProvFunc = fileProvFuncs;
|
||||
provInfo.hStoreProv = info;
|
||||
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
HANDLE file = (HANDLE)pvPara;
|
||||
|
||||
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
||||
|
||||
if (!pvPara)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
|
||||
(dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
|
||||
GetCurrentProcess(), &file, dwFlags & CERT_STORE_READONLY_FLAG ?
|
||||
GENERIC_READ : GENERIC_READ | GENERIC_WRITE, TRUE, 0))
|
||||
{
|
||||
HCERTSTORE memStore;
|
||||
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (memStore)
|
||||
{
|
||||
if (CRYPT_ReadSerializedStoreFromFile(file, memStore))
|
||||
{
|
||||
store = CRYPT_CreateFileStore(dwFlags, memStore, file,
|
||||
CERT_STORE_SAVE_AS_STORE);
|
||||
/* File store doesn't need crypto provider, so close it */
|
||||
if (hCryptProv &&
|
||||
!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", store);
|
||||
return store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
HCERTSTORE store = 0;
|
||||
LPCWSTR fileName = (LPCWSTR)pvPara;
|
||||
DWORD access, create;
|
||||
HANDLE file;
|
||||
|
||||
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));
|
||||
|
||||
if (!fileName)
|
||||
{
|
||||
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
|
||||
(dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
access = GENERIC_READ;
|
||||
if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
|
||||
access |= GENERIC_WRITE;
|
||||
if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
|
||||
create = CREATE_NEW;
|
||||
else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
|
||||
create = OPEN_EXISTING;
|
||||
else
|
||||
create = OPEN_ALWAYS;
|
||||
file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HCERTSTORE memStore = NULL;
|
||||
DWORD size = GetFileSize(file, NULL), type = 0;
|
||||
|
||||
/* If the file isn't empty, try to get the type from the file itself */
|
||||
if (size)
|
||||
{
|
||||
DWORD contentType;
|
||||
BOOL ret;
|
||||
|
||||
/* Close the file so CryptQueryObject can succeed.. */
|
||||
CloseHandle(file);
|
||||
ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName,
|
||||
CERT_QUERY_CONTENT_FLAG_CERT |
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
|
||||
CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL,
|
||||
&memStore, NULL, NULL);
|
||||
if (ret)
|
||||
{
|
||||
if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
|
||||
type = CERT_STORE_SAVE_AS_PKCS7;
|
||||
else
|
||||
type = CERT_STORE_SAVE_AS_STORE;
|
||||
/* and reopen the file. */
|
||||
file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL,
|
||||
create, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static const WCHAR spc[] = { 's','p','c',0 };
|
||||
static const WCHAR p7c[] = { 'p','7','c',0 };
|
||||
LPCWSTR ext = strrchrW(fileName, '.');
|
||||
|
||||
if (ext)
|
||||
{
|
||||
ext++;
|
||||
if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c))
|
||||
type = CERT_STORE_SAVE_AS_PKCS7;
|
||||
}
|
||||
if (!type)
|
||||
type = CERT_STORE_SAVE_AS_STORE;
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
}
|
||||
if (memStore)
|
||||
{
|
||||
store = CRYPT_CreateFileStore(dwFlags, memStore, file, type);
|
||||
/* File store doesn't need crypto provider, so close it */
|
||||
if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)store;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreA(HCRYPTPROV hCryptProv,
|
||||
DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
int len;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
|
||||
debugstr_a((LPCSTR)pvPara));
|
||||
|
||||
if (!pvPara)
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, NULL, 0);
|
||||
if (len)
|
||||
{
|
||||
LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
|
||||
|
||||
if (storeName)
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pvPara, -1, storeName, len);
|
||||
ret = CRYPT_FileNameOpenStoreW(hCryptProv, dwFlags, storeName);
|
||||
CryptMemFree(storeName);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -25,10 +25,8 @@
|
|||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winreg.h"
|
||||
#include "winnls.h"
|
||||
#include "mssip.h"
|
||||
#include "winuser.h"
|
||||
#include "advpub.h"
|
||||
#include "i_cryptasn1tls.h"
|
||||
#include "crypt32_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -46,7 +44,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
|
|||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
crypt_oid_free();
|
||||
if (hDefProv) CryptReleaseContext(hDefProv, 0);
|
||||
crypt_sip_free();
|
||||
root_store_free();
|
||||
default_chain_engine_free();
|
||||
/* Don't release the default provider on process shutdown, there's
|
||||
* no guarantee the provider dll hasn't already been unloaded.
|
||||
*/
|
||||
if (hDefProv && !pvReserved) CryptReleaseContext(hDefProv, 0);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -55,8 +59,16 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
|
|||
HCRYPTPROV CRYPT_GetDefaultProvider(void)
|
||||
{
|
||||
if (!hDefProv)
|
||||
CryptAcquireContextW(&hDefProv, NULL, MS_ENHANCED_PROV_W,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
|
||||
{
|
||||
HCRYPTPROV prov;
|
||||
|
||||
CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT);
|
||||
InterlockedCompareExchangePointer((PVOID *)&hDefProv, (PVOID)prov,
|
||||
NULL);
|
||||
if (hDefProv != prov)
|
||||
CryptReleaseContext(prov, 0);
|
||||
}
|
||||
return hDefProv;
|
||||
}
|
||||
|
||||
|
@ -75,12 +87,24 @@ BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptFindLruEntry(DWORD unk0, DWORD unk1)
|
||||
{
|
||||
FIXME("(%08x, %08x): stub!\n", unk0, unk1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2)
|
||||
{
|
||||
FIXME("(%08x, %08x, %08x): stub!\n", unk0, unk1, unk2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptCreateLruEntry(HLRUCACHE h, DWORD unk0, DWORD unk1)
|
||||
{
|
||||
FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1)
|
||||
{
|
||||
FIXME("(%p, %08x, %08x): stub!\n", h, unk0, unk1);
|
||||
|
@ -163,7 +187,7 @@ HCRYPTPROV WINAPI I_CryptGetDefaultCryptProv(DWORD reserved)
|
|||
BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name,
|
||||
DWORD *value)
|
||||
{
|
||||
static const WCHAR safer[] = {
|
||||
static const WCHAR safer[] = {
|
||||
'S','o','f','t','w','a','r','e','\\','P','o','l','i','c','i','e','s','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m',
|
||||
'C','e','r','t','i','f','i','c','a','t','e','s','\\',
|
||||
|
@ -188,7 +212,7 @@ BOOL WINAPI I_CryptReadTrustedPublisherDWORDValueFromRegistry(LPCWSTR name,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
|
||||
DWORD WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
|
||||
{
|
||||
static int ret = 8;
|
||||
ret++;
|
||||
|
@ -196,18 +220,30 @@ int WINAPI I_CryptInstallOssGlobal(DWORD x, DWORD y, DWORD z)
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptInstallAsn1Module(void *x, DWORD y, DWORD z)
|
||||
BOOL WINAPI I_CryptInstallAsn1Module(ASN1module_t x, DWORD y, void* z)
|
||||
{
|
||||
FIXME("%p %08x %08x\n", x, y, z);
|
||||
FIXME("(%p %08x %p): stub\n", x, y, z);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI I_CryptUninstallAsn1Module(void *x)
|
||||
BOOL WINAPI I_CryptUninstallAsn1Module(HCRYPTASN1MODULE x)
|
||||
{
|
||||
FIXME("%p\n", x);
|
||||
FIXME("(%08x): stub\n", x);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ASN1decoding_t WINAPI I_CryptGetAsn1Decoder(HCRYPTASN1MODULE x)
|
||||
{
|
||||
FIXME("(%08x): stub\n", x);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ASN1encoding_t WINAPI I_CryptGetAsn1Encoder(HCRYPTASN1MODULE x)
|
||||
{
|
||||
FIXME("(%08x): stub\n", x);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
|
||||
DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType,
|
||||
const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat)
|
||||
|
@ -217,28 +253,3 @@ BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
|
|||
debugstr_a(lpszStructType), pbEncoded, cbEncoded, pbFormat, pcbFormat);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void* pvObject,
|
||||
DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
|
||||
DWORD dwFlags, DWORD* pdwMsgAndCertEncodingType, DWORD* pdwContentType,
|
||||
DWORD* pdwFormatType, HCERTSTORE* phCertStore, HCRYPTMSG* phMsg,
|
||||
const void** ppvContext)
|
||||
{
|
||||
FIXME( "%08x %p %08x %08x %08x %p %p %p %p %p %p\n", dwObjectType,
|
||||
pvObject, dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
|
||||
dwFlags, pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
|
||||
phCertStore, phMsg, ppvContext);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
|
||||
DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
|
||||
BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
|
||||
{
|
||||
FIXME("stub: %p, %d, %p, %d, %p, %p, %p\n",
|
||||
pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob,
|
||||
pbDecoded, pcbDecoded, ppSignerCert);
|
||||
if (ppSignerCert)
|
||||
*ppSignerCert = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
2614
reactos/dll/win32/crypt32/msg.c
Normal file
2614
reactos/dll/win32/crypt32/msg.c
Normal file
File diff suppressed because it is too large
Load diff
522
reactos/dll/win32/crypt32/object.c
Normal file
522
reactos/dll/win32/crypt32/object.c
Normal file
|
@ -0,0 +1,522 @@
|
|||
/*
|
||||
* crypt32 Crypt*Object functions
|
||||
*
|
||||
* Copyright 2007 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "imagehlp.h"
|
||||
#include "crypt32_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
static BOOL CRYPT_ReadBlobFromFile(LPCWSTR fileName, PCERT_BLOB blob)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
HANDLE file;
|
||||
|
||||
TRACE("%s\n", debugstr_w(fileName));
|
||||
|
||||
file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ret = TRUE;
|
||||
blob->cbData = GetFileSize(file, NULL);
|
||||
if (blob->cbData)
|
||||
{
|
||||
blob->pbData = CryptMemAlloc(blob->cbData);
|
||||
if (blob->pbData)
|
||||
{
|
||||
DWORD read;
|
||||
|
||||
ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject,
|
||||
DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType,
|
||||
DWORD *pdwContentType, HCERTSTORE *phCertStore, const void **ppvContext)
|
||||
{
|
||||
CERT_BLOB fileBlob;
|
||||
const CERT_BLOB *blob;
|
||||
HCERTSTORE store;
|
||||
DWORD contentType;
|
||||
BOOL ret;
|
||||
|
||||
switch (dwObjectType)
|
||||
{
|
||||
case CERT_QUERY_OBJECT_FILE:
|
||||
/* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
|
||||
* just read the file directly
|
||||
*/
|
||||
ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob);
|
||||
blob = &fileBlob;
|
||||
break;
|
||||
case CERT_QUERY_OBJECT_BLOB:
|
||||
blob = (const CERT_BLOB *)pvObject;
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
ret = FALSE;
|
||||
}
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
ret = FALSE;
|
||||
if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT)
|
||||
{
|
||||
ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
|
||||
if (ret)
|
||||
contentType = CERT_QUERY_CONTENT_CERT;
|
||||
}
|
||||
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL))
|
||||
{
|
||||
ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
|
||||
if (ret)
|
||||
contentType = CERT_QUERY_CONTENT_CRL;
|
||||
}
|
||||
if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
|
||||
{
|
||||
ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
|
||||
blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
|
||||
if (ret)
|
||||
contentType = CERT_QUERY_CONTENT_CTL;
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
||||
if (pdwContentType)
|
||||
*pdwContentType = contentType;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertDuplicateStore(store);
|
||||
}
|
||||
CertCloseStore(store, 0);
|
||||
if (blob == &fileBlob)
|
||||
CryptMemFree(blob->pbData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QuerySerializedContextObject(DWORD dwObjectType,
|
||||
const void *pvObject, DWORD dwExpectedContentTypeFlags,
|
||||
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
|
||||
HCERTSTORE *phCertStore, const void **ppvContext)
|
||||
{
|
||||
CERT_BLOB fileBlob;
|
||||
const CERT_BLOB *blob;
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
|
||||
const void *context;
|
||||
DWORD contextType;
|
||||
BOOL ret;
|
||||
|
||||
switch (dwObjectType)
|
||||
{
|
||||
case CERT_QUERY_OBJECT_FILE:
|
||||
/* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
|
||||
* just read the file directly
|
||||
*/
|
||||
ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob);
|
||||
blob = &fileBlob;
|
||||
break;
|
||||
case CERT_QUERY_OBJECT_BLOB:
|
||||
blob = (const CERT_BLOB *)pvObject;
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
ret = FALSE;
|
||||
}
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
context = CRYPT_ReadSerializedElement(blob->pbData, blob->cbData,
|
||||
CERT_STORE_ALL_CONTEXT_FLAG, &contextType);
|
||||
if (context)
|
||||
{
|
||||
DWORD contentType, certStoreOffset;
|
||||
|
||||
ret = TRUE;
|
||||
switch (contextType)
|
||||
{
|
||||
case CERT_STORE_CERTIFICATE_CONTEXT:
|
||||
contextInterface = pCertInterface;
|
||||
contentType = CERT_QUERY_CONTENT_SERIALIZED_CERT;
|
||||
certStoreOffset = offsetof(CERT_CONTEXT, hCertStore);
|
||||
if (!(dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_CRL_CONTEXT:
|
||||
contextInterface = pCRLInterface;
|
||||
contentType = CERT_QUERY_CONTENT_SERIALIZED_CRL;
|
||||
certStoreOffset = offsetof(CRL_CONTEXT, hCertStore);
|
||||
if (!(dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case CERT_STORE_CTL_CONTEXT:
|
||||
contextInterface = pCTLInterface;
|
||||
contentType = CERT_QUERY_CONTENT_SERIALIZED_CTL;
|
||||
certStoreOffset = offsetof(CTL_CONTEXT, hCertStore);
|
||||
if (!(dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
goto end;
|
||||
}
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
||||
if (pdwContentType)
|
||||
*pdwContentType = contentType;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertDuplicateStore(
|
||||
*(HCERTSTORE *)((const BYTE *)context + certStoreOffset));
|
||||
if (ppvContext)
|
||||
*ppvContext = contextInterface->duplicate(context);
|
||||
}
|
||||
|
||||
end:
|
||||
if (contextInterface && context)
|
||||
contextInterface->free(context);
|
||||
if (blob == &fileBlob)
|
||||
CryptMemFree(blob->pbData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
|
||||
const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
|
||||
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
|
||||
{
|
||||
LPCWSTR fileName = (LPCWSTR)pvObject;
|
||||
HANDLE file;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (dwObjectType != CERT_QUERY_OBJECT_FILE)
|
||||
{
|
||||
FIXME("unimplemented for non-file type %d\n", dwObjectType);
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
return FALSE;
|
||||
}
|
||||
TRACE("%s\n", debugstr_w(fileName));
|
||||
file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
ret = CRYPT_ReadSerializedStoreFromFile(file, store);
|
||||
if (ret)
|
||||
{
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
||||
if (pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_SERIALIZED_STORE;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertDuplicateStore(store);
|
||||
}
|
||||
CertCloseStore(store, 0);
|
||||
CloseHandle(file);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Used to decode non-embedded messages */
|
||||
static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
|
||||
DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType,
|
||||
DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
|
||||
{
|
||||
CERT_BLOB fileBlob;
|
||||
const CERT_BLOB *blob;
|
||||
BOOL ret;
|
||||
HCRYPTMSG msg = NULL;
|
||||
DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
|
||||
|
||||
switch (dwObjectType)
|
||||
{
|
||||
case CERT_QUERY_OBJECT_FILE:
|
||||
/* This isn't an embedded PKCS7 message, so just read the file
|
||||
* directly
|
||||
*/
|
||||
ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob);
|
||||
blob = &fileBlob;
|
||||
break;
|
||||
case CERT_QUERY_OBJECT_BLOB:
|
||||
blob = (const CERT_BLOB *)pvObject;
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
|
||||
ret = FALSE;
|
||||
}
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
ret = FALSE;
|
||||
/* Try it first as a PKCS content info */
|
||||
if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
|
||||
{
|
||||
msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL);
|
||||
if (msg)
|
||||
{
|
||||
ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
DWORD type, len = sizeof(type);
|
||||
|
||||
ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len);
|
||||
if (ret)
|
||||
{
|
||||
if ((dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED))
|
||||
{
|
||||
if (type != CMSG_SIGNED)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
|
||||
}
|
||||
else if ((dwExpectedContentTypeFlags &
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
|
||||
{
|
||||
if (type != CMSG_DATA)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
ret = FALSE;
|
||||
}
|
||||
else if (pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
{
|
||||
CryptMsgClose(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Failing that, try explicitly typed messages */
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED))
|
||||
{
|
||||
msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_SIGNED, 0, NULL, NULL);
|
||||
if (msg)
|
||||
{
|
||||
ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
|
||||
if (!ret)
|
||||
{
|
||||
CryptMsgClose(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
if (msg && pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
|
||||
}
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
|
||||
{
|
||||
msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_DATA, 0, NULL, NULL);
|
||||
if (msg)
|
||||
{
|
||||
ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
|
||||
if (!ret)
|
||||
{
|
||||
CryptMsgClose(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
if (msg && pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED;
|
||||
}
|
||||
if (pdwMsgAndCertEncodingType)
|
||||
*pdwMsgAndCertEncodingType = encodingType;
|
||||
if (msg)
|
||||
{
|
||||
if (phMsg)
|
||||
*phMsg = msg;
|
||||
if (phCertStore)
|
||||
*phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0,
|
||||
0, msg);
|
||||
}
|
||||
if (blob == &fileBlob)
|
||||
CryptMemFree(blob->pbData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
|
||||
const void *pvObject, DWORD dwExpectedContentTypeFlags,
|
||||
DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
|
||||
HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
|
||||
{
|
||||
HANDLE file;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (dwObjectType != CERT_QUERY_OBJECT_FILE)
|
||||
{
|
||||
FIXME("don't know what to do for type %d embedded signed messages\n",
|
||||
dwObjectType);
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
file = CreateFileW((LPCWSTR)pvObject, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD len;
|
||||
|
||||
ret = ImageGetCertificateData(file, 0, NULL, &len);
|
||||
if (ret)
|
||||
{
|
||||
WIN_CERTIFICATE *winCert = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
|
||||
if (winCert)
|
||||
{
|
||||
ret = ImageGetCertificateData(file, 0, winCert, &len);
|
||||
if (ret)
|
||||
{
|
||||
CERT_BLOB blob = { winCert->dwLength,
|
||||
winCert->bCertificate };
|
||||
|
||||
ret = CRYPT_QueryMessageObject(CERT_QUERY_OBJECT_BLOB,
|
||||
&blob, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
|
||||
pdwMsgAndCertEncodingType, NULL, phCertStore, phMsg);
|
||||
if (ret && pdwContentType)
|
||||
*pdwContentType = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, winCert);
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
|
||||
DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
|
||||
DWORD dwFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
|
||||
DWORD *pdwFormatType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg,
|
||||
const void **ppvContext)
|
||||
{
|
||||
static const DWORD unimplementedTypes =
|
||||
CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_PFX |
|
||||
CERT_QUERY_CONTENT_FLAG_CERT_PAIR;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n",
|
||||
dwObjectType, pvObject, dwExpectedContentTypeFlags,
|
||||
dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType,
|
||||
pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext);
|
||||
|
||||
if (dwExpectedContentTypeFlags & unimplementedTypes)
|
||||
WARN("unimplemented for types %08x\n",
|
||||
dwExpectedContentTypeFlags & unimplementedTypes);
|
||||
if (!(dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY))
|
||||
{
|
||||
FIXME("unimplemented for anything but binary\n");
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
if (pdwFormatType)
|
||||
*pdwFormatType = CERT_QUERY_FORMAT_BINARY;
|
||||
|
||||
if (phCertStore)
|
||||
*phCertStore = NULL;
|
||||
if (phMsg)
|
||||
*phMsg = NULL;
|
||||
if (ppvContext)
|
||||
*ppvContext = NULL;
|
||||
|
||||
ret = FALSE;
|
||||
if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
|
||||
{
|
||||
ret = CRYPT_QueryContextObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, ppvContext);
|
||||
}
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE))
|
||||
{
|
||||
ret = CRYPT_QuerySerializedStoreObject(dwObjectType, pvObject,
|
||||
pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg);
|
||||
}
|
||||
if (!ret &&
|
||||
((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL)))
|
||||
{
|
||||
ret = CRYPT_QuerySerializedContextObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, ppvContext);
|
||||
}
|
||||
if (!ret &&
|
||||
((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) ||
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)))
|
||||
{
|
||||
ret = CRYPT_QueryMessageObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, phMsg);
|
||||
}
|
||||
if (!ret &&
|
||||
(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED))
|
||||
{
|
||||
ret = CRYPT_QueryEmbeddedMessageObject(dwObjectType, pvObject,
|
||||
dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
|
||||
phCertStore, phMsg);
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
|
@ -37,14 +37,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
|||
|
||||
static const WCHAR DllW[] = { 'D','l','l',0 };
|
||||
|
||||
static void init_function_sets(void);
|
||||
static void init_oid_info(HINSTANCE hinst);
|
||||
static void free_function_sets(void);
|
||||
static void free_oid_info(void);
|
||||
|
||||
void crypt_oid_init(HINSTANCE hinst)
|
||||
{
|
||||
init_function_sets();
|
||||
init_oid_info(hinst);
|
||||
}
|
||||
|
||||
|
@ -55,7 +53,14 @@ void crypt_oid_free(void)
|
|||
}
|
||||
|
||||
static CRITICAL_SECTION funcSetCS;
|
||||
static struct list funcSets;
|
||||
static CRITICAL_SECTION_DEBUG funcSetCSDebug =
|
||||
{
|
||||
0, 0, &funcSetCS,
|
||||
{ &funcSetCSDebug.ProcessLocksList, &funcSetCSDebug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": funcSetCS") }
|
||||
};
|
||||
static CRITICAL_SECTION funcSetCS = { &funcSetCSDebug, -1, 0, 0, 0, 0 };
|
||||
static struct list funcSets = { &funcSets, &funcSets };
|
||||
|
||||
struct OIDFunctionSet
|
||||
{
|
||||
|
@ -72,12 +77,12 @@ struct OIDFunction
|
|||
struct list next;
|
||||
};
|
||||
|
||||
static void init_function_sets(void)
|
||||
{
|
||||
InitializeCriticalSection(&funcSetCS);
|
||||
funcSetCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": funcSetCS");
|
||||
list_init(&funcSets);
|
||||
}
|
||||
static const WCHAR ROOT[] = {'R','O','O','T',0};
|
||||
static const WCHAR MY[] = {'M','Y',0};
|
||||
static const WCHAR CA[] = {'C','A',0};
|
||||
static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',0};
|
||||
static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK};
|
||||
static WCHAR LocalizedNames[4][256];
|
||||
|
||||
static void free_function_sets(void)
|
||||
{
|
||||
|
@ -100,8 +105,6 @@ static void free_function_sets(void)
|
|||
DeleteCriticalSection(&setCursor->cs);
|
||||
CryptMemFree(setCursor);
|
||||
}
|
||||
funcSetCS.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&funcSetCS);
|
||||
}
|
||||
|
||||
/* There is no free function associated with this; therefore, the sets are
|
||||
|
@ -181,7 +184,8 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
|
|||
len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
|
||||
szKey = CryptMemAlloc(len);
|
||||
if (szKey)
|
||||
sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid);
|
||||
sprintf(szKey, szEncodingTypeFmt,
|
||||
GET_CERT_ENCODING_TYPE(dwEncodingType), pszFuncName, oid);
|
||||
return szKey;
|
||||
}
|
||||
|
||||
|
@ -211,7 +215,7 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
|
|||
else
|
||||
{
|
||||
/* No value, return an empty list */
|
||||
if (*pcchDllList)
|
||||
if (pwszDllList && *pcchDllList)
|
||||
*pwszDllList = '\0';
|
||||
*pcchDllList = 1;
|
||||
}
|
||||
|
@ -219,8 +223,10 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
|
|||
}
|
||||
else
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
/* No value, return an empty list */
|
||||
if (pwszDllList && *pcchDllList)
|
||||
*pwszDllList = '\0';
|
||||
*pcchDllList = 1;
|
||||
}
|
||||
CryptMemFree(keyName);
|
||||
|
||||
|
@ -254,7 +260,7 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
|
|||
func = CryptMemAlloc(sizeof(struct OIDFunction));
|
||||
if (func)
|
||||
{
|
||||
func->encoding = dwEncodingType;
|
||||
func->encoding = GET_CERT_ENCODING_TYPE(dwEncodingType);
|
||||
if (HIWORD(rgFuncEntry[i].pszOID))
|
||||
{
|
||||
LPSTR oid;
|
||||
|
@ -278,6 +284,13 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct FuncAddr
|
||||
{
|
||||
HMODULE lib;
|
||||
LPWSTR dllList;
|
||||
LPWSTR currentDll;
|
||||
};
|
||||
|
||||
static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
||||
LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
|
||||
{
|
||||
|
@ -294,7 +307,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
|||
DWORD type, size = 0;
|
||||
|
||||
rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size);
|
||||
if (rc == ERROR_MORE_DATA && type == REG_SZ)
|
||||
if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
|
||||
{
|
||||
funcName = CryptMemAlloc(size);
|
||||
rc = RegQueryValueExA(key, "FuncName", NULL, &type,
|
||||
|
@ -303,7 +316,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
|||
else
|
||||
funcName = szFuncName;
|
||||
rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
|
||||
if (rc == ERROR_MORE_DATA && type == REG_SZ)
|
||||
if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
|
||||
{
|
||||
LPWSTR dllName = CryptMemAlloc(size);
|
||||
|
||||
|
@ -322,11 +335,24 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
|
|||
lib = LoadLibraryW(dllName);
|
||||
if (lib)
|
||||
{
|
||||
*ppvFuncAddr = GetProcAddress(lib, szFuncName);
|
||||
*ppvFuncAddr = GetProcAddress(lib, funcName);
|
||||
if (*ppvFuncAddr)
|
||||
{
|
||||
*phFuncAddr = (HCRYPTOIDFUNCADDR)lib;
|
||||
ret = TRUE;
|
||||
struct FuncAddr *addr =
|
||||
CryptMemAlloc(sizeof(struct FuncAddr));
|
||||
|
||||
if (addr)
|
||||
{
|
||||
addr->lib = lib;
|
||||
addr->dllList = addr->currentDll = NULL;
|
||||
*phFuncAddr = addr;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*phFuncAddr = NULL;
|
||||
FreeLibrary(lib);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -372,7 +398,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
|||
EnterCriticalSection(&set->cs);
|
||||
LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next)
|
||||
{
|
||||
if (function->encoding == dwEncodingType)
|
||||
if (function->encoding == GET_CERT_ENCODING_TYPE(dwEncodingType))
|
||||
{
|
||||
if (HIWORD(pszOID))
|
||||
{
|
||||
|
@ -399,6 +425,7 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
|||
if (!*ppvFuncAddr)
|
||||
ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name,
|
||||
ppvFuncAddr, phFuncAddr);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -411,17 +438,151 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
|
|||
* and only unload it if it can be unloaded. Also need to implement ref
|
||||
* counting on the functions.
|
||||
*/
|
||||
FreeLibrary((HMODULE)hFuncAddr);
|
||||
if (hFuncAddr)
|
||||
{
|
||||
struct FuncAddr *addr = (struct FuncAddr *)hFuncAddr;
|
||||
|
||||
CryptMemFree(addr->dllList);
|
||||
FreeLibrary(addr->lib);
|
||||
CryptMemFree(addr);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_GetFuncFromDll(LPCWSTR dll, LPCSTR func, HMODULE *lib,
|
||||
void **ppvFuncAddr)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
||||
*lib = LoadLibraryW(dll);
|
||||
if (*lib)
|
||||
{
|
||||
*ppvFuncAddr = GetProcAddress(*lib, func);
|
||||
if (*ppvFuncAddr)
|
||||
ret = TRUE;
|
||||
else
|
||||
{
|
||||
FreeLibrary(*lib);
|
||||
*lib = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr,
|
||||
HCRYPTOIDFUNCADDR *phFuncAddr)
|
||||
{
|
||||
FIXME("(%p, %d, %s, %08x, %p, %p): stub\n", hFuncSet, dwEncodingType,
|
||||
struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
|
||||
debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
|
||||
return FALSE;
|
||||
|
||||
if (pwszDll)
|
||||
{
|
||||
HMODULE lib;
|
||||
|
||||
*phFuncAddr = NULL;
|
||||
ret = CRYPT_GetFuncFromDll(pwszDll, set->name, &lib, ppvFuncAddr);
|
||||
if (ret)
|
||||
{
|
||||
struct FuncAddr *addr = CryptMemAlloc(sizeof(struct FuncAddr));
|
||||
|
||||
if (addr)
|
||||
{
|
||||
addr->lib = lib;
|
||||
addr->dllList = addr->currentDll = NULL;
|
||||
*phFuncAddr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeLibrary(lib);
|
||||
*ppvFuncAddr = NULL;
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct FuncAddr *addr = (struct FuncAddr *)*phFuncAddr;
|
||||
|
||||
if (!addr)
|
||||
{
|
||||
DWORD size;
|
||||
|
||||
ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, NULL,
|
||||
&size);
|
||||
if (ret)
|
||||
{
|
||||
LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR));
|
||||
|
||||
if (dllList)
|
||||
{
|
||||
ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType,
|
||||
dllList, &size);
|
||||
if (ret)
|
||||
{
|
||||
addr = CryptMemAlloc(sizeof(struct FuncAddr));
|
||||
if (addr)
|
||||
{
|
||||
addr->dllList = dllList;
|
||||
addr->currentDll = dllList;
|
||||
addr->lib = NULL;
|
||||
*phFuncAddr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
CryptMemFree(dllList);
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addr)
|
||||
{
|
||||
if (!*addr->currentDll)
|
||||
{
|
||||
CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
*phFuncAddr = NULL;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: as elsewhere, can't free until DllCanUnloadNow says
|
||||
* it's possible, and should defer unloading for some time to
|
||||
* avoid repeated LoadLibrary/FreeLibrary on the same dll.
|
||||
*/
|
||||
FreeLibrary(addr->lib);
|
||||
ret = CRYPT_GetFuncFromDll(addr->currentDll, set->name,
|
||||
&addr->lib, ppvFuncAddr);
|
||||
if (ret)
|
||||
{
|
||||
/* Move past the current DLL */
|
||||
addr->currentDll += lstrlenW(addr->currentDll) + 1;
|
||||
*phFuncAddr = addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
*phFuncAddr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -454,10 +615,6 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
|
|||
TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName,
|
||||
debugstr_a(pszOID), debugstr_w(pwszDll), pszOverrideFuncName);
|
||||
|
||||
/* This only registers functions for encoding certs, not messages */
|
||||
if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
|
||||
return TRUE;
|
||||
|
||||
/* Native does nothing pwszDll is NULL */
|
||||
if (!pwszDll)
|
||||
return TRUE;
|
||||
|
@ -497,7 +654,7 @@ error_close_key:
|
|||
|
||||
RegCloseKey(hKey);
|
||||
|
||||
if (r != ERROR_SUCCESS)
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(r);
|
||||
return FALSE;
|
||||
|
@ -515,10 +672,8 @@ BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
|
|||
LPSTR szKey;
|
||||
LONG rc;
|
||||
|
||||
TRACE("%x %s %s\n", dwEncodingType, pszFuncName, pszOID);
|
||||
|
||||
if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
|
||||
return TRUE;
|
||||
TRACE("%x %s %s\n", dwEncodingType, debugstr_a(pszFuncName),
|
||||
debugstr_a(pszOID));
|
||||
|
||||
if (!pszFuncName || !pszOID)
|
||||
{
|
||||
|
@ -783,11 +938,10 @@ BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
|
|||
{
|
||||
HKEY key;
|
||||
LPWSTR dlls;
|
||||
LPCWSTR existing;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%x, %s, %x, %s)\n", dwEncodingType, pszFuncName, dwIndex,
|
||||
debugstr_w(pwszDll));
|
||||
TRACE("(%x, %s, %d, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
|
||||
dwIndex, debugstr_w(pwszDll));
|
||||
|
||||
if (!pwszDll)
|
||||
{
|
||||
|
@ -799,7 +953,7 @@ BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
|
|||
return FALSE;
|
||||
|
||||
dlls = CRYPT_GetDefaultOIDDlls(key);
|
||||
if ((existing = CRYPT_FindStringInMultiString(dlls, pwszDll)))
|
||||
if (CRYPT_FindStringInMultiString(dlls, pwszDll))
|
||||
SetLastError(ERROR_FILE_EXISTS);
|
||||
else
|
||||
{
|
||||
|
@ -839,8 +993,44 @@ BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void oid_init_localizednames(HINSTANCE hInstance)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
|
||||
{
|
||||
LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* CryptFindLocalizedName (CRYPT32.@)
|
||||
*/
|
||||
LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
|
||||
{
|
||||
if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName))
|
||||
{
|
||||
return LocalizedNames[i];
|
||||
}
|
||||
}
|
||||
|
||||
FIXME("No name for: %s - stub\n",debugstr_w(pwszCryptName));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CRITICAL_SECTION oidInfoCS;
|
||||
static struct list oidInfo;
|
||||
static CRITICAL_SECTION_DEBUG oidInfoCSDebug =
|
||||
{
|
||||
0, 0, &oidInfoCS,
|
||||
{ &oidInfoCSDebug.ProcessLocksList, &oidInfoCSDebug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": oidInfoCS") }
|
||||
};
|
||||
static CRITICAL_SECTION oidInfoCS = { &oidInfoCSDebug, -1, 0, 0, 0, 0 };
|
||||
static struct list oidInfo = { &oidInfo, &oidInfo };
|
||||
|
||||
static const WCHAR tripledes[] = { '3','d','e','s',0 };
|
||||
static const WCHAR cms3deswrap[] = { 'C','M','S','3','D','E','S','w','r','a',
|
||||
|
@ -1181,9 +1371,7 @@ static void init_oid_info(HINSTANCE hinst)
|
|||
{
|
||||
DWORD i;
|
||||
|
||||
InitializeCriticalSection(&oidInfoCS);
|
||||
oidInfoCS.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": oidInfoCS");
|
||||
list_init(&oidInfo);
|
||||
oid_init_localizednames(hinst);
|
||||
for (i = 0; i < sizeof(oidInfoConstructors) /
|
||||
sizeof(oidInfoConstructors[0]); i++)
|
||||
{
|
||||
|
@ -1213,8 +1401,9 @@ static void init_oid_info(HINSTANCE hinst)
|
|||
}
|
||||
else
|
||||
{
|
||||
LPCWSTR stringresource;
|
||||
int len = LoadStringW(hinst, (UINT_PTR)oidInfoConstructors[i].pwszName,
|
||||
NULL, 0);
|
||||
(LPWSTR)&stringresource, 0);
|
||||
|
||||
if (len)
|
||||
{
|
||||
|
@ -1226,12 +1415,11 @@ static void init_oid_info(HINSTANCE hinst)
|
|||
memset(info, 0, sizeof(*info));
|
||||
info->info.cbSize = sizeof(CRYPT_OID_INFO);
|
||||
info->info.pszOID = oidInfoConstructors[i].pszOID;
|
||||
info->info.pwszName =
|
||||
(LPWSTR)((LPBYTE)info + sizeof(struct OIDInfo));
|
||||
info->info.pwszName = (LPWSTR)(info + 1);
|
||||
info->info.dwGroupId = oidInfoConstructors[i].dwGroupId;
|
||||
info->info.u.Algid = oidInfoConstructors[i].Algid;
|
||||
LoadStringW(hinst, (UINT_PTR)oidInfoConstructors[i].pwszName,
|
||||
(LPWSTR)info->info.pwszName, len + 1);
|
||||
memcpy(info + 1, stringresource, len*sizeof(WCHAR));
|
||||
((LPWSTR)(info + 1))[len] = 0;
|
||||
if (oidInfoConstructors[i].blob)
|
||||
{
|
||||
info->info.ExtraInfo.cbData =
|
||||
|
@ -1255,8 +1443,6 @@ static void free_oid_info(void)
|
|||
list_remove(&info->entry);
|
||||
CryptMemFree(info);
|
||||
}
|
||||
oidInfoCS.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&oidInfoCS);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -42,14 +42,15 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
#define CRYPT32_PROTECTDATA_PROV PROV_RSA_FULL
|
||||
#define CRYPT32_PROTECTDATA_HASH_CALG CALG_MD5
|
||||
#define CRYPT32_PROTECTDATA_KEY_CALG CALG_RC2
|
||||
#define CRYPT32_PROTECTDATA_HASH_CALG CALG_SHA1
|
||||
#define CRYPT32_PROTECTDATA_HASH_LEN 160
|
||||
#define CRYPT32_PROTECTDATA_KEY_CALG CALG_3DES
|
||||
#define CRYPT32_PROTECTDATA_KEY_LEN 168
|
||||
#define CRYPT32_PROTECTDATA_SALT_LEN 16
|
||||
|
||||
static const BYTE crypt32_protectdata_secret[] = {
|
||||
|
@ -62,21 +63,22 @@ static const BYTE crypt32_protectdata_secret[] = {
|
|||
* to be something like this:
|
||||
|
||||
DWORD count0; - how many "info0_*[16]" blocks follow (was always 1)
|
||||
BYTE info0_0[16]; - unknown information
|
||||
...
|
||||
BYTE info0_0[16]; - unknown information - persistent across invocations,
|
||||
... reboots, password changes, and users
|
||||
DWORD count1; - how many "info1_*[16]" blocks follow (was always 1)
|
||||
BYTE info1_0[16]; - unknown information
|
||||
...
|
||||
BYTE info1_0[16]; - unknown information - unique to each user, but
|
||||
... persistent across reboots and password changes
|
||||
DWORD null0; - NULL "end of records"?
|
||||
DWORD str_len; - length of WCHAR string including term
|
||||
WCHAR str[str_len]; - The "dataDescription" value
|
||||
DWORD unknown0; - unknown value (seems large, but only WORD large)
|
||||
DWORD unknown1; - unknown value (seems small, less than a BYTE)
|
||||
DWORD str_len; - byte length of WCHAR string including term
|
||||
BYTE str[str_len]; - The "dataDescription" value as a NULL-terminated
|
||||
little-endian WCHAR string
|
||||
ALG_ID cipher_alg; - cipher algo - was CALG_3DES
|
||||
DWORD cipher_key_len; - cipher key bit length - was 0xa8==168
|
||||
DWORD data_len; - length of data (was 16 in samples)
|
||||
BYTE data[data_len]; - unknown data (fingerprint?)
|
||||
DWORD null1; - NULL ?
|
||||
DWORD unknown2; - unknown value (seems large, but only WORD large)
|
||||
DWORD unknown3; - unknown value (seems small, less than a BYTE)
|
||||
ALG_ID hash_alg; - hash algo - was CALG_SHA1
|
||||
DWORD hash_len; - bit length of hash - was 0xa0==160
|
||||
DWORD salt_len; - length of salt(?) data
|
||||
BYTE salt[salt_len]; - salt(?) for symmetric encryption
|
||||
DWORD cipher_len; - length of cipher(?) data - was close to plain len
|
||||
|
@ -95,12 +97,12 @@ struct protect_data_t
|
|||
DATA_BLOB info1;
|
||||
DWORD null0;
|
||||
WCHAR * szDataDescr; /* serialized differently than the DATA_BLOBs */
|
||||
DWORD unknown0; /* perhaps the HASH alg const should go here? */
|
||||
DWORD unknown1;
|
||||
ALG_ID cipher_alg;
|
||||
DWORD cipher_key_len;
|
||||
DATA_BLOB data0;
|
||||
DWORD null1;
|
||||
DWORD unknown2; /* perhaps the KEY alg const should go here? */
|
||||
DWORD unknown3;
|
||||
ALG_ID hash_alg;
|
||||
DWORD hash_len;
|
||||
DATA_BLOB salt;
|
||||
DATA_BLOB cipher;
|
||||
DATA_BLOB fingerprint;
|
||||
|
@ -264,7 +266,7 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
|
|||
/* count0 */
|
||||
serialize_dword(pInfo->count0,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
|
||||
/* info0 */
|
||||
serialize_string(pInfo->info0.pbData,&ptr,
|
||||
pInfo->info0.cbData,sizeof(BYTE),FALSE);
|
||||
|
@ -282,19 +284,19 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
|
|||
/* null0 */
|
||||
serialize_dword(pInfo->null0,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
|
||||
/* szDataDescr */
|
||||
serialize_string((BYTE*)pInfo->szDataDescr,&ptr,
|
||||
(dwStrLen+1)*sizeof(WCHAR),sizeof(BYTE),TRUE);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
/* unknown0 */
|
||||
serialize_dword(pInfo->unknown0,&ptr);
|
||||
/* cipher_alg */
|
||||
serialize_dword(pInfo->cipher_alg,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
/* unknown1 */
|
||||
serialize_dword(pInfo->unknown1,&ptr);
|
||||
/* cipher_key_len */
|
||||
serialize_dword(pInfo->cipher_key_len,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
|
||||
/* data0 */
|
||||
serialize_string(pInfo->data0.pbData,&ptr,
|
||||
pInfo->data0.cbData,sizeof(BYTE),TRUE);
|
||||
|
@ -303,14 +305,14 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
|
|||
/* null1 */
|
||||
serialize_dword(pInfo->null1,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
/* unknown2 */
|
||||
serialize_dword(pInfo->unknown2,&ptr);
|
||||
|
||||
/* hash_alg */
|
||||
serialize_dword(pInfo->hash_alg,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
/* unknown3 */
|
||||
serialize_dword(pInfo->unknown3,&ptr);
|
||||
/* hash_len */
|
||||
serialize_dword(pInfo->hash_len,&ptr);
|
||||
/*TRACE("used %u\n",ptr-pSerial->pbData);*/
|
||||
|
||||
|
||||
/* salt */
|
||||
serialize_string(pInfo->salt.pbData,&ptr,
|
||||
pInfo->salt.cbData,sizeof(BYTE),TRUE);
|
||||
|
@ -329,7 +331,7 @@ BOOL serialize(const struct protect_data_t *pInfo, DATA_BLOB *pSerial)
|
|||
if (ptr - pSerial->pbData != dwStruct)
|
||||
{
|
||||
ERR("struct size changed!? %u != expected %u\n",
|
||||
ptr - pSerial->pbData, (unsigned int)dwStruct);
|
||||
ptr - pSerial->pbData, dwStruct);
|
||||
LocalFree(pSerial->pbData);
|
||||
pSerial->pbData=NULL;
|
||||
pSerial->cbData=0;
|
||||
|
@ -362,7 +364,7 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
ERR("reading count0 failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* info0 */
|
||||
if (!unserialize_string(ptr,&index,size,16,sizeof(BYTE),FALSE,
|
||||
&pInfo->info0.pbData, &pInfo->info0.cbData))
|
||||
|
@ -392,7 +394,7 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
ERR("reading null0 failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* szDataDescr */
|
||||
if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
|
||||
(BYTE**)&pInfo->szDataDescr, NULL))
|
||||
|
@ -401,20 +403,20 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown0 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown0))
|
||||
/* cipher_alg */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->cipher_alg))
|
||||
{
|
||||
ERR("reading unknown0 failed!\n");
|
||||
ERR("reading cipher_alg failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown1 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown1))
|
||||
|
||||
/* cipher_key_len */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->cipher_key_len))
|
||||
{
|
||||
ERR("reading unknown1 failed!\n");
|
||||
ERR("reading cipher_key_len failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* data0 */
|
||||
if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
|
||||
&pInfo->data0.pbData, &pInfo->data0.cbData))
|
||||
|
@ -429,21 +431,21 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
ERR("reading null1 failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown2 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown2))
|
||||
|
||||
/* hash_alg */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->hash_alg))
|
||||
{
|
||||
ERR("reading unknown2 failed!\n");
|
||||
ERR("reading hash_alg failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* unknown3 */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->unknown3))
|
||||
|
||||
/* hash_len */
|
||||
if (!unserialize_dword(ptr,&index,size,&pInfo->hash_len))
|
||||
{
|
||||
ERR("reading unknown3 failed!\n");
|
||||
ERR("reading hash_len failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* salt */
|
||||
if (!unserialize_string(ptr,&index,size,0,sizeof(BYTE),TRUE,
|
||||
&pInfo->salt.pbData, &pInfo->salt.cbData))
|
||||
|
@ -474,8 +476,7 @@ BOOL unserialize(const DATA_BLOB *pSerial, struct protect_data_t *pInfo)
|
|||
{
|
||||
/* this is an impossible-to-reach test, but if the padding
|
||||
* issue is ever understood, this may become more useful */
|
||||
ERR("loaded corrupt structure! (used %u expected %u)\n",
|
||||
(unsigned int)index, (unsigned int)size);
|
||||
ERR("loaded corrupt structure! (used %u expected %u)\n", index, size);
|
||||
status=FALSE;
|
||||
}
|
||||
|
||||
|
@ -596,14 +597,14 @@ BOOL fill_protect_data(struct protect_data_t * pInfo, LPCWSTR szDataDescr,
|
|||
memcpy(pInfo->szDataDescr,szDataDescr,(dwStrLen+1)*sizeof(WCHAR));
|
||||
}
|
||||
|
||||
pInfo->unknown0=0x0000;
|
||||
pInfo->unknown1=0x0000;
|
||||
pInfo->cipher_alg=CRYPT32_PROTECTDATA_KEY_CALG;
|
||||
pInfo->cipher_key_len=CRYPT32_PROTECTDATA_KEY_LEN;
|
||||
|
||||
convert_str_to_blob(crypt_magic_str, &pInfo->data0);
|
||||
|
||||
pInfo->null1=0x0000;
|
||||
pInfo->unknown2=0x0000;
|
||||
pInfo->unknown3=0x0000;
|
||||
pInfo->hash_alg=CRYPT32_PROTECTDATA_HASH_CALG;
|
||||
pInfo->hash_len=CRYPT32_PROTECTDATA_HASH_LEN;
|
||||
|
||||
/* allocate memory to hold a salt */
|
||||
pInfo->salt.cbData=CRYPT32_PROTECTDATA_SALT_LEN;
|
||||
|
@ -704,7 +705,7 @@ BOOL hash_matches_blob(HCRYPTHASH hHash, const DATA_BLOB *two)
|
|||
|
||||
/* create an encryption key from a given salt and optional entropy */
|
||||
static
|
||||
BOOL load_encryption_key(HCRYPTPROV hProv, const DATA_BLOB *salt,
|
||||
BOOL load_encryption_key(HCRYPTPROV hProv, DWORD key_len, const DATA_BLOB *salt,
|
||||
const DATA_BLOB *pOptionalEntropy, HCRYPTKEY *phKey)
|
||||
{
|
||||
BOOL rc = TRUE;
|
||||
|
@ -753,7 +754,7 @@ BOOL load_encryption_key(HCRYPTPROV hProv, const DATA_BLOB *salt,
|
|||
|
||||
/* produce a symmetric key */
|
||||
if (rc && !CryptDeriveKey(hProv,CRYPT32_PROTECTDATA_KEY_CALG,
|
||||
hSaltHash,CRYPT_EXPORTABLE,phKey))
|
||||
hSaltHash,key_len << 16 | CRYPT_EXPORTABLE,phKey))
|
||||
{
|
||||
ERR("CryptDeriveKey\n");
|
||||
rc = FALSE;
|
||||
|
@ -774,15 +775,15 @@ report(const DATA_BLOB* pDataIn, const DATA_BLOB* pOptionalEntropy,
|
|||
TRACE("pPromptStruct: %p\n", pPromptStruct);
|
||||
if (pPromptStruct)
|
||||
{
|
||||
TRACE(" cbSize: 0x%x\n",(unsigned int)pPromptStruct->cbSize);
|
||||
TRACE(" dwPromptFlags: 0x%x\n",(unsigned int)pPromptStruct->dwPromptFlags);
|
||||
TRACE(" cbSize: 0x%x\n", pPromptStruct->cbSize);
|
||||
TRACE(" dwPromptFlags: 0x%x\n", pPromptStruct->dwPromptFlags);
|
||||
TRACE(" hwndApp: %p\n", pPromptStruct->hwndApp);
|
||||
TRACE(" szPrompt: %p %s\n",
|
||||
pPromptStruct->szPrompt,
|
||||
pPromptStruct->szPrompt ? debugstr_w(pPromptStruct->szPrompt)
|
||||
: "");
|
||||
}
|
||||
TRACE("dwFlags: 0x%04x\n",(unsigned int)dwFlags);
|
||||
TRACE("dwFlags: 0x%04x\n", dwFlags);
|
||||
TRACE_DATA_BLOB(pDataIn);
|
||||
if (pOptionalEntropy)
|
||||
{
|
||||
|
@ -857,7 +858,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
szDataDescr = empty_str;
|
||||
|
||||
/* get crypt context */
|
||||
if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
if (!CryptAcquireContextW(&hProv,NULL,MS_ENHANCED_PROV_W,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
{
|
||||
ERR("CryptAcquireContextW failed\n");
|
||||
goto finished;
|
||||
|
@ -871,7 +872,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
}
|
||||
|
||||
/* load key */
|
||||
if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
if (!load_encryption_key(hProv,protect_data.cipher_key_len,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
{
|
||||
goto free_protect_data;
|
||||
}
|
||||
|
@ -891,7 +892,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
ERR("CryptEncrypt\n");
|
||||
goto free_hash;
|
||||
}
|
||||
TRACE("required encrypted storage: %u\n",(unsigned int)dwLength);
|
||||
TRACE("required encrypted storage: %u\n", dwLength);
|
||||
|
||||
/* copy plain text into cipher area for CryptEncrypt call */
|
||||
protect_data.cipher.cbData=dwLength;
|
||||
|
@ -908,7 +909,7 @@ BOOL WINAPI CryptProtectData(DATA_BLOB* pDataIn,
|
|||
if (!CryptEncrypt(hKey, hHash, TRUE, 0, protect_data.cipher.pbData,
|
||||
&dwLength, protect_data.cipher.cbData))
|
||||
{
|
||||
ERR("CryptEncrypt %u\n",(unsigned int)GetLastError());
|
||||
ERR("CryptEncrypt %u\n", GetLastError());
|
||||
goto free_hash;
|
||||
}
|
||||
protect_data.cipher.cbData=dwLength;
|
||||
|
@ -1016,6 +1017,11 @@ BOOL WINAPI CryptUnprotectData(DATA_BLOB* pDataIn,
|
|||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
goto finished;
|
||||
}
|
||||
if (!pDataIn->cbData)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
goto finished;
|
||||
}
|
||||
|
||||
/* debug: show our arguments */
|
||||
report(pDataIn,pOptionalEntropy,pPromptStruct,dwFlags);
|
||||
|
@ -1038,14 +1044,14 @@ BOOL WINAPI CryptUnprotectData(DATA_BLOB* pDataIn,
|
|||
}
|
||||
|
||||
/* get a crypt context */
|
||||
if (!CryptAcquireContextW(&hProv,NULL,NULL,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
if (!CryptAcquireContextW(&hProv,NULL,MS_ENHANCED_PROV_W,CRYPT32_PROTECTDATA_PROV,CRYPT_VERIFYCONTEXT))
|
||||
{
|
||||
ERR("CryptAcquireContextW failed\n");
|
||||
goto free_protect_data;
|
||||
}
|
||||
|
||||
/* load key */
|
||||
if (!load_encryption_key(hProv,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
if (!load_encryption_key(hProv,protect_data.cipher_key_len,&protect_data.salt,pOptionalEntropy,&hKey))
|
||||
{
|
||||
goto free_context;
|
||||
}
|
||||
|
|
300
reactos/dll/win32/crypt32/provstore.c
Normal file
300
reactos/dll/win32/crypt32/provstore.c
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_PROVIDERSTORE
|
||||
{
|
||||
WINECRYPT_CERTSTORE hdr;
|
||||
DWORD dwStoreProvFlags;
|
||||
PWINECRYPT_CERTSTORE memStore;
|
||||
HCERTSTOREPROV hStoreProv;
|
||||
PFN_CERT_STORE_PROV_CLOSE provCloseStore;
|
||||
PFN_CERT_STORE_PROV_WRITE_CERT provWriteCert;
|
||||
PFN_CERT_STORE_PROV_DELETE_CERT provDeleteCert;
|
||||
PFN_CERT_STORE_PROV_WRITE_CRL provWriteCrl;
|
||||
PFN_CERT_STORE_PROV_DELETE_CRL provDeleteCrl;
|
||||
PFN_CERT_STORE_PROV_CONTROL provControl;
|
||||
} WINE_PROVIDERSTORE, *PWINE_PROVIDERSTORE;
|
||||
|
||||
static void WINAPI CRYPT_ProvCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
|
||||
if (store->provCloseStore)
|
||||
store->provCloseStore(store->hStoreProv, dwFlags);
|
||||
if (!(store->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG))
|
||||
CertCloseStore(store->memStore, dwFlags);
|
||||
CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvAddCert(PWINECRYPT_CERTSTORE store, void *cert,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
|
||||
|
||||
if (toReplace)
|
||||
ret = ps->memStore->certs.addContext(ps->memStore, cert, toReplace,
|
||||
ppStoreContext);
|
||||
else
|
||||
{
|
||||
ret = TRUE;
|
||||
if (ps->provWriteCert)
|
||||
ret = ps->provWriteCert(ps->hStoreProv, (PCCERT_CONTEXT)cert,
|
||||
CERT_STORE_PROV_WRITE_ADD_FLAG);
|
||||
if (ret)
|
||||
ret = ps->memStore->certs.addContext(ps->memStore, cert, NULL,
|
||||
ppStoreContext);
|
||||
}
|
||||
/* dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
if (ppStoreContext)
|
||||
(*(PCERT_CONTEXT *)ppStoreContext)->hCertStore = store;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_ProvEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
void *ret;
|
||||
|
||||
ret = ps->memStore->certs.enumContext(ps->memStore, pPrev);
|
||||
if (ret)
|
||||
{
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
((PCERT_CONTEXT)ret)->hCertStore = store;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvDeleteCert(PWINECRYPT_CERTSTORE store, void *cert)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %p)\n", store, cert);
|
||||
|
||||
if (ps->provDeleteCert)
|
||||
ret = ps->provDeleteCert(ps->hStoreProv, cert, 0);
|
||||
if (ret)
|
||||
ret = ps->memStore->certs.deleteContext(ps->memStore, cert);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvAddCRL(PWINECRYPT_CERTSTORE store, void *crl,
|
||||
void *toReplace, const void **ppStoreContext)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
|
||||
|
||||
if (toReplace)
|
||||
ret = ps->memStore->crls.addContext(ps->memStore, crl, toReplace,
|
||||
ppStoreContext);
|
||||
else
|
||||
{
|
||||
if (ps->hdr.dwOpenFlags & CERT_STORE_READONLY_FLAG)
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = TRUE;
|
||||
if (ps->provWriteCrl)
|
||||
ret = ps->provWriteCrl(ps->hStoreProv, (PCCRL_CONTEXT)crl,
|
||||
CERT_STORE_PROV_WRITE_ADD_FLAG);
|
||||
if (ret)
|
||||
ret = ps->memStore->crls.addContext(ps->memStore, crl, NULL,
|
||||
ppStoreContext);
|
||||
}
|
||||
}
|
||||
/* dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
if (ppStoreContext)
|
||||
(*(PCRL_CONTEXT *)ppStoreContext)->hCertStore = store;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *CRYPT_ProvEnumCRL(PWINECRYPT_CERTSTORE store, void *pPrev)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
void *ret;
|
||||
|
||||
ret = ps->memStore->crls.enumContext(ps->memStore, pPrev);
|
||||
if (ret)
|
||||
{
|
||||
/* same dirty trick: replace the returned context's hCertStore with
|
||||
* store.
|
||||
*/
|
||||
((PCRL_CONTEXT)ret)->hCertStore = store;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_ProvDeleteCRL(PWINECRYPT_CERTSTORE store, void *crl)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ps = (PWINE_PROVIDERSTORE)store;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %p)\n", store, crl);
|
||||
|
||||
if (ps->provDeleteCrl)
|
||||
ret = ps->provDeleteCrl(ps->hStoreProv, crl, 0);
|
||||
if (ret)
|
||||
ret = ps->memStore->crls.deleteContext(ps->memStore, crl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_ProvControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_PROVIDERSTORE store = (PWINE_PROVIDERSTORE)hCertStore;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
|
||||
if (store->provControl)
|
||||
ret = store->provControl(store->hStoreProv, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvCreateStore(DWORD dwFlags,
|
||||
PWINECRYPT_CERTSTORE memStore, const CERT_STORE_PROV_INFO *pProvInfo)
|
||||
{
|
||||
PWINE_PROVIDERSTORE ret = CryptMemAlloc(sizeof(WINE_PROVIDERSTORE));
|
||||
|
||||
if (ret)
|
||||
{
|
||||
CRYPT_InitStore(&ret->hdr, dwFlags, StoreTypeProvider);
|
||||
ret->dwStoreProvFlags = pProvInfo->dwStoreProvFlags;
|
||||
if (ret->dwStoreProvFlags & CERT_STORE_PROV_EXTERNAL_FLAG)
|
||||
{
|
||||
CertCloseStore(memStore, 0);
|
||||
ret->memStore = NULL;
|
||||
}
|
||||
else
|
||||
ret->memStore = memStore;
|
||||
ret->hStoreProv = pProvInfo->hStoreProv;
|
||||
ret->hdr.closeStore = CRYPT_ProvCloseStore;
|
||||
ret->hdr.certs.addContext = CRYPT_ProvAddCert;
|
||||
ret->hdr.certs.enumContext = CRYPT_ProvEnumCert;
|
||||
ret->hdr.certs.deleteContext = CRYPT_ProvDeleteCert;
|
||||
ret->hdr.crls.addContext = CRYPT_ProvAddCRL;
|
||||
ret->hdr.crls.enumContext = CRYPT_ProvEnumCRL;
|
||||
ret->hdr.crls.deleteContext = CRYPT_ProvDeleteCRL;
|
||||
ret->hdr.control = CRYPT_ProvControl;
|
||||
if (pProvInfo->cStoreProvFunc > CERT_STORE_PROV_CLOSE_FUNC)
|
||||
ret->provCloseStore =
|
||||
pProvInfo->rgpvStoreProvFunc[CERT_STORE_PROV_CLOSE_FUNC];
|
||||
else
|
||||
ret->provCloseStore = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_WRITE_CERT_FUNC)
|
||||
ret->provWriteCert = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_WRITE_CERT_FUNC];
|
||||
else
|
||||
ret->provWriteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_DELETE_CERT_FUNC)
|
||||
ret->provDeleteCert = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_DELETE_CERT_FUNC];
|
||||
else
|
||||
ret->provDeleteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_WRITE_CRL_FUNC)
|
||||
ret->provWriteCrl = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_WRITE_CRL_FUNC];
|
||||
else
|
||||
ret->provWriteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_DELETE_CRL_FUNC)
|
||||
ret->provDeleteCrl = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_DELETE_CRL_FUNC];
|
||||
else
|
||||
ret->provDeleteCert = NULL;
|
||||
if (pProvInfo->cStoreProvFunc >
|
||||
CERT_STORE_PROV_CONTROL_FUNC)
|
||||
ret->provControl = pProvInfo->rgpvStoreProvFunc[
|
||||
CERT_STORE_PROV_CONTROL_FUNC];
|
||||
else
|
||||
ret->provControl = NULL;
|
||||
}
|
||||
return (PWINECRYPT_CERTSTORE)ret;
|
||||
}
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_ProvOpenStore(LPCSTR lpszStoreProvider,
|
||||
DWORD dwEncodingType, HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara)
|
||||
{
|
||||
static HCRYPTOIDFUNCSET set = NULL;
|
||||
PFN_CERT_DLL_OPEN_STORE_PROV_FUNC provOpenFunc;
|
||||
HCRYPTOIDFUNCADDR hFunc;
|
||||
PWINECRYPT_CERTSTORE ret = NULL;
|
||||
|
||||
if (!set)
|
||||
set = CryptInitOIDFunctionSet(CRYPT_OID_OPEN_STORE_PROV_FUNC, 0);
|
||||
CryptGetOIDFunctionAddress(set, dwEncodingType, lpszStoreProvider, 0,
|
||||
(void **)&provOpenFunc, &hFunc);
|
||||
if (provOpenFunc)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = { 0 };
|
||||
|
||||
provInfo.cbSize = sizeof(provInfo);
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
|
||||
dwFlags, pvPara, NULL, &provInfo);
|
||||
else
|
||||
{
|
||||
HCERTSTORE memStore;
|
||||
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (memStore)
|
||||
{
|
||||
if (provOpenFunc(lpszStoreProvider, dwEncodingType, hCryptProv,
|
||||
dwFlags, pvPara, memStore, &provInfo))
|
||||
ret = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
||||
else
|
||||
CertCloseStore(memStore, 0);
|
||||
}
|
||||
}
|
||||
CryptFreeOIDFunctionAddress(hFunc, 0);
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
return ret;
|
||||
}
|
550
reactos/dll/win32/crypt32/regstore.c
Normal file
550
reactos/dll/win32/crypt32/regstore.c
Normal file
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* Copyright 2004-2007 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winreg.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
typedef struct _WINE_HASH_TO_DELETE
|
||||
{
|
||||
BYTE hash[20];
|
||||
struct list entry;
|
||||
} WINE_HASH_TO_DELETE, *PWINE_HASH_TO_DELETE;
|
||||
|
||||
typedef struct _WINE_REGSTOREINFO
|
||||
{
|
||||
DWORD dwOpenFlags;
|
||||
HCERTSTORE memStore;
|
||||
HKEY key;
|
||||
BOOL dirty;
|
||||
CRITICAL_SECTION cs;
|
||||
struct list certsToDelete;
|
||||
struct list crlsToDelete;
|
||||
} WINE_REGSTOREINFO, *PWINE_REGSTOREINFO;
|
||||
|
||||
static void CRYPT_HashToStr(const BYTE *hash, LPWSTR asciiHash)
|
||||
{
|
||||
static const WCHAR fmt[] = { '%','0','2','X',0 };
|
||||
DWORD i;
|
||||
|
||||
assert(hash);
|
||||
assert(asciiHash);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
wsprintfW(asciiHash + i * 2, fmt, hash[i]);
|
||||
}
|
||||
|
||||
static const WCHAR CertsW[] = { 'C','e','r','t','i','f','i','c','a','t','e','s',
|
||||
0 };
|
||||
static const WCHAR CRLsW[] = { 'C','R','L','s',0 };
|
||||
static const WCHAR CTLsW[] = { 'C','T','L','s',0 };
|
||||
static const WCHAR BlobW[] = { 'B','l','o','b',0 };
|
||||
|
||||
static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType,
|
||||
HCERTSTORE store)
|
||||
{
|
||||
LONG rc;
|
||||
DWORD index = 0;
|
||||
WCHAR subKeyName[MAX_PATH];
|
||||
|
||||
do {
|
||||
DWORD size = sizeof(subKeyName) / sizeof(WCHAR);
|
||||
|
||||
rc = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (!rc)
|
||||
{
|
||||
HKEY subKey;
|
||||
|
||||
rc = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey);
|
||||
if (!rc)
|
||||
{
|
||||
LPBYTE buf = NULL;
|
||||
|
||||
size = 0;
|
||||
rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, NULL, &size);
|
||||
if (!rc)
|
||||
buf = CryptMemAlloc(size);
|
||||
if (buf)
|
||||
{
|
||||
rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, buf,
|
||||
&size);
|
||||
if (!rc)
|
||||
{
|
||||
const void *context;
|
||||
DWORD addedType;
|
||||
|
||||
TRACE("Adding cert with hash %s\n",
|
||||
debugstr_w(subKeyName));
|
||||
context = CRYPT_ReadSerializedElement(buf, size,
|
||||
contextType, &addedType);
|
||||
if (context)
|
||||
{
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface;
|
||||
BYTE hash[20];
|
||||
|
||||
switch (addedType)
|
||||
{
|
||||
case CERT_STORE_CERTIFICATE_CONTEXT:
|
||||
contextInterface = pCertInterface;
|
||||
break;
|
||||
case CERT_STORE_CRL_CONTEXT:
|
||||
contextInterface = pCRLInterface;
|
||||
break;
|
||||
case CERT_STORE_CTL_CONTEXT:
|
||||
contextInterface = pCTLInterface;
|
||||
break;
|
||||
default:
|
||||
contextInterface = NULL;
|
||||
}
|
||||
if (contextInterface)
|
||||
{
|
||||
size = sizeof(hash);
|
||||
if (contextInterface->getProp(context,
|
||||
CERT_HASH_PROP_ID, hash, &size))
|
||||
{
|
||||
WCHAR asciiHash[20 * 2 + 1];
|
||||
|
||||
CRYPT_HashToStr(hash, asciiHash);
|
||||
TRACE("comparing %s\n",
|
||||
debugstr_w(asciiHash));
|
||||
TRACE("with %s\n", debugstr_w(subKeyName));
|
||||
if (!lstrcmpW(asciiHash, subKeyName))
|
||||
{
|
||||
TRACE("hash matches, adding\n");
|
||||
contextInterface->addContextToStore(
|
||||
store, context,
|
||||
CERT_STORE_ADD_REPLACE_EXISTING, NULL);
|
||||
}
|
||||
else
|
||||
TRACE("hash doesn't match, ignoring\n");
|
||||
}
|
||||
contextInterface->free(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
RegCloseKey(subKey);
|
||||
}
|
||||
/* Ignore intermediate errors, continue enumerating */
|
||||
rc = ERROR_SUCCESS;
|
||||
}
|
||||
} while (!rc);
|
||||
}
|
||||
|
||||
static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store)
|
||||
{
|
||||
static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW };
|
||||
static const DWORD contextFlags[] = { CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
|
||||
CERT_STORE_CRL_CONTEXT_FLAG, CERT_STORE_CTL_CONTEXT_FLAG };
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
|
||||
{
|
||||
HKEY hKey;
|
||||
LONG rc;
|
||||
|
||||
rc = RegCreateKeyExW(key, subKeys[i], 0, NULL, 0, KEY_READ, NULL,
|
||||
&hKey, NULL);
|
||||
if (!rc)
|
||||
{
|
||||
CRYPT_RegReadSerializedFromReg(hKey, contextFlags[i], store);
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash is assumed to be 20 bytes in length (a SHA-1 hash) */
|
||||
static BOOL CRYPT_WriteSerializedToReg(HKEY key, const BYTE *hash, const BYTE *buf,
|
||||
DWORD len)
|
||||
{
|
||||
WCHAR asciiHash[20 * 2 + 1];
|
||||
LONG rc;
|
||||
HKEY subKey;
|
||||
BOOL ret;
|
||||
|
||||
CRYPT_HashToStr(hash, asciiHash);
|
||||
rc = RegCreateKeyExW(key, asciiHash, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
|
||||
&subKey, NULL);
|
||||
if (!rc)
|
||||
{
|
||||
rc = RegSetValueExW(subKey, BlobW, 0, REG_BINARY, buf, len);
|
||||
RegCloseKey(subKey);
|
||||
}
|
||||
if (!rc)
|
||||
ret = TRUE;
|
||||
else
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SerializeContextsToReg(HKEY key,
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE memStore)
|
||||
{
|
||||
const void *context = NULL;
|
||||
BOOL ret;
|
||||
|
||||
do {
|
||||
context = contextInterface->enumContextsInStore(memStore, context);
|
||||
if (context)
|
||||
{
|
||||
BYTE hash[20];
|
||||
DWORD hashSize = sizeof(hash);
|
||||
|
||||
ret = contextInterface->getProp(context, CERT_HASH_PROP_ID, hash,
|
||||
&hashSize);
|
||||
if (ret)
|
||||
{
|
||||
DWORD size = 0;
|
||||
LPBYTE buf = NULL;
|
||||
|
||||
ret = contextInterface->serialize(context, 0, NULL, &size);
|
||||
if (size)
|
||||
buf = CryptMemAlloc(size);
|
||||
if (buf)
|
||||
{
|
||||
ret = contextInterface->serialize(context, 0, buf, &size);
|
||||
if (ret)
|
||||
ret = CRYPT_WriteSerializedToReg(key, hash, buf, size);
|
||||
}
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
} while (ret && context != NULL);
|
||||
if (context)
|
||||
contextInterface->free(context);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store)
|
||||
{
|
||||
static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW };
|
||||
const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
|
||||
pCRLInterface, pCTLInterface };
|
||||
struct list *listToDelete[] = { &store->certsToDelete, &store->crlsToDelete,
|
||||
NULL };
|
||||
BOOL ret = TRUE;
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; ret && i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
|
||||
{
|
||||
HKEY key;
|
||||
LONG rc = RegCreateKeyExW(store->key, subKeys[i], 0, NULL, 0,
|
||||
KEY_ALL_ACCESS, NULL, &key, NULL);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
if (listToDelete[i])
|
||||
{
|
||||
PWINE_HASH_TO_DELETE toDelete, next;
|
||||
WCHAR asciiHash[20 * 2 + 1];
|
||||
|
||||
EnterCriticalSection(&store->cs);
|
||||
LIST_FOR_EACH_ENTRY_SAFE(toDelete, next, listToDelete[i],
|
||||
WINE_HASH_TO_DELETE, entry)
|
||||
{
|
||||
LONG rc;
|
||||
|
||||
CRYPT_HashToStr(toDelete->hash, asciiHash);
|
||||
TRACE("Removing %s\n", debugstr_w(asciiHash));
|
||||
rc = RegDeleteKeyW(key, asciiHash);
|
||||
if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
}
|
||||
list_remove(&toDelete->entry);
|
||||
CryptMemFree(toDelete);
|
||||
}
|
||||
LeaveCriticalSection(&store->cs);
|
||||
}
|
||||
ret = CRYPT_SerializeContextsToReg(key, interfaces[i],
|
||||
store->memStore);
|
||||
RegCloseKey(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(rc);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If force is true or the registry store is dirty, writes the contents of the
|
||||
* store to the registry.
|
||||
*/
|
||||
static BOOL CRYPT_RegFlushStore(PWINE_REGSTOREINFO store, BOOL force)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %d)\n", store, force);
|
||||
|
||||
if (store->dirty || force)
|
||||
ret = CRYPT_RegWriteToReg(store);
|
||||
else
|
||||
ret = TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void WINAPI CRYPT_RegCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %08x)\n", store, dwFlags);
|
||||
if (dwFlags)
|
||||
FIXME("Unimplemented flags: %08x\n", dwFlags);
|
||||
|
||||
CRYPT_RegFlushStore(store, FALSE);
|
||||
RegCloseKey(store->key);
|
||||
store->cs.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&store->cs);
|
||||
CryptMemFree(store);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegWriteContext(PWINE_REGSTOREINFO store,
|
||||
const void *context, DWORD dwFlags)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (dwFlags & CERT_STORE_PROV_WRITE_ADD_FLAG)
|
||||
{
|
||||
store->dirty = TRUE;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RegDeleteContext(PWINE_REGSTOREINFO store,
|
||||
struct list *deleteList, const void *context,
|
||||
PCWINE_CONTEXT_INTERFACE contextInterface)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (store->dwOpenFlags & CERT_STORE_READONLY_FLAG)
|
||||
{
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PWINE_HASH_TO_DELETE toDelete =
|
||||
CryptMemAlloc(sizeof(WINE_HASH_TO_DELETE));
|
||||
|
||||
if (toDelete)
|
||||
{
|
||||
DWORD size = sizeof(toDelete->hash);
|
||||
|
||||
ret = contextInterface->getProp(context, CERT_HASH_PROP_ID,
|
||||
toDelete->hash, &size);
|
||||
if (ret)
|
||||
{
|
||||
EnterCriticalSection(&store->cs);
|
||||
list_add_tail(deleteList, &toDelete->entry);
|
||||
LeaveCriticalSection(&store->cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
CryptMemFree(toDelete);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
if (ret)
|
||||
store->dirty = TRUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegWriteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, cert, dwFlags);
|
||||
|
||||
return CRYPT_RegWriteContext(store, cert, dwFlags);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegDeleteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT pCertContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", store, pCertContext, dwFlags);
|
||||
|
||||
return CRYPT_RegDeleteContext(store, &store->certsToDelete, pCertContext,
|
||||
pCertInterface);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegWriteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %d)\n", hCertStore, crl, dwFlags);
|
||||
|
||||
return CRYPT_RegWriteContext(store, crl, dwFlags);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegDeleteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
|
||||
TRACE("(%p, %p, %08x)\n", store, pCrlContext, dwFlags);
|
||||
|
||||
return CRYPT_RegDeleteContext(store, &store->crlsToDelete, pCrlContext,
|
||||
pCRLInterface);
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RegControl(HCERTSTORE hCertStore, DWORD dwFlags,
|
||||
DWORD dwCtrlType, void const *pvCtrlPara)
|
||||
{
|
||||
PWINE_REGSTOREINFO store = (PWINE_REGSTOREINFO)hCertStore;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
|
||||
pvCtrlPara);
|
||||
|
||||
switch (dwCtrlType)
|
||||
{
|
||||
case CERT_STORE_CTRL_RESYNC:
|
||||
{
|
||||
HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
CRYPT_RegFlushStore(store, FALSE);
|
||||
CRYPT_RegReadFromReg(store->key, memStore);
|
||||
I_CertUpdateStore(store->memStore, memStore, 0, 0);
|
||||
CertCloseStore(memStore, 0);
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
case CERT_STORE_CTRL_COMMIT:
|
||||
ret = CRYPT_RegFlushStore(store,
|
||||
dwFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG);
|
||||
break;
|
||||
default:
|
||||
FIXME("%d: stub\n", dwCtrlType);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *regProvFuncs[] = {
|
||||
CRYPT_RegCloseStore,
|
||||
NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
|
||||
CRYPT_RegWriteCert,
|
||||
CRYPT_RegDeleteCert,
|
||||
NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
|
||||
CRYPT_RegWriteCRL,
|
||||
CRYPT_RegDeleteCRL,
|
||||
NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
|
||||
CRYPT_RegControl,
|
||||
};
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
|
||||
const void *pvPara)
|
||||
{
|
||||
PWINECRYPT_CERTSTORE store = NULL;
|
||||
|
||||
TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
|
||||
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
DWORD rc = RegDeleteTreeW((HKEY)pvPara, CertsW);
|
||||
|
||||
if (rc == ERROR_SUCCESS || rc == ERROR_NO_MORE_ITEMS)
|
||||
rc = RegDeleteTreeW((HKEY)pvPara, CRLsW);
|
||||
if (rc == ERROR_SUCCESS || rc == ERROR_NO_MORE_ITEMS)
|
||||
rc = RegDeleteTreeW((HKEY)pvPara, CTLsW);
|
||||
if (rc == ERROR_NO_MORE_ITEMS)
|
||||
rc = ERROR_SUCCESS;
|
||||
SetLastError(rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
HKEY key;
|
||||
|
||||
if (DuplicateHandle(GetCurrentProcess(), (HANDLE)pvPara,
|
||||
GetCurrentProcess(), (LPHANDLE)&key,
|
||||
dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ : KEY_ALL_ACCESS,
|
||||
TRUE, 0))
|
||||
{
|
||||
PWINECRYPT_CERTSTORE memStore;
|
||||
|
||||
memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, hCryptProv,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (memStore)
|
||||
{
|
||||
PWINE_REGSTOREINFO regInfo = CryptMemAlloc(
|
||||
sizeof(WINE_REGSTOREINFO));
|
||||
|
||||
if (regInfo)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = { 0 };
|
||||
|
||||
regInfo->dwOpenFlags = dwFlags;
|
||||
regInfo->memStore = memStore;
|
||||
regInfo->key = key;
|
||||
InitializeCriticalSection(®Info->cs);
|
||||
regInfo->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_REGSTOREINFO->cs");
|
||||
list_init(®Info->certsToDelete);
|
||||
list_init(®Info->crlsToDelete);
|
||||
CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore);
|
||||
regInfo->dirty = FALSE;
|
||||
provInfo.cbSize = sizeof(provInfo);
|
||||
provInfo.cStoreProvFunc = sizeof(regProvFuncs) /
|
||||
sizeof(regProvFuncs[0]);
|
||||
provInfo.rgpvStoreProvFunc = regProvFuncs;
|
||||
provInfo.hStoreProv = regInfo;
|
||||
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
|
||||
/* Reg store doesn't need crypto provider, so close it */
|
||||
if (hCryptProv &&
|
||||
!(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("returning %p\n", store);
|
||||
return store;
|
||||
}
|
514
reactos/dll/win32/crypt32/rootstore.c
Normal file
514
reactos/dll/win32/crypt32/rootstore.c
Normal file
|
@ -0,0 +1,514 @@
|
|||
/*
|
||||
* Copyright 2007 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "wincrypt.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
#define INITIAL_CERT_BUFFER 1024
|
||||
|
||||
struct DynamicBuffer
|
||||
{
|
||||
DWORD allocated;
|
||||
DWORD used;
|
||||
BYTE *data;
|
||||
};
|
||||
|
||||
static inline void reset_buffer(struct DynamicBuffer *buffer)
|
||||
{
|
||||
buffer->used = 0;
|
||||
if (buffer->data) buffer->data[0] = 0;
|
||||
}
|
||||
|
||||
static BOOL add_line_to_buffer(struct DynamicBuffer *buffer, LPCSTR line)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
if (buffer->used + strlen(line) + 1 > buffer->allocated)
|
||||
{
|
||||
if (!buffer->allocated)
|
||||
{
|
||||
buffer->data = CryptMemAlloc(INITIAL_CERT_BUFFER);
|
||||
if (buffer->data)
|
||||
{
|
||||
buffer->data[0] = 0;
|
||||
buffer->allocated = INITIAL_CERT_BUFFER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD new_size = max(buffer->allocated * 2,
|
||||
buffer->used + strlen(line) + 1);
|
||||
|
||||
buffer->data = CryptMemRealloc(buffer->data, new_size);
|
||||
if (buffer->data)
|
||||
buffer->allocated = new_size;
|
||||
}
|
||||
}
|
||||
if (buffer->data)
|
||||
{
|
||||
strcpy((char *)buffer->data + strlen((char *)buffer->data), line);
|
||||
/* Not strlen + 1, otherwise we'd count the NULL for every line's
|
||||
* addition (but we overwrite the previous NULL character.) Not an
|
||||
* overrun, we allocate strlen + 1 bytes above.
|
||||
*/
|
||||
buffer->used += strlen(line);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reads any base64-encoded certificates present in fp and adds them to store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_base64_certs_from_fp(FILE *fp, HCERTSTORE store)
|
||||
{
|
||||
char line[1024];
|
||||
BOOL in_cert = FALSE;
|
||||
struct DynamicBuffer saved_cert = { 0, 0, NULL };
|
||||
int num_certs = 0;
|
||||
|
||||
TRACE("\n");
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
static const char header[] = "-----BEGIN CERTIFICATE-----";
|
||||
static const char trailer[] = "-----END CERTIFICATE-----";
|
||||
|
||||
if (!strncmp(line, header, strlen(header)))
|
||||
{
|
||||
TRACE("begin new certificate\n");
|
||||
in_cert = TRUE;
|
||||
reset_buffer(&saved_cert);
|
||||
}
|
||||
else if (!strncmp(line, trailer, strlen(trailer)))
|
||||
{
|
||||
DWORD size;
|
||||
|
||||
TRACE("end of certificate, adding cert\n");
|
||||
in_cert = FALSE;
|
||||
if (CryptStringToBinaryA((char *)saved_cert.data, saved_cert.used,
|
||||
CRYPT_STRING_BASE64, NULL, &size, NULL, NULL))
|
||||
{
|
||||
LPBYTE buf = CryptMemAlloc(size);
|
||||
|
||||
if (buf)
|
||||
{
|
||||
CryptStringToBinaryA((char *)saved_cert.data,
|
||||
saved_cert.used, CRYPT_STRING_BASE64, buf, &size, NULL,
|
||||
NULL);
|
||||
if (CertAddEncodedCertificateToStore(store,
|
||||
X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_NEW, NULL))
|
||||
num_certs++;
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (in_cert)
|
||||
add_line_to_buffer(&saved_cert, line);
|
||||
}
|
||||
CryptMemFree(saved_cert.data);
|
||||
TRACE("Read %d certs\n", num_certs);
|
||||
return num_certs > 0;
|
||||
}
|
||||
|
||||
static const char *trust_status_to_str(DWORD status)
|
||||
{
|
||||
static char buf[1024];
|
||||
int pos = 0;
|
||||
|
||||
if (status & CERT_TRUST_IS_NOT_TIME_VALID)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\texpired");
|
||||
if (status & CERT_TRUST_IS_NOT_TIME_NESTED)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad time nesting");
|
||||
if (status & CERT_TRUST_IS_REVOKED)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\trevoked");
|
||||
if (status & CERT_TRUST_IS_NOT_SIGNATURE_VALID)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad signature");
|
||||
if (status & CERT_TRUST_IS_NOT_VALID_FOR_USAGE)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad usage");
|
||||
if (status & CERT_TRUST_IS_UNTRUSTED_ROOT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tuntrusted root");
|
||||
if (status & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tunknown revocation status");
|
||||
if (status & CERT_TRUST_IS_CYCLIC)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tcyclic chain");
|
||||
if (status & CERT_TRUST_INVALID_EXTENSION)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tunsupported critical extension");
|
||||
if (status & CERT_TRUST_INVALID_POLICY_CONSTRAINTS)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, "\n\tbad policy");
|
||||
if (status & CERT_TRUST_INVALID_BASIC_CONSTRAINTS)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tbad basic constraints");
|
||||
if (status & CERT_TRUST_INVALID_NAME_CONSTRAINTS)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tbad name constraints");
|
||||
if (status & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tunsuported name constraint");
|
||||
if (status & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tundefined name constraint");
|
||||
if (status & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tdisallowed name constraint");
|
||||
if (status & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\texcluded name constraint");
|
||||
if (status & CERT_TRUST_IS_OFFLINE_REVOCATION)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\trevocation server offline");
|
||||
if (status & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY)
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos,
|
||||
"\n\tno issuance policy");
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char *get_cert_common_name(PCCERT_CONTEXT cert)
|
||||
{
|
||||
static char buf[1024];
|
||||
const char *name = NULL;
|
||||
CERT_NAME_INFO *nameInfo;
|
||||
DWORD size;
|
||||
BOOL ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME,
|
||||
cert->pCertInfo->Subject.pbData, cert->pCertInfo->Subject.cbData,
|
||||
CRYPT_DECODE_NOCOPY_FLAG | CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo,
|
||||
&size);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
PCERT_RDN_ATTR commonName = CertFindRDNAttr(szOID_COMMON_NAME,
|
||||
nameInfo);
|
||||
|
||||
if (commonName)
|
||||
{
|
||||
CertRDNValueToStrA(commonName->dwValueType,
|
||||
&commonName->Value, buf, sizeof(buf));
|
||||
name = buf;
|
||||
}
|
||||
LocalFree(nameInfo);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to)
|
||||
{
|
||||
DWORD root_count = 0;
|
||||
CERT_CHAIN_ENGINE_CONFIG chainEngineConfig =
|
||||
{ sizeof(chainEngineConfig), 0 };
|
||||
HCERTCHAINENGINE engine;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
CertDuplicateStore(to);
|
||||
engine = CRYPT_CreateChainEngine(to, &chainEngineConfig);
|
||||
if (engine)
|
||||
{
|
||||
PCCERT_CONTEXT cert = NULL;
|
||||
|
||||
do {
|
||||
cert = CertEnumCertificatesInStore(from, cert);
|
||||
if (cert)
|
||||
{
|
||||
CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
|
||||
PCCERT_CHAIN_CONTEXT chain;
|
||||
BOOL ret = CertGetCertificateChain(engine, cert, NULL, from,
|
||||
&chainPara, 0, NULL, &chain);
|
||||
|
||||
if (!ret)
|
||||
TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
|
||||
"chain creation failed");
|
||||
else
|
||||
{
|
||||
/* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */
|
||||
if (chain->TrustStatus.dwErrorStatus &
|
||||
~CERT_TRUST_IS_UNTRUSTED_ROOT)
|
||||
TRACE("rejecting %s: %s\n", get_cert_common_name(cert),
|
||||
trust_status_to_str(chain->TrustStatus.dwErrorStatus &
|
||||
~CERT_TRUST_IS_UNTRUSTED_ROOT));
|
||||
else
|
||||
{
|
||||
DWORD i, j;
|
||||
|
||||
for (i = 0; i < chain->cChain; i++)
|
||||
for (j = 0; j < chain->rgpChain[i]->cElement; j++)
|
||||
if (CertAddCertificateContextToStore(to,
|
||||
chain->rgpChain[i]->rgpElement[j]->pCertContext,
|
||||
CERT_STORE_ADD_NEW, NULL))
|
||||
root_count++;
|
||||
}
|
||||
CertFreeCertificateChain(chain);
|
||||
}
|
||||
}
|
||||
} while (cert);
|
||||
CertFreeCertificateChainEngine(engine);
|
||||
}
|
||||
TRACE("Added %d root certificates\n", root_count);
|
||||
}
|
||||
|
||||
/* Reads the file fd, and imports any certificates in it into store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_certs_from_file(int fd, HCERTSTORE store)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
FILE *fp;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
fp = fdopen(fd, "r");
|
||||
if (fp)
|
||||
{
|
||||
ret = import_base64_certs_from_fp(fp, store);
|
||||
fclose(fp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store,
|
||||
BOOL allow_dir);
|
||||
|
||||
/* Opens path, which must be a directory, and imports certificates from every
|
||||
* file in the directory into store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
DIR *dir;
|
||||
|
||||
TRACE("(%s, %p)\n", debugstr_a(path), store);
|
||||
/* UNIX functions = bad for reactos
|
||||
dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
size_t bufsize = strlen(path) + 1 + PATH_MAX + 1;
|
||||
char *filebuf = CryptMemAlloc(bufsize);
|
||||
|
||||
if (filebuf)
|
||||
{
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir)))
|
||||
{
|
||||
if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
|
||||
{
|
||||
snprintf(filebuf, bufsize, "%s/%s", path, entry->d_name);
|
||||
if (import_certs_from_path(filebuf, store, FALSE) && !ret)
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
CryptMemFree(filebuf);
|
||||
}
|
||||
}
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Opens path, which may be a file or a directory, and imports any certificates
|
||||
* it finds into store.
|
||||
* Returns TRUE if any certificates were successfully imported.
|
||||
*/
|
||||
static BOOL import_certs_from_path(LPCSTR path, HCERTSTORE store,
|
||||
BOOL allow_dir)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
int fd;
|
||||
|
||||
TRACE("(%s, %p, %d)\n", debugstr_a(path), store, allow_dir);
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd != -1)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) == 0)
|
||||
{
|
||||
if (S_ISREG(st.st_mode))
|
||||
ret = import_certs_from_file(fd, store);
|
||||
else if (S_ISDIR(st.st_mode))
|
||||
{
|
||||
if (allow_dir)
|
||||
ret = import_certs_from_dir(path, store);
|
||||
else
|
||||
WARN("%s is a directory and directories are disallowed\n",
|
||||
debugstr_a(path));
|
||||
}
|
||||
else
|
||||
ERR("%s: invalid file type\n", path);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootWriteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can't have certs added */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootDeleteCert(HCERTSTORE hCertStore,
|
||||
PCCERT_CONTEXT cert, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can't have certs deleted */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootWriteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can have CRLs added. At worst, a malicious application
|
||||
* can DoS itself, as the changes aren't persisted in any way.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL WINAPI CRYPT_RootDeleteCRL(HCERTSTORE hCertStore,
|
||||
PCCRL_CONTEXT crl, DWORD dwFlags)
|
||||
{
|
||||
/* The root store can't have CRLs deleted */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void *rootProvFuncs[] = {
|
||||
NULL, /* CERT_STORE_PROV_CLOSE_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CERT_FUNC */
|
||||
CRYPT_RootWriteCert,
|
||||
CRYPT_RootDeleteCert,
|
||||
NULL, /* CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CRL_FUNC */
|
||||
CRYPT_RootWriteCRL,
|
||||
CRYPT_RootDeleteCRL,
|
||||
NULL, /* CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_READ_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_WRITE_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_DELETE_CTL_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC */
|
||||
NULL, /* CERT_STORE_PROV_CONTROL_FUNC */
|
||||
};
|
||||
|
||||
static const char * const CRYPT_knownLocations[] = {
|
||||
"/etc/ssl/certs/ca-certificates.crt",
|
||||
"/etc/ssl/certs",
|
||||
"/etc/pki/tls/certs/ca-bundle.crt",
|
||||
};
|
||||
|
||||
/* Reads certificates from the list of known locations. Stops when any
|
||||
* location contains any certificates, to prevent spending unnecessary time
|
||||
* adding redundant certificates, e.g. when both a certificate bundle and
|
||||
* individual certificates exist in the same directory.
|
||||
*/
|
||||
static PWINECRYPT_CERTSTORE CRYPT_RootOpenStoreFromKnownLocations(void)
|
||||
{
|
||||
HCERTSTORE root = NULL;
|
||||
HCERTSTORE from = CertOpenStore(CERT_STORE_PROV_MEMORY,
|
||||
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
HCERTSTORE to = CertOpenStore(CERT_STORE_PROV_MEMORY,
|
||||
X509_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
|
||||
if (from && to)
|
||||
{
|
||||
CERT_STORE_PROV_INFO provInfo = {
|
||||
sizeof(CERT_STORE_PROV_INFO),
|
||||
sizeof(rootProvFuncs) / sizeof(rootProvFuncs[0]),
|
||||
rootProvFuncs,
|
||||
NULL,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
DWORD i;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
for (i = 0; !ret &&
|
||||
i < sizeof(CRYPT_knownLocations) / sizeof(CRYPT_knownLocations[0]);
|
||||
i++)
|
||||
ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
|
||||
check_and_store_certs(from, to);
|
||||
root = CRYPT_ProvCreateStore(0, to, &provInfo);
|
||||
}
|
||||
CertCloseStore(from, 0);
|
||||
TRACE("returning %p\n", root);
|
||||
return root;
|
||||
}
|
||||
|
||||
static PWINECRYPT_CERTSTORE CRYPT_rootStore;
|
||||
|
||||
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags)
|
||||
{
|
||||
TRACE("(%ld, %08x)\n", hCryptProv, dwFlags);
|
||||
|
||||
if (dwFlags & CERT_STORE_DELETE_FLAG)
|
||||
{
|
||||
WARN("root store can't be deleted\n");
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
return NULL;
|
||||
}
|
||||
switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
|
||||
{
|
||||
case CERT_SYSTEM_STORE_LOCAL_MACHINE:
|
||||
case CERT_SYSTEM_STORE_CURRENT_USER:
|
||||
break;
|
||||
default:
|
||||
TRACE("location %08x unsupported\n",
|
||||
dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK);
|
||||
SetLastError(E_INVALIDARG);
|
||||
return NULL;
|
||||
}
|
||||
if (!CRYPT_rootStore)
|
||||
{
|
||||
HCERTSTORE root = CRYPT_RootOpenStoreFromKnownLocations();
|
||||
|
||||
InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root,
|
||||
NULL);
|
||||
if (CRYPT_rootStore != root)
|
||||
CertCloseStore(root, 0);
|
||||
}
|
||||
CertDuplicateStore(CRYPT_rootStore);
|
||||
return CRYPT_rootStore;
|
||||
}
|
||||
|
||||
void root_store_free(void)
|
||||
{
|
||||
CertCloseStore(CRYPT_rootStore, 0);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2006 Juan Lang
|
||||
* Copyright 2004-2007 Juan Lang
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -15,12 +15,15 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wincrypt.h"
|
||||
#include "wine/debug.h"
|
||||
#include "excpt.h"
|
||||
#include "wine/exception.h"
|
||||
#include "crypt32_private.h"
|
||||
|
||||
|
@ -422,7 +425,7 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
|
|||
|
||||
static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' };
|
||||
|
||||
BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
|
||||
BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store)
|
||||
{
|
||||
BYTE fileHeaderBuf[sizeof(fileHeader)];
|
||||
DWORD read;
|
||||
|
@ -432,7 +435,11 @@ BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
|
|||
ret = ReadFile(file, fileHeaderBuf, sizeof(fileHeaderBuf), &read, NULL);
|
||||
if (ret)
|
||||
{
|
||||
if (!memcmp(fileHeaderBuf, fileHeader, read))
|
||||
if (!read)
|
||||
; /* an empty file is okay */
|
||||
else if (read != sizeof(fileHeaderBuf))
|
||||
ret = FALSE;
|
||||
else if (!memcmp(fileHeaderBuf, fileHeader, read))
|
||||
{
|
||||
WINE_CERT_PROP_HEADER propHdr;
|
||||
const void *context = NULL;
|
||||
|
@ -504,6 +511,8 @@ BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
|
|||
CryptMemFree(buf);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
|
@ -534,8 +543,11 @@ static BOOL WINAPI CRYPT_SerializeCTLNoHash(PCCTL_CONTEXT pCtlContext,
|
|||
CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
|
||||
const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
|
||||
typedef BOOL (*SerializedOutputFunc)(void *handle, const void *buffer,
|
||||
DWORD size);
|
||||
|
||||
static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output,
|
||||
void *handle, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
|
||||
{
|
||||
const void *context = NULL;
|
||||
BOOL ret;
|
||||
|
@ -554,7 +566,7 @@ static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
|
|||
{
|
||||
ret = contextInterface->serialize(context, 0, buf, &size);
|
||||
if (ret)
|
||||
ret = WriteFile(file, buf, size, &size, NULL);
|
||||
ret = output(handle, buf, size);
|
||||
}
|
||||
CryptMemFree(buf);
|
||||
}
|
||||
|
@ -566,35 +578,307 @@ static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
|
|||
return ret;
|
||||
}
|
||||
|
||||
BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store)
|
||||
static BOOL CRYPT_WriteSerializedStoreToStream(HCERTSTORE store,
|
||||
SerializedOutputFunc output, void *handle)
|
||||
{
|
||||
static const BYTE fileTrailer[12] = { 0 };
|
||||
WINE_CONTEXT_INTERFACE interface;
|
||||
BOOL ret;
|
||||
DWORD size;
|
||||
|
||||
SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||
ret = WriteFile(file, fileHeader, sizeof(fileHeader), &size, NULL);
|
||||
ret = output(handle, fileHeader, sizeof(fileHeader));
|
||||
if (ret)
|
||||
{
|
||||
memcpy(&interface, pCertInterface, sizeof(interface));
|
||||
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCertNoHash;
|
||||
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
|
||||
ret = CRYPT_SerializeContextsToStream(output, handle, &interface,
|
||||
store);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
memcpy(&interface, pCRLInterface, sizeof(interface));
|
||||
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCRLNoHash;
|
||||
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
|
||||
ret = CRYPT_SerializeContextsToStream(output, handle, &interface,
|
||||
store);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
memcpy(&interface, pCTLInterface, sizeof(interface));
|
||||
interface.serialize = (SerializeElementFunc)CRYPT_SerializeCTLNoHash;
|
||||
ret = CRYPT_SerializeContextsToFile(file, &interface, store);
|
||||
ret = CRYPT_SerializeContextsToStream(output, handle, &interface,
|
||||
store);
|
||||
}
|
||||
if (ret)
|
||||
ret = WriteFile(file, fileTrailer, sizeof(fileTrailer), &size, NULL);
|
||||
ret = output(handle, fileTrailer, sizeof(fileTrailer));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_FileOutputFunc(void *handle, const void *buffer, DWORD size)
|
||||
{
|
||||
return WriteFile(handle, buffer, size, &size, NULL);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_WriteSerializedStoreToFile(HANDLE file, HCERTSTORE store)
|
||||
{
|
||||
SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||
return CRYPT_WriteSerializedStoreToStream(store, CRYPT_FileOutputFunc,
|
||||
file);
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
||||
CRYPT_SIGNED_INFO signedInfo = { 0 };
|
||||
PCCERT_CONTEXT cert = NULL;
|
||||
PCCRL_CONTEXT crl = NULL;
|
||||
DWORD size;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%d, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData);
|
||||
|
||||
do {
|
||||
cert = CertEnumCertificatesInStore(store, cert);
|
||||
if (cert)
|
||||
signedInfo.cCertEncoded++;
|
||||
} while (cert);
|
||||
if (signedInfo.cCertEncoded)
|
||||
{
|
||||
signedInfo.rgCertEncoded = CryptMemAlloc(
|
||||
signedInfo.cCertEncoded * sizeof(CERT_BLOB));
|
||||
if (!signedInfo.rgCertEncoded)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD i = 0;
|
||||
|
||||
do {
|
||||
cert = CertEnumCertificatesInStore(store, cert);
|
||||
if (cert)
|
||||
{
|
||||
signedInfo.rgCertEncoded[i].cbData = cert->cbCertEncoded;
|
||||
signedInfo.rgCertEncoded[i].pbData = cert->pbCertEncoded;
|
||||
i++;
|
||||
}
|
||||
} while (cert);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
crl = CertEnumCRLsInStore(store, crl);
|
||||
if (crl)
|
||||
signedInfo.cCrlEncoded++;
|
||||
} while (crl);
|
||||
if (signedInfo.cCrlEncoded)
|
||||
{
|
||||
signedInfo.rgCrlEncoded = CryptMemAlloc(
|
||||
signedInfo.cCrlEncoded * sizeof(CERT_BLOB));
|
||||
if (!signedInfo.rgCrlEncoded)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD i = 0;
|
||||
|
||||
do {
|
||||
crl = CertEnumCRLsInStore(store, crl);
|
||||
if (crl)
|
||||
{
|
||||
signedInfo.rgCrlEncoded[i].cbData = crl->cbCrlEncoded;
|
||||
signedInfo.rgCrlEncoded[i].pbData = crl->pbCrlEncoded;
|
||||
i++;
|
||||
}
|
||||
} while (crl);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, NULL, &size);
|
||||
if (ret)
|
||||
{
|
||||
if (!blob->pbData)
|
||||
blob->cbData = size;
|
||||
else if (blob->cbData < size)
|
||||
{
|
||||
blob->cbData = size;
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
blob->cbData = size;
|
||||
ret = CRYPT_AsnEncodePKCSSignedInfo(&signedInfo, blob->pbData,
|
||||
&blob->cbData);
|
||||
}
|
||||
}
|
||||
}
|
||||
CryptMemFree(signedInfo.rgCertEncoded);
|
||||
CryptMemFree(signedInfo.rgCrlEncoded);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SavePKCSToFile(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
CERT_BLOB blob = { 0, NULL };
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", handle);
|
||||
|
||||
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
||||
if (ret)
|
||||
{
|
||||
blob.pbData = CryptMemAlloc(blob.cbData);
|
||||
if (blob.pbData)
|
||||
{
|
||||
ret = CRYPT_SavePKCSToMem(store, dwMsgAndCertEncodingType, &blob);
|
||||
if (ret)
|
||||
ret = WriteFile(handle, blob.pbData, blob.cbData,
|
||||
&blob.cbData, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SaveSerializedToFile(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
return CRYPT_WriteSerializedStoreToFile(handle, store);
|
||||
}
|
||||
|
||||
struct MemWrittenTracker
|
||||
{
|
||||
DWORD cbData;
|
||||
BYTE *pbData;
|
||||
DWORD written;
|
||||
};
|
||||
|
||||
/* handle is a pointer to a MemWrittenTracker. Assumes its pointer is valid. */
|
||||
static BOOL CRYPT_MemOutputFunc(void *handle, const void *buffer, DWORD size)
|
||||
{
|
||||
struct MemWrittenTracker *tracker = (struct MemWrittenTracker *)handle;
|
||||
BOOL ret;
|
||||
|
||||
if (tracker->written + size > tracker->cbData)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
/* Update written so caller can notify its caller of the required size
|
||||
*/
|
||||
tracker->written += size;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(tracker->pbData + tracker->written, buffer, size);
|
||||
tracker->written += size;
|
||||
ret = TRUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_CountSerializedBytes(void *handle, const void *buffer,
|
||||
DWORD size)
|
||||
{
|
||||
*(DWORD *)handle += size;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_SaveSerializedToMem(HCERTSTORE store,
|
||||
DWORD dwMsgAndCertEncodingType, void *handle)
|
||||
{
|
||||
CERT_BLOB *blob = (CERT_BLOB *)handle;
|
||||
DWORD size;
|
||||
BOOL ret;
|
||||
|
||||
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_CountSerializedBytes,
|
||||
&size);
|
||||
if (ret)
|
||||
{
|
||||
if (!blob->pbData)
|
||||
blob->cbData = size;
|
||||
else if (blob->cbData < size)
|
||||
{
|
||||
SetLastError(ERROR_MORE_DATA);
|
||||
blob->cbData = size;
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct MemWrittenTracker tracker = { blob->cbData, blob->pbData,
|
||||
0 };
|
||||
|
||||
ret = CRYPT_WriteSerializedStoreToStream(store, CRYPT_MemOutputFunc,
|
||||
&tracker);
|
||||
if (!ret && GetLastError() == ERROR_MORE_DATA)
|
||||
blob->cbData = tracker.written;
|
||||
}
|
||||
}
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType,
|
||||
DWORD dwSaveAs, DWORD dwSaveTo, void *pvSaveToPara, DWORD dwFlags)
|
||||
{
|
||||
BOOL (*saveFunc)(HCERTSTORE, DWORD, void *);
|
||||
void *handle;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %08x, %d, %d, %p, %08x)\n", hCertStore,
|
||||
dwMsgAndCertEncodingType, dwSaveAs, dwSaveTo, pvSaveToPara, dwFlags);
|
||||
|
||||
switch (dwSaveAs)
|
||||
{
|
||||
case CERT_STORE_SAVE_AS_STORE:
|
||||
case CERT_STORE_SAVE_AS_PKCS7:
|
||||
break;
|
||||
default:
|
||||
WARN("unimplemented for %d\n", dwSaveAs);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
switch (dwSaveTo)
|
||||
{
|
||||
case CERT_STORE_SAVE_TO_FILE:
|
||||
handle = pvSaveToPara;
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||
break;
|
||||
case CERT_STORE_SAVE_TO_FILENAME_A:
|
||||
handle = CreateFileA((LPCSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, 0, NULL);
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||
break;
|
||||
case CERT_STORE_SAVE_TO_FILENAME_W:
|
||||
handle = CreateFileW((LPCWSTR)pvSaveToPara, GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, 0, NULL);
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToFile : CRYPT_SavePKCSToFile;
|
||||
break;
|
||||
case CERT_STORE_SAVE_TO_MEMORY:
|
||||
handle = pvSaveToPara;
|
||||
saveFunc = dwSaveAs == CERT_STORE_SAVE_AS_STORE ?
|
||||
CRYPT_SaveSerializedToMem : CRYPT_SavePKCSToMem;
|
||||
break;
|
||||
default:
|
||||
WARN("unimplemented for %d\n", dwSaveTo);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
ret = saveFunc(hCertStore, dwMsgAndCertEncodingType, handle);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "winuser.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
|
||||
|
||||
|
@ -324,7 +325,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
|
|||
dos = (IMAGE_DOS_HEADER *)pMapped;
|
||||
if (dos->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
memcpy(pgSubject, &unknown, sizeof(GUID));
|
||||
*pgSubject = unknown;
|
||||
SetLastError(S_OK);
|
||||
bRet = TRUE;
|
||||
goto cleanup1;
|
||||
|
@ -334,8 +335,8 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
|
|||
* There is a lot more to be checked:
|
||||
* - Check for MSFC in the header
|
||||
* - Check for the keys CryptSIPDllIsMyFileType and CryptSIPDllIsMyFileType2
|
||||
* under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are
|
||||
* functions listed that need check if a SIP Provider can deal with the
|
||||
* under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are
|
||||
* functions listed that need check if a SIP Provider can deal with the
|
||||
* given file.
|
||||
*/
|
||||
|
||||
|
@ -354,6 +355,165 @@ cleanup3:
|
|||
return bRet;
|
||||
}
|
||||
|
||||
static LONG CRYPT_OpenSIPFunctionKey(const GUID *guid, LPCWSTR function,
|
||||
HKEY *key)
|
||||
{
|
||||
WCHAR szFullKey[ 0x100 ];
|
||||
|
||||
lstrcpyW(szFullKey, szOID);
|
||||
lstrcatW(szFullKey, function);
|
||||
CRYPT_guid2wstr(guid, &szFullKey[lstrlenW(szFullKey)]);
|
||||
return RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, key);
|
||||
}
|
||||
|
||||
/* Loads the function named function for the SIP specified by pgSubject, and
|
||||
* returns it if found. Returns NULL on error. If the function is loaded,
|
||||
* *pLib is set to the library in which it is found.
|
||||
*/
|
||||
static void *CRYPT_LoadSIPFunc(const GUID *pgSubject, LPCWSTR function,
|
||||
HMODULE *pLib)
|
||||
{
|
||||
LONG r;
|
||||
HKEY key = NULL;
|
||||
DWORD size;
|
||||
WCHAR dllName[MAX_PATH];
|
||||
char functionName[MAX_PATH];
|
||||
HMODULE lib;
|
||||
void *func = NULL;
|
||||
|
||||
TRACE("(%s, %s)\n", debugstr_guid(pgSubject), debugstr_w(function));
|
||||
|
||||
r = CRYPT_OpenSIPFunctionKey(pgSubject, function, &key);
|
||||
if (r) goto error;
|
||||
|
||||
/* Read the DLL entry */
|
||||
size = sizeof(dllName);
|
||||
r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size);
|
||||
if (r) goto error;
|
||||
|
||||
/* Read the Function entry */
|
||||
size = sizeof(functionName);
|
||||
r = RegQueryValueExA(key, "FuncName", NULL, NULL, (LPBYTE)functionName,
|
||||
&size);
|
||||
if (r) goto error;
|
||||
|
||||
lib = LoadLibraryW(dllName);
|
||||
if (!lib)
|
||||
goto error;
|
||||
func = GetProcAddress(lib, functionName);
|
||||
if (func)
|
||||
*pLib = lib;
|
||||
else
|
||||
FreeLibrary(lib);
|
||||
|
||||
error:
|
||||
RegCloseKey(key);
|
||||
TRACE("returning %p\n", func);
|
||||
return func;
|
||||
}
|
||||
|
||||
typedef struct _WINE_SIP_PROVIDER {
|
||||
GUID subject;
|
||||
SIP_DISPATCH_INFO info;
|
||||
struct list entry;
|
||||
} WINE_SIP_PROVIDER;
|
||||
|
||||
static struct list providers = { &providers, &providers };
|
||||
static CRITICAL_SECTION providers_cs;
|
||||
static CRITICAL_SECTION_DEBUG providers_cs_debug =
|
||||
{
|
||||
0, 0, &providers_cs,
|
||||
{ &providers_cs_debug.ProcessLocksList,
|
||||
&providers_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": providers_cs") }
|
||||
};
|
||||
static CRITICAL_SECTION providers_cs = { &providers_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
static void CRYPT_CacheSIP(const GUID *pgSubject, SIP_DISPATCH_INFO *info)
|
||||
{
|
||||
WINE_SIP_PROVIDER *prov = CryptMemAlloc(sizeof(WINE_SIP_PROVIDER));
|
||||
|
||||
if (prov)
|
||||
{
|
||||
prov->subject = *pgSubject;
|
||||
prov->info = *info;
|
||||
EnterCriticalSection(&providers_cs);
|
||||
list_add_tail(&providers, &prov->entry);
|
||||
LeaveCriticalSection(&providers_cs);
|
||||
}
|
||||
}
|
||||
|
||||
static WINE_SIP_PROVIDER *CRYPT_GetCachedSIP(const GUID *pgSubject)
|
||||
{
|
||||
WINE_SIP_PROVIDER *provider = NULL, *ret = NULL;
|
||||
|
||||
EnterCriticalSection(&providers_cs);
|
||||
LIST_FOR_EACH_ENTRY(provider, &providers, WINE_SIP_PROVIDER, entry)
|
||||
{
|
||||
if (IsEqualGUID(pgSubject, &provider->subject))
|
||||
break;
|
||||
}
|
||||
if (provider && IsEqualGUID(pgSubject, &provider->subject))
|
||||
ret = provider;
|
||||
LeaveCriticalSection(&providers_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline BOOL CRYPT_IsSIPCached(const GUID *pgSubject)
|
||||
{
|
||||
return CRYPT_GetCachedSIP(pgSubject) != NULL;
|
||||
}
|
||||
|
||||
void crypt_sip_free(void)
|
||||
{
|
||||
WINE_SIP_PROVIDER *prov, *next;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(prov, next, &providers, WINE_SIP_PROVIDER, entry)
|
||||
{
|
||||
list_remove(&prov->entry);
|
||||
FreeLibrary(prov->info.hSIP);
|
||||
CryptMemFree(prov);
|
||||
}
|
||||
}
|
||||
|
||||
/* Loads the SIP for pgSubject into the global cache. Returns FALSE if the
|
||||
* SIP isn't registered or is invalid.
|
||||
*/
|
||||
static BOOL CRYPT_LoadSIP(const GUID *pgSubject)
|
||||
{
|
||||
SIP_DISPATCH_INFO sip = { 0 };
|
||||
HMODULE lib = NULL, temp = NULL;
|
||||
|
||||
sip.pfGet = CRYPT_LoadSIPFunc(pgSubject, szGetSigned, &lib);
|
||||
if (!sip.pfGet)
|
||||
goto error;
|
||||
sip.pfPut = CRYPT_LoadSIPFunc(pgSubject, szPutSigned, &temp);
|
||||
if (!sip.pfPut || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.pfCreate = CRYPT_LoadSIPFunc(pgSubject, szCreate, &temp);
|
||||
if (!sip.pfCreate || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.pfVerify = CRYPT_LoadSIPFunc(pgSubject, szVerify, &temp);
|
||||
if (!sip.pfVerify || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.pfRemove = CRYPT_LoadSIPFunc(pgSubject, szRemoveSigned, &temp);
|
||||
if (!sip.pfRemove || temp != lib)
|
||||
goto error;
|
||||
FreeLibrary(temp);
|
||||
sip.hSIP = lib;
|
||||
CRYPT_CacheSIP(pgSubject, &sip);
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
FreeLibrary(lib);
|
||||
FreeLibrary(temp);
|
||||
SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CryptSIPLoad (CRYPT32.@)
|
||||
*
|
||||
|
@ -382,15 +542,24 @@ cleanup3:
|
|||
BOOL WINAPI CryptSIPLoad
|
||||
(const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch)
|
||||
{
|
||||
FIXME("(%s %d %p) stub!\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);
|
||||
TRACE("(%s %d %p)\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);
|
||||
|
||||
if (!pgSubject || dwFlags != 0 || !pSipDispatch)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (!CRYPT_IsSIPCached(pgSubject) && !CRYPT_LoadSIP(pgSubject))
|
||||
return FALSE;
|
||||
|
||||
return FALSE;
|
||||
pSipDispatch->hSIP = NULL;
|
||||
pSipDispatch->pfGet = CryptSIPGetSignedDataMsg;
|
||||
pSipDispatch->pfPut = CryptSIPPutSignedDataMsg;
|
||||
pSipDispatch->pfCreate = CryptSIPCreateIndirectData;
|
||||
pSipDispatch->pfVerify = CryptSIPVerifyIndirectData;
|
||||
pSipDispatch->pfRemove = CryptSIPRemoveSignedDataMsg;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -399,9 +568,15 @@ BOOL WINAPI CryptSIPLoad
|
|||
BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData,
|
||||
SIP_INDIRECT_DATA* pIndirectData)
|
||||
{
|
||||
FIXME("(%p %p %p) stub\n", pSubjectInfo, pcbIndirectData, pIndirectData);
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
return FALSE;
|
||||
TRACE("(%p %p %p)\n", pSubjectInfo, pcbIndirectData, pIndirectData);
|
||||
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfCreate(pSubjectInfo, pcbIndirectData, pIndirectData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -410,10 +585,17 @@ BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcb
|
|||
BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType,
|
||||
DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg)
|
||||
{
|
||||
FIXME("(%p %p %d %p %p) stub\n", pSubjectInfo, pdwEncodingType, dwIndex,
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
|
||||
pcbSignedDataMsg, pbSignedDataMsg);
|
||||
|
||||
return FALSE;
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfGet(pSubjectInfo, pdwEncodingType, dwIndex,
|
||||
pcbSignedDataMsg, pbSignedDataMsg);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -422,10 +604,17 @@ BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEn
|
|||
BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType,
|
||||
DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
|
||||
{
|
||||
FIXME("(%p %d %p %d %p) stub\n", pSubjectInfo, pdwEncodingType, pdwIndex,
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p %d %p %d %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex,
|
||||
cbSignedDataMsg, pbSignedDataMsg);
|
||||
|
||||
return FALSE;
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfPut(pSubjectInfo, pdwEncodingType, pdwIndex,
|
||||
cbSignedDataMsg, pbSignedDataMsg);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -434,9 +623,15 @@ BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEnc
|
|||
BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
|
||||
DWORD dwIndex)
|
||||
{
|
||||
FIXME("(%p %d) stub\n", pSubjectInfo, dwIndex);
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
return FALSE;
|
||||
TRACE("(%p %d)\n", pSubjectInfo, dwIndex);
|
||||
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfRemove(pSubjectInfo, dwIndex);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -445,7 +640,13 @@ BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
|
|||
BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo,
|
||||
SIP_INDIRECT_DATA* pIndirectData)
|
||||
{
|
||||
FIXME("(%p %p) stub\n", pSubjectInfo, pIndirectData);
|
||||
WINE_SIP_PROVIDER *sip;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
return FALSE;
|
||||
TRACE("(%p %p)\n", pSubjectInfo, pIndirectData);
|
||||
|
||||
if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
|
||||
ret = sip->info.pfVerify(pSubjectInfo, pIndirectData);
|
||||
TRACE("returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -59,6 +59,17 @@ DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case CERT_RDN_UTF8_STRING:
|
||||
if (!psz || !csz)
|
||||
ret = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pValue->pbData,
|
||||
pValue->cbData / sizeof(WCHAR) + 1, NULL, 0, NULL, NULL);
|
||||
else
|
||||
{
|
||||
ret = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pValue->pbData,
|
||||
pValue->cbData / sizeof(WCHAR) + 1, psz, csz - 1, NULL, NULL);
|
||||
csz -= ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("string type %d unimplemented\n", dwValueType);
|
||||
}
|
||||
|
@ -110,6 +121,24 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case CERT_RDN_UTF8_STRING:
|
||||
if (!psz || !csz)
|
||||
ret = pValue->cbData / sizeof(WCHAR);
|
||||
else
|
||||
{
|
||||
DWORD chars = min(pValue->cbData / sizeof(WCHAR), csz - 1);
|
||||
|
||||
if (chars)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < chars; i++)
|
||||
psz[i] = *((LPWSTR)pValue->pbData + i);
|
||||
ret += chars;
|
||||
csz -= chars;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("string type %d unimplemented\n", dwValueType);
|
||||
}
|
||||
|
@ -224,7 +253,7 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
|
|||
}
|
||||
/* FIXME: handle quoting */
|
||||
chars = CertRDNValueToStrA(
|
||||
info->rgRDN[i].rgRDNAttr[j].dwValueType,
|
||||
info->rgRDN[i].rgRDNAttr[j].dwValueType,
|
||||
&info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
|
||||
psz ? csz - ret : 0);
|
||||
if (chars)
|
||||
|
@ -389,7 +418,7 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
|
|||
}
|
||||
/* FIXME: handle quoting */
|
||||
chars = CertRDNValueToStrW(
|
||||
info->rgRDN[i].rgRDNAttr[j].dwValueType,
|
||||
info->rgRDN[i].rgRDNAttr[j].dwValueType,
|
||||
&info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
|
||||
psz ? csz - ret : 0);
|
||||
if (chars)
|
||||
|
@ -426,7 +455,6 @@ BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500,
|
|||
DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded,
|
||||
LPCSTR *ppszError)
|
||||
{
|
||||
LPWSTR x500, errorStr;
|
||||
BOOL ret;
|
||||
int len;
|
||||
|
||||
|
@ -435,24 +463,44 @@ BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500,
|
|||
ppszError);
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, 0, pszX500, -1, NULL, 0);
|
||||
x500 = CryptMemAlloc(len * sizeof(WCHAR));
|
||||
if (x500)
|
||||
if (len)
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len);
|
||||
ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType, pvReserved,
|
||||
pbEncoded, pcbEncoded, ppszError ? (LPCWSTR *)&errorStr : NULL);
|
||||
if (ppszError)
|
||||
{
|
||||
DWORD i;
|
||||
LPWSTR x500, errorStr;
|
||||
|
||||
*ppszError = pszX500;
|
||||
for (i = 0; i < errorStr - x500; i++)
|
||||
CharNextA(*ppszError);
|
||||
if ((x500 = CryptMemAlloc(len * sizeof(WCHAR))))
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len);
|
||||
ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType,
|
||||
pvReserved, pbEncoded, pcbEncoded,
|
||||
ppszError ? (LPCWSTR *)&errorStr : NULL);
|
||||
if (ppszError)
|
||||
{
|
||||
if (!ret)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
*ppszError = pszX500;
|
||||
for (i = 0; i < errorStr - x500; i++)
|
||||
*ppszError = CharNextA(*ppszError);
|
||||
}
|
||||
else
|
||||
*ppszError = NULL;
|
||||
}
|
||||
CryptMemFree(x500);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
CryptMemFree(x500);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
if (ppszError)
|
||||
*ppszError = pszX500;
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -501,10 +549,10 @@ static void CRYPT_KeynameKeeperFromTokenW(struct KeynameKeeper *keeper,
|
|||
TRACE("Keyname is %s\n", debugstr_w(keeper->keyName));
|
||||
}
|
||||
|
||||
static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
||||
static BOOL CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
||||
LPCWSTR *ppszError)
|
||||
{
|
||||
DWORD ret = ERROR_SUCCESS;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
while (*str && isspaceW(*str))
|
||||
str++;
|
||||
|
@ -520,7 +568,8 @@ static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
|||
TRACE("missing equals char at %s\n", debugstr_w(token->start));
|
||||
if (ppszError)
|
||||
*ppszError = token->start;
|
||||
ret = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -529,10 +578,10 @@ static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
|
|||
}
|
||||
|
||||
/* Assumes separators are characters in the 0-255 range */
|
||||
static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
||||
static BOOL CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
||||
struct X500TokenW *token, LPCWSTR *ppszError)
|
||||
{
|
||||
DWORD ret = ERROR_SUCCESS;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%s, %s, %p, %p)\n", debugstr_w(str), debugstr_w(separators), token,
|
||||
ppszError);
|
||||
|
@ -546,7 +595,7 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
{
|
||||
token->end = NULL;
|
||||
str++;
|
||||
while (!token->end && !ret)
|
||||
while (!token->end && ret)
|
||||
{
|
||||
while (*str && *str != '"')
|
||||
str++;
|
||||
|
@ -562,7 +611,8 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
TRACE("unterminated quote at %s\n", debugstr_w(str));
|
||||
if (ppszError)
|
||||
*ppszError = str;
|
||||
ret = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -572,7 +622,7 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
|
||||
while (*separators)
|
||||
map[*separators++] = 1;
|
||||
while (*str && (*str >= 0xff || !map[*(const unsigned short *)str]))
|
||||
while (*str && (*str >= 0xff || !map[*str]))
|
||||
str++;
|
||||
token->end = str;
|
||||
}
|
||||
|
@ -582,7 +632,8 @@ static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
|
|||
TRACE("missing value at %s\n", debugstr_w(str));
|
||||
if (ppszError)
|
||||
*ppszError = str;
|
||||
ret = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -597,22 +648,33 @@ static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType,
|
|||
LPCWSTR *ppszError)
|
||||
{
|
||||
CERT_NAME_VALUE nameValue = { type, { 0, NULL } };
|
||||
BOOL ret = FALSE;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) *
|
||||
sizeof(WCHAR));
|
||||
if (nameValue.Value.pbData)
|
||||
if (value->end > value->start)
|
||||
{
|
||||
DWORD i;
|
||||
LPWSTR ptr = (LPWSTR)nameValue.Value.pbData;
|
||||
|
||||
for (i = 0; i < value->end - value->start; i++)
|
||||
nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) *
|
||||
sizeof(WCHAR));
|
||||
if (!nameValue.Value.pbData)
|
||||
{
|
||||
*ptr++ = value->start[i];
|
||||
if (value->start[i] == '"')
|
||||
i++;
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
if (value->end > value->start)
|
||||
{
|
||||
DWORD i;
|
||||
LPWSTR ptr = (LPWSTR)nameValue.Value.pbData;
|
||||
|
||||
for (i = 0; i < value->end - value->start; i++)
|
||||
{
|
||||
*ptr++ = value->start[i];
|
||||
if (value->start[i] == '"')
|
||||
i++;
|
||||
}
|
||||
nameValue.Value.cbData = (LPBYTE)ptr - nameValue.Value.pbData;
|
||||
}
|
||||
nameValue.Value.cbData = (LPBYTE)ptr - nameValue.Value.pbData;
|
||||
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_UNICODE_NAME_VALUE,
|
||||
&nameValue, CRYPT_ENCODE_ALLOC_FLAG, NULL, &output->pbData,
|
||||
&output->cbData);
|
||||
|
@ -690,9 +752,12 @@ static BOOL CRYPT_ValueToRDN(DWORD dwCertEncodingType, PCERT_NAME_INFO info,
|
|||
ret = CRYPT_EncodeValue(dwCertEncodingType, value,
|
||||
&info->rgRDN[info->cRDN].rgRDNAttr[0].Value, types, ppszError);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
else
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
info->cRDN++;
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -703,7 +768,7 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
CERT_NAME_INFO info = { 0, NULL };
|
||||
LPCWSTR str;
|
||||
struct KeynameKeeper keeper;
|
||||
DWORD i, error = ERROR_SUCCESS;
|
||||
DWORD i;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType,
|
||||
|
@ -712,12 +777,12 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
|
||||
CRYPT_InitializeKeynameKeeper(&keeper);
|
||||
str = pszX500;
|
||||
while (str && *str && !error && ret)
|
||||
while (str && *str && ret)
|
||||
{
|
||||
struct X500TokenW token;
|
||||
|
||||
error = CRYPT_GetNextKeyW(str, &token, ppszError);
|
||||
if (!error && token.start)
|
||||
ret = CRYPT_GetNextKeyW(str, &token, ppszError);
|
||||
if (ret && token.start)
|
||||
{
|
||||
PCCRYPT_OID_INFO keyOID;
|
||||
|
||||
|
@ -728,7 +793,8 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
{
|
||||
if (ppszError)
|
||||
*ppszError = token.start;
|
||||
error = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -739,7 +805,8 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
{
|
||||
if (ppszError)
|
||||
*ppszError = str;
|
||||
error = CRYPT_E_INVALID_X500_STRING;
|
||||
SetLastError(CRYPT_E_INVALID_X500_STRING);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -758,9 +825,9 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
sep = crlfSep;
|
||||
else
|
||||
sep = allSeps;
|
||||
error = CRYPT_GetNextValueW(str, dwStrType, sep, &token,
|
||||
ret = CRYPT_GetNextValueW(str, dwStrType, sep, &token,
|
||||
ppszError);
|
||||
if (!error)
|
||||
if (ret)
|
||||
{
|
||||
str = token.end;
|
||||
ret = CRYPT_ValueToRDN(dwCertEncodingType, &info,
|
||||
|
@ -771,25 +838,22 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
}
|
||||
}
|
||||
CRYPT_FreeKeynameKeeper(&keeper);
|
||||
if (!error)
|
||||
if (ret)
|
||||
{
|
||||
if (ppszError)
|
||||
*ppszError = NULL;
|
||||
ret = CryptEncodeObjectEx(dwCertEncodingType, X509_NAME, &info,
|
||||
0, NULL, pbEncoded, pcbEncoded);
|
||||
for (i = 0; i < info.cRDN; i++)
|
||||
{
|
||||
DWORD j;
|
||||
|
||||
for (j = 0; j < info.rgRDN[i].cRDNAttr; j++)
|
||||
LocalFree(info.rgRDN[i].rgRDNAttr[j].Value.pbData);
|
||||
CryptMemFree(info.rgRDN[i].rgRDNAttr);
|
||||
}
|
||||
CryptMemFree(info.rgRDN);
|
||||
}
|
||||
else
|
||||
for (i = 0; i < info.cRDN; i++)
|
||||
{
|
||||
SetLastError(error);
|
||||
ret = FALSE;
|
||||
DWORD j;
|
||||
|
||||
for (j = 0; j < info.rgRDN[i].cRDNAttr; j++)
|
||||
LocalFree(info.rgRDN[i].rgRDNAttr[j].Value.pbData);
|
||||
CryptMemFree(info.rgRDN[i].rgRDNAttr);
|
||||
}
|
||||
CryptMemFree(info.rgRDN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -876,8 +940,6 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
|||
sizeof(simpleAttributeOIDs[0]); i++)
|
||||
nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info);
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
if (!nameAttr)
|
||||
{
|
||||
PCERT_EXTENSION ext = CertFindExtension(altNameOID,
|
||||
|
@ -895,12 +957,14 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
|
|||
* Failing that, look for the first attribute.
|
||||
*/
|
||||
FIXME("CERT_NAME_SIMPLE_DISPLAY_TYPE: stub\n");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
|
||||
pszNameString, cchNameString);
|
||||
if (nameAttr)
|
||||
ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
|
||||
pszNameString, cchNameString);
|
||||
else
|
||||
ret = 0;
|
||||
if (info)
|
||||
LocalFree(info);
|
||||
break;
|
||||
|
|
40
reactos/include/psdk/i_cryptasn1tls.h
Normal file
40
reactos/include/psdk/i_cryptasn1tls.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Francois Gouget
|
||||
*
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_I_CRYPTASN1TLS_H
|
||||
#define __WINE_I_CRYPTASN1TLS_H
|
||||
|
||||
typedef void *ASN1decoding_t;
|
||||
typedef void *ASN1encoding_t;
|
||||
typedef void *ASN1module_t;
|
||||
typedef DWORD HCRYPTASN1MODULE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ASN1decoding_t WINAPI I_CryptGetAsn1Decoder(HCRYPTASN1MODULE);
|
||||
ASN1encoding_t WINAPI I_CryptGetAsn1Encoder(HCRYPTASN1MODULE);
|
||||
BOOL WINAPI I_CryptInstallAsn1Module(ASN1module_t, DWORD, void*);
|
||||
BOOL WINAPI I_CryptUninstallAsn1Module(HCRYPTASN1MODULE);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_I_CRYPTASN1TLS_H */
|
|
@ -26,15 +26,17 @@ extern "C" {
|
|||
|
||||
/* some typedefs for function parameters */
|
||||
typedef unsigned int ALG_ID;
|
||||
typedef unsigned long HCRYPTPROV;
|
||||
typedef unsigned long HCRYPTPROV_LEGACY;
|
||||
typedef unsigned long HCRYPTKEY;
|
||||
typedef unsigned long HCRYPTHASH;
|
||||
typedef ULONG_PTR HCRYPTPROV;
|
||||
typedef ULONG_PTR HCRYPTPROV_OR_NCRYPT_KEY_HANDLE;
|
||||
typedef ULONG_PTR HCRYPTPROV_LEGACY;
|
||||
typedef ULONG_PTR HCRYPTKEY;
|
||||
typedef ULONG_PTR HCRYPTHASH;
|
||||
typedef void *HCERTSTORE;
|
||||
typedef void *HCRYPTMSG;
|
||||
typedef void *HCERTSTOREPROV;
|
||||
typedef void *HCRYPTOIDFUNCSET;
|
||||
typedef void *HCRYPTOIDFUNCADDR;
|
||||
typedef void *HCRYPTDEFAULTCONTEXT;
|
||||
|
||||
/* CSP Structs */
|
||||
|
||||
|
@ -628,11 +630,87 @@ typedef struct _CMSG_SIGNER_INFO {
|
|||
CRYPT_ATTRIBUTES UnauthAttrs;
|
||||
} CMSG_SIGNER_INFO, *PCMSG_SIGNER_INFO;
|
||||
|
||||
typedef struct _CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA {
|
||||
DWORD cbSize;
|
||||
HCRYPTPROV hCryptProv;
|
||||
DWORD dwSignerIndex;
|
||||
DWORD dwSignerType;
|
||||
void *pvSigner;
|
||||
} CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA, *PCMSG_CTRL_VERIFY_SIGNATURE_EX_PARA;
|
||||
|
||||
#define CMSG_VERIFY_SIGNER_PUBKEY 1
|
||||
#define CMSG_VERIFY_SIGNER_CERT 2
|
||||
#define CMSG_VERIFY_SIGNER_CHAIN 3
|
||||
#define CMSG_VERIFY_SIGNER_NULL 4
|
||||
|
||||
#define CMSG_TYPE_PARAM 1
|
||||
#define CMSG_CONTENT_PARAM 2
|
||||
#define CMSG_BARE_CONTENT_PARAM 3
|
||||
#define CMSG_INNER_CONTENT_TYPE_PARAM 4
|
||||
#define CMSG_SIGNER_COUNT_PARAM 5
|
||||
#define CMSG_SIGNER_INFO_PARAM 6
|
||||
#define CMSG_SIGNER_CERT_INFO_PARAM 7
|
||||
#define CMSG_SIGNER_HASH_ALGORITHM_PARAM 8
|
||||
#define CMSG_SIGNER_AUTH_ATTR_PARAM 9
|
||||
#define CMSG_SIGNER_UNAUTH_ATTR_PARAM 10
|
||||
#define CMSG_CERT_COUNT_PARAM 11
|
||||
#define CMSG_CERT_PARAM 12
|
||||
#define CMSG_CRL_COUNT_PARAM 13
|
||||
#define CMSG_CRL_PARAM 14
|
||||
#define CMSG_ENVELOPE_ALGORITHM_PARAM 15
|
||||
#define CMSG_RECIPIENT_COUNT_PARAM 17
|
||||
#define CMSG_RECIPIENT_INDEX_PARAM 18
|
||||
#define CMSG_RECIPIENT_INFO_PARAM 19
|
||||
#define CMSG_HASH_ALGORITHM_PARAM 20
|
||||
#define CMSG_HASH_DATA_PARAM 21
|
||||
#define CMSG_COMPUTED_HASH_PARAM 22
|
||||
#define CMSG_ENCRYPT_PARAM 26
|
||||
#define CMSG_ENCRYPTED_DIGEST 27
|
||||
#define CMSG_ENCODED_SIGNER 28
|
||||
#define CMSG_ENCODED_MESSAGE 29
|
||||
#define CMSG_VERSION_PARAM 30
|
||||
#define CMSG_ATTR_CERT_COUNT_PARAM 31
|
||||
#define CMSG_ATTR_CERT_PARAM 32
|
||||
#define CMSG_CMS_RECIPIENT_COUNT_PARAM 33
|
||||
#define CMSG_CMS_RECIPIENT_INDEX_PARAM 34
|
||||
#define CMSG_CMS_RECIPIENT_ENCRYPTED_KEY_INDEX_PARAM 35
|
||||
#define CMSG_CMS_RECIPIENT_INFO_PARAM 36
|
||||
#define CMSG_UNPROTECTED_ATTR_PARAM 37
|
||||
#define CMSG_SIGNER_CERT_ID_PARAM 38
|
||||
#define CMSG_CMS_SIGNER_INFO_PARAM 39
|
||||
|
||||
#define CMSG_SIGNED_DATA_V1 1
|
||||
#define CMSG_SIGNED_DATA_V3 3
|
||||
#define CMSG_SIGNED_DATA_PKCS_1_5_VERSION CMSG_SIGNED_DATA_V1
|
||||
#define CMSG_SIGNED_DATA_CMS_VERSION CMSG_SIGNED_DATA_V3
|
||||
|
||||
#define CMSG_SIGNER_INFO_V1 1
|
||||
#define CMSG_SIGNER_INFO_V3 3
|
||||
#define CMSG_SIGNER_INFO_PKCS_1_5_VERSION CMSG_SIGNER_INFO_V1
|
||||
#define CMSG_SIGNER_INFO_CMS_VERSION CMSG_SIGNER_INFO_V3
|
||||
|
||||
#define CMSG_HASHED_DATA_V0 0
|
||||
#define CMSG_HASHED_DATA_V2 2
|
||||
#define CMSG_HASHED_DATA_PKCS_1_5_VERSION CMSG_HASHED_DATA_V0
|
||||
#define CMSG_HASHED_DATA_CMS_VERSION CMSG_HASHED_DATA_V2
|
||||
|
||||
#define CMSG_ENVELOPED_DATA_V0 0
|
||||
#define CMSG_ENVELOPED_DATA_V2 2
|
||||
#define CMSG_ENVELOPED_DATA_PKCS_1_5_VERSION CMSG_ENVELOPED_DATA_V0
|
||||
#define CMSG_ENVELOPED_DATA_CMS_VERSION CMSG_ENVELOPED_DATA_V2
|
||||
|
||||
/* CryptMsgGetAndVerifySigner flags */
|
||||
#define CMSG_TRUSTED_SIGNER_FLAG 0x1
|
||||
#define CMSG_SIGNER_ONLY_FLAG 0x2
|
||||
#define CMSG_USE_SIGNER_INDEX_FLAG 0x4
|
||||
|
||||
/* CryptMsgSignCTL flags */
|
||||
#define CMSG_CMS_ENCAPSULATED_CTL_FLAG 0x00008000
|
||||
|
||||
/* CryptMsgEncodeAndSignCTL flags */
|
||||
#define CMSG_ENCODED_SORTED_CTL_FLAG 0x1
|
||||
#define CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG 0x2
|
||||
|
||||
typedef struct _CERT_REVOCATION_CRL_INFO {
|
||||
DWORD cbSize;
|
||||
PCCRL_CONTEXT pBaseCrlContext;
|
||||
|
@ -2198,6 +2276,16 @@ static const WCHAR CERT_PHYSICAL_STORE_AUTH_ROOT_NAME[] =
|
|||
/* CertFindChainInStore dwFindType types */
|
||||
#define CERT_CHAIN_FIND_BY_ISSUER 1
|
||||
|
||||
/* CertSaveStore dwSaveAs values */
|
||||
#define CERT_STORE_SAVE_AS_STORE 1
|
||||
#define CERT_STORE_SAVE_AS_PKCS7 2
|
||||
/* CertSaveStore dwSaveTo values */
|
||||
#define CERT_STORE_SAVE_TO_FILE 1
|
||||
#define CERT_STORE_SAVE_TO_MEMORY 2
|
||||
#define CERT_STORE_SAVE_TO_FILENAME_A 3
|
||||
#define CERT_STORE_SAVE_TO_FILENAME_W 4
|
||||
#define CERT_STORE_SAVE_TO_FILENAME CERT_STORE_SAVE_TO_FILENAME_W
|
||||
|
||||
/* CERT_INFO versions/flags */
|
||||
#define CERT_V1 0
|
||||
#define CERT_V2 1
|
||||
|
@ -3132,6 +3220,10 @@ typedef struct _CERT_ID
|
|||
} DUMMYUNIONNAME;
|
||||
} CERT_ID, *PCERT_ID;
|
||||
|
||||
#define CERT_ID_ISSUER_SERIAL_NUMBER 1
|
||||
#define CERT_ID_KEY_IDENTIFIER 2
|
||||
#define CERT_ID_SHA1_HASH 3
|
||||
|
||||
#undef CMSG_DATA /* may be defined by sys/socket.h */
|
||||
#define CMSG_DATA 1
|
||||
#define CMSG_SIGNED 2
|
||||
|
@ -3498,7 +3590,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR,DWORD);
|
|||
BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList);
|
||||
BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
|
||||
DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr,
|
||||
HCRYPTOIDFUNCADDR *phFuncAddr);
|
||||
BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
|
||||
DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr,
|
||||
|
@ -3850,7 +3942,7 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv,
|
|||
DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey);
|
||||
|
||||
BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
|
||||
DWORD dwFlags, void *pvReserved, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec,
|
||||
DWORD dwFlags, void *pvReserved, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *phCryptProv, DWORD *pdwKeySpec,
|
||||
BOOL *pfCallerFreeProv);
|
||||
|
||||
BOOL WINAPI CryptProtectData( DATA_BLOB* pDataIn, LPCWSTR szDataDescr,
|
||||
|
@ -3887,9 +3979,65 @@ BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
|
|||
LPCWSTR *ppszError);
|
||||
#define CertStrToName WINELIB_NAME_AW(CertStrToName)
|
||||
|
||||
DWORD WINAPI CryptMsgCalculateEncodedLength(DWORD dwMsgEncodingType,
|
||||
DWORD dwFlags, DWORD dwMsgType, const void *pvMsgEncodeInfo,
|
||||
LPSTR pszInnerContentObjID, DWORD cbData);
|
||||
|
||||
BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg);
|
||||
|
||||
BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
|
||||
DWORD dwCtrlType, const void *pvCtrlPara);
|
||||
|
||||
BOOL WINAPI CryptMsgCountersign(HCRYPTMSG hCryptMsg, DWORD dwIndex,
|
||||
DWORD dwCountersigners, PCMSG_SIGNER_ENCODE_INFO rgCountersigners);
|
||||
|
||||
BOOL WINAPI CryptMsgCountersignEncoded(DWORD dwEncodingType, PBYTE pbSignerInfo,
|
||||
DWORD cbSignerInfo, DWORD cCountersigners,
|
||||
PCMSG_SIGNER_ENCODE_INFO rgCountersigners, PBYTE pbCountersignature,
|
||||
PDWORD pcbCountersignature);
|
||||
|
||||
HCRYPTMSG WINAPI CryptMsgDuplicate(HCRYPTMSG hCryptMsg);
|
||||
|
||||
BOOL WINAPI CryptMsgEncodeAndSignCTL(DWORD dwMsgEncodingType,
|
||||
PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
|
||||
BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
BOOL WINAPI CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, DWORD cSignerStore,
|
||||
HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner,
|
||||
DWORD *pdwSignerIndex);
|
||||
|
||||
BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
|
||||
DWORD dwIndex, void *pvData, DWORD *pcbData);
|
||||
|
||||
HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags,
|
||||
DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo,
|
||||
PCMSG_STREAM_INFO pStreamInfo);
|
||||
|
||||
HCRYPTMSG WINAPI CryptMsgOpenToEncode(DWORD dwMsgEncodingType, DWORD dwFlags,
|
||||
DWORD dwMsgType, const void *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
|
||||
PCMSG_STREAM_INFO pStreamInfo);
|
||||
|
||||
BOOL WINAPI CryptMsgSignCTL(DWORD dwMsgEncodingType, BYTE *pbCtlContent,
|
||||
DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags,
|
||||
BYTE *pbEncoded, DWORD *pcbEncoded);
|
||||
|
||||
BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData,
|
||||
DWORD cbData, BOOL fFinal);
|
||||
|
||||
BOOL WINAPI CryptMsgVerifyCountersignatureEncoded(HCRYPTPROV_LEGACY hCryptProv,
|
||||
DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo,
|
||||
PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
|
||||
PCERT_INFO pciCountersigner);
|
||||
|
||||
BOOL WINAPI CryptMsgVerifyCountersignatureEncodedEx(HCRYPTPROV_LEGACY hCryptProv,
|
||||
DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo,
|
||||
PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature,
|
||||
DWORD dwSignerType, void *pvSigner, DWORD dwFlags, void *pvReserved);
|
||||
|
||||
BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
|
||||
BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[],
|
||||
DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob);
|
||||
|
||||
BOOL WINAPI CryptSignMessageWithKey(PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara,
|
||||
const BYTE *pbToBeSigned, DWORD cbToBeSigned, BYTE *pbSignedBlob,
|
||||
DWORD *pcbSignedBlob);
|
||||
|
@ -3897,6 +4045,7 @@ BOOL WINAPI CryptSignMessageWithKey(PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara,
|
|||
BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
|
||||
DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
|
||||
BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert);
|
||||
|
||||
BOOL WINAPI CryptVerifyMessageSignatureWithKey(
|
||||
PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara,
|
||||
PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, const BYTE *pbSignedBlob,
|
||||
|
@ -3907,6 +4056,7 @@ BOOL WINAPI CryptVerifyDetachedMessageSignature(
|
|||
const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned,
|
||||
const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[],
|
||||
PCCERT_CONTEXT *ppSignerCert);
|
||||
|
||||
LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
|
||||
const BYTE *pbSignedBlob, DWORD cbSignedBlob);
|
||||
|
||||
|
@ -3914,6 +4064,7 @@ BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,
|
|||
DWORD cRecipientCert, PCCERT_CONTEXT rgpRecipientCert[],
|
||||
const BYTE *pbToBeEncrypted, DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob,
|
||||
DWORD *pcbEncryptedBlob);
|
||||
|
||||
BOOL WINAPI CryptDecryptMessage(PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
|
||||
const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted,
|
||||
DWORD *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert);
|
||||
|
@ -3923,6 +4074,7 @@ BOOL WINAPI CryptSignAndEncryptMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
|
|||
PCCERT_CONTEXT rgpRecipientCert[], const BYTE *pbToBeSignedAndEncrypted,
|
||||
DWORD cbToBeSignedAndEncrypted, BYTE *pbSignedAndEncryptedBlob,
|
||||
DWORD *pcbSignedAndEncryptedBlob);
|
||||
|
||||
BOOL WINAPI CryptDecryptAndVerifyMessageSignature(
|
||||
PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
|
||||
PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex,
|
||||
|
|
Loading…
Reference in a new issue