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