Fixed DLLMODE handling (--mode is now --subsystem and uses -Wb).
[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     BOOL ret = FALSE;
101     RSA_CryptProv *cp;
102
103     TRACE("%p %s %08lx %p\n", phProv, debugstr_a(pszContainer),
104            dwFlags, pVTable);
105
106 #ifdef HAVE_OPENSSL_SSL_H
107
108     if( !load_libcrypto() )
109         return FALSE;
110
111     cp = HeapAlloc( GetProcessHeap(), 0, sizeof (RSA_CryptProv) );
112     if( !cp )
113     {
114         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
115         return FALSE;
116     }
117
118     cp->dwMagic = RSABASE_MAGIC;
119
120     *phProv = (HCRYPTPROV) cp;
121     ret = TRUE;
122
123 #endif
124
125     return ret;
126 }
127
128 BOOL WINAPI RSA_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash)
129 {
130     FIXME("%08lx %d %08lx %08lx %p\n", hProv, Algid, hKey, dwFlags, phHash);
131     return FALSE;
132 }
133
134 BOOL WINAPI RSA_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
135 {
136     FIXME("(stub)\n");
137     return FALSE;
138 }
139
140 BOOL WINAPI RSA_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey)
141 {
142     FIXME("(stub)\n");
143     return FALSE;
144 }
145
146 BOOL WINAPI RSA_CPDestroyHash(HCRYPTPROV hProv, HCRYPTHASH hHash)
147 {
148     FIXME("(stub)\n");
149     return FALSE;
150 }
151
152 BOOL WINAPI RSA_CPDestroyKey(HCRYPTPROV hProv, HCRYPTKEY hKey)
153 {
154     FIXME("(stub)\n");
155     return FALSE;
156 }
157
158 BOOL WINAPI RSA_CPDuplicateHash(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash)
159 {
160     FIXME("(stub)\n");
161     return FALSE;
162 }
163
164 BOOL WINAPI RSA_CPDuplicateKey(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
165 {
166     FIXME("(stub)\n");
167     return FALSE;
168 }
169
170 BOOL WINAPI RSA_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
171 {
172     FIXME("(stub)\n");
173     return FALSE;
174 }
175
176 BOOL WINAPI RSA_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
177 {
178     FIXME("(stub)\n");
179     return FALSE;
180 }
181
182 BOOL WINAPI RSA_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
183 {
184     FIXME("(stub)\n");
185     return FALSE;
186 }
187
188 BOOL WINAPI RSA_CPGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
189 {
190     BOOL ret = FALSE;
191     RSA_CryptProv *cp = (RSA_CryptProv*) hProv;
192
193     TRACE("%08lx %ld %p\n", hProv, dwLen, pbBuffer);
194
195     if( cp && ( cp->dwMagic != RSABASE_MAGIC ) )
196         return FALSE;
197
198 #ifdef HAVE_OPENSSL_SSL_H
199
200     if( !pRAND_bytes)
201         return FALSE;
202     ret = pRAND_bytes( pbBuffer, dwLen );
203
204 #endif
205
206     return ret;
207 }
208
209 BOOL WINAPI RSA_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
210 {
211     FIXME("(stub)\n");
212     return FALSE;
213 }
214
215 BOOL WINAPI RSA_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
216 {
217     FIXME("(stub)\n");
218     return FALSE;
219 }
220
221 BOOL WINAPI RSA_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
222 {
223     FIXME("(stub)\n");
224     return FALSE;
225 }
226
227 BOOL WINAPI RSA_CPGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
228 {
229     FIXME("(stub)\n");
230     return FALSE;
231 }
232
233 BOOL WINAPI RSA_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
234 {
235     FIXME("(stub)\n");
236     return FALSE;
237 }
238
239 BOOL WINAPI RSA_CPHashSessionKey(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags)
240 {
241     FIXME("(stub)\n");
242     return FALSE;
243 }
244
245 BOOL WINAPI RSA_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
246 {
247     FIXME("(stub)\n");
248     return FALSE;
249 }
250
251 BOOL WINAPI RSA_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags)
252 {
253     RSA_CryptProv *cp = (RSA_CryptProv*) hProv;
254
255     TRACE("%08lx %08lx\n", hProv, dwFlags);
256
257     if( cp && ( cp->dwMagic != RSABASE_MAGIC ) )
258         return FALSE;
259
260     HeapFree( GetProcessHeap(), 0, cp );
261
262     return TRUE;
263 }
264
265 BOOL WINAPI RSA_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
266 {
267     FIXME("(stub)\n");
268     return FALSE;
269 }
270
271 BOOL WINAPI RSA_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
272 {
273     FIXME("(stub)\n");
274     return FALSE;
275 }
276
277 BOOL WINAPI RSA_CPSetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
278 {
279     FIXME("(stub)\n");
280     return FALSE;
281 }
282
283 BOOL WINAPI RSA_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
284 {
285     FIXME("(stub)\n");
286     return FALSE;
287 }
288
289 BOOL WINAPI RSA_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
290 {
291     FIXME("(stub)\n");
292     return FALSE;
293 }
294
295 static const WCHAR szRSAKey[] = { 'S','o','f','t','w','a','r','e','\\',
296  'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
297  'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
298  'i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ','B','a','s',
299  'e',' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r',
300  'o','v','i','d','e','r',' ','v','1','.','0',0 };
301
302 /***********************************************************************
303  *              DllRegisterServer (RSABASE.@)
304  */
305 HRESULT WINAPI RSABASE_DllRegisterServer()
306 {
307     HKEY key;
308     DWORD dp;
309     long apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szRSAKey, 0, NULL,
310      REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp);
311
312     if (apiRet == ERROR_SUCCESS)
313     {
314         if (dp == REG_CREATED_NEW_KEY)
315         {
316             static const WCHAR szImagePath[] = { 'I','m','a','g','e','P','a',
317              't','h',0 };
318             static const WCHAR szRSABase[] = { 'r','s','a','b','a','s','e','.',
319              'd','l','l',0 };
320              static const WCHAR szType[] = { 'T','y','p','e',0 };
321              DWORD type = 1;
322
323             RegSetValueExW(key, szImagePath, 0, REG_SZ, (LPBYTE)szRSABase,
324              (lstrlenW(szRSABase) + 1) * sizeof(WCHAR));
325             RegSetValueExW(key, szType, 0, REG_DWORD, (LPBYTE)&type,
326              sizeof(type));
327         }
328         RegCloseKey(key);
329     }
330     return S_OK;
331 }
332
333 /***********************************************************************
334  *              DllUnregisterServer (RSABASE.@)
335  */
336 HRESULT WINAPI RSABASE_DllUnregisterServer()
337 {
338     RegDeleteKeyW(HKEY_LOCAL_MACHINE, szRSAKey);
339     return S_OK;
340 }