---
dlls/dssenh/Makefile.in | 5 +-
dlls/dssenh/cryptoprovconfig.h | 85 +++++
dlls/dssenh/dssenh.c | 96 ++++-
dlls/dssenh/dssenh.rgs | 28 ++
dlls/rsaenh/Makefile.in | 3 +-
dlls/rsaenh/cryptoprovconfig.h | 88 +++++
dlls/rsaenh/cryptoprovutils.c | 649 ++++++++++++++++++++++++++++++++
dlls/rsaenh/cryptoprovutils.h | 81 ++++
dlls/rsaenh/rsaenh.c | 656 +--------------------------------
9 files changed, 1026 insertions(+), 665 deletions(-)
create mode 100644 dlls/dssenh/cryptoprovconfig.h
create mode 100644 dlls/rsaenh/cryptoprovconfig.h
create mode 100644 dlls/rsaenh/cryptoprovutils.c
create mode 100644 dlls/rsaenh/cryptoprovutils.h
diff --git a/dlls/dssenh/Makefile.in b/dlls/dssenh/Makefile.in
index 54295f99ba..cb34ad3ae2 100644
--- a/dlls/dssenh/Makefile.in
+++ b/dlls/dssenh/Makefile.in
@@ -1,10 +1,13 @@
MODULE = dssenh.dll
IMPORTLIB = dssenh
IMPORTS = bcrypt crypt32 advapi32
+EXTRAINCL = -I$(top_srcdir)/dlls/
EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
- dssenh.c
+ dssenh.c \
+ ../rsaenh/cryptoprovutils.c \
+ ../rsaenh/handle.c
RC_SRCS = rsrc.rc
diff --git a/dlls/dssenh/cryptoprovconfig.h b/dlls/dssenh/cryptoprovconfig.h
new file mode 100644
index 0000000000..f6e307bc96
--- /dev/null
+++ b/dlls/dssenh/cryptoprovconfig.h
@@ -0,0 +1,85 @@
+/*
+ * dlls/rsaenh/cryptoprovconfig.h
+ * Definitions of some constants used by crypto provider.
+ * It is copied to build dir then included by cryptoprovutils.h,
+ * the build dir comes first in include search paths.
+ * So a new provider implementation only needs to provide its own
+ * cryptoprovconfig.h.
+ *
+ * Copyright 2002 TransGaming Technologies (David Hammerton)
+ * Copyright 2004 Mike McCormack for CodeWeavers
+ * Copyright 2004, 2005 Michael Jung
+ * Copyright 2007 Vijay Kiran Kamuju
+ *
+ * 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_CRYPTOPROVCONFIG_H
+#define __WINE_CRYPTOPROVCONFIG_H
+#define DSSENH_MAGIC_KEY 0x73620457u
+#define DSSENH_MAX_KEY_SIZE 64
+#define DSSENH_MAX_BLOCK_SIZE 24
+#define DSSENH_MAGIC_CONTAINER 0x26384993u
+#define DSSENH_REGKEY "Software\\Wine\\Crypto\\DSS\\%s"
+
+#define CRYPTO_PROV_MAGIC_KEY DSSENH_MAGIC_KEY
+#define CRYPTO_PROV_MAX_KEY_SIZE DSSENH_MAX_KEY_SIZE
+#define CRYPTO_PROV_MAX_BLOCK_SIZE DSSENH_MAX_BLOCK_SIZE
+#define CRYPTO_PROV_MAGIC_CONTAINER DSSENH_MAGIC_CONTAINER
+#define CRYPTO_PROV_REGKEY DSSENH_REGKEY
+
+/******************************************************************************
+ * CRYPTKEY - key objects
+ */
+#define DSSENH_KEYSTATE_IDLE 0
+#define DSSENH_KEYSTATE_ENCRYPTING 1
+#define DSSENH_KEYSTATE_MASTERKEY 2
+typedef struct _DSSENH_SCHANNEL_INFO
+{
+ SCHANNEL_ALG saEncAlg;
+ SCHANNEL_ALG saMACAlg;
+ CRYPT_DATA_BLOB blobClientRandom;
+ CRYPT_DATA_BLOB blobServerRandom;
+} DSSENH_SCHANNEL_INFO;
+#define CRYPTO_PROV_SCHANNEL_INFO DSSENH_SCHANNEL_INFO
+
+/******************************************************************************
+ * KEYCONTAINER - key containers
+ */
+#define DSSENH_PERSONALITY_BASE 0u
+#define DSSENH_PERSONALITY_BASE_DH 1u
+#define DSSENH_PERSONALITY_ENHANCED 2u
+#define DSSENH_PERSONALITY_SCHANNEL 3u
+
+/******************************************************************************
+ * Used by new_key_container to determine the personality via provider name.
+ * The first entry in aProvNamePersonalityPairs should be the default
personality.
+ */
+typedef struct tagPROVNAMEPERSONALITYPAIR
+{
+ LPCSTR pszProvName;
+ DWORD dwPersonality;
+} PROVNAMEPERSONALITYPAIR;
+
+static const DWORD dwNProvNamePersonalityPairs = 0;
+static const PROVNAMEPERSONALITYPAIR aProvNamePersonalityPairs[6] =
+{
+ {"", DSSENH_PERSONALITY_ENHANCED},
+ {MS_DEF_DSS_PROV_A, DSSENH_PERSONALITY_BASE},
+ {MS_DEF_DSS_DH_PROV_A, DSSENH_PERSONALITY_BASE_DH},
+ {MS_DEF_DH_SCHANNEL_PROV_A, DSSENH_PERSONALITY_SCHANNEL}
+};
+
+#endif /* __WINE_CRYPTOPROVCONFIG_H */
diff --git a/dlls/dssenh/dssenh.c b/dlls/dssenh/dssenh.c
index 5dc5464724..a3c8af8f48 100644
--- a/dlls/dssenh/dssenh.c
+++ b/dlls/dssenh/dssenh.c
@@ -21,21 +21,39 @@
#include "windef.h"
#include "winbase.h"
+#include "winreg.h"
#include "wincrypt.h"
+#include "objbase.h"
+#include "rpcproxy.h"
+#include "rsaenh/handle.h"
+#include "rsaenh/cryptoprovutils.h"
#include "wine/debug.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(dssenh);
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+static HINSTANCE instance;
+
+/******************************************************************************
+ * CSP's handle table (used by all acquired key containers)
+ */
+struct handle_table handle_table;
+
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID reserved)
{
- TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
+ TRACE("(0x%p, %d, %p)\n", hInstance, fdwReason, reserved);
switch (fdwReason)
{
- case DLL_WINE_PREATTACH:
- return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hinstDLL);
+ instance = hInstance;
+ DisableThreadLibraryCalls(hInstance);
+ init_handle_table(&handle_table);
+ break;
+
+ case DLL_PROCESS_DETACH:
+ if (reserved) break;
+ destroy_handle_table(&handle_table);
break;
}
return TRUE;
@@ -46,8 +64,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD
fdwReason, LPVOID lpvReserved)
*/
HRESULT WINAPI DllRegisterServer(void)
{
- FIXME("Not implemented.\n");
- return E_UNEXPECTED;
+ return __wine_register_resources( instance );
}
/*****************************************************
@@ -55,8 +72,63 @@ HRESULT WINAPI DllRegisterServer(void)
*/
HRESULT WINAPI DllUnregisterServer(void)
{
- FIXME("Not implemented.\n");
- return E_UNEXPECTED;
+ return __wine_unregister_resources( instance );
+}
+
+/******************************************************************************
+ * crypt_export_key [Internal]
+ *
+ * Export a key into a binary large object (BLOB). Called by CPExportKey and
+ * by store_key_pair.
+ *
+ * PARAMS
+ * pCryptKey [I] Key to be exported.
+ * hPubKey [I] Key used to encrypt sensitive BLOB data.
+ * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB.
+ * dwFlags [I] Currently none defined.
+ * force [I] If TRUE, the key is written no matter what the key's
+ * permissions are. Otherwise the key's permissions are
+ * checked before exporting.
+ * pbData [O] Pointer to a buffer where the BLOB will be written to.
+ * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB
+ *
+ * RETURNS
+ * Success: TRUE.
+ * Failure: FALSE.
+ */
+BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey,
+ DWORD dwBlobType, DWORD dwFlags, BOOL force,
+ BYTE *pbData, DWORD *pdwDataLen)
+{
+ FIXME("stub\n");
+ return FALSE;
+}
+
+/******************************************************************************
+ * import_key [Internal]
+ *
+ * Import a BLOB'ed key into a key container, optionally storing the key's
+ * value to the registry.
+ *
+ * PARAMS
+ * hProv [I] Key container into which the key is to be imported.
+ * pbData [I] Pointer to a buffer which holds the BLOB.
+ * dwDataLen [I] Length of data in buffer at pbData.
+ * hPubKey [I] Key used to decrypt sensitive BLOB data.
+ * dwFlags [I] One of:
+ * CRYPT_EXPORTABLE: the imported key is marked exportable
+ * fStoreKey [I] If TRUE, the imported key is stored to the registry.
+ * phKey [O] Handle to the imported key.
+ *
+ * RETURNS
+ * Success: TRUE.
+ * Failure: FALSE.
+ */
+BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD
dwDataLen, HCRYPTKEY hPubKey,
+ DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
+{
+ FIXME("stub\n");
+ return FALSE;
}
/******************************************************************************
@@ -87,8 +159,7 @@ HRESULT WINAPI DllUnregisterServer(void)
BOOL WINAPI DSSENH_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer,
DWORD dwFlags, PVTableProvStruc pVTable)
{
- FIXME("stub\n");
- return FALSE;
+ return CRYPTO_PROV_CPAcquireContext(phProv, pszContainer,
dwFlags, pVTable);
}
/******************************************************************************
@@ -573,8 +644,7 @@ BOOL WINAPI DSSENH_CPImportKey(HCRYPTPROV hProv,
const BYTE *pbData, DWORD dwDat
*/
BOOL WINAPI DSSENH_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
{
- FIXME("stub\n");
- return FALSE;
+ return CRYPTO_PROV_CPReleaseContext(hProv, dwFlags);
}
/******************************************************************************
diff --git a/dlls/dssenh/dssenh.rgs b/dlls/dssenh/dssenh.rgs
index 19899cb516..e16d8e0bc7 100644
--- a/dlls/dssenh/dssenh.rgs
+++ b/dlls/dssenh/dssenh.rgs
@@ -16,6 +16,24 @@ HKLM
val 'Signature' = b deadbeef
val 'Type' = d 13
}
+ ForceRemove 'Microsoft Base DSS and
Diffie-Hellman Cryptographic Provider'
+ {
+ val 'Image Path' = s '%MODULE%'
+ val 'Signature' = b deadbeef
+ val 'Type' = d 13
+ }
+ ForceRemove 'Microsoft Base DSS Cryptographic Provider'
+ {
+ val 'Image Path' = s '%MODULE%'
+ val 'Signature' = b deadbeef
+ val 'Type' = d 3
+ }
+ ForceRemove 'Microsoft DH SChannel
Cryptographic Provider'
+ {
+ val 'Image Path' = s '%MODULE%'
+ val 'Signature' = b deadbeef
+ val 'Type' = d 18
+ }
}
NoRemove 'Provider Types'
{
@@ -24,6 +42,16 @@ HKLM
val 'Name' = s 'Microsoft Enhanced DSS
and Diffie-Hellman Cryptographic Provider'
val 'TypeName' = s 'DSS Signature with
Diffe-zhellman Key Exchange'
}
+ ForceRemove 'Type 003'
+ {
+ val 'Name' = s 'Microsoft Base DSS
Cryptographic Provider'
+ val 'TypeName' = s 'DSS Signature'
+ }
+ ForceRemove 'Type 018'
+ {
+ val 'Name' = s 'Microsoft DH SChannel
Cryptographic Provider'
+ val 'TypeName' = s 'Diffie-Hellman SChannel'
+ }
}
}
}
diff --git a/dlls/rsaenh/Makefile.in b/dlls/rsaenh/Makefile.in
index 80680d6622..dd8574fcaf 100644
--- a/dlls/rsaenh/Makefile.in
+++ b/dlls/rsaenh/Makefile.in
@@ -13,6 +13,7 @@ C_SRCS = \
rc2.c \
rc4.c \
rsa.c \
- rsaenh.c
+ rsaenh.c \
+ cryptoprovutils.c
RC_SRCS = rsrc.rc
diff --git a/dlls/rsaenh/cryptoprovconfig.h b/dlls/rsaenh/cryptoprovconfig.h
new file mode 100644
index 0000000000..667bb475ac
--- /dev/null
+++ b/dlls/rsaenh/cryptoprovconfig.h
@@ -0,0 +1,88 @@
+/*
+ * dlls/rsaenh/cryptoprovconfig.h
+ * Definitions of some constants used by crypto provider.
+ * It is copied to build dir then included by cryptoprovutils.h,
+ * the build dir comes first in include search paths.
+ * So a new provider implementation only needs to provide its own
+ * cryptoprovconfig.h.
+ *
+ * Copyright 2002 TransGaming Technologies (David Hammerton)
+ * Copyright 2004 Mike McCormack for CodeWeavers
+ * Copyright 2004, 2005 Michael Jung
+ * Copyright 2007 Vijay Kiran Kamuju
+ *
+ * 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_CRYPTOPROVCONFIG_H
+#define __WINE_CRYPTOPROVCONFIG_H
+#define RSAENH_MAGIC_KEY 0x73620457u
+#define RSAENH_MAX_KEY_SIZE 64
+#define RSAENH_MAX_BLOCK_SIZE 24
+#define RSAENH_MAGIC_CONTAINER 0x26384993u
+#define RSAENH_REGKEY "Software\\Wine\\Crypto\\RSA\\%s"
+
+#define CRYPTO_PROV_MAGIC_KEY RSAENH_MAGIC_KEY
+#define CRYPTO_PROV_MAX_KEY_SIZE RSAENH_MAX_KEY_SIZE
+#define CRYPTO_PROV_MAX_BLOCK_SIZE RSAENH_MAX_BLOCK_SIZE
+#define CRYPTO_PROV_MAGIC_CONTAINER RSAENH_MAGIC_CONTAINER
+#define CRYPTO_PROV_REGKEY RSAENH_REGKEY
+
+/******************************************************************************
+ * CRYPTKEY - key objects
+ */
+#define RSAENH_KEYSTATE_IDLE 0
+#define RSAENH_KEYSTATE_ENCRYPTING 1
+#define RSAENH_KEYSTATE_MASTERKEY 2
+typedef struct _RSAENH_SCHANNEL_INFO
+{
+ SCHANNEL_ALG saEncAlg;
+ SCHANNEL_ALG saMACAlg;
+ CRYPT_DATA_BLOB blobClientRandom;
+ CRYPT_DATA_BLOB blobServerRandom;
+} RSAENH_SCHANNEL_INFO;
+#define CRYPTO_PROV_SCHANNEL_INFO RSAENH_SCHANNEL_INFO
+
+/******************************************************************************
+ * KEYCONTAINER - key containers
+ */
+#define RSAENH_PERSONALITY_BASE 0u
+#define RSAENH_PERSONALITY_STRONG 1u
+#define RSAENH_PERSONALITY_ENHANCED 2u
+#define RSAENH_PERSONALITY_SCHANNEL 3u
+#define RSAENH_PERSONALITY_AES 4u
+
+/******************************************************************************
+ * Used by new_key_container to determine the personality via provider name.
+ * The first entry in aProvNamePersonalityPairs should be the default
personality.
+ */
+typedef struct tagPROVNAMEPERSONALITYPAIR
+{
+ LPCSTR pszProvName;
+ DWORD dwPersonality;
+} PROVNAMEPERSONALITYPAIR;
+
+static const DWORD dwNProvNamePersonalityPairs = 6;
+static const PROVNAMEPERSONALITYPAIR aProvNamePersonalityPairs[6] =
+{
+ {"", RSAENH_PERSONALITY_STRONG},
+ {MS_DEF_PROV_A, RSAENH_PERSONALITY_BASE},
+ {MS_ENHANCED_PROV_A, RSAENH_PERSONALITY_ENHANCED},
+ {MS_DEF_RSA_SCHANNEL_PROV_A, RSAENH_PERSONALITY_SCHANNEL},
+ {MS_ENH_RSA_AES_PROV_A, RSAENH_PERSONALITY_AES},
+ {MS_ENH_RSA_AES_PROV_XP_A, RSAENH_PERSONALITY_AES}
+};
+
+#endif /* __WINE_CRYPTOPROVCONFIG_H */
diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c
new file mode 100644
index 0000000000..c37c4e7925
--- /dev/null
+++ b/dlls/rsaenh/cryptoprovutils.c
@@ -0,0 +1,649 @@
+/*
+ * dlls/rsaenh/cryptoprovutils.c
+ * Utility functions to implement crypto privider.
+ *
+ * Copyright 2002 TransGaming Technologies (David Hammerton)
+ * Copyright 2004 Mike McCormack for CodeWeavers
+ * Copyright 2004, 2005 Michael Jung
+ * Copyright 2007 Vijay Kiran Kamuju
+ *
+ * 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 <stdio.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "wincrypt.h"
+#include "handle.h"
+#include "cryptoprovutils.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+extern struct handle_table handle_table;
+
+/******************************************************************************
+ * create_container_key [Internal]
+ *
+ * Creates the registry key for a key container's persistent storage.
+ *
+ * PARAMS
+ * pKeyContainer [I] Pointer to the key container
+ * sam [I] Desired registry access
+ * phKey [O] Returned key
+ */
+BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey)
+{
+ CHAR szBase[sizeof(CRYPTO_PROV_REGKEY) + MAX_PATH];
+ HKEY hRootKey;
+
+ sprintf(szBase, CRYPTO_PROV_REGKEY, pKeyContainer->szName);
+
+ if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET)
+ hRootKey = HKEY_LOCAL_MACHINE;
+ else
+ hRootKey = HKEY_CURRENT_USER;
+
+ /* @@ Wine registry key: HKLM\Software\Wine\Crypto\[CRYPTO_PROV] */
+ /* @@ Wine registry key: HKCU\Software\Wine\Crypto\[CRYPTO_PROV] */
+ return RegCreateKeyExA(hRootKey, szBase, 0, NULL,
+ REG_OPTION_NON_VOLATILE, sam, NULL, phKey, NULL)
+ == ERROR_SUCCESS;
+}
+
+/******************************************************************************
+ * open_container_key [Internal]
+ *
+ * Opens a key container's persistent storage for reading.
+ *
+ * PARAMS
+ * pszContainerName [I] Name of the container to be opened. May be the empty
+ * string if the parent key of all containers is to be
+ * opened.
+ * dwFlags [I] Flags indicating which keyset to be opened.
+ * phKey [O] Returned key
+ */
+BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags,
REGSAM access, HKEY *phKey)
+{
+ CHAR szRegBase[sizeof(CRYPTO_PROV_REGKEY) + MAX_PATH];
+ HKEY hRootKey;
+
+ sprintf(szRegBase, CRYPTO_PROV_REGKEY, pszContainerName);
+
+ if (dwFlags & CRYPT_MACHINE_KEYSET)
+ hRootKey = HKEY_LOCAL_MACHINE;
+ else
+ hRootKey = HKEY_CURRENT_USER;
+
+ /* @@ Wine registry key: HKLM\Software\Wine\Crypto\[CRYPTO_PROV] */
+ /* @@ Wine registry key: HKCU\Software\Wine\Crypto\[CRYPTO_PROV] */
+ return RegOpenKeyExA(hRootKey, szRegBase, 0, access, phKey) ==
+ ERROR_SUCCESS;
+}
+
+/******************************************************************************
+ * delete_container_key [Internal]
+ *
+ * Deletes a key container's persistent storage.
+ *
+ * PARAMS
+ * pszContainerName [I] Name of the container to be opened.
+ * dwFlags [I] Flags indicating which keyset to be opened.
+ */
+static BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags)
+{
+ CHAR szRegKey[sizeof(CRYPTO_PROV_REGKEY) + MAX_PATH];
+ HKEY hRootKey;
+
+ sprintf(szRegKey, CRYPTO_PROV_REGKEY, pszContainerName);
+
+ if (dwFlags & CRYPT_MACHINE_KEYSET)
+ hRootKey = HKEY_LOCAL_MACHINE;
+ else
+ hRootKey = HKEY_CURRENT_USER;
+ if (!RegDeleteKeyA(hRootKey, szRegKey)) {
+ SetLastError(ERROR_SUCCESS);
+ return TRUE;
+ } else {
+ SetLastError(NTE_BAD_KEYSET);
+ return FALSE;
+ }
+}
+
+/******************************************************************************
+ * new_key_container [Internal]
+ *
+ * Create a new key container. The personality of the CSP is determined via
+ * the pVTable->pszProvName string.
+ *
+ * PARAMS
+ * pszContainerName [I] Name of the key container.
+ * pVTable [I] Callback functions and context info provided by the OS
+ *
+ * RETURNS
+ * Success: Handle to the new key container.
+ * Failure: INVALID_HANDLE_VALUE
+ */
+HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags,
const VTableProvStruc *pVTable)
+{
+ KEYCONTAINER *pKeyContainer;
+ HCRYPTPROV hKeyContainer;
+ DWORD i;
+
+ hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER),
+ CRYPTO_PROV_MAGIC_CONTAINER, destroy_key_container,
+ (OBJECTHDR**)&pKeyContainer);
+ if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE)
+ {
+ lstrcpynA(pKeyContainer->szName, pszContainerName, MAX_PATH);
+ pKeyContainer->dwFlags = dwFlags;
+ pKeyContainer->dwEnumAlgsCtr = 0;
+ pKeyContainer->hKeyExchangeKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE;
+ pKeyContainer->hSignatureKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE;
+ if (pVTable && pVTable->pszProvName) {
+ lstrcpynA(pKeyContainer->szProvName,
pVTable->pszProvName, MAX_PATH);
+ pKeyContainer->dwPersonality
+ = aProvNamePersonalityPairs[0].dwPersonality;
+ for (i = 1; i < dwNProvNamePersonalityPairs; i++) {
+ if (!strcmp(pVTable->pszProvName,
+ aProvNamePersonalityPairs[i].pszProvName)) {
+ pKeyContainer->dwPersonality
+ = aProvNamePersonalityPairs[i].dwPersonality;
+ break;
+ }
+ }
+ }
+
+ /* The new key container has to be inserted into the CSP immediately
+ * after creation to be available for CPGetProvParam's
PP_ENUMCONTAINERS. */
+ if (!(dwFlags & CRYPT_VERIFYCONTEXT)) {
+ HKEY hKey;
+
+ if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
+ RegCloseKey(hKey);
+ }
+ }
+
+ return hKeyContainer;
+}
+
+/******************************************************************************
+ * destroy_key_container [Internal]
+ *
+ * Destructor for key containers.
+ *
+ * PARAMS
+ * pObjectHdr [I] Pointer to the key container to be destroyed.
+ */
+void destroy_key_container(OBJECTHDR *pObjectHdr)
+{
+ KEYCONTAINER *pKeyContainer = (KEYCONTAINER*)pObjectHdr;
+
+ if (!(pKeyContainer->dwFlags & CRYPT_VERIFYCONTEXT))
+ {
+ store_key_container_keys(pKeyContainer);
+ store_key_container_permissions(pKeyContainer);
+ release_key_container_keys(pKeyContainer);
+ }
+ else
+ release_key_container_keys(pKeyContainer);
+ HeapFree( GetProcessHeap(), 0, pKeyContainer );
+}
+
+/******************************************************************************
+ * store_key_container_keys [Internal]
+ *
+ * Stores key container's keys in a persistent location.
+ *
+ * PARAMS
+ * pKeyContainer [I] Pointer to the key container whose keys are to be saved
+ */
+void store_key_container_keys(KEYCONTAINER *pKeyContainer)
+{
+ HKEY hKey;
+ DWORD dwFlags;
+
+ /* On WinXP, persistent keys are stored in a file located at:
+ * $AppData$\\Microsoft\\Crypto\\[CRYPTO_PROV]\\$SID$\\some_hex_string
+ */
+
+ if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET)
+ dwFlags = CRYPTPROTECT_LOCAL_MACHINE;
+ else
+ dwFlags = 0;
+
+ if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
+ {
+ store_key_pair(pKeyContainer->hKeyExchangeKeyPair, hKey,
+ AT_KEYEXCHANGE, dwFlags);
+ store_key_pair(pKeyContainer->hSignatureKeyPair, hKey,
+ AT_SIGNATURE, dwFlags);
+ RegCloseKey(hKey);
+ }
+}
+
+/******************************************************************************
+ * store_key_pair [Internal]
+ *
+ * Stores a key pair to the registry
+ *
+ * PARAMS
+ * hCryptKey [I] Handle to the key to be stored
+ * hKey [I] Registry key where the key pair is to be stored
+ * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
+ * dwFlags [I] Flags for protecting the key
+ */
+void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec,
DWORD dwFlags)
+{
+ LPCSTR szValueName;
+ DATA_BLOB blobIn, blobOut;
+ CRYPTKEY *pKey;
+ DWORD dwLen;
+ BYTE *pbKey;
+
+ if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec)))
+ return;
+ if (lookup_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY,
+ (OBJECTHDR**)&pKey))
+ {
+ if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, 0, &dwLen))
+ {
+ pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen);
+ if (pbKey)
+ {
+ if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, pbKey,
+ &dwLen))
+ {
+ blobIn.pbData = pbKey;
+ blobIn.cbData = dwLen;
+
+ if (CryptProtectData(&blobIn, NULL, NULL, NULL, NULL,
+ dwFlags, &blobOut))
+ {
+ RegSetValueExA(hKey, szValueName, 0, REG_BINARY,
+ blobOut.pbData, blobOut.cbData);
+ LocalFree(blobOut.pbData);
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, pbKey);
+ }
+ }
+ }
+}
+
+/******************************************************************************
+ * store_key_container_permissions [Internal]
+ *
+ * Stores key container's key permissions in a persistent location.
+ *
+ * PARAMS
+ * pKeyContainer [I] Pointer to the key container whose key permissions are to
+ * be saved
+ */
+void store_key_container_permissions(KEYCONTAINER *pKeyContainer)
+{
+ HKEY hKey;
+
+ if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
+ {
+ store_key_permissions(pKeyContainer->hKeyExchangeKeyPair, hKey,
+ AT_KEYEXCHANGE);
+ store_key_permissions(pKeyContainer->hSignatureKeyPair, hKey,
+ AT_SIGNATURE);
+ RegCloseKey(hKey);
+ }
+}
+
+/******************************************************************************
+ * store_key_permissions [Internal]
+ *
+ * Stores a key's permissions to the registry
+ *
+ * PARAMS
+ * hCryptKey [I] Handle to the key whose permissions are to be stored
+ * hKey [I] Registry key where the key permissions are to be stored
+ * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
+ */
+void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec)
+{
+ LPCSTR szValueName;
+ CRYPTKEY *pKey;
+
+ if (!(szValueName = map_key_spec_to_permissions_name(dwKeySpec)))
+ return;
+ if (lookup_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY,
+ (OBJECTHDR**)&pKey))
+ RegSetValueExA(hKey, szValueName, 0, REG_DWORD,
+ (BYTE *)&pKey->dwPermissions,
+ sizeof(pKey->dwPermissions));
+}
+
+/******************************************************************************
+ * release_key_container_keys [Internal]
+ *
+ * Releases key container's keys.
+ *
+ * PARAMS
+ * pKeyContainer [I] Pointer to the key container whose keys are to
be released.
+ */
+void release_key_container_keys(KEYCONTAINER *pKeyContainer)
+{
+ release_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair,
+ CRYPTO_PROV_MAGIC_KEY);
+ release_handle(&handle_table, pKeyContainer->hSignatureKeyPair,
+ CRYPTO_PROV_MAGIC_KEY);
+}
+
+/******************************************************************************
+ * map_key_spec_to_key_pair_name [Internal]
+ *
+ * Returns the name of the registry value associated with a key spec.
+ *
+ * PARAMS
+ * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
+ *
+ * RETURNS
+ * Success: Name of registry value.
+ * Failure: NULL
+ */
+LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec)
+{
+ LPCSTR szValueName;
+
+ switch (dwKeySpec)
+ {
+ case AT_KEYEXCHANGE:
+ szValueName = "KeyExchangeKeyPair";
+ break;
+ case AT_SIGNATURE:
+ szValueName = "SignatureKeyPair";
+ break;
+ default:
+ WARN("invalid key spec %d\n", dwKeySpec);
+ szValueName = NULL;
+ }
+ return szValueName;
+}
+
+/******************************************************************************
+ * map_key_spec_to_permissions_name [Internal]
+ *
+ * Returns the name of the registry value associated with the permissions for
+ * a key spec.
+ *
+ * PARAMS
+ * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
+ *
+ * RETURNS
+ * Success: Name of registry value.
+ * Failure: NULL
+ */
+LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec)
+{
+ LPCSTR szValueName;
+
+ switch (dwKeySpec)
+ {
+ case AT_KEYEXCHANGE:
+ szValueName = "KeyExchangePermissions";
+ break;
+ case AT_SIGNATURE:
+ szValueName = "SignaturePermissions";
+ break;
+ default:
+ WARN("invalid key spec %d\n", dwKeySpec);
+ szValueName = NULL;
+ }
+ return szValueName;
+}
+
+/******************************************************************************
+ * read_key_value [Internal]
+ *
+ * Reads a key pair value from the registry
+ *
+ * PARAMS
+ * hKeyContainer [I] Crypt provider to use to import the key
+ * hKey [I] Registry key from which to read the key pair
+ * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
+ * dwFlags [I] Flags for unprotecting the key
+ * phCryptKey [O] Returned key
+ */
+static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD
dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey)
+{
+ LPCSTR szValueName;
+ DWORD dwValueType, dwLen;
+ BYTE *pbKey;
+ DATA_BLOB blobIn, blobOut;
+ BOOL ret = FALSE;
+
+ if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec)))
+ return FALSE;
+ if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, NULL, &dwLen) ==
+ ERROR_SUCCESS)
+ {
+ pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen);
+ if (pbKey)
+ {
+ if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType,
pbKey, &dwLen) ==
+ ERROR_SUCCESS)
+ {
+ blobIn.pbData = pbKey;
+ blobIn.cbData = dwLen;
+
+ if (CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL,
+ dwFlags, &blobOut))
+ {
+ ret = import_key(hKeyContainer, blobOut.pbData,
blobOut.cbData, 0, 0,
+ FALSE, phCryptKey);
+ LocalFree(blobOut.pbData);
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, pbKey);
+ }
+ }
+ if (ret)
+ {
+ CRYPTKEY *pKey;
+
+ if (lookup_handle(&handle_table, *phCryptKey, CRYPTO_PROV_MAGIC_KEY,
+ (OBJECTHDR**)&pKey))
+ {
+ if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec)))
+ {
+ dwLen = sizeof(pKey->dwPermissions);
+ RegQueryValueExA(hKey, szValueName, 0, NULL,
+ (BYTE *)&pKey->dwPermissions, &dwLen);
+ }
+ }
+ }
+ return ret;
+}
+
+/******************************************************************************
+ * read_key_container [Internal]
+ *
+ * Tries to read the persistent state of the key container (mainly
the signature
+ * and key exchange private keys) given by pszContainerName.
+ *
+ * PARAMS
+ * pszContainerName [I] Name of the key container to read from the registry
+ * pVTable [I] Pointer to context data provided by the
operating system
+ *
+ * RETURNS
+ * Success: Handle to the key container read from the registry
+ * Failure: INVALID_HANDLE_VALUE
+ */
+static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD
dwFlags, const VTableProvStruc *pVTable)
+{
+ HKEY hKey;
+ KEYCONTAINER *pKeyContainer;
+ HCRYPTPROV hKeyContainer;
+ HCRYPTKEY hCryptKey;
+
+ if (!open_container_key(pszContainerName, dwFlags, KEY_READ, &hKey))
+ {
+ SetLastError(NTE_BAD_KEYSET);
+ return (HCRYPTPROV)INVALID_HANDLE_VALUE;
+ }
+
+ hKeyContainer = new_key_container(pszContainerName, dwFlags, pVTable);
+ if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE)
+ {
+ DWORD dwProtectFlags = (dwFlags & CRYPT_MACHINE_KEYSET) ?
+ CRYPTPROTECT_LOCAL_MACHINE : 0;
+
+ if (!lookup_handle(&handle_table, hKeyContainer,
CRYPTO_PROV_MAGIC_CONTAINER,
+ (OBJECTHDR**)&pKeyContainer))
+ return (HCRYPTPROV)INVALID_HANDLE_VALUE;
+
+ /* read_key_value calls import_key, which calls import_private_key,
+ * which implicitly installs the key value into the appropriate key
+ * container key. Thus the ref count is incremented twice, once for
+ * the output key value, and once for the implicit install, and needs
+ * to be decremented to balance the two.
+ */
+ if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE,
+ dwProtectFlags, &hCryptKey))
+ release_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY);
+ if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE,
+ dwProtectFlags, &hCryptKey))
+ release_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY);
+ }
+
+ return hKeyContainer;
+}
+
+/******************************************************************************
+ * CPAcquireContext (CRYPTO_PROV_PFX.@)
+ *
+ * Acquire a handle to the key container specified by pszContainer
+ *
+ * PARAMS
+ * phProv [O] Pointer to the location the acquired handle will
be written to.
+ * pszContainer [I] Name of the desired key container. See Notes
+ * dwFlags [I] Flags. See Notes.
+ * pVTable [I] Pointer to a PVTableProvStruct containing callbacks.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ *
+ * NOTES
+ * If pszContainer is NULL or points to a zero length string the user's login
+ * name will be used as the key container name.
+ *
+ * If the CRYPT_NEW_KEYSET flag is set in dwFlags a new keyset will
be created.
+ * If a keyset with the given name already exists, the function fails and sets
+ * last error to NTE_EXISTS. If CRYPT_NEW_KEYSET is not set and the specified
+ * key container does not exist, function fails and sets last error to
+ * NTE_BAD_KEYSET.
+ */
+BOOL CRYPTO_PROV_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer,
+ DWORD dwFlags, PVTableProvStruc pVTable)
+{
+ CHAR szKeyContainerName[MAX_PATH];
+
+ TRACE("(phProv=%p, pszContainer=%s, dwFlags=%08x, pVTable=%p)\n", phProv,
+ debugstr_a(pszContainer), dwFlags, pVTable);
+
+ if (pszContainer && *pszContainer)
+ {
+ lstrcpynA(szKeyContainerName, pszContainer, MAX_PATH);
+ }
+ else
+ {
+ DWORD dwLen = sizeof(szKeyContainerName);
+ if (!GetUserNameA(szKeyContainerName, &dwLen)) return FALSE;
+ }
+
+ switch (dwFlags & (CRYPT_NEWKEYSET|CRYPT_VERIFYCONTEXT|CRYPT_DELETEKEYSET))
+ {
+ case 0:
+ *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable);
+ break;
+
+ case CRYPT_DELETEKEYSET:
+ return delete_container_key(szKeyContainerName, dwFlags);
+
+ case CRYPT_NEWKEYSET:
+ *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable);
+ if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE)
+ {
+ release_handle(&handle_table, *phProv,
CRYPTO_PROV_MAGIC_CONTAINER);
+ TRACE("Can't create new keyset, already exists\n");
+ SetLastError(NTE_EXISTS);
+ return FALSE;
+ }
+ *phProv = new_key_container(szKeyContainerName, dwFlags, pVTable);
+ break;
+
+ case CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET:
+ case CRYPT_VERIFYCONTEXT:
+ if (pszContainer && *pszContainer) {
+ TRACE("pszContainer should be empty\n");
+ SetLastError(NTE_BAD_FLAGS);
+ return FALSE;
+ }
+ *phProv = new_key_container("", dwFlags, pVTable);
+ break;
+
+ default:
+ *phProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
+ SetLastError(NTE_BAD_FLAGS);
+ return FALSE;
+ }
+
+ if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
+ SetLastError(ERROR_SUCCESS);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/******************************************************************************
+ * CPReleaseContext (CRYPTO_PROV.@)
+ *
+ * Release a key container.
+ *
+ * PARAMS
+ * hProv [I] Key container to be released.
+ * dwFlags [I] Currently none defined.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL CRYPTO_PROV_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
+{
+ TRACE("(hProv=%08lx, dwFlags=%08x)\n", hProv, dwFlags);
+
+ if (!release_handle(&handle_table, hProv, CRYPTO_PROV_MAGIC_CONTAINER))
+ {
+ /* MSDN: hProv not containing valid context handle */
+ SetLastError(NTE_BAD_UID);
+ return FALSE;
+ }
+
+ if (dwFlags) {
+ SetLastError(NTE_BAD_FLAGS);
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h
new file mode 100644
index 0000000000..c4997bb35e
--- /dev/null
+++ b/dlls/rsaenh/cryptoprovutils.h
@@ -0,0 +1,81 @@
+/*
+ * dlls/rsaenh/cryptoprovutils.h
+ * Header of utility functions to implement crypto privider.
+ *
+ * Copyright 2002 TransGaming Technologies (David Hammerton)
+ * Copyright 2004 Mike McCormack for CodeWeavers
+ * Copyright 2004, 2005 Michael Jung
+ * Copyright 2007 Vijay Kiran Kamuju
+ *
+ * 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_CRYPTOPROVUTILS_H
+#define __WINE_CRYPTOPROVUTILS_H
+#include <cryptoprovconfig.h>
+#include "implglue.h"
+typedef struct tagKEYCONTAINER
+{
+ OBJECTHDR header;
+ DWORD dwFlags;
+ DWORD dwPersonality;
+ DWORD dwEnumAlgsCtr;
+ DWORD dwEnumContainersCtr;
+ char szName[MAX_PATH];
+ char szProvName[MAX_PATH];
+ HCRYPTKEY hKeyExchangeKeyPair;
+ HCRYPTKEY hSignatureKeyPair;
+} KEYCONTAINER;
+
+typedef struct tagCRYPTKEY
+{
+ OBJECTHDR header;
+ ALG_ID aiAlgid;
+ HCRYPTPROV hProv;
+ DWORD dwMode;
+ DWORD dwModeBits;
+ DWORD dwPermissions;
+ DWORD dwKeyLen;
+ DWORD dwEffectiveKeyLen;
+ DWORD dwSaltLen;
+ DWORD dwBlockLen;
+ DWORD dwState;
+ KEY_CONTEXT context;
+ BYTE abKeyValue[CRYPTO_PROV_MAX_KEY_SIZE];
+ BYTE abInitVector[CRYPTO_PROV_MAX_BLOCK_SIZE];
+ BYTE abChainVector[CRYPTO_PROV_MAX_BLOCK_SIZE];
+ CRYPTO_PROV_SCHANNEL_INFO siSChannelInfo;
+ CRYPT_DATA_BLOB blobHmacKey;
+} CRYPTKEY;
+
+HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags,
const VTableProvStruc *pVTable);
+BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam,
HKEY *phKey);
+void destroy_key_container(OBJECTHDR *pObjectHdr);
+void store_key_container_keys(KEYCONTAINER *pKeyContainer);
+void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec,
DWORD dwFlags);
+void store_key_container_permissions(KEYCONTAINER *pKeyContainer);
+void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec);
+void release_key_container_keys(KEYCONTAINER *pKeyContainer);
+LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec);
+BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey,
+ DWORD dwBlobType, DWORD dwFlags, BOOL force,
+ BYTE *pbData, DWORD *pdwDataLen);
+LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec);
+BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags,
REGSAM access, HKEY *phKey);
+BOOL CRYPTO_PROV_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer,
+ DWORD dwFlags, PVTableProvStruc pVTable);
+BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD
dwDataLen, HCRYPTKEY hPubKey,
+ DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey);
+#endif /* __WINE_CRYPTOPROVUTILS_H */
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c
index 9119d4be2d..6a746d7b07 100644
--- a/dlls/rsaenh/rsaenh.c
+++ b/dlls/rsaenh/rsaenh.c
@@ -34,6 +34,7 @@
#include "objbase.h"
#include "rpcproxy.h"
#include "aclapi.h"
+#include "cryptoprovutils.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@@ -66,67 +67,6 @@ typedef struct tagCRYPTHASH
RSAENH_TLS1PRF_PARAMS tpPRFParams;
} CRYPTHASH;
-/******************************************************************************
- * CRYPTKEY - key objects
- */
-#define RSAENH_MAGIC_KEY 0x73620457u
-#define RSAENH_MAX_KEY_SIZE 64
-#define RSAENH_MAX_BLOCK_SIZE 24
-#define RSAENH_KEYSTATE_IDLE 0
-#define RSAENH_KEYSTATE_ENCRYPTING 1
-#define RSAENH_KEYSTATE_MASTERKEY 2
-typedef struct _RSAENH_SCHANNEL_INFO
-{
- SCHANNEL_ALG saEncAlg;
- SCHANNEL_ALG saMACAlg;
- CRYPT_DATA_BLOB blobClientRandom;
- CRYPT_DATA_BLOB blobServerRandom;
-} RSAENH_SCHANNEL_INFO;
-
-typedef struct tagCRYPTKEY
-{
- OBJECTHDR header;
- ALG_ID aiAlgid;
- HCRYPTPROV hProv;
- DWORD dwMode;
- DWORD dwModeBits;
- DWORD dwPermissions;
- DWORD dwKeyLen;
- DWORD dwEffectiveKeyLen;
- DWORD dwSaltLen;
- DWORD dwBlockLen;
- DWORD dwState;
- KEY_CONTEXT context;
- BYTE abKeyValue[RSAENH_MAX_KEY_SIZE];
- BYTE abInitVector[RSAENH_MAX_BLOCK_SIZE];
- BYTE abChainVector[RSAENH_MAX_BLOCK_SIZE];
- RSAENH_SCHANNEL_INFO siSChannelInfo;
- CRYPT_DATA_BLOB blobHmacKey;
-} CRYPTKEY;
-
-/******************************************************************************
- * KEYCONTAINER - key containers
- */
-#define RSAENH_PERSONALITY_BASE 0u
-#define RSAENH_PERSONALITY_STRONG 1u
-#define RSAENH_PERSONALITY_ENHANCED 2u
-#define RSAENH_PERSONALITY_SCHANNEL 3u
-#define RSAENH_PERSONALITY_AES 4u
-
-#define RSAENH_MAGIC_CONTAINER 0x26384993u
-typedef struct tagKEYCONTAINER
-{
- OBJECTHDR header;
- DWORD dwFlags;
- DWORD dwPersonality;
- DWORD dwEnumAlgsCtr;
- DWORD dwEnumContainersCtr;
- CHAR szName[MAX_PATH];
- CHAR szProvName[MAX_PATH];
- HCRYPTKEY hKeyExchangeKeyPair;
- HCRYPTKEY hSignatureKeyPair;
-} KEYCONTAINER;
-
/******************************************************************************
* Some magic constants
*/
@@ -149,7 +89,6 @@ typedef struct tagKEYCONTAINER
#define RSAENH_SSL3_VERSION_MINOR 0
#define RSAENH_TLS1_VERSION_MAJOR 3
#define RSAENH_TLS1_VERSION_MINOR 1
-#define RSAENH_REGKEY "Software\\Wine\\Crypto\\RSA\\%s"
#define RSAENH_MIN(a,b) ((a)<(b)?(a):(b))
/******************************************************************************
@@ -316,26 +255,6 @@ RSAENH_CPDestroyHash(
HCRYPTHASH hHash
);
-static BOOL crypt_export_key(
- CRYPTKEY *pCryptKey,
- HCRYPTKEY hPubKey,
- DWORD dwBlobType,
- DWORD dwFlags,
- BOOL force,
- BYTE *pbData,
- DWORD *pdwDataLen
-);
-
-static BOOL import_key(
- HCRYPTPROV hProv,
- const BYTE *pbData,
- DWORD dwDataLen,
- HCRYPTKEY hPubKey,
- DWORD dwFlags,
- BOOL fStoreKey,
- HCRYPTKEY *phKey
-);
-
BOOL WINAPI
RSAENH_CPHashData(
HCRYPTPROV hProv,
@@ -348,7 +267,7 @@ RSAENH_CPHashData(
/******************************************************************************
* CSP's handle table (used by all acquired key containers)
*/
-static struct handle_table handle_table;
+struct handle_table handle_table;
/******************************************************************************
* DllMain (RSAENH.@)
@@ -933,498 +852,6 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv,
ALG_ID aiAlgid, DWORD dwFlags, CRYPTK
return hCryptKey;
}
-/******************************************************************************
- * map_key_spec_to_key_pair_name [Internal]
- *
- * Returns the name of the registry value associated with a key spec.
- *
- * PARAMS
- * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
- *
- * RETURNS
- * Success: Name of registry value.
- * Failure: NULL
- */
-static LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec)
-{
- LPCSTR szValueName;
-
- switch (dwKeySpec)
- {
- case AT_KEYEXCHANGE:
- szValueName = "KeyExchangeKeyPair";
- break;
- case AT_SIGNATURE:
- szValueName = "SignatureKeyPair";
- break;
- default:
- WARN("invalid key spec %d\n", dwKeySpec);
- szValueName = NULL;
- }
- return szValueName;
-}
-
-/******************************************************************************
- * store_key_pair [Internal]
- *
- * Stores a key pair to the registry
- *
- * PARAMS
- * hCryptKey [I] Handle to the key to be stored
- * hKey [I] Registry key where the key pair is to be stored
- * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
- * dwFlags [I] Flags for protecting the key
- */
-static void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD
dwKeySpec, DWORD dwFlags)
-{
- LPCSTR szValueName;
- DATA_BLOB blobIn, blobOut;
- CRYPTKEY *pKey;
- DWORD dwLen;
- BYTE *pbKey;
-
- if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec)))
- return;
- if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY,
- (OBJECTHDR**)&pKey))
- {
- if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, 0, &dwLen))
- {
- pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen);
- if (pbKey)
- {
- if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, pbKey,
- &dwLen))
- {
- blobIn.pbData = pbKey;
- blobIn.cbData = dwLen;
-
- if (CryptProtectData(&blobIn, NULL, NULL, NULL, NULL,
- dwFlags, &blobOut))
- {
- RegSetValueExA(hKey, szValueName, 0, REG_BINARY,
- blobOut.pbData, blobOut.cbData);
- LocalFree(blobOut.pbData);
- }
- }
- HeapFree(GetProcessHeap(), 0, pbKey);
- }
- }
- }
-}
-
-/******************************************************************************
- * map_key_spec_to_permissions_name [Internal]
- *
- * Returns the name of the registry value associated with the permissions for
- * a key spec.
- *
- * PARAMS
- * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
- *
- * RETURNS
- * Success: Name of registry value.
- * Failure: NULL
- */
-static LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec)
-{
- LPCSTR szValueName;
-
- switch (dwKeySpec)
- {
- case AT_KEYEXCHANGE:
- szValueName = "KeyExchangePermissions";
- break;
- case AT_SIGNATURE:
- szValueName = "SignaturePermissions";
- break;
- default:
- WARN("invalid key spec %d\n", dwKeySpec);
- szValueName = NULL;
- }
- return szValueName;
-}
-
-/******************************************************************************
- * store_key_permissions [Internal]
- *
- * Stores a key's permissions to the registry
- *
- * PARAMS
- * hCryptKey [I] Handle to the key whose permissions are to be stored
- * hKey [I] Registry key where the key permissions are to be stored
- * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
- */
-static void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey,
DWORD dwKeySpec)
-{
- LPCSTR szValueName;
- CRYPTKEY *pKey;
-
- if (!(szValueName = map_key_spec_to_permissions_name(dwKeySpec)))
- return;
- if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY,
- (OBJECTHDR**)&pKey))
- RegSetValueExA(hKey, szValueName, 0, REG_DWORD,
- (BYTE *)&pKey->dwPermissions,
- sizeof(pKey->dwPermissions));
-}
-
-/******************************************************************************
- * create_container_key [Internal]
- *
- * Creates the registry key for a key container's persistent storage.
- *
- * PARAMS
- * pKeyContainer [I] Pointer to the key container
- * sam [I] Desired registry access
- * phKey [O] Returned key
- */
-static BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM
sam, HKEY *phKey)
-{
- CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH];
- HKEY hRootKey;
-
- sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName);
-
- if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET)
- hRootKey = HKEY_LOCAL_MACHINE;
- else
- hRootKey = HKEY_CURRENT_USER;
-
- /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA */
- /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */
- return RegCreateKeyExA(hRootKey, szRSABase, 0, NULL,
- REG_OPTION_NON_VOLATILE, sam, NULL, phKey, NULL)
- == ERROR_SUCCESS;
-}
-
-/******************************************************************************
- * open_container_key [Internal]
- *
- * Opens a key container's persistent storage for reading.
- *
- * PARAMS
- * pszContainerName [I] Name of the container to be opened. May be the empty
- * string if the parent key of all containers is to be
- * opened.
- * dwFlags [I] Flags indicating which keyset to be opened.
- * phKey [O] Returned key
- */
-static BOOL open_container_key(LPCSTR pszContainerName, DWORD
dwFlags, REGSAM access, HKEY *phKey)
-{
- CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH];
- HKEY hRootKey;
-
- sprintf(szRSABase, RSAENH_REGKEY, pszContainerName);
-
- if (dwFlags & CRYPT_MACHINE_KEYSET)
- hRootKey = HKEY_LOCAL_MACHINE;
- else
- hRootKey = HKEY_CURRENT_USER;
-
- /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA */
- /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */
- return RegOpenKeyExA(hRootKey, szRSABase, 0, access, phKey) ==
- ERROR_SUCCESS;
-}
-
-/******************************************************************************
- * delete_container_key [Internal]
- *
- * Deletes a key container's persistent storage.
- *
- * PARAMS
- * pszContainerName [I] Name of the container to be opened.
- * dwFlags [I] Flags indicating which keyset to be opened.
- */
-static BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags)
-{
- CHAR szRegKey[sizeof(RSAENH_REGKEY) + MAX_PATH];
- HKEY hRootKey;
-
- sprintf(szRegKey, RSAENH_REGKEY, pszContainerName);
-
- if (dwFlags & CRYPT_MACHINE_KEYSET)
- hRootKey = HKEY_LOCAL_MACHINE;
- else
- hRootKey = HKEY_CURRENT_USER;
- if (!RegDeleteKeyA(hRootKey, szRegKey)) {
- SetLastError(ERROR_SUCCESS);
- return TRUE;
- } else {
- SetLastError(NTE_BAD_KEYSET);
- return FALSE;
- }
-}
-
-/******************************************************************************
- * store_key_container_keys [Internal]
- *
- * Stores key container's keys in a persistent location.
- *
- * PARAMS
- * pKeyContainer [I] Pointer to the key container whose keys are to be saved
- */
-static void store_key_container_keys(KEYCONTAINER *pKeyContainer)
-{
- HKEY hKey;
- DWORD dwFlags;
-
- /* On WinXP, persistent keys are stored in a file located at:
- * $AppData$\\Microsoft\\Crypto\\RSA\\$SID$\\some_hex_string
- */
-
- if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET)
- dwFlags = CRYPTPROTECT_LOCAL_MACHINE;
- else
- dwFlags = 0;
-
- if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
- {
- store_key_pair(pKeyContainer->hKeyExchangeKeyPair, hKey,
- AT_KEYEXCHANGE, dwFlags);
- store_key_pair(pKeyContainer->hSignatureKeyPair, hKey,
- AT_SIGNATURE, dwFlags);
- RegCloseKey(hKey);
- }
-}
-
-/******************************************************************************
- * store_key_container_permissions [Internal]
- *
- * Stores key container's key permissions in a persistent location.
- *
- * PARAMS
- * pKeyContainer [I] Pointer to the key container whose key permissions are to
- * be saved
- */
-static void store_key_container_permissions(KEYCONTAINER *pKeyContainer)
-{
- HKEY hKey;
-
- if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
- {
- store_key_permissions(pKeyContainer->hKeyExchangeKeyPair, hKey,
- AT_KEYEXCHANGE);
- store_key_permissions(pKeyContainer->hSignatureKeyPair, hKey,
- AT_SIGNATURE);
- RegCloseKey(hKey);
- }
-}
-
-/******************************************************************************
- * release_key_container_keys [Internal]
- *
- * Releases key container's keys.
- *
- * PARAMS
- * pKeyContainer [I] Pointer to the key container whose keys are to
be released.
- */
-static void release_key_container_keys(KEYCONTAINER *pKeyContainer)
-{
- release_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair,
- RSAENH_MAGIC_KEY);
- release_handle(&handle_table, pKeyContainer->hSignatureKeyPair,
- RSAENH_MAGIC_KEY);
-}
-
-/******************************************************************************
- * destroy_key_container [Internal]
- *
- * Destructor for key containers.
- *
- * PARAMS
- * pObjectHdr [I] Pointer to the key container to be destroyed.
- */
-static void destroy_key_container(OBJECTHDR *pObjectHdr)
-{
- KEYCONTAINER *pKeyContainer = (KEYCONTAINER*)pObjectHdr;
-
- if (!(pKeyContainer->dwFlags & CRYPT_VERIFYCONTEXT))
- {
- store_key_container_keys(pKeyContainer);
- store_key_container_permissions(pKeyContainer);
- release_key_container_keys(pKeyContainer);
- }
- else
- release_key_container_keys(pKeyContainer);
- HeapFree( GetProcessHeap(), 0, pKeyContainer );
-}
-
-/******************************************************************************
- * new_key_container [Internal]
- *
- * Create a new key container. The personality (RSA Base, Strong or
Enhanced CP)
- * of the CSP is determined via the pVTable->pszProvName string.
- *
- * PARAMS
- * pszContainerName [I] Name of the key container.
- * pVTable [I] Callback functions and context info provided by the OS
- *
- * RETURNS
- * Success: Handle to the new key container.
- * Failure: INVALID_HANDLE_VALUE
- */
-static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD
dwFlags, const VTableProvStruc *pVTable)
-{
- KEYCONTAINER *pKeyContainer;
- HCRYPTPROV hKeyContainer;
-
- hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER),
RSAENH_MAGIC_CONTAINER,
- destroy_key_container,
(OBJECTHDR**)&pKeyContainer);
- if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE)
- {
- lstrcpynA(pKeyContainer->szName, pszContainerName, MAX_PATH);
- pKeyContainer->dwFlags = dwFlags;
- pKeyContainer->dwEnumAlgsCtr = 0;
- pKeyContainer->hKeyExchangeKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE;
- pKeyContainer->hSignatureKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE;
- if (pVTable && pVTable->pszProvName) {
- lstrcpynA(pKeyContainer->szProvName,
pVTable->pszProvName, MAX_PATH);
- if (!strcmp(pVTable->pszProvName, MS_DEF_PROV_A)) {
- pKeyContainer->dwPersonality = RSAENH_PERSONALITY_BASE;
- } else if (!strcmp(pVTable->pszProvName, MS_ENHANCED_PROV_A)) {
- pKeyContainer->dwPersonality = RSAENH_PERSONALITY_ENHANCED;
- } else if (!strcmp(pVTable->pszProvName,
MS_DEF_RSA_SCHANNEL_PROV_A)) {
- pKeyContainer->dwPersonality = RSAENH_PERSONALITY_SCHANNEL;
- } else if (!strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_A) ||
- !strcmp(pVTable->pszProvName,
MS_ENH_RSA_AES_PROV_XP_A)) {
- pKeyContainer->dwPersonality = RSAENH_PERSONALITY_AES;
- } else {
- pKeyContainer->dwPersonality = RSAENH_PERSONALITY_STRONG;
- }
- }
-
- /* The new key container has to be inserted into the CSP immediately
- * after creation to be available for CPGetProvParam's
PP_ENUMCONTAINERS. */
- if (!(dwFlags & CRYPT_VERIFYCONTEXT)) {
- HKEY hKey;
-
- if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
- RegCloseKey(hKey);
- }
- }
-
- return hKeyContainer;
-}
-
-/******************************************************************************
- * read_key_value [Internal]
- *
- * Reads a key pair value from the registry
- *
- * PARAMS
- * hKeyContainer [I] Crypt provider to use to import the key
- * hKey [I] Registry key from which to read the key pair
- * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE
- * dwFlags [I] Flags for unprotecting the key
- * phCryptKey [O] Returned key
- */
-static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD
dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey)
-{
- LPCSTR szValueName;
- DWORD dwValueType, dwLen;
- BYTE *pbKey;
- DATA_BLOB blobIn, blobOut;
- BOOL ret = FALSE;
-
- if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec)))
- return FALSE;
- if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, NULL, &dwLen) ==
- ERROR_SUCCESS)
- {
- pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen);
- if (pbKey)
- {
- if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType,
pbKey, &dwLen) ==
- ERROR_SUCCESS)
- {
- blobIn.pbData = pbKey;
- blobIn.cbData = dwLen;
-
- if (CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL,
- dwFlags, &blobOut))
- {
- ret = import_key(hKeyContainer, blobOut.pbData,
blobOut.cbData, 0, 0,
- FALSE, phCryptKey);
- LocalFree(blobOut.pbData);
- }
- }
- HeapFree(GetProcessHeap(), 0, pbKey);
- }
- }
- if (ret)
- {
- CRYPTKEY *pKey;
-
- if (lookup_handle(&handle_table, *phCryptKey, RSAENH_MAGIC_KEY,
- (OBJECTHDR**)&pKey))
- {
- if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec)))
- {
- dwLen = sizeof(pKey->dwPermissions);
- RegQueryValueExA(hKey, szValueName, 0, NULL,
- (BYTE *)&pKey->dwPermissions, &dwLen);
- }
- }
- }
- return ret;
-}
-
-/******************************************************************************
- * read_key_container [Internal]
- *
- * Tries to read the persistent state of the key container (mainly
the signature
- * and key exchange private keys) given by pszContainerName.
- *
- * PARAMS
- * pszContainerName [I] Name of the key container to read from the registry
- * pVTable [I] Pointer to context data provided by the
operating system
- *
- * RETURNS
- * Success: Handle to the key container read from the registry
- * Failure: INVALID_HANDLE_VALUE
- */
-static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD
dwFlags, const VTableProvStruc *pVTable)
-{
- HKEY hKey;
- KEYCONTAINER *pKeyContainer;
- HCRYPTPROV hKeyContainer;
- HCRYPTKEY hCryptKey;
-
- if (!open_container_key(pszContainerName, dwFlags, KEY_READ, &hKey))
- {
- SetLastError(NTE_BAD_KEYSET);
- return (HCRYPTPROV)INVALID_HANDLE_VALUE;
- }
-
- hKeyContainer = new_key_container(pszContainerName, dwFlags, pVTable);
- if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE)
- {
- DWORD dwProtectFlags = (dwFlags & CRYPT_MACHINE_KEYSET) ?
- CRYPTPROTECT_LOCAL_MACHINE : 0;
-
- if (!lookup_handle(&handle_table, hKeyContainer,
RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
- return (HCRYPTPROV)INVALID_HANDLE_VALUE;
-
- /* read_key_value calls import_key, which calls import_private_key,
- * which implicitly installs the key value into the appropriate key
- * container key. Thus the ref count is incremented twice, once for
- * the output key value, and once for the implicit install, and needs
- * to be decremented to balance the two.
- */
- if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE,
- dwProtectFlags, &hCryptKey))
- release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY);
- if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE,
- dwProtectFlags, &hCryptKey))
- release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY);
- }
-
- return hKeyContainer;
-}
-
/******************************************************************************
* build_hash_signature [Internal]
*
@@ -2073,64 +1500,7 @@ static BOOL unpad_data(HCRYPTPROV hProv, const
BYTE *abData, DWORD dwDataLen, BY
BOOL WINAPI RSAENH_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer,
DWORD dwFlags, PVTableProvStruc pVTable)
{
- CHAR szKeyContainerName[MAX_PATH];
-
- TRACE("(phProv=%p, pszContainer=%s, dwFlags=%08x, pVTable=%p)\n", phProv,
- debugstr_a(pszContainer), dwFlags, pVTable);
-
- if (pszContainer && *pszContainer)
- {
- lstrcpynA(szKeyContainerName, pszContainer, MAX_PATH);
- }
- else
- {
- DWORD dwLen = sizeof(szKeyContainerName);
- if (!GetUserNameA(szKeyContainerName, &dwLen)) return FALSE;
- }
-
- switch (dwFlags & (CRYPT_NEWKEYSET|CRYPT_VERIFYCONTEXT|CRYPT_DELETEKEYSET))
- {
- case 0:
- *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable);
- break;
-
- case CRYPT_DELETEKEYSET:
- return delete_container_key(szKeyContainerName, dwFlags);
-
- case CRYPT_NEWKEYSET:
- *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable);
- if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE)
- {
- release_handle(&handle_table, *phProv, RSAENH_MAGIC_CONTAINER);
- TRACE("Can't create new keyset, already exists\n");
- SetLastError(NTE_EXISTS);
- return FALSE;
- }
- *phProv = new_key_container(szKeyContainerName, dwFlags, pVTable);
- break;
-
- case CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET:
- case CRYPT_VERIFYCONTEXT:
- if (pszContainer && *pszContainer) {
- TRACE("pszContainer should be empty\n");
- SetLastError(NTE_BAD_FLAGS);
- return FALSE;
- }
- *phProv = new_key_container("", dwFlags, pVTable);
- break;
-
- default:
- *phProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
- SetLastError(NTE_BAD_FLAGS);
- return FALSE;
- }
-
- if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
- SetLastError(ERROR_SUCCESS);
- return TRUE;
- } else {
- return FALSE;
- }
+ return CRYPTO_PROV_CPAcquireContext(phProv, pszContainer,
dwFlags, pVTable);
}
/******************************************************************************
@@ -2906,7 +2276,7 @@ static BOOL crypt_export_plaintext_key(CRYPTKEY
*pCryptKey, BYTE *pbData,
* Success: TRUE.
* Failure: FALSE.
*/
-static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey,
+BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey,
DWORD dwBlobType, DWORD dwFlags, BOOL force,
BYTE *pbData, DWORD *pdwDataLen)
{
@@ -3351,7 +2721,7 @@ static BOOL import_plaintext_key(HCRYPTPROV
hProv, const BYTE *pbData, DWORD dwD
* Success: TRUE.
* Failure: FALSE.
*/
-static BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD
dwDataLen, HCRYPTKEY hPubKey,
+BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD
dwDataLen, HCRYPTKEY hPubKey,
DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
{
KEYCONTAINER *pKeyContainer;
@@ -4549,21 +3919,7 @@ BOOL WINAPI RSAENH_CPHashSessionKey(HCRYPTPROV
hProv, HCRYPTHASH hHash, HCRYPTKE
*/
BOOL WINAPI RSAENH_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
{
- TRACE("(hProv=%08lx, dwFlags=%08x)\n", hProv, dwFlags);
-
- if (!release_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER))
- {
- /* MSDN: hProv not containing valid context handle */
- SetLastError(NTE_BAD_UID);
- return FALSE;
- }
-
- if (dwFlags) {
- SetLastError(NTE_BAD_FLAGS);
- return FALSE;
- }
-
- return TRUE;
+ return CRYPTO_PROV_CPReleaseContext(hProv, dwFlags);
}
/******************************************************************************
--
2.21.0