2 * RSABASE - RSA encryption for Wine
4 * Copyright 2004 Mike McCormack for CodeWeavers
5 * Copyright 2002 TransGaming Technologies
9 * (based upon code from dlls/wininet/netconnection.c)
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "wine/port.h"
38 #ifdef HAVE_OPENSSL_SSL_H
39 #define DSA __ssl_DSA /* avoid conflict with commctrl.h */
41 # include <openssl/rand.h>
43 #define FAR do_not_use_this_in_wine
47 #include "wine/library.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
52 #define RSABASE_MAGIC 0x52534100
54 #ifdef HAVE_OPENSSL_SSL_H
56 #ifndef SONAME_LIBCRYPTO
57 #define SONAME_LIBCRYPTO "libcrypto.so"
60 static void *libcrypto
;
62 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
64 /* OpenSSL funtions that we use */
65 MAKE_FUNCPTR(RAND_bytes
);
67 static BOOL
load_libcrypto( void )
69 libcrypto
= wine_dlopen(SONAME_LIBCRYPTO
, RTLD_NOW
, NULL
, 0);
72 MESSAGE("Couldn't load %s, RSA encryption not available.\n", SONAME_LIBCRYPTO
);
73 MESSAGE("Install the openssl package if you're have problems.\n");
78 p##x = wine_dlsym(libcrypto, #x, NULL, 0); \
81 ERR("failed to load symbol %s\n", #x); \
92 typedef struct _RSA_CryptProv
97 BOOL WINAPI
RSA_CPAcquireContext(HCRYPTPROV
*phProv
, LPSTR pszContainer
,
98 DWORD dwFlags
, PVTableProvStruc pVTable
)
100 TRACE("%p %s %08lx %p\n", phProv
, debugstr_a(pszContainer
),
103 #ifdef HAVE_OPENSSL_SSL_H
105 if( !load_libcrypto() )
109 RSA_CryptProv
*cp
= HeapAlloc( GetProcessHeap(), 0, sizeof (RSA_CryptProv
) );
112 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
116 cp
->dwMagic
= RSABASE_MAGIC
;
118 *phProv
= (HCRYPTPROV
) cp
;
120 SetLastError(ERROR_SUCCESS
);
124 FIXME("You have to install libcrypto.so and development headers in order to use crypto API\n");
125 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
130 BOOL WINAPI
RSA_CPCreateHash(HCRYPTPROV hProv
, ALG_ID Algid
, HCRYPTKEY hKey
, DWORD dwFlags
, HCRYPTHASH
*phHash
)
132 FIXME("%08lx %d %08lx %08lx %p\n", hProv
, Algid
, hKey
, dwFlags
, phHash
);
136 BOOL WINAPI
RSA_CPDecrypt(HCRYPTPROV hProv
, HCRYPTKEY hKey
, HCRYPTHASH hHash
, BOOL Final
, DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
)
142 BOOL WINAPI
RSA_CPDeriveKey(HCRYPTPROV hProv
, ALG_ID Algid
, HCRYPTHASH hBaseData
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
148 BOOL WINAPI
RSA_CPDestroyHash(HCRYPTPROV hProv
, HCRYPTHASH hHash
)
154 BOOL WINAPI
RSA_CPDestroyKey(HCRYPTPROV hProv
, HCRYPTKEY hKey
)
160 BOOL WINAPI
RSA_CPDuplicateHash(HCRYPTPROV hUID
, HCRYPTHASH hHash
, DWORD
*pdwReserved
, DWORD dwFlags
, HCRYPTHASH
*phHash
)
166 BOOL WINAPI
RSA_CPDuplicateKey(HCRYPTPROV hUID
, HCRYPTKEY hKey
, DWORD
*pdwReserved
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
172 BOOL WINAPI
RSA_CPEncrypt(HCRYPTPROV hProv
, HCRYPTKEY hKey
, HCRYPTHASH hHash
, BOOL Final
, DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
, DWORD dwBufLen
)
178 BOOL WINAPI
RSA_CPExportKey(HCRYPTPROV hProv
, HCRYPTKEY hKey
, HCRYPTKEY hPubKey
, DWORD dwBlobType
, DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
)
184 BOOL WINAPI
RSA_CPGenKey(HCRYPTPROV hProv
, ALG_ID Algid
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
190 BOOL WINAPI
RSA_CPGenRandom(HCRYPTPROV hProv
, DWORD dwLen
, BYTE
*pbBuffer
)
193 RSA_CryptProv
*cp
= (RSA_CryptProv
*) hProv
;
195 TRACE("%08lx %ld %p\n", hProv
, dwLen
, pbBuffer
);
197 if( cp
&& ( cp
->dwMagic
!= RSABASE_MAGIC
) )
200 #ifdef HAVE_OPENSSL_SSL_H
204 ret
= pRAND_bytes( pbBuffer
, dwLen
);
211 BOOL WINAPI
RSA_CPGetHashParam(HCRYPTPROV hProv
, HCRYPTHASH hHash
, DWORD dwParam
, BYTE
*pbData
, DWORD
*pdwDataLen
, DWORD dwFlags
)
217 BOOL WINAPI
RSA_CPGetKeyParam(HCRYPTPROV hProv
, HCRYPTKEY hKey
, DWORD dwParam
, BYTE
*pbData
, DWORD
*pdwDataLen
, DWORD dwFlags
)
223 BOOL WINAPI
RSA_CPGetProvParam(HCRYPTPROV hProv
, DWORD dwParam
, BYTE
*pbData
, DWORD
*pdwDataLen
, DWORD dwFlags
)
229 BOOL WINAPI
RSA_CPGetUserKey(HCRYPTPROV hProv
, DWORD dwKeySpec
, HCRYPTKEY
*phUserKey
)
235 BOOL WINAPI
RSA_CPHashData(HCRYPTPROV hProv
, HCRYPTHASH hHash
, CONST BYTE
*pbData
, DWORD dwDataLen
, DWORD dwFlags
)
241 BOOL WINAPI
RSA_CPHashSessionKey(HCRYPTPROV hProv
, HCRYPTHASH hHash
, HCRYPTKEY hKey
, DWORD dwFlags
)
247 BOOL WINAPI
RSA_CPImportKey(HCRYPTPROV hProv
, CONST BYTE
*pbData
, DWORD dwDataLen
, HCRYPTKEY hPubKey
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
253 BOOL WINAPI
RSA_CPReleaseContext(HCRYPTPROV hProv
, DWORD dwFlags
)
255 RSA_CryptProv
*cp
= (RSA_CryptProv
*) hProv
;
257 TRACE("%08lx %08lx\n", hProv
, dwFlags
);
259 if( cp
&& ( cp
->dwMagic
!= RSABASE_MAGIC
) )
262 HeapFree( GetProcessHeap(), 0, cp
);
267 BOOL WINAPI
RSA_CPSetHashParam(HCRYPTPROV hProv
, HCRYPTHASH hHash
, DWORD dwParam
, BYTE
*pbData
, DWORD dwFlags
)
273 BOOL WINAPI
RSA_CPSetKeyParam(HCRYPTPROV hProv
, HCRYPTKEY hKey
, DWORD dwParam
, BYTE
*pbData
, DWORD dwFlags
)
279 BOOL WINAPI
RSA_CPSetProvParam(HCRYPTPROV hProv
, DWORD dwParam
, BYTE
*pbData
, DWORD dwFlags
)
285 BOOL WINAPI
RSA_CPSignHash(HCRYPTPROV hProv
, HCRYPTHASH hHash
, DWORD dwKeySpec
, LPCWSTR sDescription
, DWORD dwFlags
, BYTE
*pbSignature
, DWORD
*pdwSigLen
)
291 BOOL WINAPI
RSA_CPVerifySignature(HCRYPTPROV hProv
, HCRYPTHASH hHash
, CONST BYTE
*pbSignature
, DWORD dwSigLen
, HCRYPTKEY hPubKey
, LPCWSTR sDescription
, DWORD dwFlags
)
297 static const WCHAR szRSAKey
[] = { 'S','o','f','t','w','a','r','e','\\',
298 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
299 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
300 'i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ','B','a','s',
301 'e',' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r',
302 'o','v','i','d','e','r',' ','v','1','.','0',0 };
303 static const WCHAR szRSAKey2
[] = { 'S','o','f','t','w','a','r','e','\\',
304 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
305 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
306 'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','0','1',0};
308 /***********************************************************************
309 * DllRegisterServer (RSABASE.@)
311 HRESULT WINAPI
RSABASE_DllRegisterServer()
315 long apiRet
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szRSAKey
, 0, NULL
,
316 REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, &dp
);
318 if (apiRet
== ERROR_SUCCESS
)
320 if (dp
== REG_CREATED_NEW_KEY
)
322 static const WCHAR szImagePath
[] = { 'I','m','a','g','e',' ','P','a','t','h',0 };
323 static const WCHAR szRSABase
[] = { 'r','s','a','b','a','s','e','.','d','l','l',0 };
324 static const WCHAR szType
[] = { 'T','y','p','e',0 };
325 static const WCHAR szSignature
[] = { 'S','i','g','n','a','t','u','r','e',0 };
327 DWORD sign
= 0xdeadbeef;
328 RegSetValueExW(key
, szImagePath
, 0, REG_SZ
, (LPBYTE
)szRSABase
, (lstrlenW(szRSABase
) + 1) * sizeof(WCHAR
));
329 RegSetValueExW(key
, szType
, 0, REG_DWORD
, (LPBYTE
)&type
, sizeof(type
));
330 RegSetValueExW(key
, szSignature
, 0, REG_BINARY
, (LPBYTE
)&sign
, sizeof(sign
));
334 if (apiRet
== ERROR_SUCCESS
)
335 apiRet
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, szRSAKey2
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &key
, &dp
);
336 if (apiRet
== ERROR_SUCCESS
)
338 if (dp
== REG_CREATED_NEW_KEY
)
340 static const WCHAR szName
[] = { 'N','a','m','e',0 };
341 static const WCHAR szRSAName
[] = {
342 'M','i','c','r','o','s','o','f','t',' ','B','a','s','e',' ','C',
343 'r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r',
344 'o','v','i','d','e','r',' ','v','1','.','0',0 };
345 static const WCHAR szTypeName
[] = { 'T','y','p','e','N','a','m','e',0 };
346 static const WCHAR szRSATypeName
[] = {
347 'R','S','A',' ','F','u','l','l',' ',
348 '(','S','i','g','n','a','t','u','r','e',' ','a','n','d',' ',
349 'K','e','y',' ','E','x','c','h','a','n','g','e',')',0 };
351 RegSetValueExW(key
, szName
, 0, REG_SZ
, (LPBYTE
)szRSAName
, sizeof(szRSAName
));
352 RegSetValueExW(key
, szTypeName
, 0, REG_SZ
, (LPBYTE
)szRSATypeName
, sizeof(szRSATypeName
));
356 return HRESULT_FROM_WIN32(apiRet
);
359 /***********************************************************************
360 * DllUnregisterServer (RSABASE.@)
362 HRESULT WINAPI
RSABASE_DllUnregisterServer()
364 RegDeleteKeyW(HKEY_LOCAL_MACHINE
, szRSAKey
);
365 RegDeleteKeyW(HKEY_LOCAL_MACHINE
, szRSAKey2
);