Signed-off-by: Zhang Shuai wxsxsdz@gmail.com --- dlls/dssenh/Makefile.in | 14 +++- dlls/dssenh/dssenh.rgs | 60 +++++++++++++++ dlls/dssenh/dssenh.spec | 4 +- dlls/dssenh/rsrc.rc | 31 ++++++++ dlls/rsaenh/rsaenh.c | 161 +++++++++++++++++++++++++++++++++++----- 5 files changed, 247 insertions(+), 23 deletions(-) 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..80c904fcab 100644 --- a/dlls/dssenh/Makefile.in +++ b/dlls/dssenh/Makefile.in @@ -1,6 +1,18 @@ MODULE = dssenh.dll +IMPORTLIB = dssenh +IMPORTS = bcrypt crypt32 advapi32
EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ - main.c + ../rsaenh/aes.c \ + ../rsaenh/des.c \ + ../rsaenh/handle.c \ + ../rsaenh/implglue.c \ + ../rsaenh/mpi.c \ + ../rsaenh/rc2.c \ + ../rsaenh/rc4.c \ + ../rsaenh/rsa.c \ + ../rsaenh/rsaenh.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/dssenh.spec b/dlls/dssenh/dssenh.spec index c5c2545281..a98b26fc6f 100644 --- a/dlls/dssenh/dssenh.spec +++ b/dlls/dssenh/dssenh.spec @@ -1,4 +1,4 @@ -@ stub CPAcquireContext +@ stdcall CPAcquireContext(ptr str long ptr) RSAENH_CPAcquireContext @ stub CPCreateHash @ stub CPDecrypt @ stub CPDeriveKey @@ -17,7 +17,7 @@ @ stub CPHashData @ stub CPHashSessionKey @ stub CPImportKey -@ stub CPReleaseContext +@ stdcall CPReleaseContext(long long) RSAENH_CPReleaseContext @ stub CPSetHashParam @ stub CPSetKeyParam @ stub CPSetProvParam 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" diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c index 9119d4be2d..8c0fb20d4b 100644 --- a/dlls/rsaenh/rsaenh.c +++ b/dlls/rsaenh/rsaenh.c @@ -39,6 +39,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
static HINSTANCE instance; +static CHAR szDllName[MAX_PATH]; +#define provider_is_rsa() (szDllName[0] == 'r' && szDllName[1] == 's' && szDllName[2] == 'a')
/****************************************************************************** * CRYPTHASH - hash objects @@ -112,6 +114,10 @@ typedef struct tagCRYPTKEY #define RSAENH_PERSONALITY_ENHANCED 2u #define RSAENH_PERSONALITY_SCHANNEL 3u #define RSAENH_PERSONALITY_AES 4u +#define DSSENH_PERSONALITY_BASE 5u +#define DSSENH_PERSONALITY_BASE_DH 6u +#define DSSENH_PERSONALITY_ENHANCED 7u +#define DSSENH_PERSONALITY_SCHANNEL 8u
#define RSAENH_MAGIC_CONTAINER 0x26384993u typedef struct tagKEYCONTAINER @@ -150,6 +156,7 @@ typedef struct tagKEYCONTAINER #define RSAENH_TLS1_VERSION_MAJOR 3 #define RSAENH_TLS1_VERSION_MINOR 1 #define RSAENH_REGKEY "Software\Wine\Crypto\RSA\%s" +#define DSSENH_REGKEY "Software\Wine\Crypto\DSS\%s"
#define RSAENH_MIN(a,b) ((a)<(b)?(a):(b)) /****************************************************************************** @@ -158,7 +165,7 @@ typedef struct tagKEYCONTAINER #define RSAENH_MAX_ENUMALGS 24 #define RSAENH_PCT1_SSL2_SSL3_TLS1 (CRYPT_FLAG_PCT1|CRYPT_FLAG_SSL2|CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1) #define S(s) sizeof(s), s -static const PROV_ENUMALGS_EX aProvEnumAlgsEx[5][RSAENH_MAX_ENUMALGS+1] = +static const PROV_ENUMALGS_EX aProvEnumAlgsEx[9][RSAENH_MAX_ENUMALGS+1] = { { {CALG_RC2, 40, 40, 56, 0, S("RC2"), S("RSA Data Security's RC2")}, @@ -254,6 +261,61 @@ static const PROV_ENUMALGS_EX aProvEnumAlgsEx[5][RSAENH_MAX_ENUMALGS+1] = {CALG_RSA_KEYX, 1024, 384, 16384, CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC, S("RSA_KEYX"), S("RSA Key Exchange")}, {CALG_HMAC, 0, 0, 0, 0, S("HMAC"), S("Hugo's MAC (HMAC)")}, {0, 0, 0, 0, 0, S(""), S("")} + }, + /* MS_DEF_DSS_PROV */ + { + {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")}, + {CALG_MD5, 128, 128, 128, 0, S("MD5"), S("Message Digest 5 (MD5)")}, + {CALG_DSS_SIGN, 1024, 512, 1024, CRYPT_FLAG_SIGNING, S("DSA_SIGN"), S("Digital Signature Algorithm")}, + {0, 0, 0, 0, 0, S(""), S("")} + }, + /* MS_DEF_DSS_DH_PROV */ + { + {CALG_CYLINK_MEK, 40, 40, 40, 0, S("CYLINK MEK"), S("CYLINK Message Encryption Algorithm")}, + {CALG_RC2, 40, 40, 56, 0, S("RC2"), S("RSA Data Security's RC2")}, + {CALG_RC4, 40, 40, 56, 0, S("RC4"), S("RSA Data Security's RC4")}, + {CALG_DES, 56, 56, 56, 0, S("DES"), S("Data Encryption Standard (DES)")}, + {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")}, + {CALG_MD5, 128, 128, 128, 0, S("MD5"), S("Message Digest 5 (MD5)")}, + {CALG_DSS_SIGN, 1024, 512, 1024, CRYPT_FLAG_SIGNING, S("DSA_SIGN"), S("Digital Signature Algorithm")}, + {CALG_DH_SF, 512, 512, 1024, 0, S("DH_KEYX"), S("Diffie-Hellman Key Exchange Algorithm")}, + {CALG_DH_EPHEM, 512, 512, 1024, 0, S("DH_KEYX"), S("Diffie-Hellman Ephemeral Algorithm")}, + {0, 0, 0, 0, 0, S(""), S("")} + }, + /* MS_ENH_DSS_DH_PROV */ + { + {CALG_CYLINK_MEK, 40, 40, 40, 0, S("CYLINK MEK"), S("CYLINK Message Encryption Algorithm")}, + {CALG_RC2, 128, 40, 128, 0, S("RC2"), S("RSA Data Security's RC2")}, + {CALG_RC4, 128, 40, 128, 0, S("RC4"), S("RSA Data Security's RC4")}, + {CALG_3DES_112, 112, 112, 112, 0, S("3DES TWO KEY"), S("Two Key Triple DES")}, + {CALG_3DES, 168, 168, 168, 0, S("3DES"), S("Three Key Triple DES")}, + {CALG_DES, 56, 56, 56, 0, S("DES"), S("Data Encryption Standard (DES)")}, + {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")}, + {CALG_MD5, 128, 128, 128, 0, S("MD5"), S("Message Digest 5 (MD5)")}, + {CALG_DSS_SIGN, 1024, 512, 1024, CRYPT_FLAG_SIGNING, S("DSA_SIGN"), S("Digital Signature Algorithm")}, + {CALG_DH_SF, 512, 512, 1024, 0, S("DH_KEYX"), S("Diffie-Hellman Key Exchange Algorithm")}, + {CALG_DH_EPHEM, 512, 512, 1024, 0, S("DH_KEYX"), S("Diffie-Hellman Ephemeral Algorithm")}, + {0, 0, 0, 0, 0, S(""), S("")} + }, + /* MS_DEF_DH_SCHANNEL_PROV */ + { + {CALG_CYLINK_MEK, 40, 40, 40, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("CYLINK MEK"), S("CYLINK Message Encryption Algorithm")}, + {CALG_RC2, 40, 40, 128, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("RC2"), S("RSA Data Security's RC2")}, + {CALG_RC4, 40, 40, 128, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("RC4"), S("RSA Data Security's RC4")}, + {CALG_3DES_112, 112, 112, 112, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("3DES TWO KEY"), S("Two Key Triple DES")}, + {CALG_3DES, 168, 168, 168, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("3DES"), S("Three Key Triple DES")}, + {CALG_DES, 56, 56, 56, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("DES"), S("Data Encryption Standard (DES)")}, + {CALG_SHA, 160, 160, 160, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1|CRYPT_FLAG_SIGNING, S("SHA-1"), S("Secure Hash Algorithm (SHA-1)")}, + {CALG_MD5, 128, 128, 128, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1|CRYPT_FLAG_SIGNING, S("MD5"), S("Message Digest 5 (MD5)")}, + {CALG_DSS_SIGN, 1024, 512, 1024, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1|CRYPT_FLAG_SIGNING, S("DSA_SIGN"), S("Digital Signature Algorithm")}, + {CALG_DH_SF, 512, 512, 4096, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("DH_KEYX"), S("Diffie-Hellman Key Exchange Algorithm")}, + {CALG_DH_EPHEM, 512, 512, 4096, CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1, S("DH_KEYX"), S("Diffie-Hellman Ephemeral Algorithm")}, + {CALG_SSL3_MASTER, 384, 384, 384, CRYPT_FLAG_SSL3, S("SSL3 MASTER"), S("SSL3 Master")}, + {CALG_TLS1_MASTER, 384, 384, 384, CRYPT_FLAG_TLS1, S("TLS1 MASTER"), S("TLS1 Master")}, + {CALG_SCHANNEL_MASTER_HASH, 0, 0, -1, 0, S("SCH MASTER HASH"), S("SChannel Master Hash")}, + {CALG_SCHANNEL_MAC_KEY, 0, 0, -1, 0, S("SCH MAC KEY"), S("SChannel MAC Key")}, + {CALG_SCHANNEL_ENC_KEY, 0, 0, -1, 0, S("SCH ENC KEY"), S("SChannel Encryption Key")}, + {0, 0, 0, 0, 0, S(""), S("")} } }; #undef S @@ -350,6 +412,40 @@ RSAENH_CPHashData( */ static struct handle_table handle_table;
+/****************************************************************************** + * get_dll_name [Internal] + * + * Get the dll name by calling GetModuleFileNameA. Use dll name to distinguish + * whether we are RSA or DSS. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + * NOTES + * We assume the filepath returned by GetModuleFileNameA is always of the + * format "C:\windows\system32\xxxxxx.dll". + */ +static BOOL get_dll_name(void) +{ + DWORD i, dwLastBkslashPos = -1; + GetModuleFileNameA(instance, szDllName, sizeof(szDllName)); + if (GetLastError() != ERROR_SUCCESS) { + TRACE("Unable to get dll name: error %08lx", GetLastError()); + return FALSE; + } + for (i = 0; szDllName[i]; i++) { + if (szDllName[i] == '\') + dwLastBkslashPos = i; + } + if (dwLastBkslashPos != -1) { + for (i = 0; szDllName[i + dwLastBkslashPos]; i++) { + szDllName[i] = szDllName[i + dwLastBkslashPos + 1]; + } + } + return TRUE; +} + /****************************************************************************** * DllMain (RSAENH.@) * @@ -363,6 +459,9 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID reserved) instance = hInstance; DisableThreadLibraryCalls(hInstance); init_handle_table(&handle_table); + if (!get_dll_name()) { + return FALSE; + } break;
case DLL_PROCESS_DETACH: @@ -1084,15 +1183,18 @@ static BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY * CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH]; HKEY hRootKey;
- sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName); + if (provider_is_rsa()) + sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName); + else /* provider_is_dss */ + sprintf(szRSABase, DSSENH_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 */ + /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA|DSS */ + /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA|DSS */ return RegCreateKeyExA(hRootKey, szRSABase, 0, NULL, REG_OPTION_NON_VOLATILE, sam, NULL, phKey, NULL) == ERROR_SUCCESS; @@ -1115,15 +1217,18 @@ static BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM ac CHAR szRSABase[sizeof(RSAENH_REGKEY) + MAX_PATH]; HKEY hRootKey;
- sprintf(szRSABase, RSAENH_REGKEY, pszContainerName); + if (provider_is_rsa()) + sprintf(szRSABase, RSAENH_REGKEY, pszContainerName); + else /* provider_is_dss */ + sprintf(szRSABase, DSSENH_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 */ + /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA|DSS */ + /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA|DSS */ return RegOpenKeyExA(hRootKey, szRSABase, 0, access, phKey) == ERROR_SUCCESS; } @@ -1142,7 +1247,10 @@ static BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags) CHAR szRegKey[sizeof(RSAENH_REGKEY) + MAX_PATH]; HKEY hRootKey;
- sprintf(szRegKey, RSAENH_REGKEY, pszContainerName); + if (provider_is_rsa()) + sprintf(szRegKey, RSAENH_REGKEY, pszContainerName); + else /* provider_is_dss */ + sprintf(szRegKey, DSSENH_REGKEY, pszContainerName);
if (dwFlags & CRYPT_MACHINE_KEYSET) hRootKey = HKEY_LOCAL_MACHINE; @@ -1171,7 +1279,7 @@ static 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\RSA|DSS\$SID$\some_hex_string */
if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) @@ -1281,17 +1389,30 @@ 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; + if (provider_is_rsa()) { + 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; + } + } + else /* provider_is_dss */ { + if (!strcmp(pVTable->pszProvName, MS_DEF_DSS_DH_PROV_A)) { + pKeyContainer->dwPersonality = DSSENH_PERSONALITY_BASE_DH; + } else if (!strcmp(pVTable->pszProvName, MS_DEF_DH_SCHANNEL_PROV_A)) { + pKeyContainer->dwPersonality = DSSENH_PERSONALITY_SCHANNEL; + } else if (!strcmp(pVTable->pszProvName, MS_DEF_DSS_PROV_A)) { + pKeyContainer->dwPersonality = DSSENH_PERSONALITY_BASE; + } else { + pKeyContainer->dwPersonality = DSSENH_PERSONALITY_ENHANCED; + } } }