| /* | |
| * RSABASE - RSA encryption for Wine | |
| * | |
| * Copyright 2004 Mike McCormack for CodeWeavers | |
| * Copyright 2002 TransGaming Technologies | |
| * | |
| * David Hammerton | |
| * | |
| * (based upon code from dlls/wininet/netconnection.c) | |
| * | |
| * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| */ | |
| #include "config.h" | |
| #include "wine/port.h" | |
| #include <stdarg.h> | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "winreg.h" | |
| #include "wincrypt.h" | |
| #ifdef HAVE_OPENSSL_SSL_H | |
| #define DSA __ssl_DSA /* avoid conflict with commctrl.h */ | |
| #undef FAR | |
| # include <openssl/rand.h> | |
| #undef FAR | |
| #define FAR do_not_use_this_in_wine | |
| #undef DSA | |
| #endif | |
| #include "wine/library.h" | |
| #include "wine/debug.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(crypt); | |
| #define RSABASE_MAGIC 0x52534100 | |
| #ifdef HAVE_OPENSSL_SSL_H | |
| #ifndef SONAME_LIBCRYPTO | |
| #define SONAME_LIBCRYPTO "libcrypto.so" | |
| #endif | |
| static void *libcrypto; | |
| #define MAKE_FUNCPTR(f) static typeof(f) * p##f | |
| /* OpenSSL funtions that we use */ | |
| MAKE_FUNCPTR(RAND_bytes); | |
| static BOOL load_libcrypto( void ) | |
| { | |
| libcrypto = wine_dlopen(SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0); | |
| if (!libcrypto) | |
| { | |
| MESSAGE("Couldn't load %s, RSA encryption not available.\n", SONAME_LIBCRYPTO); | |
| MESSAGE("Install the openssl package if you're have problems.\n"); | |
| return FALSE; | |
| } | |
| #define GETFUNC(x) \ | |
| p##x = wine_dlsym(libcrypto, #x, NULL, 0); \ | |
| if (!p##x) \ | |
| { \ | |
| ERR("failed to load symbol %s\n", #x); \ | |
| return FALSE; \ | |
| } | |
| GETFUNC(RAND_bytes); | |
| return TRUE; | |
| } | |
| #endif | |
| typedef struct _RSA_CryptProv | |
| { | |
| DWORD dwMagic; | |
| } RSA_CryptProv; | |
| BOOL WINAPI RSA_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer, | |
| DWORD dwFlags, PVTableProvStruc pVTable) | |
| { | |
| TRACE("%p %s %08lx %p\n", phProv, debugstr_a(pszContainer), | |
| dwFlags, pVTable); | |
| #ifdef HAVE_OPENSSL_SSL_H | |
| if( !load_libcrypto() ) | |
| return FALSE; | |
| else | |
| { | |
| RSA_CryptProv *cp = HeapAlloc( GetProcessHeap(), 0, sizeof (RSA_CryptProv) ); | |
| if( !cp ) | |
| { | |
| SetLastError(ERROR_NOT_ENOUGH_MEMORY); | |
| return FALSE; | |
| } | |
| cp->dwMagic = RSABASE_MAGIC; | |
| *phProv = (HCRYPTPROV) cp; | |
| SetLastError(ERROR_SUCCESS); | |
| return TRUE; | |
| } | |
| #else | |
| FIXME("You have to install libcrypto.so and development headers in order to use crypto API\n"); | |
| SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
| return FALSE; | |
| #endif | |
| } | |
| BOOL WINAPI RSA_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash) | |
| { | |
| FIXME("%08lx %d %08lx %08lx %p\n", hProv, Algid, hKey, dwFlags, phHash); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPDestroyHash(HCRYPTPROV hProv, HCRYPTHASH hHash) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPDestroyKey(HCRYPTPROV hProv, HCRYPTKEY hKey) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPDuplicateHash(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPDuplicateKey(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) | |
| { | |
| BOOL ret = FALSE; | |
| RSA_CryptProv *cp = (RSA_CryptProv*) hProv; | |
| TRACE("%08lx %ld %p\n", hProv, dwLen, pbBuffer); | |
| if( cp && ( cp->dwMagic != RSABASE_MAGIC ) ) | |
| return FALSE; | |
| #ifdef HAVE_OPENSSL_SSL_H | |
| if( !pRAND_bytes) | |
| return FALSE; | |
| ret = pRAND_bytes( pbBuffer, dwLen ); | |
| #endif | |
| return ret; | |
| } | |
| BOOL WINAPI RSA_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbData, DWORD dwDataLen, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPHashSessionKey(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags) | |
| { | |
| RSA_CryptProv *cp = (RSA_CryptProv*) hProv; | |
| TRACE("%08lx %08lx\n", hProv, dwFlags); | |
| if( cp && ( cp->dwMagic != RSABASE_MAGIC ) ) | |
| return FALSE; | |
| HeapFree( GetProcessHeap(), 0, cp ); | |
| return TRUE; | |
| } | |
| BOOL WINAPI RSA_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPSetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| BOOL WINAPI RSA_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags) | |
| { | |
| FIXME("(stub)\n"); | |
| return FALSE; | |
| } | |
| static const WCHAR szRSAKey[] = { 'S','o','f','t','w','a','r','e','\\', | |
| 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r', | |
| 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v', | |
| 'i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ','B','a','s', | |
| 'e',' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r', | |
| 'o','v','i','d','e','r',' ','v','1','.','0',0 }; | |
| static const WCHAR szRSAKey2[] = { 'S','o','f','t','w','a','r','e','\\', | |
| 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r', | |
| 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v', | |
| 'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','0','1',0}; | |
| /*********************************************************************** | |
| * DllRegisterServer (RSABASE.@) | |
| */ | |
| HRESULT WINAPI RSABASE_DllRegisterServer() | |
| { | |
| HKEY key; | |
| DWORD dp; | |
| long apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szRSAKey, 0, NULL, | |
| REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp); | |
| if (apiRet == ERROR_SUCCESS) | |
| { | |
| if (dp == REG_CREATED_NEW_KEY) | |
| { | |
| static const WCHAR szImagePath[] = { 'I','m','a','g','e',' ','P','a','t','h',0 }; | |
| static const WCHAR szRSABase[] = { 'r','s','a','b','a','s','e','.','d','l','l',0 }; | |
| static const WCHAR szType[] = { 'T','y','p','e',0 }; | |
| static const WCHAR szSignature[] = { 'S','i','g','n','a','t','u','r','e',0 }; | |
| DWORD type = 1; | |
| DWORD sign = 0xdeadbeef; | |
| RegSetValueExW(key, szImagePath, 0, REG_SZ, (LPBYTE)szRSABase, (lstrlenW(szRSABase) + 1) * sizeof(WCHAR)); | |
| RegSetValueExW(key, szType, 0, REG_DWORD, (LPBYTE)&type, sizeof(type)); | |
| RegSetValueExW(key, szSignature, 0, REG_BINARY, (LPBYTE)&sign, sizeof(sign)); | |
| } | |
| RegCloseKey(key); | |
| } | |
| if (apiRet == ERROR_SUCCESS) | |
| apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szRSAKey2, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp); | |
| if (apiRet == ERROR_SUCCESS) | |
| { | |
| if (dp == REG_CREATED_NEW_KEY) | |
| { | |
| static const WCHAR szName[] = { 'N','a','m','e',0 }; | |
| static const WCHAR szRSAName[] = { | |
| 'M','i','c','r','o','s','o','f','t',' ','B','a','s','e',' ','C', | |
| 'r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r', | |
| 'o','v','i','d','e','r',' ','v','1','.','0',0 }; | |
| static const WCHAR szTypeName[] = { 'T','y','p','e','N','a','m','e',0 }; | |
| static const WCHAR szRSATypeName[] = { | |
| 'R','S','A',' ','F','u','l','l',' ', | |
| '(','S','i','g','n','a','t','u','r','e',' ','a','n','d',' ', | |
| 'K','e','y',' ','E','x','c','h','a','n','g','e',')',0 }; | |
| RegSetValueExW(key, szName, 0, REG_SZ, (LPBYTE)szRSAName, sizeof(szRSAName)); | |
| RegSetValueExW(key, szTypeName, 0, REG_SZ, (LPBYTE)szRSATypeName, sizeof(szRSATypeName)); | |
| } | |
| RegCloseKey(key); | |
| } | |
| return HRESULT_FROM_WIN32(apiRet); | |
| } | |
| /*********************************************************************** | |
| * DllUnregisterServer (RSABASE.@) | |
| */ | |
| HRESULT WINAPI RSABASE_DllUnregisterServer() | |
| { | |
| RegDeleteKeyW(HKEY_LOCAL_MACHINE, szRSAKey); | |
| RegDeleteKeyW(HKEY_LOCAL_MACHINE, szRSAKey2); | |
| return S_OK; | |
| } |