Keep all REAMDEs in sync.
[wine] / dlls / rsabase / main.c
1 /*
2  * RSABASE - RSA encryption for Wine
3  *
4  * Copyright 2004 Mike McCormack for CodeWeavers
5  * Copyright 2002 TransGaming Technologies
6  *
7  * David Hammerton
8  *
9  * (based upon code from dlls/wininet/netconnection.c)
10  *
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.
15  *
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.
20  *
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
24
25  */
26
27
28 #include "config.h"
29 #include "wine/port.h"
30
31 #include <stdarg.h>
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winreg.h"
36 #include "wincrypt.h"
37
38 #ifdef HAVE_OPENSSL_SSL_H
39 #define DSA __ssl_DSA  /* avoid conflict with commctrl.h */
40 #undef FAR
41 # include <openssl/rand.h>
42 #undef FAR
43 #define FAR do_not_use_this_in_wine
44 #undef DSA
45 #endif
46
47 #include "wine/library.h"
48 #include "wine/debug.h"
49
50 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
51
52 #define RSABASE_MAGIC 0x52534100
53
54 #ifdef HAVE_OPENSSL_SSL_H
55
56 #ifndef SONAME_LIBCRYPTO
57 #define SONAME_LIBCRYPTO "libcrypto.so"
58 #endif
59
60 static void *libcrypto;
61
62 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
63
64 /* OpenSSL funtions that we use */
65 MAKE_FUNCPTR(RAND_bytes);
66
67 static BOOL load_libcrypto( void )
68 {
69     libcrypto = wine_dlopen(SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0);
70     if (!libcrypto)
71     {
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");
74         return FALSE;
75     }
76
77     #define GETFUNC(x) \
78     p##x = wine_dlsym(libcrypto, #x, NULL, 0); \
79     if (!p##x) \
80     { \
81         ERR("failed to load symbol %s\n", #x); \
82         return FALSE; \
83     }
84
85     GETFUNC(RAND_bytes);
86
87     return TRUE;
88 }
89
90 #endif
91
92 typedef struct _RSA_CryptProv
93 {
94     DWORD dwMagic;
95 } RSA_CryptProv;
96
97 BOOL WINAPI RSA_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer,
98                    DWORD dwFlags, PVTableProvStruc pVTable)
99 {
100     TRACE("%p %s %08lx %p\n", phProv, debugstr_a(pszContainer),
101            dwFlags, pVTable);
102
103 #ifdef HAVE_OPENSSL_SSL_H
104
105     if( !load_libcrypto() )
106         return FALSE;
107     else
108     {
109         RSA_CryptProv *cp = HeapAlloc( GetProcessHeap(), 0, sizeof (RSA_CryptProv) );
110         if( !cp )
111         {
112             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
113             return FALSE;
114         }
115
116         cp->dwMagic = RSABASE_MAGIC;
117
118         *phProv = (HCRYPTPROV) cp;
119
120         SetLastError(ERROR_SUCCESS);
121         return TRUE;
122     }
123 #else
124     FIXME("You have to install libcrypto.so and development headers in order to use crypto API\n");
125     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
126     return FALSE;
127 #endif
128 }
129
130 BOOL WINAPI RSA_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash)
131 {
132     FIXME("%08lx %d %08lx %08lx %p\n", hProv, Algid, hKey, dwFlags, phHash);
133     return FALSE;
134 }
135
136 BOOL WINAPI RSA_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
137 {
138     FIXME("(stub)\n");
139     return FALSE;
140 }
141
142 BOOL WINAPI RSA_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey)
143 {
144     FIXME("(stub)\n");
145     return FALSE;
146 }
147
148 BOOL WINAPI RSA_CPDestroyHash(HCRYPTPROV hProv, HCRYPTHASH hHash)
149 {
150     FIXME("(stub)\n");
151     return FALSE;
152 }
153
154 BOOL WINAPI RSA_CPDestroyKey(HCRYPTPROV hProv, HCRYPTKEY hKey)
155 {
156     FIXME("(stub)\n");
157     return FALSE;
158 }
159
160 BOOL WINAPI RSA_CPDuplicateHash(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash)
161 {
162     FIXME("(stub)\n");
163     return FALSE;
164 }
165
166 BOOL WINAPI RSA_CPDuplicateKey(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
167 {
168     FIXME("(stub)\n");
169     return FALSE;
170 }
171
172 BOOL WINAPI RSA_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
173 {
174     FIXME("(stub)\n");
175     return FALSE;
176 }
177
178 BOOL WINAPI RSA_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
179 {
180     FIXME("(stub)\n");
181     return FALSE;
182 }
183
184 BOOL WINAPI RSA_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
185 {
186     FIXME("(stub)\n");
187     return FALSE;
188 }
189
190 BOOL WINAPI RSA_CPGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
191 {
192     BOOL ret = FALSE;
193     RSA_CryptProv *cp = (RSA_CryptProv*) hProv;
194
195     TRACE("%08lx %ld %p\n", hProv, dwLen, pbBuffer);
196
197     if( cp && ( cp->dwMagic != RSABASE_MAGIC ) )
198         return FALSE;
199
200 #ifdef HAVE_OPENSSL_SSL_H
201
202     if( !pRAND_bytes)
203         return FALSE;
204     ret = pRAND_bytes( pbBuffer, dwLen );
205
206 #endif
207
208     return ret;
209 }
210
211 BOOL WINAPI RSA_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
212 {
213     FIXME("(stub)\n");
214     return FALSE;
215 }
216
217 BOOL WINAPI RSA_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
218 {
219     FIXME("(stub)\n");
220     return FALSE;
221 }
222
223 BOOL WINAPI RSA_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
224 {
225     FIXME("(stub)\n");
226     return FALSE;
227 }
228
229 BOOL WINAPI RSA_CPGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
230 {
231     FIXME("(stub)\n");
232     return FALSE;
233 }
234
235 BOOL WINAPI RSA_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
236 {
237     FIXME("(stub)\n");
238     return FALSE;
239 }
240
241 BOOL WINAPI RSA_CPHashSessionKey(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags)
242 {
243     FIXME("(stub)\n");
244     return FALSE;
245 }
246
247 BOOL WINAPI RSA_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
248 {
249     FIXME("(stub)\n");
250     return FALSE;
251 }
252
253 BOOL WINAPI RSA_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
254 {
255     RSA_CryptProv *cp = (RSA_CryptProv*) hProv;
256
257     TRACE("%08lx %08lx\n", hProv, dwFlags);
258
259     if( cp && ( cp->dwMagic != RSABASE_MAGIC ) )
260         return FALSE;
261
262     HeapFree( GetProcessHeap(), 0, cp );
263
264     return TRUE;
265 }
266
267 BOOL WINAPI RSA_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
268 {
269     FIXME("(stub)\n");
270     return FALSE;
271 }
272
273 BOOL WINAPI RSA_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
274 {
275     FIXME("(stub)\n");
276     return FALSE;
277 }
278
279 BOOL WINAPI RSA_CPSetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
280 {
281     FIXME("(stub)\n");
282     return FALSE;
283 }
284
285 BOOL WINAPI RSA_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
286 {
287     FIXME("(stub)\n");
288     return FALSE;
289 }
290
291 BOOL WINAPI RSA_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
292 {
293     FIXME("(stub)\n");
294     return FALSE;
295 }
296
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};
307
308 /***********************************************************************
309  *              DllRegisterServer (RSABASE.@)
310  */
311 HRESULT WINAPI RSABASE_DllRegisterServer()
312 {
313     HKEY key;
314     DWORD dp;
315     long apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szRSAKey, 0, NULL,
316      REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp);
317
318     if (apiRet == ERROR_SUCCESS)
319     {
320         if (dp == REG_CREATED_NEW_KEY)
321         {
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 };
326             DWORD type = 1;
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));
331         }
332         RegCloseKey(key);
333     }
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)
337     {
338         if (dp == REG_CREATED_NEW_KEY)
339         {
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 };
350
351             RegSetValueExW(key, szName, 0, REG_SZ, (LPBYTE)szRSAName, sizeof(szRSAName));
352             RegSetValueExW(key, szTypeName, 0, REG_SZ, (LPBYTE)szRSATypeName, sizeof(szRSATypeName));
353         }
354         RegCloseKey(key);
355     }
356     return HRESULT_FROM_WIN32(apiRet);
357 }
358
359 /***********************************************************************
360  *              DllUnregisterServer (RSABASE.@)
361  */
362 HRESULT WINAPI RSABASE_DllUnregisterServer()
363 {
364     RegDeleteKeyW(HKEY_LOCAL_MACHINE, szRSAKey);
365     RegDeleteKeyW(HKEY_LOCAL_MACHINE, szRSAKey2);
366     return S_OK;
367 }