This series of patches and follow-ups will implement dssenh. Dssenh has a lot of functionalities in common with rsaenh, so try to extract the codes that are irrelavent to the specific module and reuse them as much as possible. The behaviour of dssenh is well-understood (through dssenh/tests, at least for CPAcquireContext and CPReleaseContext). And my first goal would be to pass all dssenh/tests. Currently CPAcquireContext and CPReleaseContext is implemented. I'm new here and not familiar with how to email patches, so sorry for spamming the mail list with bad patches. Besides, is there a way to let the robot test a series of patches without sending to the maillist?
Zhang Shuai (10): dssenh: refactor rsaenh - create new files. dssenh: refactor rsaenh - table driven new_key_container. dssenh: refactor rsaenh - move create_container_key, open_container_key, delete_container_key from rsaenh/rsaenh.c to rsaenh/cryptoprovutils.c dssenh: refactor rsaenh - move map_key_spec_to_permissions_name, store_key_permissions from rsaenh/rsaenh.c to rsaenh/cryptoprovutils.c dssenh: refactor rsaenh - move store_key_container_keys, store_key_container_permissions, map_key_spec_to_permissions_name from rsaenh/rsaenh.c to rsaenh/cryptoprovutils.c dssenh: refactor rsaenh - move release_key_container_keys, destroy_key_container, read_key_value, read_key_container, new_key_container, import_key from rsaenh/rsaenh.c to rsaenh/cryptoprovutils.c dssenh: refactor rsaenh - Change constant names. dssenh: Makefile and registry. refactor rsaenh - move CPAcquireContext, CPReleaseContext from rsaenh/rsaenh.c to rsaenh/cryptoprovutils.c dssenh: implement CPAcquireContext and CPReleaseContext for dssenh.
dlls/dssenh/Makefile.in | 9 +- dlls/dssenh/cryptoprovconfig.h | 83 +++++ dlls/dssenh/cryptoprovutils.c | 22 ++ dlls/dssenh/dssenh.c | 184 +++++++++ dlls/dssenh/dssenh.rgs | 60 +++ dlls/dssenh/dssenh.spec | 4 +- dlls/dssenh/handle.c | 22 ++ dlls/dssenh/main.c | 59 --- dlls/dssenh/rsrc.rc | 31 ++ dlls/rsaenh/Makefile.in | 3 +- dlls/rsaenh/cryptoprovconfig.h | 86 +++++ dlls/rsaenh/cryptoprovutils.c | 653 ++++++++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 94 +++++ dlls/rsaenh/rsaenh.c | 657 +-------------------------------- 14 files changed, 1254 insertions(+), 713 deletions(-) create mode 100644 dlls/dssenh/cryptoprovconfig.h create mode 100644 dlls/dssenh/cryptoprovutils.c create mode 100644 dlls/dssenh/dssenh.c create mode 100644 dlls/dssenh/dssenh.rgs create mode 100644 dlls/dssenh/handle.c delete mode 100644 dlls/dssenh/main.c create mode 100644 dlls/dssenh/rsrc.rc create mode 100644 dlls/rsaenh/cryptoprovconfig.h create mode 100644 dlls/rsaenh/cryptoprovutils.c create mode 100644 dlls/rsaenh/cryptoprovutils.h
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/Makefile.in | 3 ++- dlls/rsaenh/cryptoprovconfig.h | 31 +++++++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.c | 34 ++++++++++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 29 +++++++++++++++++++++++++++++ dlls/rsaenh/rsaenh.c | 1 + 5 files changed, 97 insertions(+), 1 deletion(-) 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/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..79a93a85f4 --- /dev/null +++ b/dlls/rsaenh/cryptoprovconfig.h @@ -0,0 +1,31 @@ +/* + * 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 +#endif /* __WINE_CRYPTOPROVCONFIG_H */ diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c new file mode 100644 index 0000000000..76ee7bbe86 --- /dev/null +++ b/dlls/rsaenh/cryptoprovutils.c @@ -0,0 +1,34 @@ +/* + * 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" diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h new file mode 100644 index 0000000000..832b09e4ce --- /dev/null +++ b/dlls/rsaenh/cryptoprovutils.h @@ -0,0 +1,29 @@ +/* + * 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" +#endif /* __WINE_CRYPTOPROVUTILS_H */ diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 9119d4be2d..f8fbd8071a 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);
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/cryptoprovconfig.h | 32 ++++++++++++++++++++++++++++++++ dlls/rsaenh/rsaenh.c | 27 ++++++++++----------------- 2 files changed, 42 insertions(+), 17 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovconfig.h b/dlls/rsaenh/cryptoprovconfig.h index 79a93a85f4..da6d526be2 100644 --- a/dlls/rsaenh/cryptoprovconfig.h +++ b/dlls/rsaenh/cryptoprovconfig.h @@ -28,4 +28,36 @@
#ifndef __WINE_CRYPTOPROVCONFIG_H #define __WINE_CRYPTOPROVCONFIG_H +#include "wincrypt.h" + +/****************************************************************************** + * 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/rsaenh.c b/dlls/rsaenh/rsaenh.c index f8fbd8071a..e05785e142 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -108,12 +108,6 @@ typedef struct tagCRYPTKEY /****************************************************************************** * 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 { @@ -1270,6 +1264,7 @@ static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const { KEYCONTAINER *pKeyContainer; HCRYPTPROV hKeyContainer; + DWORD i;
hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER), RSAENH_MAGIC_CONTAINER, destroy_key_container, (OBJECTHDR**)&pKeyContainer); @@ -1282,17 +1277,15 @@ static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const 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; + pKeyContainer->dwPersonality + = aProvNamePersonalityPairs[0].dwPersonality; + for (i = 1; i < dwNProvNamePersonalityPairs; i++) { + if (!strcmp(pVTable->pszProvName, + aProvNamePersonalityPairs[i].pszProvName)) { + pKeyContainer->dwPersonality + = aProvNamePersonalityPairs[i].dwPersonality; + break; + } } }
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/cryptoprovconfig.h | 7 +++ dlls/rsaenh/cryptoprovutils.c | 89 +++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 16 +++++ dlls/rsaenh/rsaenh.c | 106 --------------------------------- 4 files changed, 112 insertions(+), 106 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovconfig.h b/dlls/rsaenh/cryptoprovconfig.h index da6d526be2..d282d0db1e 100644 --- a/dlls/rsaenh/cryptoprovconfig.h +++ b/dlls/rsaenh/cryptoprovconfig.h @@ -39,6 +39,8 @@ #define RSAENH_PERSONALITY_SCHANNEL 3u #define RSAENH_PERSONALITY_AES 4u
+#define RSAENH_MAGIC_CONTAINER 0x26384993u + /****************************************************************************** * Used by new_key_container to determine the personality via provider name. * The first entry in aProvNamePersonalityPairs should be the default personality. @@ -60,4 +62,9 @@ static const PROVNAMEPERSONALITYPAIR aProvNamePersonalityPairs[6] = {MS_ENH_RSA_AES_PROV_XP_A, RSAENH_PERSONALITY_AES} };
+/****************************************************************************** + * Some magic constants + */ +#define RSAENH_REGKEY "Software\Wine\Crypto\RSA\%s" + #endif /* __WINE_CRYPTOPROVCONFIG_H */ diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c index 76ee7bbe86..23e0e11626 100644 --- a/dlls/rsaenh/cryptoprovutils.c +++ b/dlls/rsaenh/cryptoprovutils.c @@ -32,3 +32,92 @@ #include "handle.h" #include "cryptoprovutils.h" #include "wine/debug.h" + +/****************************************************************************** + * 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 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 + */ +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. + */ +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; + } +} + diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h index 832b09e4ce..17d665e398 100644 --- a/dlls/rsaenh/cryptoprovutils.h +++ b/dlls/rsaenh/cryptoprovutils.h @@ -26,4 +26,20 @@ #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; + +BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey); +BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, HKEY *phKey); +BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags); #endif /* __WINE_CRYPTOPROVUTILS_H */ diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index e05785e142..069aee569f 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -105,23 +105,6 @@ typedef struct tagCRYPTKEY CRYPT_DATA_BLOB blobHmacKey; } CRYPTKEY;
-/****************************************************************************** - * KEYCONTAINER - key containers - */ -#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 */ @@ -144,7 +127,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)) /****************************************************************************** @@ -1064,94 +1046,6 @@ static void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpe 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] *
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/cryptoprovconfig.h | 14 ++++ dlls/rsaenh/cryptoprovutils.c | 87 +++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 35 +++++++++ dlls/rsaenh/rsaenh.c | 133 +-------------------------------- 4 files changed, 139 insertions(+), 130 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovconfig.h b/dlls/rsaenh/cryptoprovconfig.h index d282d0db1e..10cbc31b8b 100644 --- a/dlls/rsaenh/cryptoprovconfig.h +++ b/dlls/rsaenh/cryptoprovconfig.h @@ -29,6 +29,7 @@ #ifndef __WINE_CRYPTOPROVCONFIG_H #define __WINE_CRYPTOPROVCONFIG_H #include "wincrypt.h" +#include "implglue.h"
/****************************************************************************** * KEYCONTAINER - key containers @@ -62,9 +63,22 @@ static const PROVNAMEPERSONALITYPAIR aProvNamePersonalityPairs[6] = {MS_ENH_RSA_AES_PROV_XP_A, RSAENH_PERSONALITY_AES} };
+/****************************************************************************** + * CRYPTKEY - key objects + */ +#define RSAENH_MAGIC_KEY 0x73620457u +#define RSAENH_KEYSTATE_IDLE 0 +#define RSAENH_KEYSTATE_ENCRYPTING 1 +#define RSAENH_KEYSTATE_MASTERKEY 2 + /****************************************************************************** * Some magic constants */ #define RSAENH_REGKEY "Software\Wine\Crypto\RSA\%s"
+/****************************************************************************** + * Definitions concerning prefix. + */ +#define RSAENH_SCHANNEL_INFO SCHANNEL_INFO + #endif /* __WINE_CRYPTOPROVCONFIG_H */ diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c index 23e0e11626..9f774bad1d 100644 --- a/dlls/rsaenh/cryptoprovutils.c +++ b/dlls/rsaenh/cryptoprovutils.c @@ -33,6 +33,13 @@ #include "cryptoprovutils.h" #include "wine/debug.h"
+WINE_DEFAULT_DEBUG_CHANNEL(crypt); + +/****************************************************************************** + * CSP's handle table (used by all acquired key containers) + */ +extern struct handle_table handle_table; + /****************************************************************************** * create_container_key [Internal] * @@ -121,3 +128,83 @@ BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags) } }
+/****************************************************************************** + * 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; +} + +/****************************************************************************** + * 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, 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); + } + } + } +} + diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h index 17d665e398..499b0b8140 100644 --- a/dlls/rsaenh/cryptoprovutils.h +++ b/dlls/rsaenh/cryptoprovutils.h @@ -39,7 +39,42 @@ typedef struct tagKEYCONTAINER HCRYPTKEY hSignatureKeyPair; } KEYCONTAINER;
+typedef struct _SCHANNEL_INFO +{ + SCHANNEL_ALG saEncAlg; + SCHANNEL_ALG saMACAlg; + CRYPT_DATA_BLOB blobClientRandom; + CRYPT_DATA_BLOB blobServerRandom; +} SCHANNEL_INFO; + +#define RSAENH_MAX_KEY_SIZE 64 +#define RSAENH_MAX_BLOCK_SIZE 24 +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]; + SCHANNEL_INFO siSChannelInfo; + CRYPT_DATA_BLOB blobHmacKey; +} CRYPTKEY; + BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey); BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, HKEY *phKey); BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags); +BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, DWORD dwBlobType, + DWORD dwFlags, BOOL force, BYTE *pbData, DWORD *pdwDataLen); +LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec); +void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags); #endif /* __WINE_CRYPTOPROVUTILS_H */ diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 069aee569f..8925abefab 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -67,44 +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; - /****************************************************************************** * Some magic constants */ @@ -293,16 +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, @@ -325,7 +277,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.@) @@ -910,86 +862,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] * @@ -2773,6 +2645,7 @@ static BOOL crypt_export_plaintext_key(CRYPTKEY *pCryptKey, BYTE *pbData, *pdwDataLen = dwDataLen; return TRUE; } + /****************************************************************************** * crypt_export_key [Internal] * @@ -2794,7 +2667,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) {
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/cryptoprovutils.c | 111 ++++++++++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 4 ++ dlls/rsaenh/rsaenh.c | 111 ---------------------------------- 3 files changed, 115 insertions(+), 111 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c index 9f774bad1d..44bbc923b8 100644 --- a/dlls/rsaenh/cryptoprovutils.c +++ b/dlls/rsaenh/cryptoprovutils.c @@ -208,3 +208,114 @@ void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFla } }
+/****************************************************************************** + * 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\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); + } +} + +/****************************************************************************** + * 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; +} + +/****************************************************************************** + * 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, RSAENH_MAGIC_KEY, + (OBJECTHDR**)&pKey)) + RegSetValueExA(hKey, szValueName, 0, REG_DWORD, + (BYTE *)&pKey->dwPermissions, + sizeof(pKey->dwPermissions)); +} + +/****************************************************************************** + * 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); + } +} + diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h index 499b0b8140..4b5fcf2f22 100644 --- a/dlls/rsaenh/cryptoprovutils.h +++ b/dlls/rsaenh/cryptoprovutils.h @@ -77,4 +77,8 @@ BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BOOL force, BYTE *pbData, DWORD *pdwDataLen); LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec); void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags); +void store_key_container_keys(KEYCONTAINER *pKeyContainer); +LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec); +void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec); +void store_key_container_permissions(KEYCONTAINER *pKeyContainer); #endif /* __WINE_CRYPTOPROVUTILS_H */ diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 8925abefab..5557068813 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -862,117 +862,6 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK return hCryptKey; }
-/****************************************************************************** - * 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)); -} - -/****************************************************************************** - * 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] *
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/cryptoprovutils.c | 212 ++++++++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 7 ++ dlls/rsaenh/rsaenh.c | 224 +--------------------------------- 3 files changed, 220 insertions(+), 223 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c index 44bbc923b8..7262ead819 100644 --- a/dlls/rsaenh/cryptoprovutils.c +++ b/dlls/rsaenh/cryptoprovutils.c @@ -319,3 +319,215 @@ void store_key_container_permissions(KEYCONTAINER *pKeyContainer) } }
+/****************************************************************************** + * 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, + 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. + */ +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 ); +} + +/****************************************************************************** + * 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 + */ +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 + */ +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; +} + +/****************************************************************************** + * 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 + */ +HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable) +{ + KEYCONTAINER *pKeyContainer; + HCRYPTPROV hKeyContainer; + DWORD i; + + 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); + 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; +} + diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h index 4b5fcf2f22..f745ada8d4 100644 --- a/dlls/rsaenh/cryptoprovutils.h +++ b/dlls/rsaenh/cryptoprovutils.h @@ -81,4 +81,11 @@ void store_key_container_keys(KEYCONTAINER *pKeyContainer); LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec); void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec); void store_key_container_permissions(KEYCONTAINER *pKeyContainer); +void release_key_container_keys(KEYCONTAINER *pKeyContainer); +void destroy_key_container(OBJECTHDR *pObjectHdr); +BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey); +HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable); +HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *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 5557068813..310863a514 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -255,16 +255,6 @@ RSAENH_CPDestroyHash( HCRYPTHASH hHash );
-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, @@ -862,218 +852,6 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK return hCryptKey; }
-/****************************************************************************** - * 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; - DWORD i; - - 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); - 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; -} - -/****************************************************************************** - * 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] * @@ -3001,7 +2779,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;
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/cryptoprovconfig.h | 8 +++++- dlls/rsaenh/cryptoprovutils.c | 46 +++++++++++++++++----------------- dlls/rsaenh/cryptoprovutils.h | 10 ++++---- 3 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovconfig.h b/dlls/rsaenh/cryptoprovconfig.h index 10cbc31b8b..e482d37ad4 100644 --- a/dlls/rsaenh/cryptoprovconfig.h +++ b/dlls/rsaenh/cryptoprovconfig.h @@ -79,6 +79,12 @@ static const PROVNAMEPERSONALITYPAIR aProvNamePersonalityPairs[6] = /****************************************************************************** * Definitions concerning prefix. */ -#define RSAENH_SCHANNEL_INFO SCHANNEL_INFO +#define RSAENH_SCHANNEL_INFO SCHANNEL_INFO +#define RSAENH_MAX_KEY_SIZE CRYPTO_PROV_MAX_KEY_SIZE +#define RSAENH_MAX_BLOCK_SIZE CRYPTO_PROV_MAX_BLOCK_SIZE + +#define CRYPTO_PROV_REGKEY RSAENH_REGKEY +#define CRYPTO_PROV_MAGIC_KEY RSAENH_MAGIC_KEY +#define CRYPTO_PROV_MAGIC_CONTAINER RSAENH_MAGIC_CONTAINER
#endif /* __WINE_CRYPTOPROVCONFIG_H */ diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c index 7262ead819..ed3b16b13a 100644 --- a/dlls/rsaenh/cryptoprovutils.c +++ b/dlls/rsaenh/cryptoprovutils.c @@ -52,19 +52,19 @@ extern struct handle_table handle_table; */ BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey) { - CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH]; + CHAR szBase[sizeof(CRYPTO_PROV_REGKEY) + MAX_PATH]; HKEY hRootKey;
- sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName); + 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\RSA */ - /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */ - return RegCreateKeyExA(hRootKey, szRSABase, 0, NULL, + /* @@ 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; } @@ -83,19 +83,19 @@ BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey) */ BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, HKEY *phKey) { - CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH]; + CHAR szBase[sizeof(CRYPTO_PROV_REGKEY) + MAX_PATH]; HKEY hRootKey;
- sprintf(szRSABase, RSAENH_REGKEY, pszContainerName); + sprintf(szBase, 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\RSA */ - /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */ - return RegOpenKeyExA(hRootKey, szRSABase, 0, access, phKey) == + /* @@ Wine registry key: HKLM\Software\Wine\Crypto(CRYPTO_PROV) */ + /* @@ Wine registry key: HKCU\Software\Wine\Crypto(CRYPTO_PROV) */ + return RegOpenKeyExA(hRootKey, szBase, 0, access, phKey) == ERROR_SUCCESS; }
@@ -110,10 +110,10 @@ BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, H */ BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags) { - CHAR szRegKey[sizeof(RSAENH_REGKEY) + MAX_PATH]; + CHAR szRegKey[sizeof(CRYPTO_PROV_REGKEY) + MAX_PATH]; HKEY hRootKey;
- sprintf(szRegKey, RSAENH_REGKEY, pszContainerName); + sprintf(szRegKey, CRYPTO_PROV_REGKEY, pszContainerName);
if (dwFlags & CRYPT_MACHINE_KEYSET) hRootKey = HKEY_LOCAL_MACHINE; @@ -180,7 +180,7 @@ void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFla
if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec))) return; - if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, + if (lookup_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY, (OBJECTHDR**)&pKey)) { if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, 0, &dwLen)) @@ -222,7 +222,7 @@ void store_key_container_keys(KEYCONTAINER *pKeyContainer) DWORD dwFlags;
/* On WinXP, persistent keys are stored in a file located at: - * $AppData$\Microsoft\Crypto\RSA\$SID$\some_hex_string + * $AppData$\Microsoft\Crypto\(CRYPTO_PROV)\$SID$\some_hex_string */
if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) @@ -289,7 +289,7 @@ void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec)
if (!(szValueName = map_key_spec_to_permissions_name(dwKeySpec))) return; - if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, + if (lookup_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY, (OBJECTHDR**)&pKey)) RegSetValueExA(hKey, szValueName, 0, REG_DWORD, (BYTE *)&pKey->dwPermissions, @@ -330,9 +330,9 @@ void store_key_container_permissions(KEYCONTAINER *pKeyContainer) void release_key_container_keys(KEYCONTAINER *pKeyContainer) { release_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair, - RSAENH_MAGIC_KEY); + CRYPTO_PROV_MAGIC_KEY); release_handle(&handle_table, pKeyContainer->hSignatureKeyPair, - RSAENH_MAGIC_KEY); + CRYPTO_PROV_MAGIC_KEY); }
/****************************************************************************** @@ -407,7 +407,7 @@ BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD { CRYPTKEY *pKey;
- if (lookup_handle(&handle_table, *phCryptKey, RSAENH_MAGIC_KEY, + if (lookup_handle(&handle_table, *phCryptKey, CRYPTO_PROV_MAGIC_KEY, (OBJECTHDR**)&pKey)) { if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec))) @@ -454,7 +454,7 @@ HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTabl DWORD dwProtectFlags = (dwFlags & CRYPT_MACHINE_KEYSET) ? CRYPTPROTECT_LOCAL_MACHINE : 0;
- if (!lookup_handle(&handle_table, hKeyContainer, RSAENH_MAGIC_CONTAINER, + if (!lookup_handle(&handle_table, hKeyContainer, CRYPTO_PROV_MAGIC_CONTAINER, (OBJECTHDR**)&pKeyContainer)) return (HCRYPTPROV)INVALID_HANDLE_VALUE;
@@ -466,10 +466,10 @@ HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTabl */ if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE, dwProtectFlags, &hCryptKey)) - release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); + release_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY); if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE, dwProtectFlags, &hCryptKey)) - release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); + release_handle(&handle_table, hCryptKey, CRYPTO_PROV_MAGIC_KEY); }
return hKeyContainer; @@ -478,7 +478,7 @@ HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTabl /****************************************************************************** * new_key_container [Internal] * - * Create a new key container. The personality (RSA Base, Strong or Enhanced CP) + * Create a new key container. The personality * of the CSP is determined via the pVTable->pszProvName string. * * PARAMS @@ -495,7 +495,7 @@ HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableP HCRYPTPROV hKeyContainer; DWORD i;
- hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER), RSAENH_MAGIC_CONTAINER, + hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER), CRYPTO_PROV_MAGIC_CONTAINER, destroy_key_container, (OBJECTHDR**)&pKeyContainer); if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE) { diff --git a/dlls/rsaenh/cryptoprovutils.h b/dlls/rsaenh/cryptoprovutils.h index f745ada8d4..3a756d3735 100644 --- a/dlls/rsaenh/cryptoprovutils.h +++ b/dlls/rsaenh/cryptoprovutils.h @@ -47,8 +47,8 @@ typedef struct _SCHANNEL_INFO CRYPT_DATA_BLOB blobServerRandom; } SCHANNEL_INFO;
-#define RSAENH_MAX_KEY_SIZE 64 -#define RSAENH_MAX_BLOCK_SIZE 24 +#define CRYPTO_PROV_MAX_KEY_SIZE 64 +#define CRYPTO_PROV_MAX_BLOCK_SIZE 24 typedef struct tagCRYPTKEY { OBJECTHDR header; @@ -63,9 +63,9 @@ typedef struct tagCRYPTKEY 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]; + BYTE abKeyValue[CRYPTO_PROV_MAX_KEY_SIZE]; + BYTE abInitVector[CRYPTO_PROV_MAX_BLOCK_SIZE]; + BYTE abChainVector[CRYPTO_PROV_MAX_BLOCK_SIZE]; SCHANNEL_INFO siSChannelInfo; CRYPT_DATA_BLOB blobHmacKey; } CRYPTKEY;
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/dssenh/Makefile.in | 5 ++++ dlls/dssenh/dssenh.rgs | 60 +++++++++++++++++++++++++++++++++++++++++ dlls/dssenh/rsrc.rc | 31 +++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 dlls/dssenh/dssenh.rgs create mode 100644 dlls/dssenh/rsrc.rc
diff --git a/dlls/dssenh/Makefile.in b/dlls/dssenh/Makefile.in index 4f05beee51..132ad755ee 100644 --- a/dlls/dssenh/Makefile.in +++ b/dlls/dssenh/Makefile.in @@ -1,6 +1,11 @@ MODULE = dssenh.dll +IMPORTLIB = dssenh +IMPORTS = bcrypt crypt32 advapi32 +EXTRAINCL = -I$(top_srcdir)/dlls/
EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ main.c + +RC_SRCS = rsrc.rc diff --git a/dlls/dssenh/dssenh.rgs b/dlls/dssenh/dssenh.rgs new file mode 100644 index 0000000000..e16d8e0bc7 --- /dev/null +++ b/dlls/dssenh/dssenh.rgs @@ -0,0 +1,60 @@ +HKLM +{ + NoRemove Software + { + NoRemove Microsoft + { + NoRemove Cryptography + { + NoRemove Defaults + { + NoRemove Provider + { + ForceRemove 'Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider' + { + val 'Image Path' = s '%MODULE%' + 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' + { + ForceRemove 'Type 013' + { + 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/dssenh/rsrc.rc b/dlls/dssenh/rsrc.rc new file mode 100644 index 0000000000..3ec4fc17f1 --- /dev/null +++ b/dlls/dssenh/rsrc.rc @@ -0,0 +1,31 @@ +/* + * Resources for dssenh + * + * Copyright (c) 2007 Alexandre Julliard + * + * 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 + */ + +/* @makedep: dssenh.rgs */ +1 WINE_REGISTRY dssenh.rgs + +#define WINE_FILEDESCRIPTION_STR "Wine dssenh" +#define WINE_FILENAME_STR "dssenh.dll" +#define WINE_FILEVERSION 5,1,2600,2180 +#define WINE_FILEVERSION_STR "5.1.2600.2180" +#define WINE_PRODUCTVERSION 5,1,2600,2180 +#define WINE_PRODUCTVERSION_STR "5.1.2600.2180" + +#include "wine/wine_common_ver.rc"
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/rsaenh/cryptoprovutils.c | 120 ++++++++++++++++++++++++++++++++++ dlls/rsaenh/cryptoprovutils.h | 3 + dlls/rsaenh/rsaenh.c | 75 +-------------------- 3 files changed, 125 insertions(+), 73 deletions(-)
diff --git a/dlls/rsaenh/cryptoprovutils.c b/dlls/rsaenh/cryptoprovutils.c index ed3b16b13a..e4580a655d 100644 --- a/dlls/rsaenh/cryptoprovutils.c +++ b/dlls/rsaenh/cryptoprovutils.c @@ -531,3 +531,123 @@ HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableP return hKeyContainer; }
+/****************************************************************************** + * CPAcquireContext [internal] + * + * 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 WINAPI 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 [internal] + * + * Release a key container. + * + * PARAMS + * hProv [I] Key container to be released. + * dwFlags [I] Currently none defined. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI 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 index 3a756d3735..b5efd14491 100644 --- a/dlls/rsaenh/cryptoprovutils.h +++ b/dlls/rsaenh/cryptoprovutils.h @@ -88,4 +88,7 @@ HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTabl HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable); BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey); +BOOL WINAPI CRYPTO_PROV_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer, + DWORD dwFlags, PVTableProvStruc pVTable); +BOOL WINAPI CRYPTO_PROV_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags); #endif /* __WINE_CRYPTOPROVUTILS_H */ diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 310863a514..9a2756e5a3 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -1500,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); }
/****************************************************************************** @@ -3977,21 +3920,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); }
/******************************************************************************
Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/dssenh/Makefile.in | 4 +- dlls/dssenh/cryptoprovconfig.h | 83 +++++++++++++++ dlls/dssenh/cryptoprovutils.c | 22 ++++ dlls/dssenh/dssenh.c | 184 +++++++++++++++++++++++++++++++++ dlls/dssenh/dssenh.spec | 4 +- dlls/dssenh/handle.c | 22 ++++ dlls/dssenh/main.c | 59 ----------- dlls/rsaenh/cryptoprovconfig.h | 6 +- 8 files changed, 317 insertions(+), 67 deletions(-) create mode 100644 dlls/dssenh/cryptoprovconfig.h create mode 100644 dlls/dssenh/cryptoprovutils.c create mode 100644 dlls/dssenh/dssenh.c create mode 100644 dlls/dssenh/handle.c delete mode 100644 dlls/dssenh/main.c
diff --git a/dlls/dssenh/Makefile.in b/dlls/dssenh/Makefile.in index 132ad755ee..733e908bda 100644 --- a/dlls/dssenh/Makefile.in +++ b/dlls/dssenh/Makefile.in @@ -6,6 +6,8 @@ EXTRAINCL = -I$(top_srcdir)/dlls/ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ - main.c + dssenh.c \ + cryptoprovutils.c \ + handle.c
RC_SRCS = rsrc.rc diff --git a/dlls/dssenh/cryptoprovconfig.h b/dlls/dssenh/cryptoprovconfig.h new file mode 100644 index 0000000000..548ff15e5c --- /dev/null +++ b/dlls/dssenh/cryptoprovconfig.h @@ -0,0 +1,83 @@ +/* + * dlls/dssenh/cryptoprovconfig.h + * Definitions of crypto provider specific constants and structures. + * + * Copyright 2002 TransGaming Technologies (David Hammerton) + * Copyright 2004 Mike McCormack for CodeWeavers + * Copyright 2004, 2005 Michael Jung + * Copyright 2007 Vijay Kiran Kamuju + * Copyright 2019 Zhang Shuai + * + * 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" + +/****************************************************************************** + * 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} +}; + +/****************************************************************************** + * Define constants with CRYPTO_PROV prefix + */ +#define CRYPTO_PROV_REGKEY DSSENH_REGKEY +#define CRYPTO_PROV_MAGIC_KEY DSSENH_MAGIC_KEY +#define CRYPTO_PROV_MAGIC_CONTAINER DSSENH_MAGIC_CONTAINER + +#endif /* __WINE_CRYPTOPROVCONFIG_H */ diff --git a/dlls/dssenh/cryptoprovutils.c b/dlls/dssenh/cryptoprovutils.c new file mode 100644 index 0000000000..1cc859e6bc --- /dev/null +++ b/dlls/dssenh/cryptoprovutils.c @@ -0,0 +1,22 @@ +/* + * dlls/dssenh/cryptoprovutils.c + * Utility functions to implement crypto privider. + * + * Copyright 2019 Zhang Shuai + * + * 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 "rsaenh/cryptoprovutils.c" diff --git a/dlls/dssenh/dssenh.c b/dlls/dssenh/dssenh.c new file mode 100644 index 0000000000..474d3f53eb --- /dev/null +++ b/dlls/dssenh/dssenh.c @@ -0,0 +1,184 @@ +/* + * dlls/dssenh/dssenh.c + * DSSENH - DSS encryption for Wine + * + * Copyright 2019 Zhang Shuai + * + * 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 "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); + +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", hInstance, fdwReason, reserved); + + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + 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; +} + +/***************************************************** + * DllRegisterServer (DSSENH.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/***************************************************** + * DllUnregisterServer (DSSENH.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + 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; +} + +/****************************************************************************** + * CPAcquireContext (DSSENH.@) + * + * 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 VTableProvStruc 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 WINAPI DSSENH_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer, + DWORD dwFlags, PVTableProvStruc pVTable) +{ + return CRYPTO_PROV_CPAcquireContext(phProv, pszContainer, dwFlags, pVTable); +} + +/****************************************************************************** + * CPReleaseContext (DSSENH.@) + * + * Release a key container. + * + * PARAMS + * hProv [I] Key container to be released. + * dwFlags [I] Currently none defined. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI DSSENH_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags) +{ + return CRYPTO_PROV_CPReleaseContext(hProv, dwFlags); +} diff --git a/dlls/dssenh/dssenh.spec b/dlls/dssenh/dssenh.spec index c5c2545281..42768f48ae 100644 --- a/dlls/dssenh/dssenh.spec +++ b/dlls/dssenh/dssenh.spec @@ -1,4 +1,4 @@ -@ stub CPAcquireContext +@ stdcall CPAcquireContext(ptr str long ptr) DSSENH_CPAcquireContext @ stub CPCreateHash @ stub CPDecrypt @ stub CPDeriveKey @@ -17,7 +17,7 @@ @ stub CPHashData @ stub CPHashSessionKey @ stub CPImportKey -@ stub CPReleaseContext +@ stdcall CPReleaseContext(long long) DSSENH_CPReleaseContext @ stub CPSetHashParam @ stub CPSetKeyParam @ stub CPSetProvParam diff --git a/dlls/dssenh/handle.c b/dlls/dssenh/handle.c new file mode 100644 index 0000000000..f5bb1f7205 --- /dev/null +++ b/dlls/dssenh/handle.c @@ -0,0 +1,22 @@ +/* + * dlls/dssenh/handle.c + * Support code to manage HANDLE tables. + * + * Copyright 2019 Zhang Shuai + * + * 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 "rsaenh/handle.c" diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c deleted file mode 100644 index b60b3447a3..0000000000 --- a/dlls/dssenh/main.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008 Maarten Lankhorst - * - * 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 "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(dssenh); - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); - - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - } - return TRUE; -} - -/***************************************************** - * DllRegisterServer (DSSENH.@) - */ -HRESULT WINAPI DllRegisterServer(void) -{ - FIXME("Not implemented.\n"); - return E_UNEXPECTED; -} - -/***************************************************** - * DllUnregisterServer (DSSENH.@) - */ -HRESULT WINAPI DllUnregisterServer(void) -{ - FIXME("Not implemented.\n"); - return E_UNEXPECTED; -} diff --git a/dlls/rsaenh/cryptoprovconfig.h b/dlls/rsaenh/cryptoprovconfig.h index e482d37ad4..c93ef3000f 100644 --- a/dlls/rsaenh/cryptoprovconfig.h +++ b/dlls/rsaenh/cryptoprovconfig.h @@ -1,10 +1,6 @@ /* * 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. + * Definitions of crypto provider specific constants and structures. * * Copyright 2002 TransGaming Technologies (David Hammerton) * Copyright 2004 Mike McCormack for CodeWeavers