1 /*
2 * Copyright 1999 Ian Schmidt
3 * Copyright 2001 Travis Michielsen
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 /***********************************************************************
21 *
22 * TODO:
23 * - Reference counting
24 * - Thread-safing
25 */
26
27 #ifdef __REACTOS__
28 #include <advapi32.h>
29 #else
30 #include "config.h"
31 #include "wine/port.h"
32
33 #include <limits.h>
34 #include <time.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <sys/types.h>
38 #ifdef HAVE_SYS_STAT_H
39 # include <sys/stat.h>
40 #endif
41 #include <fcntl.h>
42 #ifdef HAVE_UNISTD_H
43 # include <unistd.h>
44 #endif
45
46 #include "ntstatus.h"
47 #define WIN32_NO_STATUS
48 #include "crypt.h"
49 #include "winnls.h"
50 #include "winreg.h"
51 #include "rpc.h"
52 #include "wine/debug.h"
53 #include "wine/unicode.h"
54 #include "winternl.h"
55 #endif /* __REACTOS__ */
56
57 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
58
59 static HWND crypt_hWindow;
60
61 #define CRYPT_Alloc(size) (LocalAlloc(LMEM_ZEROINIT, size))
62 #define CRYPT_Free(buffer) (LocalFree(buffer))
63
CRYPT_GetProvKeyName(PCWSTR pProvName)64 static inline PWSTR CRYPT_GetProvKeyName(PCWSTR pProvName)
65 {
66 static const WCHAR KEYSTR[] = {
67 'S','o','f','t','w','a','r','e','\\',
68 'M','i','c','r','o','s','o','f','t','\\',
69 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
70 'D','e','f','a','u','l','t','s','\\',
71 'P','r','o','v','i','d','e','r','\\',0
72 };
73 PWSTR keyname;
74
75 keyname = CRYPT_Alloc((strlenW(KEYSTR) + strlenW(pProvName) +1)*sizeof(WCHAR));
76 if (keyname)
77 {
78 strcpyW(keyname, KEYSTR);
79 strcpyW(keyname + strlenW(KEYSTR), pProvName);
80 } else
81 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
82 return keyname;
83 }
84
CRYPT_GetTypeKeyName(DWORD dwType,BOOL user)85 static inline PWSTR CRYPT_GetTypeKeyName(DWORD dwType, BOOL user)
86 {
87 static const WCHAR MACHINESTR[] = {
88 'S','o','f','t','w','a','r','e','\\',
89 'M','i','c','r','o','s','o','f','t','\\',
90 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
91 'D','e','f','a','u','l','t','s','\\',
92 'P','r','o','v','i','d','e','r',' ','T','y','p','e','s','\\',
93 'T','y','p','e',' ','X','X','X',0
94 };
95 static const WCHAR USERSTR[] = {
96 'S','o','f','t','w','a','r','e','\\',
97 'M','i','c','r','o','s','o','f','t','\\',
98 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
99 'P','r','o','v','i','d','e','r',' ','T','y','p','e',' ','X','X','X',0
100 };
101 PWSTR keyname;
102 PWSTR ptr;
103
104 keyname = CRYPT_Alloc( ((user ? strlenW(USERSTR) : strlenW(MACHINESTR)) +1)*sizeof(WCHAR));
105 if (keyname)
106 {
107 user ? strcpyW(keyname, USERSTR) : strcpyW(keyname, MACHINESTR);
108 ptr = keyname + strlenW(keyname);
109 *(--ptr) = (dwType % 10) + '0';
110 *(--ptr) = ((dwType / 10) % 10) + '0';
111 *(--ptr) = (dwType / 100) + '0';
112 } else
113 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
114 return keyname;
115 }
116
117 /* CRYPT_UnicodeToANSI
118 * wstr - unicode string
119 * str - pointer to ANSI string or pointer to null pointer if we have to do the allocation
120 * strsize - size of buffer pointed to by str
121 *
122 * returns TRUE if unsuccessful, FALSE otherwise.
123 * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call
124 */
CRYPT_UnicodeToANSI(LPCWSTR wstr,LPSTR * str,int strsize)125 static inline BOOL CRYPT_UnicodeToANSI(LPCWSTR wstr, LPSTR* str, int strsize)
126 {
127 if (!wstr)
128 {
129 *str = NULL;
130 return TRUE;
131 }
132
133 if (!*str)
134 {
135 strsize = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
136 *str = CRYPT_Alloc(strsize * sizeof(CHAR));
137 }
138 else if (strsize < 0)
139 {
140 strsize = INT_MAX; /* windows will pretend that the buffer is infinitely long */
141 }
142
143 if (*str)
144 {
145 WideCharToMultiByte(CP_ACP, 0, wstr, -1, *str, strsize, NULL, NULL);
146 return TRUE;
147 }
148
149 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
150 return FALSE;
151 }
152
153 /* CRYPT_ANSITOUnicode
154 * str - ANSI string
155 * wstr - pointer to unicode string
156 * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation
157 */
CRYPT_ANSIToUnicode(LPCSTR str,LPWSTR * wstr,int wstrsize)158 static inline BOOL CRYPT_ANSIToUnicode(LPCSTR str, LPWSTR* wstr, int wstrsize)
159 {
160 unsigned int wcount;
161
162 if (!str)
163 {
164 *wstr = NULL;
165 return TRUE;
166 }
167 wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
168 if (wstrsize == -1)
169 *wstr = CRYPT_Alloc(wcount * sizeof(WCHAR));
170 else
171 wcount = min( wcount, wstrsize/sizeof(WCHAR) );
172 if (*wstr)
173 {
174 MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount);
175 return TRUE;
176 }
177 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
178 return FALSE;
179 }
180
181 /* These next 2 functions are used by the VTableProvStruc structure */
CRYPT_VerifyImage(LPCSTR lpszImage,BYTE * pData)182 static BOOL CALLBACK CRYPT_VerifyImage(LPCSTR lpszImage, BYTE* pData)
183 {
184 if (!lpszImage || !pData)
185 {
186 SetLastError(ERROR_INVALID_PARAMETER);
187 return FALSE;
188 }
189
190 FIXME("(%s, %p): not verifying image\n", lpszImage, pData);
191
192 return TRUE;
193 }
194
CRYPT_ReturnhWnd(HWND * phWnd)195 static void CALLBACK CRYPT_ReturnhWnd(HWND *phWnd)
196 {
197 if (phWnd) *phWnd = crypt_hWindow;
198 }
199
200 #define CRYPT_GetProvFunc(name) \
201 if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error
202 #define CRYPT_GetProvFuncOpt(name) \
203 provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)
CRYPT_LoadProvider(PCWSTR pImage)204 static PCRYPTPROV CRYPT_LoadProvider(PCWSTR pImage)
205 {
206 PCRYPTPROV provider;
207 DWORD errorcode = ERROR_NOT_ENOUGH_MEMORY;
208
209 if ( !(provider = CRYPT_Alloc(sizeof(CRYPTPROV))) ) goto error;
210 if ( !(provider->pFuncs = CRYPT_Alloc(sizeof(PROVFUNCS))) ) goto error;
211 if ( !(provider->pVTable = CRYPT_Alloc(sizeof(VTableProvStruc))) ) goto error;
212 if ( !(provider->hModule = LoadLibraryW(pImage)) )
213 {
214 errorcode = (GetLastError() == ERROR_FILE_NOT_FOUND) ? NTE_PROV_DLL_NOT_FOUND : NTE_PROVIDER_DLL_FAIL;
215 FIXME("Failed to load dll %s\n", debugstr_w(pImage));
216 goto error;
217 }
218 provider->dwMagic = MAGIC_CRYPTPROV;
219 provider->refcount = 1;
220
221 errorcode = NTE_PROVIDER_DLL_FAIL;
222 CRYPT_GetProvFunc(CPAcquireContext);
223 CRYPT_GetProvFunc(CPCreateHash);
224 CRYPT_GetProvFunc(CPDecrypt);
225 CRYPT_GetProvFunc(CPDeriveKey);
226 CRYPT_GetProvFunc(CPDestroyHash);
227 CRYPT_GetProvFunc(CPDestroyKey);
228 CRYPT_GetProvFuncOpt(CPDuplicateHash);
229 CRYPT_GetProvFuncOpt(CPDuplicateKey);
230 CRYPT_GetProvFunc(CPEncrypt);
231 CRYPT_GetProvFunc(CPExportKey);
232 CRYPT_GetProvFunc(CPGenKey);
233 CRYPT_GetProvFunc(CPGenRandom);
234 CRYPT_GetProvFunc(CPGetHashParam);
235 CRYPT_GetProvFunc(CPGetKeyParam);
236 CRYPT_GetProvFunc(CPGetProvParam);
237 CRYPT_GetProvFunc(CPGetUserKey);
238 CRYPT_GetProvFunc(CPHashData);
239 CRYPT_GetProvFunc(CPHashSessionKey);
240 CRYPT_GetProvFunc(CPImportKey);
241 CRYPT_GetProvFunc(CPReleaseContext);
242 CRYPT_GetProvFunc(CPSetHashParam);
243 CRYPT_GetProvFunc(CPSetKeyParam);
244 CRYPT_GetProvFunc(CPSetProvParam);
245 CRYPT_GetProvFunc(CPSignHash);
246 CRYPT_GetProvFunc(CPVerifySignature);
247
248 /* FIXME: Not sure what the pbContextInfo field is for.
249 * Does it need memory allocation?
250 */
251 provider->pVTable->Version = 3;
252 provider->pVTable->FuncVerifyImage = CRYPT_VerifyImage;
253 provider->pVTable->FuncReturnhWnd = CRYPT_ReturnhWnd;
254 provider->pVTable->dwProvType = 0;
255 provider->pVTable->pbContextInfo = NULL;
256 provider->pVTable->cbContextInfo = 0;
257 provider->pVTable->pszProvName = NULL;
258 return provider;
259
260 error:
261 SetLastError(errorcode);
262 if (provider)
263 {
264 provider->dwMagic = 0;
265 if (provider->hModule)
266 FreeLibrary(provider->hModule);
267 CRYPT_Free(provider->pVTable);
268 CRYPT_Free(provider->pFuncs);
269 CRYPT_Free(provider);
270 }
271 return NULL;
272 }
273 #undef CRYPT_GetProvFunc
274 #undef CRYPT_GetProvFuncOpt
275
276
CRYPT_CreateMachineGuid(void)277 static void CRYPT_CreateMachineGuid(void)
278 {
279 static const WCHAR cryptographyW[] = {
280 'S','o','f','t','w','a','r','e','\\',
281 'M','i','c','r','o','s','o','f','t','\\',
282 'C','r','y','p','t','o','g','r','a','p','h','y',0 };
283 static const WCHAR machineGuidW[] = {
284 'M','a','c','h','i','n','e','G','u','i','d',0 };
285 LONG r;
286 HKEY key;
287
288 r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, cryptographyW, 0, KEY_ALL_ACCESS,
289 &key);
290 if (!r)
291 {
292 DWORD size;
293
294 r = RegQueryValueExW(key, machineGuidW, NULL, NULL, NULL, &size);
295 if (r == ERROR_FILE_NOT_FOUND)
296 {
297 UUID uuid;
298 WCHAR buf[37];
299 RPC_STATUS rs;
300 static const WCHAR uuidFmt[] = {
301 '%','0','8','x','-','%','0','4','x','-',
302 '%','0','4','x','-','%','0','2','x',
303 '%','0','2','x','-','%','0','2','x',
304 '%','0','2','x','%','0','2','x',
305 '%','0','2','x','%','0','2','x',
306 '%','0','2','x',0 };
307
308 rs = UuidCreate(&uuid);
309 if (rs == S_OK)
310 {
311 sprintfW(buf, uuidFmt,
312 uuid.Data1, uuid.Data2, uuid.Data3,
313 uuid.Data4[0], uuid.Data4[1],
314 uuid.Data4[2], uuid.Data4[3],
315 uuid.Data4[4], uuid.Data4[5],
316 uuid.Data4[6], uuid.Data4[7] );
317 RegSetValueExW(key, machineGuidW, 0, REG_SZ,
318 (const BYTE *)buf,
319 (lstrlenW(buf)+1)*sizeof(WCHAR));
320 }
321 }
322 RegCloseKey(key);
323 }
324 }
325
326
327 /******************************************************************************
328 * CloseEncryptedFileRaw (ADVAPI32.@)
329 *
330 * Close encrypted files
331 *
332 * PARAMS
333 * context [I] pointer to the context
334 * RETURNS
335 * Success: ERROR_SUCCESS
336 * Failure: NTSTATUS error code
337 */
CloseEncryptedFileRaw(PVOID context)338 void WINAPI CloseEncryptedFileRaw(PVOID context)
339 {
340 FIXME("(%p): stub\n", context);
341 }
342
343 /******************************************************************************
344 * CryptAcquireContextW (ADVAPI32.@)
345 *
346 * Acquire a crypto provider context handle.
347 *
348 * PARAMS
349 * phProv [O] Pointer to HCRYPTPROV for the output.
350 * pszContainer [I] Key Container Name
351 * pszProvider [I] Cryptographic Service Provider Name
352 * dwProvType [I] Crypto provider type to get a handle.
353 * dwFlags [I] flags for the operation
354 *
355 * RETURNS
356 * TRUE on success, FALSE on failure.
357 */
CryptAcquireContextW(HCRYPTPROV * phProv,LPCWSTR pszContainer,LPCWSTR pszProvider,DWORD dwProvType,DWORD dwFlags)358 BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer,
359 LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
360 {
361 PCRYPTPROV pProv = NULL;
362 HKEY key;
363 PWSTR imagepath = NULL, keyname = NULL, provname = NULL, temp = NULL;
364 PSTR provnameA = NULL, pszContainerA = NULL;
365 DWORD keytype, type, len;
366 ULONG r;
367 static const WCHAR nameW[] = {'N','a','m','e',0};
368 static const WCHAR typeW[] = {'T','y','p','e',0};
369 static const WCHAR imagepathW[] = {'I','m','a','g','e',' ','P','a','t','h',0};
370
371 TRACE("(%p, %s, %s, %d, %08x)\n", phProv, debugstr_w(pszContainer),
372 debugstr_w(pszProvider), dwProvType, dwFlags);
373
374 if (dwProvType < 1 || dwProvType > MAXPROVTYPES)
375 {
376 SetLastError(NTE_BAD_PROV_TYPE);
377 return FALSE;
378 }
379
380 if (!phProv)
381 {
382 SetLastError(ERROR_INVALID_PARAMETER);
383 return FALSE;
384 }
385
386 /* Make sure the MachineGuid value exists */
387 CRYPT_CreateMachineGuid();
388
389 if (!pszProvider || !*pszProvider)
390 {
391 /* No CSP name specified so try the user default CSP first
392 * then try the machine default CSP
393 */
394 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, TRUE)) ) {
395 TRACE("No provider registered for crypto provider type %d.\n", dwProvType);
396 SetLastError(NTE_PROV_TYPE_NOT_DEF);
397 return FALSE;
398 }
399 if (RegOpenKeyW(HKEY_CURRENT_USER, keyname, &key))
400 {
401 CRYPT_Free(keyname);
402 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, FALSE)) ) {
403 TRACE("No type registered for crypto provider type %d.\n", dwProvType);
404 RegCloseKey(key);
405 SetLastError(NTE_PROV_TYPE_NOT_DEF);
406 goto error;
407 }
408 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, keyname, &key)) {
409 TRACE("Did not find registry entry of crypto provider for %s.\n", debugstr_w(keyname));
410 CRYPT_Free(keyname);
411 RegCloseKey(key);
412 SetLastError(NTE_PROV_TYPE_NOT_DEF);
413 goto error;
414 }
415 }
416 CRYPT_Free(keyname);
417 r = RegQueryValueExW(key, nameW, NULL, &keytype, NULL, &len);
418 if( r != ERROR_SUCCESS || !len || keytype != REG_SZ)
419 {
420 TRACE("error %d reading size of 'Name' from registry\n", r );
421 RegCloseKey(key);
422 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
423 goto error;
424 }
425 if(!(provname = CRYPT_Alloc(len)))
426 {
427 RegCloseKey(key);
428 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
429 goto error;
430 }
431 r = RegQueryValueExW(key, nameW, NULL, NULL, (LPBYTE)provname, &len);
432 if( r != ERROR_SUCCESS )
433 {
434 TRACE("error %d reading 'Name' from registry\n", r );
435 RegCloseKey(key);
436 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
437 goto error;
438 }
439 RegCloseKey(key);
440 } else {
441 if ( !(provname = CRYPT_Alloc((strlenW(pszProvider) +1)*sizeof(WCHAR))) )
442 {
443 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
444 goto error;
445 }
446 strcpyW(provname, pszProvider);
447 }
448
449 keyname = CRYPT_GetProvKeyName(provname);
450 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, keyname, &key);
451 CRYPT_Free(keyname);
452 if (r != ERROR_SUCCESS)
453 {
454 SetLastError(NTE_KEYSET_NOT_DEF);
455 goto error;
456 }
457 len = sizeof(DWORD);
458 r = RegQueryValueExW(key, typeW, NULL, NULL, (BYTE*)&type, &len);
459 if (r != ERROR_SUCCESS)
460 {
461 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
462 goto error;
463 }
464 if (type != dwProvType)
465 {
466 TRACE("Crypto provider has wrong type (%d vs expected %d).\n", type, dwProvType);
467 SetLastError(NTE_PROV_TYPE_NO_MATCH);
468 goto error;
469 }
470
471 r = RegQueryValueExW(key, imagepathW, NULL, &keytype, NULL, &len);
472 if ( r != ERROR_SUCCESS || keytype != REG_SZ)
473 {
474 TRACE("error %d reading size of 'Image Path' from registry\n", r );
475 RegCloseKey(key);
476 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
477 goto error;
478 }
479 if (!(temp = CRYPT_Alloc(len)))
480 {
481 RegCloseKey(key);
482 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
483 goto error;
484 }
485 r = RegQueryValueExW(key, imagepathW, NULL, NULL, (LPBYTE)temp, &len);
486 if( r != ERROR_SUCCESS )
487 {
488 TRACE("error %d reading 'Image Path' from registry\n", r );
489 RegCloseKey(key);
490 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
491 goto error;
492 }
493 RegCloseKey(key);
494 len = ExpandEnvironmentStringsW(temp, NULL, 0);
495 if ( !(imagepath = CRYPT_Alloc(len*sizeof(WCHAR))) )
496 {
497 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
498 goto error;
499 }
500 if (!ExpandEnvironmentStringsW(temp, imagepath, len))
501 {
502 /* ExpandEnvironmentStrings will call SetLastError */
503 goto error;
504 }
505 pProv = CRYPT_LoadProvider(imagepath);
506 if (!pProv) {
507 /* CRYPT_LoadProvider calls SetLastError */
508 goto error;
509 }
510 pProv->pVTable->dwProvType = dwProvType;
511 if(!CRYPT_UnicodeToANSI(provname, &provnameA, 0))
512 {
513 /* CRYPT_UnicodeToANSI calls SetLastError */
514 goto error;
515 }
516 pProv->pVTable->pszProvName = provnameA;
517 if(!CRYPT_UnicodeToANSI(pszContainer, &pszContainerA, 0))
518 {
519 /* CRYPT_UnicodeToANSI calls SetLastError */
520 goto error;
521 }
522 if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, pszContainerA, dwFlags, pProv->pVTable))
523 {
524 /* MSDN: When this flag is set, the value returned in phProv is undefined,
525 * and thus, the CryptReleaseContext function need not be called afterwards.
526 * Therefore, we must clean up everything now.
527 */
528 if (dwFlags & CRYPT_DELETEKEYSET)
529 {
530 pProv->dwMagic = 0;
531 FreeLibrary(pProv->hModule);
532 CRYPT_Free(provnameA);
533 CRYPT_Free(pProv->pVTable);
534 CRYPT_Free(pProv->pFuncs);
535 CRYPT_Free(pProv);
536 } else {
537 *phProv = (HCRYPTPROV)pProv;
538 }
539 CRYPT_Free(pszContainerA);
540 CRYPT_Free(provname);
541 CRYPT_Free(temp);
542 CRYPT_Free(imagepath);
543 return TRUE;
544 }
545 /* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */
546 error:
547 if (pProv)
548 {
549 pProv->dwMagic = 0;
550 if (pProv->hModule)
551 FreeLibrary(pProv->hModule);
552 CRYPT_Free(pProv->pVTable);
553 CRYPT_Free(pProv->pFuncs);
554 CRYPT_Free(pProv);
555 }
556 CRYPT_Free(pszContainerA);
557 CRYPT_Free(provnameA);
558 CRYPT_Free(provname);
559 CRYPT_Free(temp);
560 CRYPT_Free(imagepath);
561 return FALSE;
562 }
563
564 /******************************************************************************
565 * CryptAcquireContextA (ADVAPI32.@)
566 *
567 * See CryptAcquireContextW.
568 */
CryptAcquireContextA(HCRYPTPROV * phProv,LPCSTR pszContainer,LPCSTR pszProvider,DWORD dwProvType,DWORD dwFlags)569 BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer,
570 LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
571 {
572 PWSTR pProvider = NULL, pContainer = NULL;
573 BOOL ret = FALSE;
574
575 TRACE("(%p, %s, %s, %d, %08x)\n", phProv, debugstr_a(pszContainer),
576 debugstr_a(pszProvider), dwProvType, dwFlags);
577
578 if ( !CRYPT_ANSIToUnicode(pszContainer, &pContainer, -1) )
579 {
580 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
581 return FALSE;
582 }
583 if ( !CRYPT_ANSIToUnicode(pszProvider, &pProvider, -1) )
584 {
585 CRYPT_Free(pContainer);
586 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
587 return FALSE;
588 }
589
590 ret = CryptAcquireContextW(phProv, pContainer, pProvider, dwProvType, dwFlags);
591
592 CRYPT_Free(pContainer);
593 CRYPT_Free(pProvider);
594
595 return ret;
596 }
597
598 /******************************************************************************
599 * CryptContextAddRef (ADVAPI32.@)
600 *
601 * Increases reference count of a cryptographic service provider handle
602 * by one.
603 *
604 * PARAMS
605 * hProv [I] Handle to the CSP whose reference is being incremented.
606 * pdwReserved [IN] Reserved for future use and must be NULL.
607 * dwFlags [I] Reserved for future use and must be 0.
608 *
609 * RETURNS
610 * Success: TRUE
611 * Failure: FALSE
612 */
CryptContextAddRef(HCRYPTPROV hProv,DWORD * pdwReserved,DWORD dwFlags)613 BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags)
614 {
615 PCRYPTPROV pProv = (PCRYPTPROV)hProv;
616
617 TRACE("(0x%lx, %p, %08x)\n", hProv, pdwReserved, dwFlags);
618
619 if (!pProv)
620 {
621 SetLastError(NTE_BAD_UID);
622 return FALSE;
623 }
624
625 if (pProv->dwMagic != MAGIC_CRYPTPROV)
626 {
627 SetLastError(ERROR_INVALID_PARAMETER);
628 return FALSE;
629 }
630
631 InterlockedIncrement(&pProv->refcount);
632 return TRUE;
633 }
634
635 /******************************************************************************
636 * CryptReleaseContext (ADVAPI32.@)
637 *
638 * Releases the handle of a CSP. Reference count is decreased.
639 *
640 * PARAMS
641 * hProv [I] Handle of a CSP.
642 * dwFlags [I] Reserved for future use and must be 0.
643 *
644 * RETURNS
645 * Success: TRUE
646 * Failure: FALSE
647 */
CryptReleaseContext(HCRYPTPROV hProv,DWORD dwFlags)648 BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags)
649 {
650 PCRYPTPROV pProv = (PCRYPTPROV)hProv;
651 BOOL ret = TRUE;
652
653 TRACE("(0x%lx, %08x)\n", hProv, dwFlags);
654
655 if (!pProv)
656 {
657 SetLastError(ERROR_INVALID_PARAMETER);
658 return FALSE;
659 }
660
661 if (pProv->dwMagic != MAGIC_CRYPTPROV)
662 {
663 SetLastError(ERROR_INVALID_PARAMETER);
664 return FALSE;
665 }
666
667 if (InterlockedDecrement(&pProv->refcount) == 0)
668 {
669 ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
670 pProv->dwMagic = 0;
671 FreeLibrary(pProv->hModule);
672 #if 0
673 CRYPT_Free(pProv->pVTable->pContextInfo);
674 #endif
675 CRYPT_Free(pProv->pVTable->pszProvName);
676 CRYPT_Free(pProv->pVTable);
677 CRYPT_Free(pProv->pFuncs);
678 CRYPT_Free(pProv);
679 }
680 return ret;
681 }
682
683 /******************************************************************************
684 * CryptGenRandom (ADVAPI32.@)
685 *
686 * Fills a buffer with cryptographically random bytes.
687 *
688 * PARAMS
689 * hProv [I] Handle of a CSP.
690 * dwLen [I] Number of bytes to generate.
691 * pbBuffer [I/O] Buffer to contain random bytes.
692 *
693 * RETURNS
694 * Success: TRUE
695 * Failure: FALSE
696 *
697 * NOTES
698 * pdBuffer must be at least dwLen bytes long.
699 */
CryptGenRandom(HCRYPTPROV hProv,DWORD dwLen,BYTE * pbBuffer)700 BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
701 {
702 PCRYPTPROV prov = (PCRYPTPROV)hProv;
703
704 TRACE("(0x%lx, %d, %p)\n", hProv, dwLen, pbBuffer);
705
706 if (!hProv)
707 {
708 SetLastError(ERROR_INVALID_HANDLE);
709 return FALSE;
710 }
711
712 if (prov->dwMagic != MAGIC_CRYPTPROV)
713 {
714 SetLastError(ERROR_INVALID_PARAMETER);
715 return FALSE;
716 }
717
718 return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer);
719 }
720
721 /******************************************************************************
722 * CryptCreateHash (ADVAPI32.@)
723 *
724 * Initiates the hashing of a stream of data.
725 *
726 * PARAMS
727 * hProv [I] Handle of a CSP.
728 * Algid [I] Identifies the hash algorithm to use.
729 * hKey [I] Key for the hash (if required).
730 * dwFlags [I] Reserved for future use and must be 0.
731 * phHash [O] Address of the future handle to the new hash object.
732 *
733 * RETURNS
734 * Success: TRUE
735 * Failure: FALSE
736 *
737 * NOTES
738 * If the algorithm is a keyed hash, hKey is the key.
739 */
CryptCreateHash(HCRYPTPROV hProv,ALG_ID Algid,HCRYPTKEY hKey,DWORD dwFlags,HCRYPTHASH * phHash)740 BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
741 DWORD dwFlags, HCRYPTHASH *phHash)
742 {
743 PCRYPTPROV prov = (PCRYPTPROV)hProv;
744 PCRYPTKEY key = (PCRYPTKEY)hKey;
745 PCRYPTHASH hash;
746
747 TRACE("(0x%lx, 0x%x, 0x%lx, %08x, %p)\n", hProv, Algid, hKey, dwFlags, phHash);
748
749 if (!prov || !phHash || prov->dwMagic != MAGIC_CRYPTPROV ||
750 (key && key->dwMagic != MAGIC_CRYPTKEY))
751 {
752 SetLastError(ERROR_INVALID_PARAMETER);
753 return FALSE;
754 }
755 if (dwFlags)
756 {
757 SetLastError(NTE_BAD_FLAGS);
758 return FALSE;
759 }
760 if ( !(hash = CRYPT_Alloc(sizeof(CRYPTHASH))) )
761 {
762 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
763 return FALSE;
764 }
765
766 hash->pProvider = prov;
767 hash->dwMagic = MAGIC_CRYPTHASH;
768 if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid,
769 key ? key->hPrivate : 0, 0, &hash->hPrivate))
770 {
771 *phHash = (HCRYPTHASH)hash;
772 return TRUE;
773 }
774
775 /* CSP error! */
776 hash->dwMagic = 0;
777 CRYPT_Free(hash);
778 *phHash = 0;
779 return FALSE;
780 }
781
782 /******************************************************************************
783 * CryptDecrypt (ADVAPI32.@)
784 *
785 * Decrypts data encrypted by CryptEncrypt.
786 *
787 * PARAMS
788 * hKey [I] Handle to the decryption key.
789 * hHash [I] Handle to a hash object.
790 * Final [I] TRUE if this is the last section to be decrypted.
791 * dwFlags [I] Reserved for future use. Can be CRYPT_OAEP.
792 * pbData [I/O] Buffer that holds the encrypted data. Holds decrypted
793 * data on return
794 * pdwDataLen [I/O] Length of pbData before and after the call.
795 *
796 * RETURNS
797 * Success: TRUE
798 * Failure: FALSE
799 */
CryptDecrypt(HCRYPTKEY hKey,HCRYPTHASH hHash,BOOL Final,DWORD dwFlags,BYTE * pbData,DWORD * pdwDataLen)800 BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
801 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
802 {
803 PCRYPTPROV prov;
804 PCRYPTKEY key = (PCRYPTKEY)hKey;
805 PCRYPTHASH hash = (PCRYPTHASH)hHash;
806
807 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
808
809 if (!key || !pbData || !pdwDataLen ||
810 !key->pProvider || key->dwMagic != MAGIC_CRYPTKEY ||
811 key->pProvider->dwMagic != MAGIC_CRYPTPROV)
812 {
813 SetLastError(ERROR_INVALID_PARAMETER);
814 return FALSE;
815 }
816
817 prov = key->pProvider;
818 return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
819 Final, dwFlags, pbData, pdwDataLen);
820 }
821
822 /******************************************************************************
823 * CryptDeriveKey (ADVAPI32.@)
824 *
825 * Generates session keys derived from a base data value.
826 *
827 * PARAMS
828 * hProv [I] Handle to a CSP.
829 * Algid [I] Identifies the symmetric encryption algorithm to use.
830 * hBaseData [I] Handle to a hash object.
831 * dwFlags [I] Type of key to generate.
832 * phKey [I/O] Address of the newly generated key.
833 *
834 * RETURNS
835 * Success: TRUE
836 * Failure: FALSE
837 */
CryptDeriveKey(HCRYPTPROV hProv,ALG_ID Algid,HCRYPTHASH hBaseData,DWORD dwFlags,HCRYPTKEY * phKey)838 BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData,
839 DWORD dwFlags, HCRYPTKEY *phKey)
840 {
841 PCRYPTPROV prov = (PCRYPTPROV)hProv;
842 PCRYPTHASH hash = (PCRYPTHASH)hBaseData;
843 PCRYPTKEY key;
844
845 TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08x, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey);
846
847 if (!prov || !hash)
848 {
849 SetLastError(ERROR_INVALID_HANDLE);
850 return FALSE;
851 }
852 if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV || hash->dwMagic != MAGIC_CRYPTHASH)
853 {
854 SetLastError(ERROR_INVALID_PARAMETER);
855 return FALSE;
856 }
857 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
858 {
859 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
860 return FALSE;
861 }
862
863 key->pProvider = prov;
864 key->dwMagic = MAGIC_CRYPTKEY;
865 if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate))
866 {
867 *phKey = (HCRYPTKEY)key;
868 return TRUE;
869 }
870
871 /* CSP error! */
872 key->dwMagic = 0;
873 CRYPT_Free(key);
874 *phKey = 0;
875 return FALSE;
876 }
877
878 /******************************************************************************
879 * CryptDestroyHash (ADVAPI32.@)
880 *
881 * Destroys the hash object referenced by hHash.
882 *
883 * PARAMS
884 * hHash [I] Handle of the hash object to be destroyed.
885 *
886 * RETURNS
887 * Success: TRUE
888 * Failure: FALSE
889 */
CryptDestroyHash(HCRYPTHASH hHash)890 BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash)
891 {
892 PCRYPTHASH hash = (PCRYPTHASH)hHash;
893 PCRYPTPROV prov;
894 BOOL ret;
895
896 TRACE("(0x%lx)\n", hHash);
897
898 if (!hash)
899 {
900 SetLastError(ERROR_INVALID_HANDLE);
901 return FALSE;
902 }
903
904 if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH ||
905 hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
906 {
907 SetLastError(ERROR_INVALID_PARAMETER);
908 return FALSE;
909 }
910
911 prov = hash->pProvider;
912 ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate);
913 hash->dwMagic = 0;
914 CRYPT_Free(hash);
915 return ret;
916 }
917
918 /******************************************************************************
919 * CryptDestroyKey (ADVAPI32.@)
920 *
921 * Releases the handle referenced by hKey.
922 *
923 * PARAMS
924 * hKey [I] Handle of the key to be destroyed.
925 *
926 * RETURNS
927 * Success: TRUE
928 * Failure: FALSE
929 */
CryptDestroyKey(HCRYPTKEY hKey)930 BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey)
931 {
932 PCRYPTKEY key = (PCRYPTKEY)hKey;
933 PCRYPTPROV prov;
934 BOOL ret;
935
936 TRACE("(0x%lx)\n", hKey);
937
938 if (!key)
939 {
940 SetLastError(ERROR_INVALID_HANDLE);
941 return FALSE;
942 }
943
944 if (!key->pProvider || key->dwMagic != MAGIC_CRYPTKEY ||
945 key->pProvider->dwMagic != MAGIC_CRYPTPROV)
946 {
947 SetLastError(ERROR_INVALID_PARAMETER);
948 return FALSE;
949 }
950
951 prov = key->pProvider;
952 ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate);
953 key->dwMagic = 0;
954 CRYPT_Free(key);
955 return ret;
956 }
957
958 /******************************************************************************
959 * CryptDuplicateHash (ADVAPI32.@)
960 *
961 * Duplicates a hash.
962 *
963 * PARAMS
964 * hHash [I] Handle to the hash to be copied.
965 * pdwReserved [I] Reserved for future use and must be NULL.
966 * dwFlags [I] Reserved for future use and must be zero.
967 * phHash [O] Address of the handle to receive the copy.
968 *
969 * RETURNS
970 * Success: TRUE
971 * Failure: FALSE
972 */
CryptDuplicateHash(HCRYPTHASH hHash,DWORD * pdwReserved,DWORD dwFlags,HCRYPTHASH * phHash)973 BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved,
974 DWORD dwFlags, HCRYPTHASH *phHash)
975 {
976 PCRYPTPROV prov;
977 PCRYPTHASH orghash, newhash;
978
979 TRACE("(0x%lx, %p, %08x, %p)\n", hHash, pdwReserved, dwFlags, phHash);
980
981 orghash = (PCRYPTHASH)hHash;
982 if (!orghash || pdwReserved || !phHash || !orghash->pProvider ||
983 orghash->dwMagic != MAGIC_CRYPTHASH || orghash->pProvider->dwMagic != MAGIC_CRYPTPROV)
984 {
985 SetLastError(ERROR_INVALID_PARAMETER);
986 return FALSE;
987 }
988
989 prov = orghash->pProvider;
990 if (!prov->pFuncs->pCPDuplicateHash)
991 {
992 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
993 return FALSE;
994 }
995
996 if ( !(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))) )
997 {
998 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
999 return FALSE;
1000 }
1001
1002 newhash->pProvider = prov;
1003 newhash->dwMagic = MAGIC_CRYPTHASH;
1004 if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate))
1005 {
1006 *phHash = (HCRYPTHASH)newhash;
1007 return TRUE;
1008 }
1009 newhash->dwMagic = 0;
1010 CRYPT_Free(newhash);
1011 return FALSE;
1012 }
1013
1014 /******************************************************************************
1015 * CryptDuplicateKey (ADVAPI32.@)
1016 *
1017 * Duplicate a key and the key's state.
1018 *
1019 * PARAMS
1020 * hKey [I] Handle of the key to copy.
1021 * pdwReserved [I] Reserved for future use and must be NULL.
1022 * dwFlags [I] Reserved for future use and must be zero.
1023 * phKey [I] Address of the handle to the duplicated key.
1024 *
1025 * RETURNS
1026 * Success: TRUE
1027 * Failure: FALSE
1028 */
CryptDuplicateKey(HCRYPTKEY hKey,DWORD * pdwReserved,DWORD dwFlags,HCRYPTKEY * phKey)1029 BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
1030 {
1031 PCRYPTPROV prov;
1032 PCRYPTKEY orgkey, newkey;
1033
1034 TRACE("(0x%lx, %p, %08x, %p)\n", hKey, pdwReserved, dwFlags, phKey);
1035
1036 orgkey = (PCRYPTKEY)hKey;
1037 if (!orgkey || pdwReserved || !phKey || !orgkey->pProvider ||
1038 orgkey->dwMagic != MAGIC_CRYPTKEY ||
1039 orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV)
1040 {
1041 SetLastError(ERROR_INVALID_PARAMETER);
1042 return FALSE;
1043 }
1044
1045 prov = orgkey->pProvider;
1046 if (!prov->pFuncs->pCPDuplicateKey)
1047 {
1048 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1049 return FALSE;
1050 }
1051
1052 if ( !(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))) )
1053 {
1054 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1055 return FALSE;
1056 }
1057
1058 newkey->pProvider = prov;
1059 newkey->dwMagic = MAGIC_CRYPTKEY;
1060 if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate))
1061 {
1062 *phKey = (HCRYPTKEY)newkey;
1063 return TRUE;
1064 }
1065 newkey->dwMagic = 0;
1066 CRYPT_Free(newkey);
1067 return FALSE;
1068 }
1069
1070 /******************************************************************************
1071 * CryptEncrypt (ADVAPI32.@)
1072 *
1073 * Encrypts data.
1074 *
1075 * PARAMS
1076 * hKey [I] Handle to the encryption key.
1077 * hHash [I] Handle to a hash object.
1078 * Final [I] TRUE if this is the last section to encrypt.
1079 * dwFlags [I] Can be CRYPT_OAEP.
1080 * pbData [I/O] Data to be encrypted. Contains encrypted data after call.
1081 * pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the
1082 * encrypted data after call.
1083 * dwBufLen [I] Length of the input pbData buffer.
1084 *
1085 * RETURNS
1086 * Success: TRUE
1087 * Failure: FALSE
1088 *
1089 * NOTES
1090 * If pbData is NULL, CryptEncrypt determines stores the number of bytes
1091 * required for the returned data in pdwDataLen.
1092 */
CryptEncrypt(HCRYPTKEY hKey,HCRYPTHASH hHash,BOOL Final,DWORD dwFlags,BYTE * pbData,DWORD * pdwDataLen,DWORD dwBufLen)1093 BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
1094 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
1095 {
1096 PCRYPTPROV prov;
1097 PCRYPTKEY key = (PCRYPTKEY)hKey;
1098 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1099
1100 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p, %d)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
1101
1102 if (!key || !pdwDataLen || !key->pProvider ||
1103 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
1104 {
1105 SetLastError(ERROR_INVALID_PARAMETER);
1106 return FALSE;
1107 }
1108
1109 prov = key->pProvider;
1110 return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
1111 Final, dwFlags, pbData, pdwDataLen, dwBufLen);
1112 }
1113
1114 /******************************************************************************
1115 * CryptEnumProvidersW (ADVAPI32.@)
1116 *
1117 * Returns the next available CSP.
1118 *
1119 * PARAMS
1120 * dwIndex [I] Index of the next provider to be enumerated.
1121 * pdwReserved [I] Reserved for future use and must be NULL.
1122 * dwFlags [I] Reserved for future use and must be zero.
1123 * pdwProvType [O] DWORD designating the type of the provider.
1124 * pszProvName [O] Buffer that receives data from the provider.
1125 * pcbProvName [I/O] Specifies the size of pszProvName. Contains the number
1126 * of bytes stored in the buffer on return.
1127 *
1128 * RETURNS
1129 * Success: TRUE
1130 * Failure: FALSE
1131 *
1132 * NOTES
1133 * If pszProvName is NULL, CryptEnumProvidersW sets the size of the name
1134 * for memory allocation purposes.
1135 */
CryptEnumProvidersW(DWORD dwIndex,DWORD * pdwReserved,DWORD dwFlags,DWORD * pdwProvType,LPWSTR pszProvName,DWORD * pcbProvName)1136 BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved,
1137 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName)
1138 {
1139 HKEY hKey;
1140 static const WCHAR providerW[] = {
1141 'S','o','f','t','w','a','r','e','\\',
1142 'M','i','c','r','o','s','o','f','t','\\',
1143 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
1144 'D','e','f','a','u','l','t','s','\\',
1145 'P','r','o','v','i','d','e','r',0
1146 };
1147 static const WCHAR typeW[] = {'T','y','p','e',0};
1148 BOOL ret;
1149
1150 TRACE("(%d, %p, %d, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
1151 pdwProvType, pszProvName, pcbProvName);
1152
1153 if (pdwReserved || !pcbProvName)
1154 {
1155 SetLastError(ERROR_INVALID_PARAMETER);
1156 return FALSE;
1157 }
1158 if (dwFlags)
1159 {
1160 SetLastError(NTE_BAD_FLAGS);
1161 return FALSE;
1162 }
1163
1164 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, providerW, &hKey))
1165 {
1166 SetLastError(NTE_FAIL);
1167 return FALSE;
1168 }
1169
1170 ret = TRUE;
1171 if (!pszProvName)
1172 {
1173 DWORD numkeys;
1174 WCHAR *provNameW;
1175
1176 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, pcbProvName,
1177 NULL, NULL, NULL, NULL, NULL, NULL);
1178
1179 if (!(provNameW = CRYPT_Alloc(*pcbProvName * sizeof(WCHAR))))
1180 {
1181 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1182 RegCloseKey(hKey);
1183 return FALSE;
1184 }
1185
1186 RegEnumKeyExW(hKey, dwIndex, provNameW, pcbProvName, NULL, NULL, NULL, NULL);
1187 CRYPT_Free(provNameW);
1188 (*pcbProvName)++;
1189 *pcbProvName *= sizeof(WCHAR);
1190
1191 if (dwIndex >= numkeys)
1192 {
1193 SetLastError(ERROR_NO_MORE_ITEMS);
1194 ret = FALSE;
1195 }
1196 } else {
1197 DWORD size = sizeof(DWORD);
1198 DWORD result;
1199 HKEY subkey;
1200
1201 result = RegEnumKeyW(hKey, dwIndex, pszProvName, *pcbProvName / sizeof(WCHAR));
1202 if (result)
1203 {
1204 SetLastError(result);
1205 RegCloseKey(hKey);
1206 return FALSE;
1207 }
1208 if (RegOpenKeyW(hKey, pszProvName, &subkey))
1209 {
1210 RegCloseKey(hKey);
1211 return FALSE;
1212 }
1213
1214 if (RegQueryValueExW(subkey, typeW, NULL, NULL, (BYTE*)pdwProvType, &size))
1215 ret = FALSE;
1216
1217 RegCloseKey(subkey);
1218 }
1219 RegCloseKey(hKey);
1220 return ret;
1221 }
1222
1223 /******************************************************************************
1224 * CryptEnumProvidersA (ADVAPI32.@)
1225 *
1226 * See CryptEnumProvidersW.
1227 */
CryptEnumProvidersA(DWORD dwIndex,DWORD * pdwReserved,DWORD dwFlags,DWORD * pdwProvType,LPSTR pszProvName,DWORD * pcbProvName)1228 BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved,
1229 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName)
1230 {
1231 PWSTR str = NULL;
1232 DWORD bufsize;
1233 BOOL ret;
1234
1235 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
1236 pdwProvType, pszProvName, pcbProvName);
1237
1238 if(!CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, NULL, &bufsize))
1239 return FALSE;
1240 if ( pszProvName && !(str = CRYPT_Alloc(bufsize)) )
1241 {
1242 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1243 return FALSE;
1244 }
1245 ret = CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &bufsize);
1246 if (str)
1247 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName);
1248 *pcbProvName = bufsize / sizeof(WCHAR); /* FIXME: not correct */
1249 if (str)
1250 {
1251 CRYPT_Free(str);
1252 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1253 {
1254 SetLastError(ERROR_MORE_DATA);
1255 return FALSE;
1256 }
1257 }
1258 return ret;
1259 }
1260
1261 /******************************************************************************
1262 * CryptEnumProviderTypesW (ADVAPI32.@)
1263 *
1264 * Retrieves the next type of CSP supported.
1265 *
1266 * PARAMS
1267 * dwIndex [I] Index of the next provider to be enumerated.
1268 * pdwReserved [I] Reserved for future use and must be NULL.
1269 * dwFlags [I] Reserved for future use and must be zero.
1270 * pdwProvType [O] DWORD designating the type of the provider.
1271 * pszTypeName [O] Buffer that receives data from the provider type.
1272 * pcbTypeName [I/O] Specifies the size of pszTypeName. Contains the number
1273 * of bytes stored in the buffer on return.
1274 *
1275 * RETURNS
1276 * Success: TRUE
1277 * Failure: FALSE
1278 *
1279 * NOTES
1280 * If pszTypeName is NULL, CryptEnumProviderTypesW sets the size of the name
1281 * for memory allocation purposes.
1282 */
CryptEnumProviderTypesW(DWORD dwIndex,DWORD * pdwReserved,DWORD dwFlags,DWORD * pdwProvType,LPWSTR pszTypeName,DWORD * pcbTypeName)1283 BOOL WINAPI CryptEnumProviderTypesW (DWORD dwIndex, DWORD *pdwReserved,
1284 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszTypeName, DWORD *pcbTypeName)
1285 {
1286 HKEY hKey, hSubkey;
1287 DWORD keylen, numkeys, dwType;
1288 PWSTR keyname, ch;
1289 DWORD result;
1290 static const WCHAR KEYSTR[] = {
1291 'S','o','f','t','w','a','r','e','\\',
1292 'M','i','c','r','o','s','o','f','t','\\',
1293 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
1294 'D','e','f','a','u','l','t','s','\\',
1295 'P','r','o','v','i','d','e','r',' ','T','y','p','e','s',0
1296 };
1297 static const WCHAR typenameW[] = {'T','y','p','e','N','a','m','e',0};
1298
1299 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved,
1300 dwFlags, pdwProvType, pszTypeName, pcbTypeName);
1301
1302 if (pdwReserved || !pdwProvType || !pcbTypeName)
1303 {
1304 SetLastError(ERROR_INVALID_PARAMETER);
1305 return FALSE;
1306 }
1307 if (dwFlags)
1308 {
1309 SetLastError(NTE_BAD_FLAGS);
1310 return FALSE;
1311 }
1312
1313 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, KEYSTR, &hKey))
1314 return FALSE;
1315
1316 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, &keylen, NULL, NULL, NULL, NULL, NULL, NULL);
1317 if (dwIndex >= numkeys)
1318 {
1319 SetLastError(ERROR_NO_MORE_ITEMS);
1320 RegCloseKey(hKey);
1321 return FALSE;
1322 }
1323 keylen++;
1324 if ( !(keyname = CRYPT_Alloc(keylen*sizeof(WCHAR))) )
1325 {
1326 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1327 RegCloseKey(hKey);
1328 return FALSE;
1329 }
1330 if ( RegEnumKeyW(hKey, dwIndex, keyname, keylen) ) {
1331 CRYPT_Free(keyname);
1332 RegCloseKey(hKey);
1333 return FALSE;
1334 }
1335 RegOpenKeyW(hKey, keyname, &hSubkey);
1336 RegCloseKey(hKey);
1337
1338 ch = keyname + strlenW(keyname);
1339 /* Convert "Type 000" to 0, etc/ */
1340 *pdwProvType = *(--ch) - '0';
1341 *pdwProvType += (*(--ch) - '0') * 10;
1342 *pdwProvType += (*(--ch) - '0') * 100;
1343 CRYPT_Free(keyname);
1344
1345 result = RegQueryValueExW(hSubkey, typenameW, NULL, &dwType, (LPBYTE)pszTypeName, pcbTypeName);
1346 if (result)
1347 {
1348 SetLastError(result);
1349 RegCloseKey(hSubkey);
1350 return FALSE;
1351 }
1352
1353 RegCloseKey(hSubkey);
1354 return TRUE;
1355 }
1356
1357 /******************************************************************************
1358 * CryptEnumProviderTypesA (ADVAPI32.@)
1359 *
1360 * See CryptEnumProviderTypesW.
1361 */
CryptEnumProviderTypesA(DWORD dwIndex,DWORD * pdwReserved,DWORD dwFlags,DWORD * pdwProvType,LPSTR pszTypeName,DWORD * pcbTypeName)1362 BOOL WINAPI CryptEnumProviderTypesA (DWORD dwIndex, DWORD *pdwReserved,
1363 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszTypeName, DWORD *pcbTypeName)
1364 {
1365 PWSTR str = NULL;
1366 DWORD bufsize;
1367 BOOL ret;
1368
1369 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
1370 pdwProvType, pszTypeName, pcbTypeName);
1371
1372 if(!CryptEnumProviderTypesW(dwIndex, pdwReserved, dwFlags, pdwProvType, NULL, &bufsize))
1373 return FALSE;
1374 if ( pszTypeName && !(str = CRYPT_Alloc(bufsize)) )
1375 {
1376 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1377 return FALSE;
1378 }
1379 ret = CryptEnumProviderTypesW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &bufsize);
1380 if (str)
1381 CRYPT_UnicodeToANSI(str, &pszTypeName, *pcbTypeName);
1382 *pcbTypeName = bufsize / sizeof(WCHAR);
1383 if (str)
1384 {
1385 CRYPT_Free(str);
1386 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1387 {
1388 SetLastError(ERROR_MORE_DATA);
1389 return FALSE;
1390 }
1391 }
1392 return ret;
1393 }
1394
1395 /******************************************************************************
1396 * CryptExportKey (ADVAPI32.@)
1397 *
1398 * Exports a cryptographic key from a CSP.
1399 *
1400 * PARAMS
1401 * hKey [I] Handle to the key to export.
1402 * hExpKey [I] Handle to a cryptographic key of the end user.
1403 * dwBlobType [I] Type of BLOB to be exported.
1404 * dwFlags [I] CRYPT_DESTROYKEY/SSL2_FALLBACK/OAEP.
1405 * pbData [O] Buffer to receive BLOB data.
1406 * pdwDataLen [I/O] Specifies the size of pbData.
1407 *
1408 * RETURNS
1409 * Success: TRUE
1410 * Failure: FALSE
1411 *
1412 * NOTES
1413 * if pbData is NULL, CryptExportKey sets pdwDataLen as the size of the
1414 * buffer needed to hold the BLOB.
1415 */
CryptExportKey(HCRYPTKEY hKey,HCRYPTKEY hExpKey,DWORD dwBlobType,DWORD dwFlags,BYTE * pbData,DWORD * pdwDataLen)1416 BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType,
1417 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
1418 {
1419 PCRYPTPROV prov;
1420 PCRYPTKEY key = (PCRYPTKEY)hKey, expkey = (PCRYPTKEY)hExpKey;
1421
1422 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen);
1423
1424 if (!key || !pdwDataLen || !key->pProvider ||
1425 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
1426 {
1427 SetLastError(ERROR_INVALID_PARAMETER);
1428 return FALSE;
1429 }
1430
1431 prov = key->pProvider;
1432 return prov->pFuncs->pCPExportKey(prov->hPrivate, key->hPrivate, expkey ? expkey->hPrivate : 0,
1433 dwBlobType, dwFlags, pbData, pdwDataLen);
1434 }
1435
1436 /******************************************************************************
1437 * CryptGenKey (ADVAPI32.@)
1438 *
1439 * Generates a random cryptographic session key or a pub/priv key pair.
1440 *
1441 * PARAMS
1442 * hProv [I] Handle to a CSP.
1443 * Algid [I] Algorithm to use to make key.
1444 * dwFlags [I] Specifies type of key to make.
1445 * phKey [I] Address of the handle to which the new key is copied.
1446 *
1447 * RETURNS
1448 * Success: TRUE
1449 * Failure: FALSE
1450 */
CryptGenKey(HCRYPTPROV hProv,ALG_ID Algid,DWORD dwFlags,HCRYPTKEY * phKey)1451 BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
1452 {
1453 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1454 PCRYPTKEY key;
1455
1456 TRACE("(0x%lx, %d, %08x, %p)\n", hProv, Algid, dwFlags, phKey);
1457
1458 if (!phKey || !prov || prov->dwMagic != MAGIC_CRYPTPROV)
1459 {
1460 SetLastError(ERROR_INVALID_PARAMETER);
1461 return FALSE;
1462 }
1463 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
1464 {
1465 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1466 return FALSE;
1467 }
1468
1469 key->pProvider = prov;
1470 key->dwMagic = MAGIC_CRYPTKEY;
1471 if (prov->pFuncs->pCPGenKey(prov->hPrivate, Algid, dwFlags, &key->hPrivate))
1472 {
1473 *phKey = (HCRYPTKEY)key;
1474 return TRUE;
1475 }
1476
1477 /* CSP error! */
1478 key->dwMagic = 0;
1479 CRYPT_Free(key);
1480 return FALSE;
1481 }
1482
1483 /******************************************************************************
1484 * CryptGetDefaultProviderW (ADVAPI32.@)
1485 *
1486 * Finds the default CSP of a certain provider type.
1487 *
1488 * PARAMS
1489 * dwProvType [I] Provider type to look for.
1490 * pdwReserved [I] Reserved for future use and must be NULL.
1491 * dwFlags [I] CRYPT_MACHINE_DEFAULT/USER_DEFAULT
1492 * pszProvName [O] Name of the default CSP.
1493 * pcbProvName [I/O] Size of pszProvName
1494 *
1495 * RETURNS
1496 * Success: TRUE
1497 * Failure: FALSE
1498 *
1499 * NOTES
1500 * If pszProvName is NULL, pcbProvName will hold the size of the buffer for
1501 * memory allocation purposes on return.
1502 */
CryptGetDefaultProviderW(DWORD dwProvType,DWORD * pdwReserved,DWORD dwFlags,LPWSTR pszProvName,DWORD * pcbProvName)1503 BOOL WINAPI CryptGetDefaultProviderW (DWORD dwProvType, DWORD *pdwReserved,
1504 DWORD dwFlags, LPWSTR pszProvName, DWORD *pcbProvName)
1505 {
1506 HKEY hKey;
1507 PWSTR keyname;
1508 DWORD result;
1509 static const WCHAR nameW[] = {'N','a','m','e',0};
1510
1511 if (pdwReserved || !pcbProvName)
1512 {
1513 SetLastError(ERROR_INVALID_PARAMETER);
1514 return FALSE;
1515 }
1516 if (dwFlags & ~(CRYPT_USER_DEFAULT | CRYPT_MACHINE_DEFAULT))
1517 {
1518 SetLastError(NTE_BAD_FLAGS);
1519 return FALSE;
1520 }
1521 if (dwProvType > 999)
1522 {
1523 SetLastError(NTE_BAD_PROV_TYPE);
1524 return FALSE;
1525 }
1526 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) )
1527 {
1528 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1529 return FALSE;
1530 }
1531 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
1532 {
1533 CRYPT_Free(keyname);
1534 SetLastError(NTE_PROV_TYPE_NOT_DEF);
1535 return FALSE;
1536 }
1537 CRYPT_Free(keyname);
1538
1539 result = RegQueryValueExW(hKey, nameW, NULL, NULL, (LPBYTE)pszProvName, pcbProvName);
1540 RegCloseKey(hKey);
1541
1542 if (result)
1543 {
1544 if (result != ERROR_MORE_DATA)
1545 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
1546 else
1547 SetLastError(result);
1548
1549 return FALSE;
1550 }
1551
1552 return TRUE;
1553 }
1554
1555 /******************************************************************************
1556 * CryptGetDefaultProviderA (ADVAPI32.@)
1557 *
1558 * See CryptGetDefaultProviderW.
1559 */
CryptGetDefaultProviderA(DWORD dwProvType,DWORD * pdwReserved,DWORD dwFlags,LPSTR pszProvName,DWORD * pcbProvName)1560 BOOL WINAPI CryptGetDefaultProviderA (DWORD dwProvType, DWORD *pdwReserved,
1561 DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName)
1562 {
1563 PWSTR str = NULL;
1564 DWORD bufsize;
1565 BOOL ret;
1566
1567 TRACE("(%d, %p, %08x, %p, %p)\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName);
1568
1569 CryptGetDefaultProviderW(dwProvType, pdwReserved, dwFlags, NULL, &bufsize);
1570 if ( pszProvName && !(str = CRYPT_Alloc(bufsize)) )
1571 {
1572 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1573 return FALSE;
1574 }
1575 ret = CryptGetDefaultProviderW(dwProvType, pdwReserved, dwFlags, str, &bufsize);
1576 if (str)
1577 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName);
1578 *pcbProvName = bufsize / sizeof(WCHAR);
1579 if (str)
1580 {
1581 CRYPT_Free(str);
1582 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1583 {
1584 SetLastError(ERROR_MORE_DATA);
1585 return FALSE;
1586 }
1587 }
1588 return ret;
1589 }
1590
1591 /******************************************************************************
1592 * CryptGetHashParam (ADVAPI32.@)
1593 *
1594 * Retrieves data that controls the operations of a hash object.
1595 *
1596 * PARAMS
1597 * hHash [I] Handle of the hash object to question.
1598 * dwParam [I] Query type.
1599 * pbData [O] Buffer that receives the value data.
1600 * pdwDataLen [I/O] Size of the pbData buffer.
1601 * dwFlags [I] Reserved for future use and must be zero.
1602 *
1603 * RETURNS
1604 * Success: TRUE
1605 * Failure: FALSE
1606 *
1607 * NOTES
1608 * If pbData is NULL, pdwDataLen will contain the length required.
1609 */
CryptGetHashParam(HCRYPTHASH hHash,DWORD dwParam,BYTE * pbData,DWORD * pdwDataLen,DWORD dwFlags)1610 BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData,
1611 DWORD *pdwDataLen, DWORD dwFlags)
1612 {
1613 PCRYPTPROV prov;
1614 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1615
1616 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags);
1617
1618 if (!hash || !pdwDataLen || !hash->pProvider ||
1619 hash->dwMagic != MAGIC_CRYPTHASH || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
1620 {
1621 SetLastError(ERROR_INVALID_PARAMETER);
1622 return FALSE;
1623 }
1624
1625 prov = hash->pProvider;
1626 return prov->pFuncs->pCPGetHashParam(prov->hPrivate, hash->hPrivate, dwParam,
1627 pbData, pdwDataLen, dwFlags);
1628 }
1629
1630 /******************************************************************************
1631 * CryptGetKeyParam (ADVAPI32.@)
1632 *
1633 * Retrieves data that controls the operations of a key.
1634 *
1635 * PARAMS
1636 * hKey [I] Handle to they key in question.
1637 * dwParam [I] Specifies query type.
1638 * pbData [O] Sequence of bytes to receive data.
1639 * pdwDataLen [I/O] Size of pbData.
1640 * dwFlags [I] Reserved for future use and must be zero.
1641 *
1642 * RETURNS
1643 * Success: TRUE
1644 * Failure: FALSE
1645 *
1646 * NOTES
1647 * If pbData is NULL, pdwDataLen is set to the needed length of the buffer.
1648 */
CryptGetKeyParam(HCRYPTKEY hKey,DWORD dwParam,BYTE * pbData,DWORD * pdwDataLen,DWORD dwFlags)1649 BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData,
1650 DWORD *pdwDataLen, DWORD dwFlags)
1651 {
1652 PCRYPTPROV prov;
1653 PCRYPTKEY key = (PCRYPTKEY)hKey;
1654
1655 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags);
1656
1657 if (!key || !pdwDataLen || !key->pProvider ||
1658 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
1659 {
1660 SetLastError(ERROR_INVALID_PARAMETER);
1661 return FALSE;
1662 }
1663
1664 prov = key->pProvider;
1665 return prov->pFuncs->pCPGetKeyParam(prov->hPrivate, key->hPrivate, dwParam,
1666 pbData, pdwDataLen, dwFlags);
1667 }
1668
1669 /******************************************************************************
1670 * CryptGetProvParam (ADVAPI32.@)
1671 *
1672 * Retrieves parameters that control the operations of a CSP.
1673 *
1674 * PARAMS
1675 * hProv [I] Handle of the CSP in question.
1676 * dwParam [I] Specifies query type.
1677 * pbData [O] Buffer to receive the data.
1678 * pdwDataLen [I/O] Size of pbData.
1679 * dwFlags [I] see MSDN Docs.
1680 *
1681 * RETURNS
1682 * Success: TRUE
1683 * Failure: FALSE
1684 *
1685 * NOTES
1686 * If pbData is NULL, pdwDataLen is set to the needed buffer length.
1687 */
CryptGetProvParam(HCRYPTPROV hProv,DWORD dwParam,BYTE * pbData,DWORD * pdwDataLen,DWORD dwFlags)1688 BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
1689 DWORD *pdwDataLen, DWORD dwFlags)
1690 {
1691 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1692
1693 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags);
1694
1695 if (!prov || prov->dwMagic != MAGIC_CRYPTPROV)
1696 {
1697 SetLastError(ERROR_INVALID_PARAMETER);
1698 return FALSE;
1699 }
1700
1701 return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags);
1702 }
1703
1704 /******************************************************************************
1705 * CryptGetUserKey (ADVAPI32.@)
1706 *
1707 * Gets a handle of one of a user's two public/private key pairs.
1708 *
1709 * PARAMS
1710 * hProv [I] Handle of a CSP.
1711 * dwKeySpec [I] Private key to use.
1712 * phUserKey [O] Pointer to the handle of the retrieved keys.
1713 *
1714 * RETURNS
1715 * Success: TRUE
1716 * Failure: FALSE
1717 */
CryptGetUserKey(HCRYPTPROV hProv,DWORD dwKeySpec,HCRYPTKEY * phUserKey)1718 BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
1719 {
1720 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1721 PCRYPTKEY key;
1722
1723 TRACE("(0x%lx, %d, %p)\n", hProv, dwKeySpec, phUserKey);
1724
1725 if (!prov)
1726 {
1727 SetLastError(ERROR_INVALID_HANDLE);
1728 return FALSE;
1729 }
1730 if (!phUserKey || prov->dwMagic != MAGIC_CRYPTPROV)
1731 {
1732 SetLastError(ERROR_INVALID_PARAMETER);
1733 return FALSE;
1734 }
1735 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
1736 {
1737 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1738 return FALSE;
1739 }
1740
1741 key->pProvider = prov;
1742 key->dwMagic = MAGIC_CRYPTKEY;
1743 if (prov->pFuncs->pCPGetUserKey(prov->hPrivate, dwKeySpec, &key->hPrivate))
1744 {
1745 *phUserKey = (HCRYPTKEY)key;
1746 return TRUE;
1747 }
1748
1749 /* CSP Error */
1750 key->dwMagic = 0;
1751 CRYPT_Free(key);
1752 *phUserKey = 0;
1753 return FALSE;
1754 }
1755
1756 /******************************************************************************
1757 * CryptHashData (ADVAPI32.@)
1758 *
1759 * Adds data to a hash object.
1760 *
1761 * PARAMS
1762 * hHash [I] Handle of the hash object.
1763 * pbData [I] Buffer of data to be hashed.
1764 * dwDataLen [I] Number of bytes to add.
1765 * dwFlags [I] Can be CRYPT_USERDATA
1766 *
1767 * RETURNS
1768 * Success: TRUE
1769 * Failure: FALSE
1770 */
CryptHashData(HCRYPTHASH hHash,const BYTE * pbData,DWORD dwDataLen,DWORD dwFlags)1771 BOOL WINAPI CryptHashData (HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
1772 {
1773 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1774 PCRYPTPROV prov;
1775
1776 TRACE("(0x%lx, %p, %d, %08x)\n", hHash, pbData, dwDataLen, dwFlags);
1777
1778 if (!hash)
1779 {
1780 SetLastError(ERROR_INVALID_HANDLE);
1781 return FALSE;
1782 }
1783 if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH ||
1784 hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
1785 {
1786 SetLastError(ERROR_INVALID_PARAMETER);
1787 return FALSE;
1788 }
1789
1790 prov = hash->pProvider;
1791 return prov->pFuncs->pCPHashData(prov->hPrivate, hash->hPrivate, pbData, dwDataLen, dwFlags);
1792 }
1793
1794 /******************************************************************************
1795 * CryptHashSessionKey (ADVAPI32.@)
1796 *
1797 * Compute the cryptographic hash of a session key object.
1798 *
1799 * PARAMS
1800 * hHash [I] Handle to the hash object.
1801 * hKey [I] Handle to the key to be hashed.
1802 * dwFlags [I] Can be CRYPT_LITTLE_ENDIAN.
1803 *
1804 * RETURNS
1805 * Success: TRUE
1806 * Failure: FALSE
1807 */
CryptHashSessionKey(HCRYPTHASH hHash,HCRYPTKEY hKey,DWORD dwFlags)1808 BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags)
1809 {
1810 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1811 PCRYPTKEY key = (PCRYPTKEY)hKey;
1812 PCRYPTPROV prov;
1813
1814 TRACE("(0x%lx, 0x%lx, %08x)\n", hHash, hKey, dwFlags);
1815
1816 if (!hash || !key)
1817 {
1818 SetLastError(ERROR_INVALID_HANDLE);
1819 return FALSE;
1820 }
1821
1822 if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH ||
1823 hash->pProvider->dwMagic != MAGIC_CRYPTPROV || key->dwMagic != MAGIC_CRYPTKEY)
1824 {
1825 SetLastError(ERROR_INVALID_PARAMETER);
1826 return FALSE;
1827 }
1828
1829 prov = hash->pProvider;
1830 return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags);
1831 }
1832
1833 /******************************************************************************
1834 * CryptImportKey (ADVAPI32.@)
1835 *
1836 * Transfer a cryptographic key from a key BLOB into a cryptographic service provider (CSP).
1837 *
1838 * PARAMS
1839 * hProv [I] Handle of a CSP.
1840 * pbData [I] Contains the key to be imported.
1841 * dwDataLen [I] Length of the key.
1842 * hPubKey [I] Cryptographic key that decrypts pdData
1843 * dwFlags [I] Used only with a public/private key pair.
1844 * phKey [O] Imported key.
1845 *
1846 * RETURNS
1847 * Success: TRUE
1848 * Failure: FALSE
1849 */
CryptImportKey(HCRYPTPROV hProv,const BYTE * pbData,DWORD dwDataLen,HCRYPTKEY hPubKey,DWORD dwFlags,HCRYPTKEY * phKey)1850 BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen,
1851 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
1852 {
1853 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1854 PCRYPTKEY pubkey = (PCRYPTKEY)hPubKey, importkey;
1855
1856 TRACE("(0x%lx, %p, %d, 0x%lx, %08x, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
1857
1858 if (!prov || !pbData || !dwDataLen || !phKey ||
1859 prov->dwMagic != MAGIC_CRYPTPROV ||
1860 (pubkey && pubkey->dwMagic != MAGIC_CRYPTKEY))
1861 {
1862 SetLastError(ERROR_INVALID_PARAMETER);
1863 return FALSE;
1864 }
1865
1866 if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) )
1867 {
1868 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1869 return FALSE;
1870 }
1871
1872 importkey->pProvider = prov;
1873 importkey->dwMagic = MAGIC_CRYPTKEY;
1874 if (prov->pFuncs->pCPImportKey(prov->hPrivate, pbData, dwDataLen,
1875 pubkey ? pubkey->hPrivate : 0, dwFlags, &importkey->hPrivate))
1876 {
1877 *phKey = (HCRYPTKEY)importkey;
1878 return TRUE;
1879 }
1880
1881 importkey->dwMagic = 0;
1882 CRYPT_Free(importkey);
1883 return FALSE;
1884 }
1885
1886 /******************************************************************************
1887 * CryptSignHashW (ADVAPI32.@)
1888 *
1889 * Signs data.
1890 *
1891 * PARAMS
1892 * hHash [I] Handle of the hash object to be signed.
1893 * dwKeySpec [I] Private key to use.
1894 * sDescription [I] Should be NULL.
1895 * dwFlags [I] CRYPT_NOHASHOID/X931_FORMAT.
1896 * pbSignature [O] Buffer of the signature data.
1897 * pdwSigLen [I/O] Size of the pbSignature buffer.
1898 *
1899 * RETURNS
1900 * Success: TRUE
1901 * Failure: FALSE
1902 *
1903 * NOTES
1904 * Because of security flaws sDescription should not be used and should thus be
1905 * NULL. It is supported only for compatibility with Microsoft's Cryptographic
1906 * Providers.
1907 */
CryptSignHashW(HCRYPTHASH hHash,DWORD dwKeySpec,LPCWSTR sDescription,DWORD dwFlags,BYTE * pbSignature,DWORD * pdwSigLen)1908 BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription,
1909 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
1910 {
1911 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1912 PCRYPTPROV prov;
1913
1914 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n",
1915 hHash, dwKeySpec, debugstr_w(sDescription), dwFlags, pbSignature, pdwSigLen);
1916
1917 if (!hash)
1918 {
1919 SetLastError(ERROR_INVALID_HANDLE);
1920 return FALSE;
1921 }
1922 if (!pdwSigLen || !hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH ||
1923 hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
1924 {
1925 SetLastError(ERROR_INVALID_PARAMETER);
1926 return FALSE;
1927 }
1928
1929 prov = hash->pProvider;
1930 return prov->pFuncs->pCPSignHash(prov->hPrivate, hash->hPrivate, dwKeySpec, sDescription,
1931 dwFlags, pbSignature, pdwSigLen);
1932 }
1933
1934 /******************************************************************************
1935 * CryptSignHashA (ADVAPI32.@)
1936 *
1937 * See CryptSignHashW.
1938 */
CryptSignHashA(HCRYPTHASH hHash,DWORD dwKeySpec,LPCSTR sDescription,DWORD dwFlags,BYTE * pbSignature,DWORD * pdwSigLen)1939 BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription,
1940 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
1941 {
1942 LPWSTR wsDescription;
1943 BOOL result;
1944
1945 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n",
1946 hHash, dwKeySpec, debugstr_a(sDescription), dwFlags, pbSignature, pdwSigLen);
1947
1948 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1);
1949 result = CryptSignHashW(hHash, dwKeySpec, wsDescription, dwFlags, pbSignature, pdwSigLen);
1950 CRYPT_Free(wsDescription);
1951
1952 return result;
1953 }
1954
1955 /******************************************************************************
1956 * CryptSetHashParam (ADVAPI32.@)
1957 *
1958 * Customizes the operations of a hash object.
1959 *
1960 * PARAMS
1961 * hHash [I] Handle of the hash object to set parameters.
1962 * dwParam [I] HP_HMAC_INFO/HASHVAL.
1963 * pbData [I] Value data buffer.
1964 * dwFlags [I] Reserved for future use and must be zero.
1965 *
1966 * RETURNS
1967 * Success: TRUE
1968 * Failure: FALSE
1969 */
CryptSetHashParam(HCRYPTHASH hHash,DWORD dwParam,const BYTE * pbData,DWORD dwFlags)1970 BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, const BYTE *pbData, DWORD dwFlags)
1971 {
1972 PCRYPTPROV prov;
1973 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1974
1975 TRACE("(0x%lx, %d, %p, %08x)\n", hHash, dwParam, pbData, dwFlags);
1976
1977 if (!hash || !pbData || !hash->pProvider ||
1978 hash->dwMagic != MAGIC_CRYPTHASH || hash->pProvider->dwMagic != MAGIC_CRYPTPROV)
1979 {
1980 SetLastError(ERROR_INVALID_PARAMETER);
1981 return FALSE;
1982 }
1983
1984 prov = hash->pProvider;
1985 return prov->pFuncs->pCPSetHashParam(prov->hPrivate, hash->hPrivate,
1986 dwParam, pbData, dwFlags);
1987 }
1988
1989 /******************************************************************************
1990 * CryptSetKeyParam (ADVAPI32.@)
1991 *
1992 * Customizes a session key's operations.
1993 *
1994 * PARAMS
1995 * hKey [I] Handle to the key to set values.
1996 * dwParam [I] See MSDN Doc.
1997 * pbData [I] Buffer of values to set.
1998 * dwFlags [I] Only used when dwParam == KP_ALGID.
1999 *
2000 * RETURNS
2001 * Success: TRUE
2002 * Failure: FALSE
2003 */
CryptSetKeyParam(HCRYPTKEY hKey,DWORD dwParam,const BYTE * pbData,DWORD dwFlags)2004 BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, const BYTE *pbData, DWORD dwFlags)
2005 {
2006 PCRYPTPROV prov;
2007 PCRYPTKEY key = (PCRYPTKEY)hKey;
2008
2009 TRACE("(0x%lx, %d, %p, %08x)\n", hKey, dwParam, pbData, dwFlags);
2010
2011 if (!key || !pbData || !key->pProvider ||
2012 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
2013 {
2014 SetLastError(ERROR_INVALID_PARAMETER);
2015 return FALSE;
2016 }
2017
2018 prov = key->pProvider;
2019 return prov->pFuncs->pCPSetKeyParam(prov->hPrivate, key->hPrivate,
2020 dwParam, pbData, dwFlags);
2021 }
2022
2023 /******************************************************************************
2024 * CryptSetProviderA (ADVAPI32.@)
2025 *
2026 * Specifies the current user's default CSP.
2027 *
2028 * PARAMS
2029 * pszProvName [I] Name of the new default CSP.
2030 * dwProvType [I] Provider type of the CSP.
2031 *
2032 * RETURNS
2033 * Success: TRUE
2034 * Failure: FALSE
2035 */
CryptSetProviderA(LPCSTR pszProvName,DWORD dwProvType)2036 BOOL WINAPI CryptSetProviderA (LPCSTR pszProvName, DWORD dwProvType)
2037 {
2038 TRACE("(%s, %d)\n", pszProvName, dwProvType);
2039 return CryptSetProviderExA(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT);
2040 }
2041
2042 /******************************************************************************
2043 * CryptSetProviderW (ADVAPI32.@)
2044 *
2045 * See CryptSetProviderA.
2046 */
CryptSetProviderW(LPCWSTR pszProvName,DWORD dwProvType)2047 BOOL WINAPI CryptSetProviderW (LPCWSTR pszProvName, DWORD dwProvType)
2048 {
2049 TRACE("(%s, %d)\n", debugstr_w(pszProvName), dwProvType);
2050 return CryptSetProviderExW(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT);
2051 }
2052
2053 /******************************************************************************
2054 * CryptSetProviderExW (ADVAPI32.@)
2055 *
2056 * Specifies the default CSP.
2057 *
2058 * PARAMS
2059 * pszProvName [I] Name of the new default CSP.
2060 * dwProvType [I] Provider type of the CSP.
2061 * pdwReserved [I] Reserved for future use and must be NULL.
2062 * dwFlags [I] See MSDN Doc.
2063 *
2064 * RETURNS
2065 * Success: TRUE
2066 * Failure: FALSE
2067 */
CryptSetProviderExW(LPCWSTR pszProvName,DWORD dwProvType,DWORD * pdwReserved,DWORD dwFlags)2068 BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags)
2069 {
2070 HKEY hProvKey, hTypeKey;
2071 PWSTR keyname;
2072 static const WCHAR nameW[] = {'N','a','m','e',0};
2073
2074 TRACE("(%s, %d, %p, %08x)\n", debugstr_w(pszProvName), dwProvType, pdwReserved, dwFlags);
2075
2076 if (!pszProvName || pdwReserved)
2077 {
2078 SetLastError(ERROR_INVALID_PARAMETER);
2079 return FALSE;
2080 }
2081 if (dwProvType > MAXPROVTYPES)
2082 {
2083 SetLastError(NTE_BAD_PROV_TYPE);
2084 return FALSE;
2085 }
2086 if (dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT)
2087 || dwFlags == CRYPT_DELETE_DEFAULT)
2088 {
2089 SetLastError(NTE_BAD_FLAGS);
2090 return FALSE;
2091 }
2092
2093 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)))
2094 {
2095 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2096 return FALSE;
2097 }
2098 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
2099 keyname, &hTypeKey))
2100 {
2101 CRYPT_Free(keyname);
2102 SetLastError(NTE_BAD_PROVIDER);
2103 return FALSE;
2104 }
2105 CRYPT_Free(keyname);
2106
2107 if (dwFlags & CRYPT_DELETE_DEFAULT)
2108 {
2109 RegDeleteValueW(hTypeKey, nameW);
2110 }
2111 else
2112 {
2113 if (!(keyname = CRYPT_GetProvKeyName(pszProvName)))
2114 {
2115 RegCloseKey(hTypeKey);
2116 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2117 return FALSE;
2118 }
2119 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
2120 keyname, &hProvKey))
2121 {
2122 CRYPT_Free(keyname);
2123 RegCloseKey(hTypeKey);
2124 SetLastError(NTE_BAD_PROVIDER);
2125 return FALSE;
2126 }
2127 CRYPT_Free(keyname);
2128
2129 if (RegSetValueExW(hTypeKey, nameW, 0, REG_SZ, (const BYTE *)pszProvName,
2130 (strlenW(pszProvName) + 1)*sizeof(WCHAR)))
2131 {
2132 RegCloseKey(hTypeKey);
2133 RegCloseKey(hProvKey);
2134 return FALSE;
2135 }
2136
2137 RegCloseKey(hProvKey);
2138 }
2139 RegCloseKey(hTypeKey);
2140
2141 return TRUE;
2142 }
2143
2144 /******************************************************************************
2145 * CryptSetProviderExA (ADVAPI32.@)
2146 *
2147 * See CryptSetProviderExW.
2148 */
CryptSetProviderExA(LPCSTR pszProvName,DWORD dwProvType,DWORD * pdwReserved,DWORD dwFlags)2149 BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags)
2150 {
2151 BOOL ret = FALSE;
2152 PWSTR str = NULL;
2153
2154 TRACE("(%s, %d, %p, %08x)\n", pszProvName, dwProvType, pdwReserved, dwFlags);
2155
2156 if (CRYPT_ANSIToUnicode(pszProvName, &str, -1))
2157 {
2158 ret = CryptSetProviderExW(str, dwProvType, pdwReserved, dwFlags);
2159 CRYPT_Free(str);
2160 }
2161 return ret;
2162 }
2163
2164 /******************************************************************************
2165 * CryptSetProvParam (ADVAPI32.@)
2166 *
2167 * Customizes the operations of a CSP.
2168 *
2169 * PARAMS
2170 * hProv [I] Handle of a CSP.
2171 * dwParam [I] See MSDN Doc.
2172 * pbData [I] Buffer that contains a value to set as a parameter.
2173 * dwFlags [I] if dwParam is PP_USE_HARDWARE_RNG, dwFlags must be zero.
2174 *
2175 * RETURNS
2176 * Success: TRUE
2177 * Failure: FALSE
2178 */
CryptSetProvParam(HCRYPTPROV hProv,DWORD dwParam,const BYTE * pbData,DWORD dwFlags)2179 BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, const BYTE *pbData, DWORD dwFlags)
2180 {
2181 PCRYPTPROV prov = (PCRYPTPROV)hProv;
2182
2183 TRACE("(0x%lx, %d, %p, %08x)\n", hProv, dwParam, pbData, dwFlags);
2184
2185 if (!prov)
2186 {
2187 SetLastError(ERROR_INVALID_HANDLE);
2188 return FALSE;
2189 }
2190 if (prov->dwMagic != MAGIC_CRYPTPROV)
2191 {
2192 SetLastError(ERROR_INVALID_PARAMETER);
2193 return FALSE;
2194 }
2195 if (dwParam == PP_USE_HARDWARE_RNG)
2196 {
2197 FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n");
2198 FIXME("\tLetting the CSP decide.\n");
2199 }
2200 if (dwFlags & PP_CLIENT_HWND)
2201 {
2202 /* FIXME: Should verify the parameter */
2203 if (pbData /* && IsWindow((HWND)pbData) */)
2204 {
2205 crypt_hWindow = (HWND)(pbData);
2206 return TRUE;
2207 } else {
2208 SetLastError(ERROR_INVALID_PARAMETER);
2209 return FALSE;
2210 }
2211 }
2212 /* All other flags go to the CSP */
2213 return prov->pFuncs->pCPSetProvParam(prov->hPrivate, dwParam, pbData, dwFlags);
2214 }
2215
2216 /******************************************************************************
2217 * CryptVerifySignatureW (ADVAPI32.@)
2218 *
2219 * Verifies the signature of a hash object.
2220 *
2221 * PARAMS
2222 * hHash [I] Handle of the hash object to verify.
2223 * pbSignature [I] Signature data to verify.
2224 * dwSigLen [I] Size of pbSignature.
2225 * hPubKey [I] Handle to the public key to authenticate signature.
2226 * sDescription [I] Should be NULL.
2227 * dwFlags [I] See MSDN doc.
2228 *
2229 * RETURNS
2230 * Success: TRUE
2231 * Failure: FALSE
2232 *
2233 * NOTES
2234 * Because of security flaws sDescription should not be used and should thus be
2235 * NULL. It is supported only for compatibility with Microsoft's Cryptographic
2236 * Providers.
2237 */
CryptVerifySignatureW(HCRYPTHASH hHash,const BYTE * pbSignature,DWORD dwSigLen,HCRYPTKEY hPubKey,LPCWSTR sDescription,DWORD dwFlags)2238 BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen,
2239 HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
2240 {
2241 PCRYPTHASH hash = (PCRYPTHASH)hHash;
2242 PCRYPTKEY key = (PCRYPTKEY)hPubKey;
2243 PCRYPTPROV prov;
2244
2245 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature,
2246 dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags);
2247
2248 if (!hash || !key || key->dwMagic != MAGIC_CRYPTKEY || hash->dwMagic != MAGIC_CRYPTHASH ||
2249 !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV ||
2250 !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV)
2251 {
2252 SetLastError(ERROR_INVALID_PARAMETER);
2253 return FALSE;
2254 }
2255
2256 prov = hash->pProvider;
2257 return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen,
2258 key->hPrivate, sDescription, dwFlags);
2259 }
2260
2261 /******************************************************************************
2262 * CryptVerifySignatureA (ADVAPI32.@)
2263 *
2264 * See CryptVerifySignatureW.
2265 */
CryptVerifySignatureA(HCRYPTHASH hHash,const BYTE * pbSignature,DWORD dwSigLen,HCRYPTKEY hPubKey,LPCSTR sDescription,DWORD dwFlags)2266 BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen,
2267 HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags)
2268 {
2269 LPWSTR wsDescription;
2270 BOOL result;
2271
2272 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature,
2273 dwSigLen, hPubKey, debugstr_a(sDescription), dwFlags);
2274
2275 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1);
2276 result = CryptVerifySignatureW(hHash, pbSignature, dwSigLen, hPubKey, wsDescription, dwFlags);
2277 CRYPT_Free(wsDescription);
2278
2279 return result;
2280 }
2281
2282 /******************************************************************************
2283 * OpenEncryptedFileRawA (ADVAPI32.@)
2284 *
2285 * See OpenEncryptedFileRawW
2286 */
OpenEncryptedFileRawA(LPCSTR filename,ULONG flags,PVOID * context)2287 DWORD WINAPI OpenEncryptedFileRawA(LPCSTR filename, ULONG flags, PVOID *context)
2288 {
2289 FIXME("(%s, %x, %p): stub\n", debugstr_a(filename), flags, context);
2290 return ERROR_CALL_NOT_IMPLEMENTED;
2291 }
2292
2293 /******************************************************************************
2294 * OpenEncryptedFileRawW (ADVAPI32.@)
2295 *
2296 * Opens an EFS encrypted file for backup/restore
2297 *
2298 * PARAMS
2299 * filename [I] Filename to operate on
2300 * flags [I] Operation to perform
2301 * context [I] Handle to the context (out)
2302 * RETURNS
2303 * Success: ERROR_SUCCESS
2304 * Failure: NTSTATUS error code
2305 */
OpenEncryptedFileRawW(LPCWSTR filename,ULONG flags,PVOID * context)2306 DWORD WINAPI OpenEncryptedFileRawW(LPCWSTR filename, ULONG flags, PVOID *context)
2307 {
2308 FIXME("(%s, %x, %p): stub\n", debugstr_w(filename), flags, context);
2309 return ERROR_CALL_NOT_IMPLEMENTED;
2310 }
2311
2312 /******************************************************************************
2313 * ReadEncryptedFileRaw (ADVAPI32.@)
2314 *
2315 * Export encrypted files
2316 *
2317 * PARAMS
2318 * export [I] pointer to the export callback function
2319 * callback [I] pointer to the application defined context
2320 * context [I] pointer to the system context
2321 * RETURNS
2322 * Success: ERROR_SUCCESS
2323 * Failure: NTSTATUS error code
2324 */
ReadEncryptedFileRaw(PFE_EXPORT_FUNC export,PVOID callback,PVOID context)2325 DWORD WINAPI ReadEncryptedFileRaw(PFE_EXPORT_FUNC export, PVOID callback, PVOID context)
2326 {
2327 FIXME("(%p, %p, %p): stub\n", export, callback, context);
2328 return ERROR_CALL_NOT_IMPLEMENTED;
2329 }
2330
2331 #ifndef __REACTOS__
2332 /******************************************************************************
2333 * SystemFunction030 (ADVAPI32.@)
2334 *
2335 * Tests if two blocks of 16 bytes are equal
2336 *
2337 * PARAMS
2338 * b1,b2 [I] block of 16 bytes
2339 *
2340 * RETURNS
2341 * TRUE if blocks are the same
2342 * FALSE if blocks are different
2343 */
SystemFunction030(LPCVOID b1,LPCVOID b2)2344 BOOL WINAPI SystemFunction030(LPCVOID b1, LPCVOID b2)
2345 {
2346 return !memcmp(b1, b2, 0x10);
2347 }
2348
2349 /******************************************************************************
2350 * SystemFunction035 (ADVAPI32.@)
2351 *
2352 * Described here:
2353 http://disc.server.com/discussion.cgi?disc=148775;article=942;title=Coding%2FASM%2FSystem
2354 *
2355 * NOTES
2356 * Stub, always return TRUE.
2357 */
SystemFunction035(LPCSTR lpszDllFilePath)2358 BOOL WINAPI SystemFunction035(LPCSTR lpszDllFilePath)
2359 {
2360 FIXME("%s: stub\n", debugstr_a(lpszDllFilePath));
2361 return TRUE;
2362 }
2363
2364 /******************************************************************************
2365 * SystemFunction036 (ADVAPI32.@)
2366 *
2367 * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h
2368 *
2369 * PARAMS
2370 * pbBuffer [O] Pointer to memory to receive random bytes.
2371 * dwLen [I] Number of random bytes to fetch.
2372 *
2373 * RETURNS
2374 * Success: TRUE
2375 * Failure: FALSE
2376 */
2377
SystemFunction036(PVOID pbBuffer,ULONG dwLen)2378 BOOLEAN WINAPI SystemFunction036(PVOID pbBuffer, ULONG dwLen)
2379 {
2380 int dev_random;
2381
2382 dev_random = open("/dev/urandom", O_RDONLY);
2383 if (dev_random != -1)
2384 {
2385 if (!IsBadWritePtr( pbBuffer, dwLen ) &&
2386 read(dev_random, pbBuffer, dwLen) == (ssize_t)dwLen)
2387 {
2388 close(dev_random);
2389 return TRUE;
2390 }
2391 close(dev_random);
2392 }
2393 else
2394 FIXME("couldn't open /dev/urandom\n");
2395 SetLastError(NTE_FAIL);
2396 return FALSE;
2397 }
2398
2399 /*
2400 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
2401 in crypt32.dll.
2402 */
2403
2404 /******************************************************************************
2405 * SystemFunction040 (ADVAPI32.@)
2406 *
2407 * MSDN documents this function as RtlEncryptMemory and declares it in ntsecapi.h.
2408 *
2409 * PARAMS
2410 * memory [I/O] Pointer to memory to encrypt.
2411 * length [I] Length of region to encrypt in bytes.
2412 * flags [I] Control whether other processes are able to decrypt the memory.
2413 * RTL_ENCRYPT_OPTION_SAME_PROCESS
2414 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
2415 * RTL_ENCRYPT_OPTION_SAME_LOGON
2416 *
2417 * RETURNS
2418 * Success: STATUS_SUCCESS
2419 * Failure: NTSTATUS error code
2420 *
2421 * NOTES
2422 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
2423 * If flags are specified when encrypting, the same flag value must be given
2424 * when decrypting the memory.
2425 */
SystemFunction040(PVOID memory,ULONG length,ULONG flags)2426 NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags)
2427 {
2428 FIXME("(%p, %x, %x): stub [RtlEncryptMemory]\n", memory, length, flags);
2429 return STATUS_SUCCESS;
2430 }
2431
2432 /******************************************************************************
2433 * SystemFunction041 (ADVAPI32.@)
2434 *
2435 * MSDN documents this function as RtlDecryptMemory and declares it in ntsecapi.h.
2436 *
2437 * PARAMS
2438 * memory [I/O] Pointer to memory to decrypt.
2439 * length [I] Length of region to decrypt in bytes.
2440 * flags [I] Control whether other processes are able to decrypt the memory.
2441 * RTL_ENCRYPT_OPTION_SAME_PROCESS
2442 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
2443 * RTL_ENCRYPT_OPTION_SAME_LOGON
2444 *
2445 * RETURNS
2446 * Success: STATUS_SUCCESS
2447 * Failure: NTSTATUS error code
2448 *
2449 * NOTES
2450 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
2451 * If flags are specified when encrypting, the same flag value must be given
2452 * when decrypting the memory.
2453 */
SystemFunction041(PVOID memory,ULONG length,ULONG flags)2454 NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags)
2455 {
2456 FIXME("(%p, %x, %x): stub [RtlDecryptMemory]\n", memory, length, flags);
2457 return STATUS_SUCCESS;
2458 }
2459 #endif /* !__REACTOS __ */
2460
2461 /******************************************************************************
2462 * WriteEncryptedFileRaw (ADVAPI32.@)
2463 *
2464 * Import encrypted files
2465 *
2466 * PARAMS
2467 * import [I] pointer to the import callback function
2468 * callback [I] pointer to the application defined context
2469 * context [I] pointer to the system context
2470 * RETURNS
2471 * Success: ERROR_SUCCESS
2472 * Failure: NTSTATUS error code
2473 */
WriteEncryptedFileRaw(PFE_IMPORT_FUNC import,PVOID callback,PVOID context)2474 DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC import, PVOID callback, PVOID context)
2475 {
2476 FIXME("(%p, %p, %p): stub\n", import, callback, context);
2477 return ERROR_CALL_NOT_IMPLEMENTED;
2478 }
2479