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