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