ca505fc3ef8474da57e05ea33d54a6aef0b5fec8
[reactos.git] / reactos / lib / advapi32 / crypt / crypt.c
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 /***********************************************************************
21 *
22 * TODO:
23 * - Reference counting
24 * - Thread-safing
25 * - Signature checking
26 */
27
28 #include "advapi32.h"
29 #include "crypt.h"
30
31 #define NDEBUG
32 #include <debug.h>
33
34
35 HWND crypt_hWindow = 0;
36
37 #define CRYPT_ReturnLastError(err) {SetLastError(err); return FALSE;}
38
39 #define CRYPT_Alloc(size) ((LPVOID)LocalAlloc(LMEM_ZEROINIT, size))
40 #define CRYPT_Free(buffer) (LocalFree((HLOCAL)buffer))
41
42 static inline PSTR CRYPT_GetProvKeyName(PCSTR pProvName)
43 {
44 PCSTR KEYSTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\";
45 PSTR keyname;
46
47 keyname = CRYPT_Alloc(strlen(KEYSTR) + strlen(pProvName) +1);
48 if (keyname)
49 {
50 strcpy(keyname, KEYSTR);
51 strcpy(keyname + strlen(KEYSTR), pProvName);
52 }
53 else
54 {
55 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
56 }
57
58 return keyname;
59 }
60
61 static inline PSTR CRYPT_GetTypeKeyName(DWORD dwType, BOOL user)
62 {
63 PCSTR MACHINESTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
64 PCSTR USERSTR = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
65 PSTR keyname;
66 PSTR ptr;
67
68 keyname = CRYPT_Alloc( (user ? strlen(USERSTR) : strlen(MACHINESTR)) +1);
69 if (keyname)
70 {
71 user ? strcpy(keyname, USERSTR) : strcpy(keyname, MACHINESTR);
72 ptr = keyname + strlen(keyname);
73 *(--ptr) = (dwType % 10) + '0';
74 *(--ptr) = ((dwType / 10) % 10) + '0';
75 *(--ptr) = (dwType / 100) + '0';
76 }
77 else
78 {
79 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
80 }
81 return keyname;
82 }
83
84 /* CRYPT_UnicodeTOANSI
85 * wstr - unicode string
86 * str - pointer to ANSI string
87 * strsize - size of buffer pointed to by str or -1 if we have to do the allocation
88 *
89 * returns TRUE if unsuccessfull, FALSE otherwise.
90 * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call
91 */
92 static inline BOOL CRYPT_UnicodeToANSI(LPCWSTR wstr, LPSTR* str, int strsize)
93 {
94 int count;
95
96 if (!wstr)
97 {
98 *str = NULL;
99 return TRUE;
100 }
101 count = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
102 count = count < strsize ? count : strsize;
103 if (strsize == -1)
104 *str = CRYPT_Alloc(count * sizeof(CHAR));
105 if (*str)
106 {
107 WideCharToMultiByte(CP_ACP, 0, wstr, -1, *str, count, NULL, NULL);
108 return TRUE;
109 }
110 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
111 return FALSE;
112 }
113
114 /* CRYPT_ANSITOUnicode
115 * str - ANSI string
116 * wstr - pointer to unicode string
117 * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation
118 */
119 static inline BOOL CRYPT_ANSIToUnicode(LPCSTR str, LPWSTR* wstr, int wstrsize)
120 {
121 int wcount;
122
123 if (!str)
124 {
125 *wstr = NULL;
126 return TRUE;
127 }
128 wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
129 wcount = wcount < wstrsize/sizeof(WCHAR) ? wcount : wstrsize/sizeof(WCHAR);
130 if (wstrsize == -1)
131 *wstr = CRYPT_Alloc(wcount * sizeof(WCHAR));
132 if (*wstr)
133 {
134 MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount);
135 return TRUE;
136 }
137 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
138 return FALSE;
139 }
140
141 /* These next 2 functions are used by the VTableProvStruc structure */
142 static BOOL CALLBACK CRYPT_VerifyImage(LPCSTR lpszImage, BYTE* pData)
143 {
144 if (!lpszImage || !pData)
145 {
146 SetLastError(ERROR_INVALID_PARAMETER);
147 return FALSE;
148 }
149
150 DPRINT1("FIXME (%s, %p): not verifying image\n", lpszImage, pData);
151
152 return TRUE;
153 }
154
155 static BOOL CALLBACK CRYPT_ReturnhWnd(HWND *phWnd)
156 {
157 if (!phWnd)
158 return FALSE;
159 *phWnd = crypt_hWindow;
160 return TRUE;
161 }
162
163 #define CRYPT_GetProvFunc(name) \
164 if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error
165
166 #define CRYPT_GetProvFuncOpt(name) \
167 provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)
168 PCRYPTPROV CRYPT_LoadProvider(PSTR pImage)
169 {
170 PCRYPTPROV provider;
171 DWORD errorcode = ERROR_NOT_ENOUGH_MEMORY;
172
173 if (!(provider = CRYPT_Alloc(sizeof(CRYPTPROV))))
174 goto error;
175 if (!(provider->pFuncs = CRYPT_Alloc(sizeof(PROVFUNCS))))
176 goto error;
177 if (!(provider->pVTable = CRYPT_Alloc(sizeof(VTableProvStruc))))
178 goto error;
179 if (!(provider->hModule = LoadLibraryA(pImage)))
180 {
181 errorcode = (GetLastError() == ERROR_FILE_NOT_FOUND) ? NTE_PROV_DLL_NOT_FOUND : NTE_PROVIDER_DLL_FAIL;
182 DPRINT1("Failed to load dll %s\n", pImage);
183 goto error;
184 }
185 provider->refcount = 1;
186
187 errorcode = NTE_PROVIDER_DLL_FAIL;
188 CRYPT_GetProvFunc(CPAcquireContext);
189 CRYPT_GetProvFunc(CPCreateHash);
190 CRYPT_GetProvFunc(CPDecrypt);
191 CRYPT_GetProvFunc(CPDeriveKey);
192 CRYPT_GetProvFunc(CPDestroyHash);
193 CRYPT_GetProvFunc(CPDestroyKey);
194 CRYPT_GetProvFuncOpt(CPDuplicateHash);
195 CRYPT_GetProvFuncOpt(CPDuplicateKey);
196 CRYPT_GetProvFunc(CPEncrypt);
197 CRYPT_GetProvFunc(CPExportKey);
198 CRYPT_GetProvFunc(CPGenKey);
199 CRYPT_GetProvFunc(CPGenRandom);
200 CRYPT_GetProvFunc(CPGetHashParam);
201 CRYPT_GetProvFunc(CPGetKeyParam);
202 CRYPT_GetProvFunc(CPGetProvParam);
203 CRYPT_GetProvFunc(CPGetUserKey);
204 CRYPT_GetProvFunc(CPHashData);
205 CRYPT_GetProvFunc(CPHashSessionKey);
206 CRYPT_GetProvFunc(CPImportKey);
207 CRYPT_GetProvFunc(CPReleaseContext);
208 CRYPT_GetProvFunc(CPSetHashParam);
209 CRYPT_GetProvFunc(CPSetKeyParam);
210 CRYPT_GetProvFunc(CPSetProvParam);
211 CRYPT_GetProvFunc(CPSignHash);
212 CRYPT_GetProvFunc(CPVerifySignature);
213
214 /* FIXME: Not sure what the pbContextInfo field is for.
215 * Does it need memory allocation?
216 */
217 provider->pVTable->Version = 3;
218 provider->pVTable->pFuncVerifyImage = (FARPROC)CRYPT_VerifyImage;
219 provider->pVTable->pFuncReturnhWnd = (FARPROC)CRYPT_ReturnhWnd;
220 provider->pVTable->dwProvType = 0;
221 provider->pVTable->pbContextInfo = NULL;
222 provider->pVTable->cbContextInfo = 0;
223 provider->pVTable->pszProvName = NULL;
224 return provider;
225
226 error:
227 SetLastError(errorcode);
228 if (provider)
229 {
230 if (provider->hModule)
231 FreeLibrary(provider->hModule);
232 CRYPT_Free(provider->pVTable);
233 CRYPT_Free(provider->pFuncs);
234 CRYPT_Free(provider);
235 }
236 return NULL;
237 }
238 #undef CRYPT_GetProvFunc
239 #undef CRYPT_GetProvFuncOpt
240
241
242 /******************************************************************************
243 * CryptAcquireContextA (ADVAPI32.@)
244 * Acquire a crypto provider context handle.
245 *
246 * PARAMS
247 * phProv: Pointer to HCRYPTPROV for the output.
248 * pszContainer: Key Container Name
249 * pszProvider: Cryptographic Service Provider Name
250 * dwProvType: Crypto provider type to get a handle.
251 * dwFlags: flags for the operation
252 *
253 * RETURNS TRUE on success, FALSE on failure.
254 */
255 BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer,
256 LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
257 {
258 PCRYPTPROV pProv = NULL;
259 HKEY key;
260 PSTR imagepath = NULL, keyname = NULL, provname = NULL, temp = NULL;
261 BYTE* signature;
262 DWORD keytype, type, len;
263 ULONG r;
264
265 DPRINT("(%p, %s, %s, %ld, %08lx)\n", phProv, pszContainer,
266 pszProvider, dwProvType, dwFlags);
267
268 if (dwProvType < 1 || dwProvType > MAXPROVTYPES)
269 {
270 SetLastError(NTE_BAD_PROV_TYPE);
271 return FALSE;
272 }
273
274 if (!phProv)
275 {
276 SetLastError(ERROR_INVALID_PARAMETER);
277 return FALSE;
278 }
279
280 if (!pszProvider || !*pszProvider)
281 {
282 /* No CSP name specified so try the user default CSP first
283 * then try the machine default CSP
284 */
285 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, TRUE)))
286 {
287 DPRINT("No provider registered for crypto provider type %ld.\n", dwProvType);
288 SetLastError(NTE_PROV_TYPE_NOT_DEF);
289 return FALSE;
290 }
291
292 if (RegOpenKeyA(HKEY_CURRENT_USER, keyname, &key))
293 {
294 CRYPT_Free(keyname);
295 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, FALSE)))
296 {
297 DPRINT("No type registered for crypto provider type %ld.\n", dwProvType);
298 RegCloseKey(key);
299 SetLastError(NTE_PROV_TYPE_NOT_DEF);
300 goto error;
301 }
302
303 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key))
304 {
305 DPRINT("Did not find registry entry of crypto provider for %S.\n", keyname);
306 CRYPT_Free(keyname);
307 RegCloseKey(key);
308 SetLastError(NTE_PROV_TYPE_NOT_DEF);
309 goto error;
310 }
311 }
312
313 CRYPT_Free(keyname);
314 r = RegQueryValueExA(key, "Name", NULL, &keytype, NULL, &len);
315 if (r != ERROR_SUCCESS || !len || keytype != REG_SZ)
316 {
317 DPRINT("error %ld reading size of 'Name' from registry\n", r );
318 RegCloseKey(key);
319 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
320 goto error;
321 }
322 if (!(provname = CRYPT_Alloc(len)))
323 {
324 RegCloseKey(key);
325 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
326 goto error;
327 }
328 r = RegQueryValueExA(key, "Name", NULL, NULL, (LPBYTE)provname, &len);
329 if (r != ERROR_SUCCESS)
330 {
331 DPRINT("error %ld reading 'Name' from registry\n", r );
332 RegCloseKey(key);
333 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
334 goto error;
335 }
336 RegCloseKey(key);
337 }
338 else
339 {
340 if (!(provname = CRYPT_Alloc(strlen(pszProvider) +1)))
341 {
342 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
343 goto error;
344 }
345 strcpy(provname, pszProvider);
346 }
347
348 keyname = CRYPT_GetProvKeyName(provname);
349 r = RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key);
350 CRYPT_Free(keyname);
351 if (r != ERROR_SUCCESS)
352 {
353 SetLastError(NTE_KEYSET_NOT_DEF);
354 goto error;
355 }
356 len = sizeof(DWORD);
357 r = RegQueryValueExA(key, "Type", NULL, NULL, (BYTE*)&type, &len);
358 if (r != ERROR_SUCCESS)
359 {
360 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
361 goto error;
362 }
363 if (type != dwProvType)
364 {
365 DPRINT("Crypto provider has wrong type (%ld vs expected %ld).\n", type, dwProvType);
366 SetLastError(NTE_PROV_TYPE_NO_MATCH);
367 goto error;
368 }
369
370 r = RegQueryValueExA(key, "Image Path", NULL, &keytype, NULL, &len);
371 if ( r != ERROR_SUCCESS || keytype != REG_SZ)
372 {
373 DPRINT("error %ld reading size of 'Image Path' from registry\n", r );
374 RegCloseKey(key);
375 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
376 goto error;
377 }
378 if (!(temp = CRYPT_Alloc(len)))
379 {
380 RegCloseKey(key);
381 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
382 goto error;
383 }
384 r = RegQueryValueExA(key, "Image Path", NULL, NULL, (LPBYTE)temp, &len);
385 if (r != ERROR_SUCCESS)
386 {
387 DPRINT("error %ld reading 'Image Path' from registry\n", r );
388 RegCloseKey(key);
389 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
390 goto error;
391 }
392
393 r = RegQueryValueExA(key, "Signature", NULL, &keytype, NULL, &len);
394 if (r == ERROR_SUCCESS && keytype == REG_BINARY)
395 {
396 if (!(signature = CRYPT_Alloc(len)))
397 {
398 RegCloseKey(key);
399 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
400 goto error;
401 }
402 r = RegQueryValueExA(key, "Signature", NULL, NULL, signature, &len);
403 if (r != ERROR_SUCCESS)
404 {
405 DPRINT("error %ld reading 'Signature'\n", r );
406 CRYPT_Free(signature);
407 RegCloseKey(key);
408 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
409 goto error;
410 }
411 }
412 else
413 {
414 r = RegQueryValueExA(key, "SigInFile", NULL, &keytype, NULL, &len);
415 if (r != ERROR_SUCCESS)
416 {
417 DPRINT("error %ld reading size of 'SigInFile'\n", r );
418 RegCloseKey(key);
419 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
420 goto error;
421 }
422 else
423 {
424 /* FIXME: The presence of the SigInFile value indicates the
425 * provider's signature is in its resources, so need to read it.
426 * But since CRYPT_VerifyImage is stubbed, provide any old thing
427 * for now.
428 */
429 if (!(signature = CRYPT_Alloc(1)))
430 {
431 RegCloseKey(key);
432 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
433 goto error;
434 }
435 }
436 }
437 RegCloseKey(key);
438 len = ExpandEnvironmentStringsA(temp, NULL, 0);
439 if (!(imagepath = CRYPT_Alloc(len)))
440 {
441 CRYPT_Free(signature);
442 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
443 goto error;
444 }
445 if (!ExpandEnvironmentStringsA(temp, imagepath, len))
446 {
447 CRYPT_Free(signature);
448 /* ExpandEnvironmentStrings will call SetLastError */
449 goto error;
450 }
451
452 if (!CRYPT_VerifyImage(imagepath, signature))
453 {
454 CRYPT_Free(signature);
455 SetLastError(NTE_SIGNATURE_FILE_BAD);
456 goto error;
457 }
458 pProv = CRYPT_LoadProvider(imagepath);
459 CRYPT_Free(signature);
460 if (!pProv)
461 {
462 /* CRYPT_LoadProvider calls SetLastError */
463 goto error;
464 }
465 pProv->pVTable->dwProvType = dwProvType;
466 pProv->pVTable->pszProvName = provname;
467 if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, (CHAR*)pszContainer, dwFlags, pProv->pVTable))
468 {
469 /* MSDN: When this flag is set, the value returned in phProv is undefined,
470 * and thus, the CryptReleaseContext function need not be called afterwards.
471 * Therefore, we must clean up everything now.
472 */
473 if (dwFlags & CRYPT_DELETEKEYSET)
474 {
475 FreeLibrary(pProv->hModule);
476 CRYPT_Free(provname);
477 CRYPT_Free(pProv->pFuncs);
478 CRYPT_Free(pProv);
479 }
480 else
481 {
482 *phProv = (HCRYPTPROV)pProv;
483 }
484 CRYPT_Free(temp);
485 CRYPT_Free(imagepath);
486 return TRUE;
487 }
488 /* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */
489 error:
490 if (pProv)
491 {
492 if (pProv->hModule)
493 FreeLibrary(pProv->hModule);
494 if (pProv->pVTable)
495 CRYPT_Free(pProv->pVTable);
496 if (pProv->pFuncs)
497 CRYPT_Free(pProv->pFuncs);
498 CRYPT_Free(pProv);
499 }
500 if (provname)
501 CRYPT_Free(provname);
502 if (temp)
503 CRYPT_Free(temp);
504 if (imagepath)
505 CRYPT_Free(imagepath);
506 return FALSE;
507 }
508
509 /******************************************************************************
510 * CryptAcquireContextW (ADVAPI32.@)
511 *
512 * see CryptAcquireContextA
513 */
514 BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer,
515 LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
516 {
517 PSTR pProvider = NULL, pContainer = NULL;
518 BOOL ret = FALSE;
519
520 DPRINT("(%p, %S, %S, %ld, %08lx)\n", phProv, pszContainer,
521 pszProvider, dwProvType, dwFlags);
522
523 if (!CRYPT_UnicodeToANSI(pszContainer, &pContainer, -1))
524 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
525 if (!CRYPT_UnicodeToANSI(pszProvider, &pProvider, -1))
526 {
527 CRYPT_Free(pContainer);
528 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
529 }
530
531 ret = CryptAcquireContextA(phProv, pContainer, pProvider, dwProvType, dwFlags);
532
533 if (pContainer)
534 CRYPT_Free(pContainer);
535 if (pProvider)
536 CRYPT_Free(pProvider);
537
538 return ret;
539 }
540
541 /******************************************************************************
542 * CryptContextAddRef (ADVAPI32.@)
543 *
544 * Increases reference count of a cryptographic service provider handle
545 * by one.
546 *
547 * PARAMS
548 * hProv [I] Handle to the CSP whose reference is being incremented.
549 * pdwReserved [IN] Reserved for future use and must be NULL.
550 * dwFlags [I] Reserved for future use and must be NULL.
551 *
552 * RETURNS
553 * Success: TRUE
554 * Failure: FALSE
555 */
556 BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags)
557 {
558 PCRYPTPROV pProv = (PCRYPTPROV)hProv;
559
560 DPRINT("(0x%lx, %p, %08lx)\n", hProv, pdwReserved, dwFlags);
561
562 if (!pProv)
563 {
564 SetLastError(NTE_BAD_UID);
565 return FALSE;
566 }
567
568 pProv->refcount++;
569 return TRUE;
570 }
571
572 /******************************************************************************
573 * CryptReleaseContext (ADVAPI32.@)
574 *
575 * Releases the handle of a CSP. Reference count is decreased.
576 *
577 * PARAMS
578 * hProv [I] Handle of a CSP.
579 * dwFlags [I] Reserved for future use and must be NULL.
580 *
581 * RETURNS
582 * Success: TRUE
583 * Failure: FALSE
584 */
585 BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags)
586 {
587 PCRYPTPROV pProv = (PCRYPTPROV)hProv;
588 BOOL ret = TRUE;
589
590 DPRINT("(0x%lx, %08ld)\n", hProv, dwFlags);
591
592 if (!pProv)
593 {
594 SetLastError(NTE_BAD_UID);
595 return FALSE;
596 }
597
598 pProv->refcount--;
599 if (pProv->refcount <= 0)
600 {
601 ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
602 FreeLibrary(pProv->hModule);
603 #if 0
604 CRYPT_Free(pProv->pVTable->pContextInfo);
605 #endif
606 CRYPT_Free(pProv->pVTable->pszProvName);
607 CRYPT_Free(pProv->pVTable);
608 CRYPT_Free(pProv->pFuncs);
609 CRYPT_Free(pProv);
610 }
611 return ret;
612 }
613
614 /******************************************************************************
615 * CryptGenRandom (ADVAPI32.@)
616 *
617 * Fills a buffer with cryptographically random bytes.
618 *
619 * PARAMS
620 * hProv [I] Handle of a CSP.
621 * dwLen [I] Number of bytes to generate.
622 * pbBuffer [I/O] Buffer to contain random bytes.
623 *
624 * RETURNS
625 * Success: TRUE
626 * Failure: FALSE
627 *
628 * NOTES
629 * pdBuffer must be at least dwLen bytes long.
630 */
631 BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
632 {
633 PCRYPTPROV prov = (PCRYPTPROV)hProv;
634
635 DPRINT("(0x%lx, %ld, %p)\n", hProv, dwLen, pbBuffer);
636
637 if (!hProv)
638 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
639
640 return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer);
641 }
642
643 /******************************************************************************
644 * CryptCreateHash (ADVAPI32.@)
645 *
646 * Initiates the hashing of a stream of data.
647 *
648 * PARAMS
649 * hProv [I] Handle of a CSP.
650 * Algid [I] Identifies the hash algorithm to use.
651 * hKey [I] Key for the hash (if required).
652 * dwFlags [I] Reserved for future use and must be NULL.
653 * phHash [O] Address of the future handle to the new hash object.
654 *
655 * RETURNS
656 * Success: TRUE
657 * Failure: FALSE
658 *
659 * NOTES
660 * If the algorithm is a keyed hash, hKey is the key.
661 */
662 BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
663 DWORD dwFlags, HCRYPTHASH *phHash)
664 {
665 PCRYPTPROV prov = (PCRYPTPROV)hProv;
666 PCRYPTKEY key = (PCRYPTKEY)hKey;
667 PCRYPTHASH hash;
668
669 DPRINT("(0x%lx, 0x%x, 0x%lx, %08lx, %p)\n", hProv, Algid, hKey, dwFlags, phHash);
670
671 if (!prov)
672 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
673 if (!phHash)
674 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
675 if (dwFlags)
676 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
677 if (!(hash = CRYPT_Alloc(sizeof(CRYPTHASH))))
678 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
679
680 hash->pProvider = prov;
681
682 if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid,
683 key ? key->hPrivate : 0, 0, &hash->hPrivate))
684 {
685 *phHash = (HCRYPTHASH)hash;
686 return TRUE;
687 }
688
689 /* CSP error! */
690 CRYPT_Free(hash);
691 *phHash = 0;
692 return FALSE;
693 }
694
695 /******************************************************************************
696 * CryptDecrypt (ADVAPI32.@)
697 *
698 * Decrypts data encrypted by CryptEncrypt.
699 *
700 * PARAMS
701 * hKey [I] Handle to the decryption key.
702 * hHash [I] Handle to a hash object.
703 * Final [I] TRUE if this is the last section to be decrypted.
704 * dwFlags [I] Reserved for future use. Can be CRYPT_OAEP.
705 * pbData [I/O] Buffer that holds the encrypted data. Holds decrypted
706 * data on return
707 * pdwDataLen [I/O] Length of pbData before and after the call.
708 *
709 * RETURNS
710 * Success: TRUE
711 * Failure: FALSE
712 */
713 BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
714 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
715 {
716 PCRYPTPROV prov;
717 PCRYPTKEY key = (PCRYPTKEY)hKey;
718 PCRYPTHASH hash = (PCRYPTHASH)hHash;
719
720 DPRINT("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
721
722 if (!key || !pbData || !pdwDataLen)
723 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
724
725 prov = key->pProvider;
726 return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
727 Final, dwFlags, pbData, pdwDataLen);
728 }
729
730 /******************************************************************************
731 * CryptDeriveKey (ADVAPI32.@)
732 *
733 * Generates session keys derived from a base data value.
734 *
735 * PARAMS
736 * hProv [I] Handle to a CSP.
737 * Algid [I] Identifies the symmetric encryption algorithm to use.
738 * hBaseData [I] Handle to a hash object.
739 * dwFlags [I] Type of key to generate.
740 * phKey [I/O] Address of the newly generated key.
741 *
742 * RETURNS
743 * Success: TRUE
744 * Failure: FALSE
745 */
746 BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData,
747 DWORD dwFlags, HCRYPTKEY *phKey)
748 {
749 PCRYPTPROV prov = (PCRYPTPROV)hProv;
750 PCRYPTHASH hash = (PCRYPTHASH)hBaseData;
751 PCRYPTKEY key;
752
753 DPRINT("(0x%lx, 0x%08x, 0x%lx, 0x%08lx, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey);
754
755 if (!prov || !hash)
756 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
757 if (!phKey)
758 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
759 if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
760 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
761
762 key->pProvider = prov;
763 if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate))
764 {
765 *phKey = (HCRYPTKEY)key;
766 return TRUE;
767 }
768
769 /* CSP error! */
770 CRYPT_Free(key);
771 *phKey = 0;
772 return FALSE;
773 }
774
775 /******************************************************************************
776 * CryptDestroyHash (ADVAPI32.@)
777 *
778 * Destroys the hash object referenced by hHash.
779 *
780 * PARAMS
781 * hHash [I] Handle of the hash object to be destroyed.
782 *
783 * RETURNS
784 * Success: TRUE
785 * Failure: FALSE
786 */
787 BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash)
788 {
789 PCRYPTHASH hash = (PCRYPTHASH)hHash;
790 PCRYPTPROV prov;
791 BOOL ret;
792
793 DPRINT("(0x%lx)\n", hHash);
794
795 if (!hash)
796 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
797
798 prov = hash->pProvider;
799 ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate);
800 CRYPT_Free(hash);
801 return ret;
802 }
803
804 /******************************************************************************
805 * CryptDestroyKey (ADVAPI32.@)
806 *
807 * Releases the handle referenced by hKey.
808 *
809 * PARAMS
810 * hKey [I] Handle of the key to be destroyed.
811 *
812 * RETURNS
813 * Success: TRUE
814 * Failure: FALSE
815 */
816 BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey)
817 {
818 PCRYPTKEY key = (PCRYPTKEY)hKey;
819 PCRYPTPROV prov;
820 BOOL ret;
821
822 DPRINT("(0x%lx)\n", hKey);
823
824 if (!key)
825 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
826
827 prov = key->pProvider;
828 ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate);
829 CRYPT_Free(key);
830 return ret;
831 }
832
833 /******************************************************************************
834 * CryptDuplicateHash (ADVAPI32.@)
835 *
836 * Duplicates a hash.
837 *
838 * PARAMS
839 * hHash [I] Handle to the hash to be copied.
840 * pdwReserved [I] Reserved for future use and must be zero.
841 * dwFlags [I] Reserved for future use and must be zero.
842 * phHash [O] Address of the handle to receive the copy.
843 *
844 * RETURNS
845 * Success: TRUE
846 * Failure: FALSE
847 */
848 BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved,
849 DWORD dwFlags, HCRYPTHASH *phHash)
850 {
851 PCRYPTPROV prov;
852 PCRYPTHASH orghash, newhash;
853
854 DPRINT("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash);
855
856 orghash = (PCRYPTHASH)hHash;
857 if (!orghash || pdwReserved || !phHash)
858 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
859
860 prov = orghash->pProvider;
861 if (!prov->pFuncs->pCPDuplicateHash)
862 CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
863
864 if (!(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))))
865 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
866
867 newhash->pProvider = prov;
868 if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate))
869 {
870 *phHash = (HCRYPTHASH)newhash;
871 return TRUE;
872 }
873 CRYPT_Free(newhash);
874 return FALSE;
875 }
876
877 /******************************************************************************
878 * CryptDuplicateKey (ADVAPI32.@)
879 *
880 * Duplicate a key and the key's state.
881 *
882 * PARAMS
883 * hKey [I] Handle of the key to copy.
884 * pdwReserved [I] Reserved for future use and must be NULL.
885 * dwFlags [I] Reserved for future use and must be zero.
886 * phKey [I] Address of the handle to the duplicated key.
887 *
888 * RETURNS
889 * Success: TRUE
890 * Failure: FALSE
891 */
892 BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
893 {
894 PCRYPTPROV prov;
895 PCRYPTKEY orgkey, newkey;
896
897 DPRINT("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey);
898
899 orgkey = (PCRYPTKEY)hKey;
900 if (!orgkey || pdwReserved || !phKey)
901 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
902
903 prov = orgkey->pProvider;
904 if (!prov->pFuncs->pCPDuplicateKey)
905 CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
906
907 if (!(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))))
908 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
909
910 newkey->pProvider = prov;
911 if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate))
912 {
913 *phKey = (HCRYPTKEY)newkey;
914 return TRUE;
915 }
916 CRYPT_Free(newkey);
917 return FALSE;
918 }
919
920 /******************************************************************************
921 * CryptEncrypt (ADVAPI32.@)
922 *
923 * Encrypts data.
924 *
925 * PARAMS
926 * hKey [I] Handle to the enryption key.
927 * hHash [I] Handle to a hash object.
928 * Final [I] TRUE if this is the last section to encrypt.
929 * dwFlags [I] Can be CRYPT_OAEP.
930 * pbData [I/O] Data to be encrypted. Contains encrypted data after call.
931 * pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the
932 * encrypted data after call.
933 * dwBufLen [I] Length of the input pbData buffer.
934 *
935 * RETURNS
936 * Success: TRUE
937 * Failure: FALSE
938 *
939 * NOTES
940 * If pbData is NULL, CryptEncrypt determines stores the number of bytes
941 * required for the returned data in pdwDataLen.
942 */
943 BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
944 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
945 {
946 PCRYPTPROV prov;
947 PCRYPTKEY key = (PCRYPTKEY)hKey;
948 PCRYPTHASH hash = (PCRYPTHASH)hHash;
949
950 DPRINT("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
951
952 if (!key || !pdwDataLen)
953 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
954
955 prov = key->pProvider;
956 return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
957 Final, dwFlags, pbData, pdwDataLen, dwBufLen);
958 }
959
960 /******************************************************************************
961 * CryptEnumProvidersW (ADVAPI32.@)
962 *
963 * Returns the next availabe CSP.
964 *
965 * PARAMS
966 * dwIndex [I] Index of the next provider to be enumerated.
967 * pdwReserved [I] Reserved for future use and must be NULL.
968 * dwFlags [I] Reserved for future use and must be zero.
969 * pdwProvType [O] DWORD designating the type of the provider.
970 * pszProvName [O] Buffer that receives data from the provider.
971 * pcbProvName [I/O] Specifies the size of pszProvName. Contains the number
972 * of bytes stored in the buffer on return.
973 *
974 * RETURNS
975 * Success: TRUE
976 * Failure: FALSE
977 *
978 * NOTES
979 * If pszProvName is NULL, CryptEnumProvidersW sets the size of the name
980 * for memory allocation purposes.
981 */
982 BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved,
983 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName)
984 {
985 HKEY hKey;
986
987 DPRINT("(%ld, %p, %ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
988 pdwProvType, pszProvName, pcbProvName);
989
990 if (pdwReserved || !pcbProvName)
991 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
992 if (dwFlags)
993 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
994
995 if (RegOpenKeyW(HKEY_LOCAL_MACHINE,
996 L"Software\\Microsoft\\Cryptography\\Defaults\\Provider",
997 &hKey))
998 CRYPT_ReturnLastError(NTE_FAIL);
999
1000 if (!pszProvName)
1001 {
1002 DWORD numkeys;
1003 WCHAR *provNameW;
1004
1005 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, pcbProvName,
1006 NULL, NULL, NULL, NULL, NULL, NULL);
1007
1008 if (!(provNameW = CRYPT_Alloc(*pcbProvName * sizeof(WCHAR))))
1009 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1010
1011 RegEnumKeyExW(hKey, dwIndex, provNameW, pcbProvName, NULL, NULL, NULL, NULL);
1012 (*pcbProvName)++;
1013 *pcbProvName *= sizeof(WCHAR);
1014
1015 CRYPT_Free(provNameW);
1016
1017 if (dwIndex >= numkeys)
1018 CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS);
1019 }
1020 else
1021 {
1022 DWORD size = sizeof(DWORD);
1023 DWORD result;
1024 HKEY subkey;
1025
1026 result = RegEnumKeyW(hKey, dwIndex, pszProvName, *pcbProvName / sizeof(WCHAR));
1027 if (result)
1028 CRYPT_ReturnLastError(result);
1029 if (RegOpenKeyW(hKey, pszProvName, &subkey))
1030 return FALSE;
1031 if (RegQueryValueExW(subkey, L"Type", NULL, NULL, (BYTE*)pdwProvType, &size))
1032 return FALSE;
1033 RegCloseKey(subkey);
1034 }
1035 RegCloseKey(hKey);
1036 return TRUE;
1037 }
1038
1039 /******************************************************************************
1040 * CryptEnumProvidersA (ADVAPI32.@)
1041 *
1042 * see CryptEnumProvidersW
1043 */
1044 BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved,
1045 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName)
1046 {
1047 PWSTR str = NULL;
1048 DWORD strlen;
1049 BOOL ret; /* = FALSE; */
1050
1051 DPRINT("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
1052 pdwProvType, pszProvName, pcbProvName);
1053
1054 strlen = *pcbProvName * sizeof(WCHAR);
1055 if (pszProvName && !(str = CRYPT_Alloc(strlen)))
1056 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1057 ret = CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &strlen);
1058 if (str)
1059 {
1060 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName);
1061 CRYPT_Free(str);
1062 }
1063 *pcbProvName = strlen / sizeof(WCHAR); /* FIXME: not correct */
1064 return ret;
1065 }
1066
1067 /******************************************************************************
1068 * CryptEnumProviderTypesA (ADVAPI32i.@)
1069 *
1070 * Retrieves the next type of CSP supported.
1071 *
1072 * PARAMS
1073 * dwIndex [I] Index of the next provider to be enumerated.
1074 * pdwReserved [I] Reserved for future use and must be NULL.
1075 * dwFlags [I] Reserved for future use and must be zero.
1076 * pdwProvType [O] DWORD designating the type of the provider.
1077 * pszTypeName [O] Buffer that receives data from the provider type.
1078 * pcbTypeName [I/O] Specifies the size of pszTypeName. Contains the number
1079 * of bytes stored in the buffer on return.
1080 *
1081 * RETURNS
1082 * Success: TRUE
1083 * Failure: FALSE
1084 *
1085 * NOTES
1086 * If pszTypeName is NULL, CryptEnumProviderTypesA sets the size of the name
1087 * for memory allocation purposes.
1088 */
1089 BOOL WINAPI CryptEnumProviderTypesA (DWORD dwIndex, DWORD *pdwReserved,
1090 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszTypeName, DWORD *pcbTypeName)
1091 {
1092 HKEY hKey, hSubkey;
1093 DWORD keylen, numkeys, dwType;
1094 PSTR keyname, ch;
1095 DWORD result;
1096
1097 DPRINT("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved,
1098 dwFlags, pdwProvType, pszTypeName, pcbTypeName);
1099
1100 if (pdwReserved || !pdwProvType || !pcbTypeName)
1101 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1102 if (dwFlags)
1103 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
1104
1105 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
1106 return FALSE;
1107
1108 RegQueryInfoKeyA(hKey, NULL, NULL, NULL, &numkeys, &keylen, NULL, NULL, NULL, NULL, NULL, NULL);
1109 if (dwIndex >= numkeys)
1110 CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS);
1111 keylen++;
1112 if ( !(keyname = CRYPT_Alloc(keylen)) )
1113 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1114 if ( RegEnumKeyA(hKey, dwIndex, keyname, keylen) )
1115 {
1116 CRYPT_Free(keyname);
1117 return FALSE;
1118 }
1119 RegOpenKeyA(hKey, keyname, &hSubkey);
1120 ch = keyname + strlen(keyname);
1121 /* Convert "Type 000" to 0, etc/ */
1122 *pdwProvType = *(--ch) - '0';
1123 *pdwProvType += (*(--ch) - '0') * 10;
1124 *pdwProvType += (*(--ch) - '0') * 100;
1125 CRYPT_Free(keyname);
1126
1127 result = RegQueryValueExA(hSubkey, "TypeName", NULL, &dwType, (LPBYTE)pszTypeName, pcbTypeName);
1128 if (result)
1129 CRYPT_ReturnLastError(result);
1130
1131 RegCloseKey(hSubkey);
1132 RegCloseKey(hKey);
1133 return TRUE;
1134 }
1135
1136 /******************************************************************************
1137 * CryptEnumProviderTypesW (ADVAPI32.@)
1138 *
1139 * see CryptEnumProviderTypesA
1140 */
1141 BOOL WINAPI CryptEnumProviderTypesW (DWORD dwIndex, DWORD *pdwReserved,
1142 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszTypeName, DWORD *pcbTypeName)
1143 {
1144 PSTR str = NULL;
1145 DWORD strlen;
1146 BOOL ret;
1147
1148 DPRINT("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
1149 pdwProvType, pszTypeName, pcbTypeName);
1150 strlen = *pcbTypeName / sizeof(WCHAR);
1151 if (pszTypeName && !(str = CRYPT_Alloc(strlen)))
1152 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1153 ret = CryptEnumProviderTypesA(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &strlen);
1154 if (str)
1155 {
1156 CRYPT_ANSIToUnicode(str, &pszTypeName, *pcbTypeName);
1157 CRYPT_Free(str);
1158 }
1159 *pcbTypeName = strlen * sizeof(WCHAR);
1160 return ret;
1161 }
1162
1163 /******************************************************************************
1164 * CryptExportKey (ADVAPI32.@)
1165 *
1166 * Exports a cryptographic key from a CSP.
1167 *
1168 * PARAMS
1169 * hKey [I] Handle to the key to export.
1170 * hExpKey [I] Handle to a cryptographic key of the end user.
1171 * dwBlobType [I] Type of BLOB to be exported.
1172 * dwFlags [I] CRYPT_DESTROYKEY/SSL2_FALLBACK/OAEP.
1173 * pbData [O] Buffer to receive BLOB data.
1174 * pdwDataLen [I/O] Specifies the size of pbData.
1175 *
1176 * RETURNS
1177 * Success: TRUE
1178 * Failure: FALSE
1179 *
1180 * NOTES
1181 * if pbData is NULL, CryptExportKey sets pdwDataLen as the size of the
1182 * buffer needed to hold the BLOB.
1183 */
1184 BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType,
1185 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
1186 {
1187 PCRYPTPROV prov;
1188 PCRYPTKEY key = (PCRYPTKEY)hKey, expkey = (PCRYPTKEY)hExpKey;
1189
1190 DPRINT("(0x%lx, 0x%lx, %ld, %08ld, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen);
1191
1192 if (!key || !pdwDataLen)
1193 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1194
1195 prov = key->pProvider;
1196 return prov->pFuncs->pCPExportKey(prov->hPrivate, key->hPrivate, expkey ? expkey->hPrivate : 0,
1197 dwBlobType, dwFlags, pbData, pdwDataLen);
1198 }
1199
1200 /******************************************************************************
1201 * CryptGenKey (ADVAPI32.@)
1202 *
1203 * Generates a random cryptographic session key or a pub/priv key pair.
1204 *
1205 * PARAMS
1206 * hProv [I] Handle to a CSP.
1207 * Algid [I] Algorithm to use to make key.
1208 * dwFlags [I] Specifies type of key to make.
1209 * phKey [I] Address of the handle to which the new key is copied.
1210 *
1211 * RETURNS
1212 * Success: TRUE
1213 * Failure: FALSE
1214 */
1215 BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
1216 {
1217 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1218 PCRYPTKEY key;
1219
1220 DPRINT("(0x%lx, %d, %08ld, %p)\n", hProv, Algid, dwFlags, phKey);
1221
1222 if (!prov)
1223 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1224 if (!phKey)
1225 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1226 if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
1227 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1228
1229 key->pProvider = prov;
1230
1231 if (prov->pFuncs->pCPGenKey(prov->hPrivate, Algid, dwFlags, &key->hPrivate))
1232 {
1233 *phKey = (HCRYPTKEY)key;
1234 return TRUE;
1235 }
1236
1237 /* CSP error! */
1238 CRYPT_Free(key);
1239 return FALSE;
1240 }
1241
1242 /******************************************************************************
1243 * CryptGetDefaultProviderA (ADVAPI32.@)
1244 *
1245 * Finds the default CSP of a certain provider type.
1246 *
1247 * PARAMS
1248 * dwProvType [I] Provider type to look for.
1249 * pdwReserved [I] Reserved for future use and must be NULL.
1250 * dwFlags [I] CRYPT_MACHINE_DEFAULT/USER_DEFAULT
1251 * pszProvName [O] Name of the default CSP.
1252 * pcbProvName [I/O] Size of pszProvName
1253 *
1254 * RETURNS
1255 * Success: TRUE
1256 * Failure: FALSE
1257 *
1258 * NOTES
1259 * If pszProvName is NULL, pcbProvName will hold the size of the buffer for
1260 * memory allocation purposes on return.
1261 */
1262 BOOL WINAPI CryptGetDefaultProviderA (DWORD dwProvType, DWORD *pdwReserved,
1263 DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName)
1264 {
1265 HKEY hKey;
1266 PSTR keyname;
1267 DWORD result;
1268
1269 if (pdwReserved || !pcbProvName)
1270 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1271 if (dwFlags & ~(CRYPT_USER_DEFAULT | CRYPT_MACHINE_DEFAULT))
1272 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
1273 if (dwProvType > 999)
1274 CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE);
1275 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)))
1276 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1277 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
1278 {
1279 CRYPT_Free(keyname);
1280 CRYPT_ReturnLastError(NTE_PROV_TYPE_NOT_DEF);
1281 }
1282 CRYPT_Free(keyname);
1283
1284 result = RegQueryValueExA(hKey, "Name", NULL, NULL, (LPBYTE)pszProvName, pcbProvName);
1285 if (result)
1286 {
1287 if (result != ERROR_MORE_DATA)
1288 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
1289 else
1290 SetLastError(result);
1291
1292 return FALSE;
1293 }
1294
1295 RegCloseKey(hKey);
1296 return TRUE;
1297 }
1298
1299 /******************************************************************************
1300 * CryptGetDefaultProviderW (ADVAPI32.@)
1301 *
1302 * see CryptGetDefaultProviderA
1303 */
1304 BOOL WINAPI CryptGetDefaultProviderW (DWORD dwProvType, DWORD *pdwReserved,
1305 DWORD dwFlags, LPWSTR pszProvName, DWORD *pcbProvName)
1306 {
1307 PSTR str = NULL;
1308 DWORD strlen;
1309 BOOL ret = FALSE;
1310
1311 DPRINT("(%ld, %p, %08ld, %p, %p)\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName);
1312
1313 strlen = *pcbProvName / sizeof(WCHAR);
1314 if (pszProvName && !(str = CRYPT_Alloc(strlen)))
1315 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1316 ret = CryptGetDefaultProviderA(dwProvType, pdwReserved, dwFlags, str, &strlen);
1317 if (str)
1318 {
1319 CRYPT_ANSIToUnicode(str, &pszProvName, *pcbProvName);
1320 CRYPT_Free(str);
1321 }
1322 *pcbProvName = strlen * sizeof(WCHAR);
1323 return ret;
1324 }
1325
1326 /******************************************************************************
1327 * CryptGetHashParam (ADVAPI32.@)
1328 *
1329 * Retrieves data that controls the operations of a hash object.
1330 *
1331 * PARAMS
1332 * hHash [I] Handle of the hash object to question.
1333 * dwParam [I] Query type.
1334 * pbData [O] Buffer that receives the value data.
1335 * pdwDataLen [I/O] Size of the pbData buffer.
1336 * dwFlags [I] Reserved for future use and must be zero.
1337 *
1338 * RETURNS
1339 * Success: TRUE
1340 * Failure: FALSE
1341 *
1342 * NOTES
1343 * If pbData is NULL, pdwDataLen will contain the length required.
1344 */
1345 BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData,
1346 DWORD *pdwDataLen, DWORD dwFlags)
1347 {
1348 PCRYPTPROV prov;
1349 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1350
1351 DPRINT("(0x%lx, %ld, %p, %p, %08ld)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags);
1352
1353 if (!hash || !pdwDataLen)
1354 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1355
1356 prov = hash->pProvider;
1357 return prov->pFuncs->pCPGetHashParam(prov->hPrivate, hash->hPrivate, dwParam,
1358 pbData, pdwDataLen, dwFlags);
1359 }
1360
1361 /******************************************************************************
1362 * CryptGetKeyParam (ADVAPI32.@)
1363 *
1364 * Retrieves data that controls the operations of a key.
1365 *
1366 * PARAMS
1367 * hKey [I] Handle to they key in question.
1368 * dwParam [I] Specifies query type.
1369 * pbData [O] Sequence of bytes to receive data.
1370 * pdwDataLen [I/O] Size of pbData.
1371 * dwFlags [I] Reserved for future use and must be zero.
1372 *
1373 * RETURNS
1374 * Success: TRUE
1375 * Failure: FALSE
1376 *
1377 * NOTES
1378 * If pbData is NULL, pdwDataLen is set to the needed length of the buffer.
1379 */
1380 BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData,
1381 DWORD *pdwDataLen, DWORD dwFlags)
1382 {
1383 PCRYPTPROV prov;
1384 PCRYPTKEY key = (PCRYPTKEY)hKey;
1385
1386 DPRINT("(0x%lx, %ld, %p, %p, %08ld)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags);
1387
1388 if (!key || !pdwDataLen)
1389 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1390
1391 prov = key->pProvider;
1392 return prov->pFuncs->pCPGetKeyParam(prov->hPrivate, key->hPrivate, dwParam,
1393 pbData, pdwDataLen, dwFlags);
1394 }
1395
1396 /******************************************************************************
1397 * CryptGetProvParam (ADVAPI32.@)
1398 *
1399 * Retrieves parameters that control the operations of a CSP.
1400 *
1401 * PARAMS
1402 * hProv [I] Handle of the CSP in question.
1403 * dwParam [I] Specifies query type.
1404 * pbData [O] Buffer to receive the data.
1405 * pdwDataLen [I/O] Size of pbData.
1406 * dwFlags [I] see MSDN Docs.
1407 *
1408 * RETURNS
1409 * Success: TRUE
1410 * Failure: FALSE
1411 *
1412 * NOTES
1413 * If pbData is NULL, pdwDataLen is set to the needed buffer length.
1414 */
1415 BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
1416 DWORD *pdwDataLen, DWORD dwFlags)
1417 {
1418 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1419
1420 DPRINT("(0x%lx, %ld, %p, %p, %08ld)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags);
1421
1422 return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags);
1423 }
1424
1425 /******************************************************************************
1426 * CryptGetUserKey (ADVAPI32.@)
1427 *
1428 * Gets a handle of one of a user's two public/private key pairs.
1429 *
1430 * PARAMS
1431 * hProv [I] Handle of a CSP.
1432 * dwKeySpec [I] Private key to use.
1433 * phUserKey [O] Pointer to the handle of the retrieved keys.
1434 *
1435 * RETURNS
1436 * Success: TRUE
1437 * Failure: FALSE
1438 */
1439 BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
1440 {
1441 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1442 PCRYPTKEY key;
1443
1444 DPRINT("(0x%lx, %ld, %p)\n", hProv, dwKeySpec, phUserKey);
1445
1446 if (!prov)
1447 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1448 if (!phUserKey)
1449 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1450 if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
1451 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1452
1453 key->pProvider = prov;
1454
1455 if (prov->pFuncs->pCPGetUserKey(prov->hPrivate, dwKeySpec, &key->hPrivate))
1456 {
1457 *phUserKey = (HCRYPTKEY)key;
1458 return TRUE;
1459 }
1460
1461 /* CSP Error */
1462 CRYPT_Free(key);
1463 *phUserKey = 0;
1464 return FALSE;
1465 }
1466
1467 /******************************************************************************
1468 * CryptHashData (ADVAPI32.@)
1469 *
1470 * Adds data to a hash object.
1471 *
1472 * PARAMS
1473 * hHash [I] Handle of the hash object.
1474 * pbData [I] Buffer of data to be hashed.
1475 * dwDataLen [I] Number of bytes to add.
1476 * dwFlags [I] Can be CRYPT_USERDATA
1477 *
1478 * RETURNS
1479 * Success: TRUE
1480 * Failure: FALSE
1481 */
1482 BOOL WINAPI CryptHashData (HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
1483 {
1484 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1485 PCRYPTPROV prov;
1486
1487 DPRINT("(0x%lx, %p, %ld, %08ld)\n", hHash, pbData, dwDataLen, dwFlags);
1488
1489 if (!hash)
1490 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1491 if (!pbData || !dwDataLen)
1492 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1493
1494 prov = hash->pProvider;
1495 return prov->pFuncs->pCPHashData(prov->hPrivate, hash->hPrivate, pbData, dwDataLen, dwFlags);
1496 }
1497
1498 /******************************************************************************
1499 * CryptHashSessionKey (ADVAPI32.@)
1500 *
1501 * PARAMS
1502 * hHash [I] Handle to the hash object.
1503 * hKey [I] Handle to the key to be hashed.
1504 * dwFlags [I] Can be CRYPT_LITTLE_ENDIAN.
1505 *
1506 * RETURNS
1507 * Success: TRUE
1508 * Failure: FALSE
1509 */
1510 BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags)
1511 {
1512 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1513 PCRYPTKEY key = (PCRYPTKEY)hKey;
1514 PCRYPTPROV prov;
1515
1516 DPRINT("(0x%lx, 0x%lx, %08ld)\n", hHash, hKey, dwFlags);
1517
1518 if (!hash || !key)
1519 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1520
1521 prov = hash->pProvider;
1522 return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags);
1523 }
1524
1525 /******************************************************************************
1526 * CryptImportKey (ADVAPI32.@)
1527 *
1528 * PARAMS
1529 * hProv [I] Handle of a CSP.
1530 * pbData [I] Contains the key to be imported.
1531 * dwDataLen [I] Length of the key.
1532 * hPubKey [I] Cryptographic key that decrypts pdData
1533 * dwFlags [I] Used only with a public/private key pair.
1534 * phKey [O] Imported key.
1535 *
1536 * RETURNS
1537 * Success: TRUE
1538 * Failure: FALSE
1539 */
1540 BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen,
1541 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
1542 {
1543 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1544 PCRYPTKEY pubkey = (PCRYPTKEY)hPubKey, importkey;
1545
1546 DPRINT("(0x%lx, %p, %ld, 0x%lx, %08ld, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
1547
1548 if (!prov || !pbData || !dwDataLen || !phKey)
1549 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1550
1551 if (!(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))))
1552 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1553
1554 importkey->pProvider = prov;
1555 if (prov->pFuncs->pCPImportKey(prov->hPrivate, pbData, dwDataLen,
1556 pubkey ? pubkey->hPrivate : 0, dwFlags, &importkey->hPrivate))
1557 {
1558 *phKey = (HCRYPTKEY)importkey;
1559 return TRUE;
1560 }
1561
1562 CRYPT_Free(importkey);
1563 return FALSE;
1564 }
1565
1566 /******************************************************************************
1567 * CryptSignHashA
1568 *
1569 * Note: Since the sDesciption (string) is supposed to be NULL and
1570 * is only retained for compatibility no string conversions are required
1571 * and only one implementation is required for both ANSI and Unicode.
1572 * We still need to export both:
1573 *
1574 * CryptSignHashA (ADVAPI32.@)
1575 * CryptSignHashW (ADVAPI32.@)
1576 *
1577 * Signs data.
1578 *
1579 * PARAMS
1580 * hHash [I] Handle of the hash object to be signed.
1581 * dwKeySpec [I] Private key to use.
1582 * sDescription [I] Must be NULL.
1583 * dwFlags [I] CRYPT_NOHASHOID/X931_FORMAT.
1584 * pbSignature [O] Buffer of the signature data.
1585 * pdwSigLen [I/O] Size of the pbSignature buffer.
1586 *
1587 * RETURNS
1588 * Success: TRUE
1589 * Failure: FALSE
1590 */
1591 BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription,
1592 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
1593 {
1594 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1595 PCRYPTPROV prov;
1596
1597 DPRINT("(0x%lx, %ld, %08ld, %p, %p)\n", hHash, dwKeySpec, dwFlags, pbSignature, pdwSigLen);
1598 if (sDescription)
1599 {
1600 DPRINT("The sDescription parameter is not supported (and no longer used). Ignoring.\n");
1601 }
1602
1603 if (!hash)
1604 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1605 if (!pdwSigLen)
1606 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1607
1608 prov = hash->pProvider;
1609 return prov->pFuncs->pCPSignHash(prov->hPrivate, hash->hPrivate, dwKeySpec, NULL,
1610 dwFlags, pbSignature, pdwSigLen);
1611 }
1612
1613 /******************************************************************************
1614 * CryptSetHashParam (ADVAPI32.@)
1615 *
1616 * Customizes the operations of a hash object.
1617 *
1618 * PARAMS
1619 * hHash [I] Handle of the hash object to set parameters.
1620 * dwParam [I] HP_HMAC_INFO/HASHVAL.
1621 * pbData [I] Value data buffer.
1622 * dwFlags [I] Reserved for future use and must be zero.
1623 *
1624 * RETURNS
1625 * Success: TRUE
1626 * Failure: FALSE
1627 */
1628 BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
1629 {
1630 PCRYPTPROV prov;
1631 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1632
1633 DPRINT("(0x%lx, %ld, %p, %08ld)\n", hHash, dwParam, pbData, dwFlags);
1634
1635 if (!hash || !pbData)
1636 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1637
1638 prov = hash->pProvider;
1639 return prov->pFuncs->pCPSetHashParam(prov->hPrivate, hash->hPrivate,
1640 dwParam, pbData, dwFlags);
1641 }
1642
1643 /******************************************************************************
1644 * CryptSetKeyParam (ADVAPI32.@)
1645 *
1646 * Customizes a session key's operations.
1647 *
1648 * PARAMS
1649 * hKey [I] Handle to the key to set values.
1650 * dwParam [I] See MSDN Doc.
1651 * pbData [I] Buffer of values to set.
1652 * dwFlags [I] Only used when dwParam == KP_ALGID.
1653 *
1654 * RETURNS
1655 * Success: TRUE
1656 * Failure: FALSE
1657 */
1658 BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
1659 {
1660 PCRYPTPROV prov;
1661 PCRYPTKEY key = (PCRYPTKEY)hKey;
1662
1663 DPRINT("(0x%lx, %ld, %p, %08ld)\n", hKey, dwParam, pbData, dwFlags);
1664
1665 if (!key || !pbData)
1666 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1667
1668 prov = key->pProvider;
1669 return prov->pFuncs->pCPSetKeyParam(prov->hPrivate, key->hPrivate,
1670 dwParam, pbData, dwFlags);
1671 }
1672
1673 /******************************************************************************
1674 * CryptSetProviderA (ADVAPI32.@)
1675 *
1676 * Specifies the current user's default CSP.
1677 *
1678 * PARAMS
1679 * pszProvName [I] Name of the new default CSP.
1680 * dwProvType [I] Provider type of the CSP.
1681 *
1682 * RETURNS
1683 * Success: TRUE
1684 * Failure: FALSE
1685 */
1686 BOOL WINAPI CryptSetProviderA (LPCSTR pszProvName, DWORD dwProvType)
1687 {
1688 DPRINT("(%s, %ld)\n", pszProvName, dwProvType);
1689 return CryptSetProviderExA(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT);
1690 }
1691
1692 /******************************************************************************
1693 * CryptSetProviderW (ADVAPI32.@)
1694 *
1695 * See CryptSetProviderA
1696 */
1697 BOOL WINAPI CryptSetProviderW (LPCWSTR pszProvName, DWORD dwProvType)
1698 {
1699 DPRINT("(%S, %ld)\n", pszProvName, dwProvType);
1700 return CryptSetProviderExW(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT);
1701 }
1702
1703 /******************************************************************************
1704 * CryptSetProviderExA (ADVAPI32.@)
1705 *
1706 * Specifies the default CSP.
1707 *
1708 * PARAMS
1709 * pszProvName [I] Name of the new default CSP.
1710 * dwProvType [I] Provider type of the CSP.
1711 * pdwReserved [I] Reserved for future use and must be NULL.
1712 * dwFlags [I] See MSDN Doc.
1713 *
1714 * RETURNS
1715 * Success: TRUE
1716 * Failure: FALSE
1717 */
1718 BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags)
1719 {
1720 HKEY hProvKey, hTypeKey;
1721 PSTR keyname;
1722
1723 DPRINT("(%s, %ld, %p, %08ld)\n", pszProvName, dwProvType, pdwReserved, dwFlags);
1724
1725 if (!pszProvName || pdwReserved)
1726 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1727 if (dwProvType > MAXPROVTYPES)
1728 CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE);
1729 if (dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT)
1730 || dwFlags == CRYPT_DELETE_DEFAULT)
1731 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
1732
1733 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)))
1734 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1735 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
1736 keyname, &hTypeKey))
1737 {
1738 CRYPT_Free(keyname);
1739 CRYPT_ReturnLastError(NTE_BAD_PROVIDER);
1740 }
1741 CRYPT_Free(keyname);
1742
1743 if (dwFlags & CRYPT_DELETE_DEFAULT)
1744 {
1745 RegDeleteValueA(hTypeKey, "Name");
1746 }
1747 else
1748 {
1749 if (!(keyname = CRYPT_GetProvKeyName(pszProvName)))
1750 {
1751 RegCloseKey(hTypeKey);
1752 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1753 }
1754 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
1755 keyname, &hProvKey))
1756 {
1757 CRYPT_Free(keyname);
1758 RegCloseKey(hTypeKey);
1759 CRYPT_ReturnLastError(NTE_BAD_PROVIDER);
1760 }
1761 CRYPT_Free(keyname);
1762
1763 if (RegSetValueExA(hTypeKey, "Name", 0, REG_SZ, (LPBYTE)pszProvName, strlen(pszProvName) + 1))
1764 {
1765 RegCloseKey(hTypeKey);
1766 RegCloseKey(hProvKey);
1767 return FALSE;
1768 }
1769
1770 RegCloseKey(hProvKey);
1771 }
1772 RegCloseKey(hTypeKey);
1773
1774 return TRUE;
1775 }
1776
1777 /******************************************************************************
1778 * CryptSetProviderExW (ADVAPI32.@)
1779 *
1780 * See CryptSetProviderExA
1781 */
1782 BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags)
1783 {
1784 BOOL ret = FALSE;
1785 PSTR str = NULL;
1786
1787 DPRINT("(%S, %ld, %p, %08ld)\n", pszProvName, dwProvType, pdwReserved, dwFlags);
1788
1789 if (CRYPT_UnicodeToANSI(pszProvName, &str, -1))
1790 {
1791 ret = CryptSetProviderExA(str, dwProvType, pdwReserved, dwFlags);
1792 CRYPT_Free(str);
1793 }
1794 return ret;
1795 }
1796
1797 /******************************************************************************
1798 * CryptSetProvParam (ADVAPI32.@)
1799 *
1800 * Customizes the operations of a CSP.
1801 *
1802 * PARAMS
1803 * hProv [I] Handle of a CSP.
1804 * dwParam [I] See MSDN Doc.
1805 * pbData [I] Buffer that contains a value to set as a parameter.
1806 * dwFlags [I] if dwParam is PP_USE_HARDWARE_RNG, dwFlags must be zero.
1807 *
1808 * RETURNS
1809 * Success: TRUE
1810 * Failure: FALSE
1811 */
1812 BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
1813 {
1814 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1815
1816 DPRINT("(0x%lx, %ld, %p, %08ld)\n", hProv, dwParam, pbData, dwFlags);
1817
1818 if (!prov)
1819 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1820 if (dwFlags & PP_USE_HARDWARE_RNG)
1821 {
1822 DPRINT1("PP_USE_HARDWARE_RNG: What do I do with this?\n");
1823 DPRINT1("\tLetting the CSP decide.\n");
1824 }
1825 if (dwFlags & PP_CLIENT_HWND)
1826 {
1827 /* FIXME: Should verify the parameter */
1828 if (pbData /* && IsWindow((HWND)pbData) */)
1829 {
1830 crypt_hWindow = (HWND)(pbData);
1831 return TRUE;
1832 } else {
1833 SetLastError(ERROR_INVALID_PARAMETER);
1834 return FALSE;
1835 }
1836 }
1837 /* All other flags go to the CSP */
1838 return prov->pFuncs->pCPSetProvParam(prov->hPrivate, dwParam, pbData, dwFlags);
1839 }
1840
1841 /******************************************************************************
1842 * CryptVerifySignatureA
1843 *
1844 * Note: Since the sDesciption (string) is supposed to be NULL and
1845 * is only retained for compatibility no string conversions are required
1846 * and only one implementation is required for both ANSI and Unicode.
1847 * We still need to export both:
1848 *
1849 * CryptVerifySignatureA (ADVAPI32.@)
1850 * CryptVerifySignatureW (ADVAPI32.@)
1851 *
1852 * Verifies the signature of a hash object.
1853 *
1854 * PARAMS
1855 * hHash [I] Handle of the hash object to verify.
1856 * pbSignature [I] Signature data to verify.
1857 * dwSigLen [I] Size of pbSignature.
1858 * hPubKey [I] Handle to the public key to authenticate signature.
1859 * sDescription [I] Must be set to NULL.
1860 * dwFlags [I] See MSDN doc.
1861 *
1862 * RETURNS
1863 * Success: TRUE
1864 * Failure: FALSE
1865 */
1866 BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen,
1867 HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags)
1868 {
1869 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1870 PCRYPTKEY key = (PCRYPTKEY)hPubKey;
1871 PCRYPTPROV prov;
1872
1873 DPRINT("(0x%lx, %p, %ld, 0x%lx, %08ld)\n", hHash, pbSignature,
1874 dwSigLen, hPubKey, dwFlags);
1875 if (sDescription)
1876 {
1877 DPRINT("The sDescription parameter is not supported (and no longer used). Ignoring.\n");
1878 }
1879
1880 if (!hash || !key)
1881 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1882 if (!pbSignature || !dwSigLen)
1883 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1884
1885 prov = hash->pProvider;
1886 return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen,
1887 key->hPrivate, NULL, dwFlags);
1888 }
1889
1890
1891 /*
1892 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
1893 in crypt32.dll.
1894 */
1895
1896 /******************************************************************************
1897 * SystemFunction040 (ADVAPI32.@)
1898 *
1899 * PARAMS:
1900 * memory : pointer to memory to encrypt
1901 * length : length of region to encrypt, in bytes. must be multiple of RTL_ENCRYPT_MEMORY_SIZE
1902 * flags : RTL_ENCRYPT_OPTION_SAME_PROCESS | RTL_ENCRYPT_OPTION_CROSS_PROCESS, | RTL_ENCRYPT_OPTION_SAME_LOGON
1903 * control whether other processes are able to decrypt the memory. The same value must be given
1904 * when decrypting the memory.
1905 */
1906 NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags) /* RtlEncryptMemory */
1907 {
1908 DPRINT1("(%p, %lx, %lx): stub [RtlEncryptMemory]\n", memory, length, flags);
1909 return STATUS_SUCCESS;
1910 }
1911
1912 /******************************************************************************
1913 * SystemFunction041 (ADVAPI32.@)
1914 *
1915 * PARAMS:
1916 * memory : pointer to memory to decrypt
1917 * length : length of region to decrypt, in bytes. must be multiple of RTL_ENCRYPT_MEMORY_SIZE
1918 * flags : RTL_ENCRYPT_OPTION_SAME_PROCESS | RTL_ENCRYPT_OPTION_CROSS_PROCESS, | RTL_ENCRYPT_OPTION_SAME_LOGON
1919 * control whether other processes are able to decrypt the memory. The same value must be given
1920 * when encrypting the memory.
1921 */
1922 NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags) /* RtlDecryptMemory */
1923 {
1924 DPRINT1("(%p, %lx, %lx): stub [RtlDecryptMemory]\n", memory, length, flags);
1925 return STATUS_SUCCESS;
1926 }