2 * Copyright 1999 Ian Schmidt
3 * Copyright 2001 Travis Michielsen
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.
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.
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
20 /***********************************************************************
23 * - Reference counting
28 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
32 * Note: this code is harmless on little-endian machines.
34 VOID
byteReverse(unsigned char *buf
, unsigned longs
)
40 t
= (unsigned int)((unsigned)buf
[3] << 8 | buf
[2]) << 16 |
41 ((unsigned)buf
[1] << 8 | buf
[0]);
42 *(unsigned int *)buf
= t
;
47 static HWND crypt_hWindow
;
49 #define CRYPT_Alloc(size) (LocalAlloc(LMEM_ZEROINIT, size))
50 #define CRYPT_Free(buffer) (LocalFree(buffer))
52 static inline PWSTR
CRYPT_GetProvKeyName(PCWSTR pProvName
)
54 static const WCHAR KEYSTR
[] = {
55 'S','o','f','t','w','a','r','e','\\',
56 'M','i','c','r','o','s','o','f','t','\\',
57 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
58 'D','e','f','a','u','l','t','s','\\',
59 'P','r','o','v','i','d','e','r','\\',0
63 keyname
= CRYPT_Alloc((strlenW(KEYSTR
) + strlenW(pProvName
) +1)*sizeof(WCHAR
));
66 strcpyW(keyname
, KEYSTR
);
67 strcpyW(keyname
+ strlenW(KEYSTR
), pProvName
);
69 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
73 static inline PWSTR
CRYPT_GetTypeKeyName(DWORD dwType
, BOOL user
)
75 static const WCHAR MACHINESTR
[] = {
76 'S','o','f','t','w','a','r','e','\\',
77 'M','i','c','r','o','s','o','f','t','\\',
78 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
79 'D','e','f','a','u','l','t','s','\\',
80 'P','r','o','v','i','d','e','r',' ','T','y','p','e','s','\\',
81 'T','y','p','e',' ','X','X','X',0
83 static const WCHAR USERSTR
[] = {
84 'S','o','f','t','w','a','r','e','\\',
85 'M','i','c','r','o','s','o','f','t','\\',
86 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
87 'P','r','o','v','i','d','e','r',' ','T','y','p','e',' ','X','X','X',0
92 keyname
= CRYPT_Alloc( ((user
? strlenW(USERSTR
) : strlenW(MACHINESTR
)) +1)*sizeof(WCHAR
));
95 user
? strcpyW(keyname
, USERSTR
) : strcpyW(keyname
, MACHINESTR
);
96 ptr
= keyname
+ strlenW(keyname
);
97 *(--ptr
) = (dwType
% 10) + '0';
98 *(--ptr
) = ((dwType
/ 10) % 10) + '0';
99 *(--ptr
) = (dwType
/ 100) + '0';
101 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
105 /* CRYPT_UnicodeToANSI
106 * wstr - unicode string
107 * str - pointer to ANSI string or pointer to null pointer if we have to do the allocation
108 * strsize - size of buffer pointed to by str
110 * returns TRUE if unsuccessful, FALSE otherwise.
111 * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call
113 static inline BOOL
CRYPT_UnicodeToANSI(LPCWSTR wstr
, LPSTR
* str
, int strsize
)
123 strsize
= WideCharToMultiByte(CP_ACP
, 0, wstr
, -1, NULL
, 0, NULL
, NULL
);
124 *str
= CRYPT_Alloc(strsize
* sizeof(CHAR
));
126 else if (strsize
< 0)
128 strsize
= INT_MAX
; /* windows will pretend that the buffer is infinitely long */
133 WideCharToMultiByte(CP_ACP
, 0, wstr
, -1, *str
, strsize
, NULL
, NULL
);
137 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
141 /* CRYPT_ANSITOUnicode
143 * wstr - pointer to unicode string
144 * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation
146 static inline BOOL
CRYPT_ANSIToUnicode(LPCSTR str
, LPWSTR
* wstr
, int wstrsize
)
155 wcount
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
157 *wstr
= CRYPT_Alloc(wcount
* sizeof(WCHAR
));
159 wcount
= min( wcount
, wstrsize
/sizeof(WCHAR
) );
162 MultiByteToWideChar(CP_ACP
, 0, str
, -1, *wstr
, wcount
);
165 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
169 /* These next 2 functions are used by the VTableProvStruc structure */
170 static BOOL CALLBACK
CRYPT_VerifyImage(LPCSTR lpszImage
, BYTE
* pData
)
172 if (!lpszImage
|| !pData
)
174 SetLastError(ERROR_INVALID_PARAMETER
);
178 FIXME("(%s, %p): not verifying image\n", lpszImage
, pData
);
183 static void CALLBACK
CRYPT_ReturnhWnd(HWND
*phWnd
)
185 if (phWnd
) *phWnd
= crypt_hWindow
;
188 #define CRYPT_GetProvFunc(name) \
189 if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error
190 #define CRYPT_GetProvFuncOpt(name) \
191 provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)
192 static PCRYPTPROV
CRYPT_LoadProvider(PCWSTR pImage
)
195 DWORD errorcode
= ERROR_NOT_ENOUGH_MEMORY
;
197 if ( !(provider
= CRYPT_Alloc(sizeof(CRYPTPROV
))) ) goto error
;
198 if ( !(provider
->pFuncs
= CRYPT_Alloc(sizeof(PROVFUNCS
))) ) goto error
;
199 if ( !(provider
->pVTable
= CRYPT_Alloc(sizeof(VTableProvStruc
))) ) goto error
;
200 if ( !(provider
->hModule
= LoadLibraryW(pImage
)) )
202 errorcode
= (GetLastError() == ERROR_FILE_NOT_FOUND
) ? NTE_PROV_DLL_NOT_FOUND
: NTE_PROVIDER_DLL_FAIL
;
203 FIXME("Failed to load dll %s\n", debugstr_w(pImage
));
206 provider
->dwMagic
= MAGIC_CRYPTPROV
;
207 provider
->refcount
= 1;
209 errorcode
= NTE_PROVIDER_DLL_FAIL
;
210 CRYPT_GetProvFunc(CPAcquireContext
);
211 CRYPT_GetProvFunc(CPCreateHash
);
212 CRYPT_GetProvFunc(CPDecrypt
);
213 CRYPT_GetProvFunc(CPDeriveKey
);
214 CRYPT_GetProvFunc(CPDestroyHash
);
215 CRYPT_GetProvFunc(CPDestroyKey
);
216 CRYPT_GetProvFuncOpt(CPDuplicateHash
);
217 CRYPT_GetProvFuncOpt(CPDuplicateKey
);
218 CRYPT_GetProvFunc(CPEncrypt
);
219 CRYPT_GetProvFunc(CPExportKey
);
220 CRYPT_GetProvFunc(CPGenKey
);
221 CRYPT_GetProvFunc(CPGenRandom
);
222 CRYPT_GetProvFunc(CPGetHashParam
);
223 CRYPT_GetProvFunc(CPGetKeyParam
);
224 CRYPT_GetProvFunc(CPGetProvParam
);
225 CRYPT_GetProvFunc(CPGetUserKey
);
226 CRYPT_GetProvFunc(CPHashData
);
227 CRYPT_GetProvFunc(CPHashSessionKey
);
228 CRYPT_GetProvFunc(CPImportKey
);
229 CRYPT_GetProvFunc(CPReleaseContext
);
230 CRYPT_GetProvFunc(CPSetHashParam
);
231 CRYPT_GetProvFunc(CPSetKeyParam
);
232 CRYPT_GetProvFunc(CPSetProvParam
);
233 CRYPT_GetProvFunc(CPSignHash
);
234 CRYPT_GetProvFunc(CPVerifySignature
);
236 /* FIXME: Not sure what the pbContextInfo field is for.
237 * Does it need memory allocation?
239 provider
->pVTable
->Version
= 3;
240 provider
->pVTable
->FuncVerifyImage
= CRYPT_VerifyImage
;
241 provider
->pVTable
->FuncReturnhWnd
= CRYPT_ReturnhWnd
;
242 provider
->pVTable
->dwProvType
= 0;
243 provider
->pVTable
->pbContextInfo
= NULL
;
244 provider
->pVTable
->cbContextInfo
= 0;
245 provider
->pVTable
->pszProvName
= NULL
;
249 SetLastError(errorcode
);
252 provider
->dwMagic
= 0;
253 if (provider
->hModule
)
254 FreeLibrary(provider
->hModule
);
255 CRYPT_Free(provider
->pVTable
);
256 CRYPT_Free(provider
->pFuncs
);
257 CRYPT_Free(provider
);
261 #undef CRYPT_GetProvFunc
262 #undef CRYPT_GetProvFuncOpt
265 static void CRYPT_CreateMachineGuid(void)
267 static const WCHAR cryptographyW
[] = {
268 'S','o','f','t','w','a','r','e','\\',
269 'M','i','c','r','o','s','o','f','t','\\',
270 'C','r','y','p','t','o','g','r','a','p','h','y',0 };
271 static const WCHAR machineGuidW
[] = {
272 'M','a','c','h','i','n','e','G','u','i','d',0 };
276 r
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, cryptographyW
, 0, KEY_ALL_ACCESS
,
282 r
= RegQueryValueExW(key
, machineGuidW
, NULL
, NULL
, NULL
, &size
);
283 if (r
== ERROR_FILE_NOT_FOUND
)
288 static const WCHAR uuidFmt
[] = {
289 '%','0','8','x','-','%','0','4','x','-',
290 '%','0','4','x','-','%','0','2','x',
291 '%','0','2','x','-','%','0','2','x',
292 '%','0','2','x','%','0','2','x',
293 '%','0','2','x','%','0','2','x',
296 rs
= UuidCreate(&uuid
);
299 sprintfW(buf
, uuidFmt
,
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
, machineGuidW
, 0, REG_SZ
,
307 (lstrlenW(buf
)+1)*sizeof(WCHAR
));
314 /******************************************************************************
315 * CryptAcquireContextW (ADVAPI32.@)
317 * Acquire a crypto provider context handle.
320 * phProv [O] Pointer to HCRYPTPROV for the output.
321 * pszContainer [I] Key Container Name
322 * pszProvider [I] Cryptographic Service Provider Name
323 * dwProvType [I] Crypto provider type to get a handle.
324 * dwFlags [I] flags for the operation
327 * TRUE on success, FALSE on failure.
329 BOOL WINAPI
CryptAcquireContextW (HCRYPTPROV
*phProv
, LPCWSTR pszContainer
,
330 LPCWSTR pszProvider
, DWORD dwProvType
, DWORD dwFlags
)
332 PCRYPTPROV pProv
= NULL
;
334 PWSTR imagepath
= NULL
, keyname
= NULL
, provname
= NULL
, temp
= NULL
;
335 PSTR provnameA
= NULL
, pszContainerA
= NULL
;
336 DWORD keytype
, type
, len
;
338 static const WCHAR nameW
[] = {'N','a','m','e',0};
339 static const WCHAR typeW
[] = {'T','y','p','e',0};
340 static const WCHAR imagepathW
[] = {'I','m','a','g','e',' ','P','a','t','h',0};
342 TRACE("(%p, %s, %s, %d, %08x)\n", phProv
, debugstr_w(pszContainer
),
343 debugstr_w(pszProvider
), dwProvType
, dwFlags
);
345 if (dwProvType
< 1 || dwProvType
> MAXPROVTYPES
)
347 SetLastError(NTE_BAD_PROV_TYPE
);
353 SetLastError(ERROR_INVALID_PARAMETER
);
357 /* Make sure the MachineGuid value exists */
358 CRYPT_CreateMachineGuid();
360 if (!pszProvider
|| !*pszProvider
)
362 /* No CSP name specified so try the user default CSP first
363 * then try the machine default CSP
365 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, TRUE
)) ) {
366 TRACE("No provider registered for crypto provider type %d.\n", dwProvType
);
367 SetLastError(NTE_PROV_TYPE_NOT_DEF
);
370 if (RegOpenKeyW(HKEY_CURRENT_USER
, keyname
, &key
))
373 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, FALSE
)) ) {
374 TRACE("No type registered for crypto provider type %d.\n", dwProvType
);
376 SetLastError(NTE_PROV_TYPE_NOT_DEF
);
379 if (RegOpenKeyW(HKEY_LOCAL_MACHINE
, keyname
, &key
)) {
380 TRACE("Did not find registry entry of crypto provider for %s.\n", debugstr_w(keyname
));
383 SetLastError(NTE_PROV_TYPE_NOT_DEF
);
388 r
= RegQueryValueExW(key
, nameW
, NULL
, &keytype
, NULL
, &len
);
389 if( r
!= ERROR_SUCCESS
|| !len
|| keytype
!= REG_SZ
)
391 TRACE("error %d reading size of 'Name' from registry\n", r
);
393 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
396 if(!(provname
= CRYPT_Alloc(len
)))
399 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
402 r
= RegQueryValueExW(key
, nameW
, NULL
, NULL
, (LPBYTE
)provname
, &len
);
403 if( r
!= ERROR_SUCCESS
)
405 TRACE("error %d reading 'Name' from registry\n", r
);
407 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
412 if ( !(provname
= CRYPT_Alloc((strlenW(pszProvider
) +1)*sizeof(WCHAR
))) )
414 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
417 strcpyW(provname
, pszProvider
);
420 keyname
= CRYPT_GetProvKeyName(provname
);
421 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, keyname
, &key
);
423 if (r
!= ERROR_SUCCESS
)
425 SetLastError(NTE_KEYSET_NOT_DEF
);
429 r
= RegQueryValueExW(key
, typeW
, NULL
, NULL
, (BYTE
*)&type
, &len
);
430 if (r
!= ERROR_SUCCESS
)
432 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
435 if (type
!= dwProvType
)
437 TRACE("Crypto provider has wrong type (%d vs expected %d).\n", type
, dwProvType
);
438 SetLastError(NTE_PROV_TYPE_NO_MATCH
);
442 r
= RegQueryValueExW(key
, imagepathW
, NULL
, &keytype
, NULL
, &len
);
443 if ( r
!= ERROR_SUCCESS
|| keytype
!= REG_SZ
)
445 TRACE("error %d reading size of 'Image Path' from registry\n", r
);
447 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
450 if (!(temp
= CRYPT_Alloc(len
)))
453 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
456 r
= RegQueryValueExW(key
, imagepathW
, NULL
, NULL
, (LPBYTE
)temp
, &len
);
457 if( r
!= ERROR_SUCCESS
)
459 TRACE("error %d reading 'Image Path' from registry\n", r
);
461 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
465 len
= ExpandEnvironmentStringsW(temp
, NULL
, 0);
466 if ( !(imagepath
= CRYPT_Alloc(len
*sizeof(WCHAR
))) )
468 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
471 if (!ExpandEnvironmentStringsW(temp
, imagepath
, len
))
473 /* ExpandEnvironmentStrings will call SetLastError */
476 pProv
= CRYPT_LoadProvider(imagepath
);
478 /* CRYPT_LoadProvider calls SetLastError */
481 pProv
->pVTable
->dwProvType
= dwProvType
;
482 if(!CRYPT_UnicodeToANSI(provname
, &provnameA
, 0))
484 /* CRYPT_UnicodeToANSI calls SetLastError */
487 pProv
->pVTable
->pszProvName
= provnameA
;
488 if(!CRYPT_UnicodeToANSI(pszContainer
, &pszContainerA
, 0))
490 /* CRYPT_UnicodeToANSI calls SetLastError */
493 if (pProv
->pFuncs
->pCPAcquireContext(&pProv
->hPrivate
, pszContainerA
, dwFlags
, pProv
->pVTable
))
495 /* MSDN: When this flag is set, the value returned in phProv is undefined,
496 * and thus, the CryptReleaseContext function need not be called afterwards.
497 * Therefore, we must clean up everything now.
499 if (dwFlags
& CRYPT_DELETEKEYSET
)
502 FreeLibrary(pProv
->hModule
);
503 CRYPT_Free(provnameA
);
504 CRYPT_Free(pProv
->pVTable
);
505 CRYPT_Free(pProv
->pFuncs
);
508 *phProv
= (HCRYPTPROV
)pProv
;
510 CRYPT_Free(pszContainerA
);
511 CRYPT_Free(provname
);
513 CRYPT_Free(imagepath
);
516 /* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */
522 FreeLibrary(pProv
->hModule
);
523 CRYPT_Free(pProv
->pVTable
);
524 CRYPT_Free(pProv
->pFuncs
);
527 CRYPT_Free(pszContainerA
);
528 CRYPT_Free(provnameA
);
529 CRYPT_Free(provname
);
531 CRYPT_Free(imagepath
);
535 /******************************************************************************
536 * CryptAcquireContextA (ADVAPI32.@)
538 * See CryptAcquireContextW.
540 BOOL WINAPI
CryptAcquireContextA (HCRYPTPROV
*phProv
, LPCSTR pszContainer
,
541 LPCSTR pszProvider
, DWORD dwProvType
, DWORD dwFlags
)
543 PWSTR pProvider
= NULL
, pContainer
= NULL
;
546 TRACE("(%p, %s, %s, %d, %08x)\n", phProv
, debugstr_a(pszContainer
),
547 debugstr_a(pszProvider
), dwProvType
, dwFlags
);
549 if ( !CRYPT_ANSIToUnicode(pszContainer
, &pContainer
, -1) )
551 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
554 if ( !CRYPT_ANSIToUnicode(pszProvider
, &pProvider
, -1) )
556 CRYPT_Free(pContainer
);
557 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
561 ret
= CryptAcquireContextW(phProv
, pContainer
, pProvider
, dwProvType
, dwFlags
);
563 CRYPT_Free(pContainer
);
564 CRYPT_Free(pProvider
);
569 /******************************************************************************
570 * CryptContextAddRef (ADVAPI32.@)
572 * Increases reference count of a cryptographic service provider handle
576 * hProv [I] Handle to the CSP whose reference is being incremented.
577 * pdwReserved [IN] Reserved for future use and must be NULL.
578 * dwFlags [I] Reserved for future use and must be NULL.
584 BOOL WINAPI
CryptContextAddRef (HCRYPTPROV hProv
, DWORD
*pdwReserved
, DWORD dwFlags
)
586 PCRYPTPROV pProv
= (PCRYPTPROV
)hProv
;
588 TRACE("(0x%lx, %p, %08x)\n", hProv
, pdwReserved
, dwFlags
);
592 SetLastError(NTE_BAD_UID
);
596 if (pProv
->dwMagic
!= MAGIC_CRYPTPROV
)
598 SetLastError(ERROR_INVALID_PARAMETER
);
606 /******************************************************************************
607 * CryptReleaseContext (ADVAPI32.@)
609 * Releases the handle of a CSP. Reference count is decreased.
612 * hProv [I] Handle of a CSP.
613 * dwFlags [I] Reserved for future use and must be NULL.
619 BOOL WINAPI
CryptReleaseContext (HCRYPTPROV hProv
, DWORD dwFlags
)
621 PCRYPTPROV pProv
= (PCRYPTPROV
)hProv
;
624 TRACE("(0x%lx, %08lx)\n", hProv
, dwFlags
);
628 SetLastError(NTE_BAD_UID
);
632 if (pProv
->dwMagic
!= MAGIC_CRYPTPROV
)
634 SetLastError(ERROR_INVALID_PARAMETER
);
639 if (pProv
->refcount
<= 0)
641 ret
= pProv
->pFuncs
->pCPReleaseContext(pProv
->hPrivate
, dwFlags
);
643 FreeLibrary(pProv
->hModule
);
645 CRYPT_Free(pProv
->pVTable
->pContextInfo
);
647 CRYPT_Free(pProv
->pVTable
->pszProvName
);
648 CRYPT_Free(pProv
->pVTable
);
649 CRYPT_Free(pProv
->pFuncs
);
655 /******************************************************************************
656 * CryptGenRandom (ADVAPI32.@)
658 * Fills a buffer with cryptographically random bytes.
661 * hProv [I] Handle of a CSP.
662 * dwLen [I] Number of bytes to generate.
663 * pbBuffer [I/O] Buffer to contain random bytes.
670 * pdBuffer must be at least dwLen bytes long.
672 BOOL WINAPI
CryptGenRandom (HCRYPTPROV hProv
, DWORD dwLen
, BYTE
*pbBuffer
)
674 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
676 TRACE("(0x%lx, %d, %p)\n", hProv
, dwLen
, pbBuffer
);
680 SetLastError(ERROR_INVALID_HANDLE
);
684 if (prov
->dwMagic
!= MAGIC_CRYPTPROV
)
686 SetLastError(ERROR_INVALID_PARAMETER
);
690 return prov
->pFuncs
->pCPGenRandom(prov
->hPrivate
, dwLen
, pbBuffer
);
693 /******************************************************************************
694 * CryptCreateHash (ADVAPI32.@)
696 * Initiates the hashing of a stream of data.
699 * hProv [I] Handle of a CSP.
700 * Algid [I] Identifies the hash algorithm to use.
701 * hKey [I] Key for the hash (if required).
702 * dwFlags [I] Reserved for future use and must be NULL.
703 * phHash [O] Address of the future handle to the new hash object.
710 * If the algorithm is a keyed hash, hKey is the key.
712 BOOL WINAPI
CryptCreateHash (HCRYPTPROV hProv
, ALG_ID Algid
, HCRYPTKEY hKey
,
713 DWORD dwFlags
, HCRYPTHASH
*phHash
)
715 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
716 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
719 TRACE("(0x%lx, 0x%x, 0x%lx, %08x, %p)\n", hProv
, Algid
, hKey
, dwFlags
, phHash
);
721 if (!prov
|| !phHash
|| prov
->dwMagic
!= MAGIC_CRYPTPROV
||
722 (key
&& key
->dwMagic
!= MAGIC_CRYPTKEY
))
724 SetLastError(ERROR_INVALID_PARAMETER
);
729 SetLastError(NTE_BAD_FLAGS
);
732 if ( !(hash
= CRYPT_Alloc(sizeof(CRYPTHASH
))) )
734 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
738 hash
->pProvider
= prov
;
739 hash
->dwMagic
= MAGIC_CRYPTHASH
;
740 if (prov
->pFuncs
->pCPCreateHash(prov
->hPrivate
, Algid
,
741 key
? key
->hPrivate
: 0, 0, &hash
->hPrivate
))
743 *phHash
= (HCRYPTHASH
)hash
;
754 /******************************************************************************
755 * CryptDecrypt (ADVAPI32.@)
757 * Decrypts data encrypted by CryptEncrypt.
760 * hKey [I] Handle to the decryption key.
761 * hHash [I] Handle to a hash object.
762 * Final [I] TRUE if this is the last section to be decrypted.
763 * dwFlags [I] Reserved for future use. Can be CRYPT_OAEP.
764 * pbData [I/O] Buffer that holds the encrypted data. Holds decrypted
766 * pdwDataLen [I/O] Length of pbData before and after the call.
772 BOOL WINAPI
CryptDecrypt (HCRYPTKEY hKey
, HCRYPTHASH hHash
, BOOL Final
,
773 DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
)
776 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
777 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
779 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey
, hHash
, Final
, dwFlags
, pbData
, pdwDataLen
);
781 if (!key
|| !pbData
|| !pdwDataLen
||
782 !key
->pProvider
|| key
->dwMagic
!= MAGIC_CRYPTKEY
||
783 key
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
785 SetLastError(ERROR_INVALID_PARAMETER
);
789 prov
= key
->pProvider
;
790 return prov
->pFuncs
->pCPDecrypt(prov
->hPrivate
, key
->hPrivate
, hash
? hash
->hPrivate
: 0,
791 Final
, dwFlags
, pbData
, pdwDataLen
);
794 /******************************************************************************
795 * CryptDeriveKey (ADVAPI32.@)
797 * Generates session keys derived from a base data value.
800 * hProv [I] Handle to a CSP.
801 * Algid [I] Identifies the symmetric encryption algorithm to use.
802 * hBaseData [I] Handle to a hash object.
803 * dwFlags [I] Type of key to generate.
804 * phKey [I/O] Address of the newly generated key.
810 BOOL WINAPI
CryptDeriveKey (HCRYPTPROV hProv
, ALG_ID Algid
, HCRYPTHASH hBaseData
,
811 DWORD dwFlags
, HCRYPTKEY
*phKey
)
813 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
814 PCRYPTHASH hash
= (PCRYPTHASH
)hBaseData
;
817 TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08x, %p)\n", hProv
, Algid
, hBaseData
, dwFlags
, phKey
);
821 SetLastError(ERROR_INVALID_HANDLE
);
824 if (!phKey
|| prov
->dwMagic
!= MAGIC_CRYPTPROV
|| hash
->dwMagic
!= MAGIC_CRYPTHASH
)
826 SetLastError(ERROR_INVALID_PARAMETER
);
829 if ( !(key
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
831 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
835 key
->pProvider
= prov
;
836 key
->dwMagic
= MAGIC_CRYPTKEY
;
837 if (prov
->pFuncs
->pCPDeriveKey(prov
->hPrivate
, Algid
, hash
->hPrivate
, dwFlags
, &key
->hPrivate
))
839 *phKey
= (HCRYPTKEY
)key
;
850 /******************************************************************************
851 * CryptDestroyHash (ADVAPI32.@)
853 * Destroys the hash object referenced by hHash.
856 * hHash [I] Handle of the hash object to be destroyed.
862 BOOL WINAPI
CryptDestroyHash (HCRYPTHASH hHash
)
864 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
868 TRACE("(0x%lx)\n", hHash
);
872 SetLastError(ERROR_INVALID_HANDLE
);
876 if (!hash
->pProvider
|| hash
->dwMagic
!= MAGIC_CRYPTHASH
||
877 hash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
879 SetLastError(ERROR_INVALID_PARAMETER
);
883 prov
= hash
->pProvider
;
884 ret
= prov
->pFuncs
->pCPDestroyHash(prov
->hPrivate
, hash
->hPrivate
);
890 /******************************************************************************
891 * CryptDestroyKey (ADVAPI32.@)
893 * Releases the handle referenced by hKey.
896 * hKey [I] Handle of the key to be destroyed.
902 BOOL WINAPI
CryptDestroyKey (HCRYPTKEY hKey
)
904 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
908 TRACE("(0x%lx)\n", hKey
);
912 SetLastError(ERROR_INVALID_HANDLE
);
916 if (!key
->pProvider
|| key
->dwMagic
!= MAGIC_CRYPTKEY
||
917 key
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
919 SetLastError(ERROR_INVALID_PARAMETER
);
923 prov
= key
->pProvider
;
924 ret
= prov
->pFuncs
->pCPDestroyKey(prov
->hPrivate
, key
->hPrivate
);
930 /******************************************************************************
931 * CryptDuplicateHash (ADVAPI32.@)
936 * hHash [I] Handle to the hash to be copied.
937 * pdwReserved [I] Reserved for future use and must be zero.
938 * dwFlags [I] Reserved for future use and must be zero.
939 * phHash [O] Address of the handle to receive the copy.
945 BOOL WINAPI
CryptDuplicateHash (HCRYPTHASH hHash
, DWORD
*pdwReserved
,
946 DWORD dwFlags
, HCRYPTHASH
*phHash
)
949 PCRYPTHASH orghash
, newhash
;
951 TRACE("(0x%lx, %p, %08x, %p)\n", hHash
, pdwReserved
, dwFlags
, phHash
);
953 orghash
= (PCRYPTHASH
)hHash
;
954 if (!orghash
|| pdwReserved
|| !phHash
|| !orghash
->pProvider
||
955 orghash
->dwMagic
!= MAGIC_CRYPTHASH
|| orghash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
957 SetLastError(ERROR_INVALID_PARAMETER
);
961 prov
= orghash
->pProvider
;
962 if (!prov
->pFuncs
->pCPDuplicateHash
)
964 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
968 if ( !(newhash
= CRYPT_Alloc(sizeof(CRYPTHASH
))) )
970 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
974 newhash
->pProvider
= prov
;
975 newhash
->dwMagic
= MAGIC_CRYPTHASH
;
976 if (prov
->pFuncs
->pCPDuplicateHash(prov
->hPrivate
, orghash
->hPrivate
, pdwReserved
, dwFlags
, &newhash
->hPrivate
))
978 *phHash
= (HCRYPTHASH
)newhash
;
981 newhash
->dwMagic
= 0;
986 /******************************************************************************
987 * CryptDuplicateKey (ADVAPI32.@)
989 * Duplicate a key and the key's state.
992 * hKey [I] Handle of the key to copy.
993 * pdwReserved [I] Reserved for future use and must be NULL.
994 * dwFlags [I] Reserved for future use and must be zero.
995 * phKey [I] Address of the handle to the duplicated key.
1001 BOOL WINAPI
CryptDuplicateKey (HCRYPTKEY hKey
, DWORD
*pdwReserved
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
1004 PCRYPTKEY orgkey
, newkey
;
1006 TRACE("(0x%lx, %p, %08x, %p)\n", hKey
, pdwReserved
, dwFlags
, phKey
);
1008 orgkey
= (PCRYPTKEY
)hKey
;
1009 if (!orgkey
|| pdwReserved
|| !phKey
|| !orgkey
->pProvider
||
1010 orgkey
->dwMagic
!= MAGIC_CRYPTKEY
||
1011 orgkey
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1013 SetLastError(ERROR_INVALID_PARAMETER
);
1017 prov
= orgkey
->pProvider
;
1018 if (!prov
->pFuncs
->pCPDuplicateKey
)
1020 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1024 if ( !(newkey
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
1026 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1030 newkey
->pProvider
= prov
;
1031 newkey
->dwMagic
= MAGIC_CRYPTKEY
;
1032 if (prov
->pFuncs
->pCPDuplicateKey(prov
->hPrivate
, orgkey
->hPrivate
, pdwReserved
, dwFlags
, &newkey
->hPrivate
))
1034 *phKey
= (HCRYPTKEY
)newkey
;
1037 newkey
->dwMagic
= 0;
1042 /******************************************************************************
1043 * CryptEncrypt (ADVAPI32.@)
1048 * hKey [I] Handle to the encryption key.
1049 * hHash [I] Handle to a hash object.
1050 * Final [I] TRUE if this is the last section to encrypt.
1051 * dwFlags [I] Can be CRYPT_OAEP.
1052 * pbData [I/O] Data to be encrypted. Contains encrypted data after call.
1053 * pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the
1054 * encrypted data after call.
1055 * dwBufLen [I] Length of the input pbData buffer.
1062 * If pbData is NULL, CryptEncrypt determines stores the number of bytes
1063 * required for the returned data in pdwDataLen.
1065 BOOL WINAPI
CryptEncrypt (HCRYPTKEY hKey
, HCRYPTHASH hHash
, BOOL Final
,
1066 DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
, DWORD dwBufLen
)
1069 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
1070 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1072 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p, %d)\n", hKey
, hHash
, Final
, dwFlags
, pbData
, pdwDataLen
, dwBufLen
);
1074 if (!key
|| !pdwDataLen
|| !key
->pProvider
||
1075 key
->dwMagic
!= MAGIC_CRYPTKEY
|| key
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1077 SetLastError(ERROR_INVALID_PARAMETER
);
1081 prov
= key
->pProvider
;
1082 return prov
->pFuncs
->pCPEncrypt(prov
->hPrivate
, key
->hPrivate
, hash
? hash
->hPrivate
: 0,
1083 Final
, dwFlags
, pbData
, pdwDataLen
, dwBufLen
);
1086 /******************************************************************************
1087 * CryptEnumProvidersW (ADVAPI32.@)
1089 * Returns the next available CSP.
1092 * dwIndex [I] Index of the next provider to be enumerated.
1093 * pdwReserved [I] Reserved for future use and must be NULL.
1094 * dwFlags [I] Reserved for future use and must be zero.
1095 * pdwProvType [O] DWORD designating the type of the provider.
1096 * pszProvName [O] Buffer that receives data from the provider.
1097 * pcbProvName [I/O] Specifies the size of pszProvName. Contains the number
1098 * of bytes stored in the buffer on return.
1105 * If pszProvName is NULL, CryptEnumProvidersW sets the size of the name
1106 * for memory allocation purposes.
1108 BOOL WINAPI
CryptEnumProvidersW (DWORD dwIndex
, DWORD
*pdwReserved
,
1109 DWORD dwFlags
, DWORD
*pdwProvType
, LPWSTR pszProvName
, DWORD
*pcbProvName
)
1112 static const WCHAR providerW
[] = {
1113 'S','o','f','t','w','a','r','e','\\',
1114 'M','i','c','r','o','s','o','f','t','\\',
1115 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
1116 'D','e','f','a','u','l','t','s','\\',
1117 'P','r','o','v','i','d','e','r',0
1119 static const WCHAR typeW
[] = {'T','y','p','e',0};
1122 TRACE("(%d, %p, %d, %p, %p, %p)\n", dwIndex
, pdwReserved
, dwFlags
,
1123 pdwProvType
, pszProvName
, pcbProvName
);
1125 if (pdwReserved
|| !pcbProvName
)
1127 SetLastError(ERROR_INVALID_PARAMETER
);
1132 SetLastError(NTE_BAD_FLAGS
);
1136 if (RegOpenKeyW(HKEY_LOCAL_MACHINE
, providerW
, &hKey
))
1138 SetLastError(NTE_FAIL
);
1148 RegQueryInfoKeyW(hKey
, NULL
, NULL
, NULL
, &numkeys
, pcbProvName
,
1149 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
1151 if (!(provNameW
= CRYPT_Alloc(*pcbProvName
* sizeof(WCHAR
))))
1153 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1158 RegEnumKeyExW(hKey
, dwIndex
, provNameW
, pcbProvName
, NULL
, NULL
, NULL
, NULL
);
1159 CRYPT_Free(provNameW
);
1161 *pcbProvName
*= sizeof(WCHAR
);
1163 if (dwIndex
>= numkeys
)
1165 SetLastError(ERROR_NO_MORE_ITEMS
);
1169 DWORD size
= sizeof(DWORD
);
1173 result
= RegEnumKeyW(hKey
, dwIndex
, pszProvName
, *pcbProvName
/ sizeof(WCHAR
));
1176 SetLastError(result
);
1180 if (RegOpenKeyW(hKey
, pszProvName
, &subkey
))
1186 if (RegQueryValueExW(subkey
, typeW
, NULL
, NULL
, (BYTE
*)pdwProvType
, &size
))
1189 RegCloseKey(subkey
);
1195 /******************************************************************************
1196 * CryptEnumProvidersA (ADVAPI32.@)
1198 * See CryptEnumProvidersW.
1200 BOOL WINAPI
CryptEnumProvidersA (DWORD dwIndex
, DWORD
*pdwReserved
,
1201 DWORD dwFlags
, DWORD
*pdwProvType
, LPSTR pszProvName
, DWORD
*pcbProvName
)
1207 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex
, pdwReserved
, dwFlags
,
1208 pdwProvType
, pszProvName
, pcbProvName
);
1210 if(!CryptEnumProvidersW(dwIndex
, pdwReserved
, dwFlags
, pdwProvType
, NULL
, &bufsize
))
1212 if ( pszProvName
&& !(str
= CRYPT_Alloc(bufsize
)) )
1214 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1217 ret
= CryptEnumProvidersW(dwIndex
, pdwReserved
, dwFlags
, pdwProvType
, str
, &bufsize
);
1219 CRYPT_UnicodeToANSI(str
, &pszProvName
, *pcbProvName
);
1220 *pcbProvName
= bufsize
/ sizeof(WCHAR
); /* FIXME: not correct */
1224 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1226 SetLastError(ERROR_MORE_DATA
);
1233 /******************************************************************************
1234 * CryptEnumProviderTypesW (ADVAPI32.@)
1236 * Retrieves the next type of CSP supported.
1239 * dwIndex [I] Index of the next provider to be enumerated.
1240 * pdwReserved [I] Reserved for future use and must be NULL.
1241 * dwFlags [I] Reserved for future use and must be zero.
1242 * pdwProvType [O] DWORD designating the type of the provider.
1243 * pszTypeName [O] Buffer that receives data from the provider type.
1244 * pcbTypeName [I/O] Specifies the size of pszTypeName. Contains the number
1245 * of bytes stored in the buffer on return.
1252 * If pszTypeName is NULL, CryptEnumProviderTypesW sets the size of the name
1253 * for memory allocation purposes.
1255 BOOL WINAPI
CryptEnumProviderTypesW (DWORD dwIndex
, DWORD
*pdwReserved
,
1256 DWORD dwFlags
, DWORD
*pdwProvType
, LPWSTR pszTypeName
, DWORD
*pcbTypeName
)
1259 DWORD keylen
, numkeys
, dwType
;
1262 static const WCHAR KEYSTR
[] = {
1263 'S','o','f','t','w','a','r','e','\\',
1264 'M','i','c','r','o','s','o','f','t','\\',
1265 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
1266 'D','e','f','a','u','l','t','s','\\',
1267 'P','r','o','v','i','d','e','r',' ','T','y','p','e','s',0
1269 static const WCHAR typenameW
[] = {'T','y','p','e','N','a','m','e',0};
1271 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex
, pdwReserved
,
1272 dwFlags
, pdwProvType
, pszTypeName
, pcbTypeName
);
1274 if (pdwReserved
|| !pdwProvType
|| !pcbTypeName
)
1276 SetLastError(ERROR_INVALID_PARAMETER
);
1281 SetLastError(NTE_BAD_FLAGS
);
1285 if (RegOpenKeyW(HKEY_LOCAL_MACHINE
, KEYSTR
, &hKey
))
1288 RegQueryInfoKeyW(hKey
, NULL
, NULL
, NULL
, &numkeys
, &keylen
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
1289 if (dwIndex
>= numkeys
)
1291 SetLastError(ERROR_NO_MORE_ITEMS
);
1296 if ( !(keyname
= CRYPT_Alloc(keylen
*sizeof(WCHAR
))) )
1298 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1302 if ( RegEnumKeyW(hKey
, dwIndex
, keyname
, keylen
) ) {
1303 CRYPT_Free(keyname
);
1307 RegOpenKeyW(hKey
, keyname
, &hSubkey
);
1310 ch
= keyname
+ strlenW(keyname
);
1311 /* Convert "Type 000" to 0, etc/ */
1312 *pdwProvType
= *(--ch
) - '0';
1313 *pdwProvType
+= (*(--ch
) - '0') * 10;
1314 *pdwProvType
+= (*(--ch
) - '0') * 100;
1315 CRYPT_Free(keyname
);
1317 result
= RegQueryValueExW(hSubkey
, typenameW
, NULL
, &dwType
, (LPBYTE
)pszTypeName
, pcbTypeName
);
1320 SetLastError(result
);
1321 RegCloseKey(hSubkey
);
1325 RegCloseKey(hSubkey
);
1329 /******************************************************************************
1330 * CryptEnumProviderTypesA (ADVAPI32.@)
1332 * See CryptEnumProviderTypesW.
1334 BOOL WINAPI
CryptEnumProviderTypesA (DWORD dwIndex
, DWORD
*pdwReserved
,
1335 DWORD dwFlags
, DWORD
*pdwProvType
, LPSTR pszTypeName
, DWORD
*pcbTypeName
)
1341 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex
, pdwReserved
, dwFlags
,
1342 pdwProvType
, pszTypeName
, pcbTypeName
);
1344 if(!CryptEnumProviderTypesW(dwIndex
, pdwReserved
, dwFlags
, pdwProvType
, NULL
, &bufsize
))
1346 if ( pszTypeName
&& !(str
= CRYPT_Alloc(bufsize
)) )
1348 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1351 ret
= CryptEnumProviderTypesW(dwIndex
, pdwReserved
, dwFlags
, pdwProvType
, str
, &bufsize
);
1353 CRYPT_UnicodeToANSI(str
, &pszTypeName
, *pcbTypeName
);
1354 *pcbTypeName
= bufsize
/ sizeof(WCHAR
);
1358 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1360 SetLastError(ERROR_MORE_DATA
);
1367 /******************************************************************************
1368 * CryptExportKey (ADVAPI32.@)
1370 * Exports a cryptographic key from a CSP.
1373 * hKey [I] Handle to the key to export.
1374 * hExpKey [I] Handle to a cryptographic key of the end user.
1375 * dwBlobType [I] Type of BLOB to be exported.
1376 * dwFlags [I] CRYPT_DESTROYKEY/SSL2_FALLBACK/OAEP.
1377 * pbData [O] Buffer to receive BLOB data.
1378 * pdwDataLen [I/O] Specifies the size of pbData.
1385 * if pbData is NULL, CryptExportKey sets pdwDataLen as the size of the
1386 * buffer needed to hold the BLOB.
1388 BOOL WINAPI
CryptExportKey (HCRYPTKEY hKey
, HCRYPTKEY hExpKey
, DWORD dwBlobType
,
1389 DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
)
1392 PCRYPTKEY key
= (PCRYPTKEY
)hKey
, expkey
= (PCRYPTKEY
)hExpKey
;
1394 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey
, hExpKey
, dwBlobType
, dwFlags
, pbData
, pdwDataLen
);
1396 if (!key
|| !pdwDataLen
|| !key
->pProvider
||
1397 key
->dwMagic
!= MAGIC_CRYPTKEY
|| key
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1399 SetLastError(ERROR_INVALID_PARAMETER
);
1403 prov
= key
->pProvider
;
1404 return prov
->pFuncs
->pCPExportKey(prov
->hPrivate
, key
->hPrivate
, expkey
? expkey
->hPrivate
: 0,
1405 dwBlobType
, dwFlags
, pbData
, pdwDataLen
);
1408 /******************************************************************************
1409 * CryptGenKey (ADVAPI32.@)
1411 * Generates a random cryptographic session key or a pub/priv key pair.
1414 * hProv [I] Handle to a CSP.
1415 * Algid [I] Algorithm to use to make key.
1416 * dwFlags [I] Specifies type of key to make.
1417 * phKey [I] Address of the handle to which the new key is copied.
1423 BOOL WINAPI
CryptGenKey (HCRYPTPROV hProv
, ALG_ID Algid
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
1425 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1428 TRACE("(0x%lx, %d, %08x, %p)\n", hProv
, Algid
, dwFlags
, phKey
);
1430 if (!phKey
|| !prov
|| prov
->dwMagic
!= MAGIC_CRYPTPROV
)
1432 SetLastError(ERROR_INVALID_PARAMETER
);
1435 if ( !(key
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
1437 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1441 key
->pProvider
= prov
;
1442 key
->dwMagic
= MAGIC_CRYPTKEY
;
1443 if (prov
->pFuncs
->pCPGenKey(prov
->hPrivate
, Algid
, dwFlags
, &key
->hPrivate
))
1445 *phKey
= (HCRYPTKEY
)key
;
1455 /******************************************************************************
1456 * CryptGetDefaultProviderW (ADVAPI32.@)
1458 * Finds the default CSP of a certain provider type.
1461 * dwProvType [I] Provider type to look for.
1462 * pdwReserved [I] Reserved for future use and must be NULL.
1463 * dwFlags [I] CRYPT_MACHINE_DEFAULT/USER_DEFAULT
1464 * pszProvName [O] Name of the default CSP.
1465 * pcbProvName [I/O] Size of pszProvName
1472 * If pszProvName is NULL, pcbProvName will hold the size of the buffer for
1473 * memory allocation purposes on return.
1475 BOOL WINAPI
CryptGetDefaultProviderW (DWORD dwProvType
, DWORD
*pdwReserved
,
1476 DWORD dwFlags
, LPWSTR pszProvName
, DWORD
*pcbProvName
)
1481 static const WCHAR nameW
[] = {'N','a','m','e',0};
1483 if (pdwReserved
|| !pcbProvName
)
1485 SetLastError(ERROR_INVALID_PARAMETER
);
1488 if (dwFlags
& ~(CRYPT_USER_DEFAULT
| CRYPT_MACHINE_DEFAULT
))
1490 SetLastError(NTE_BAD_FLAGS
);
1493 if (dwProvType
> 999)
1495 SetLastError(NTE_BAD_PROV_TYPE
);
1498 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, dwFlags
& CRYPT_USER_DEFAULT
)) )
1500 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1503 if (RegOpenKeyW((dwFlags
& CRYPT_USER_DEFAULT
) ? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
,keyname
, &hKey
))
1505 CRYPT_Free(keyname
);
1506 SetLastError(NTE_PROV_TYPE_NOT_DEF
);
1509 CRYPT_Free(keyname
);
1511 result
= RegQueryValueExW(hKey
, nameW
, NULL
, NULL
, (LPBYTE
)pszProvName
, pcbProvName
);
1516 if (result
!= ERROR_MORE_DATA
)
1517 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
1519 SetLastError(result
);
1527 /******************************************************************************
1528 * CryptGetDefaultProviderA (ADVAPI32.@)
1530 * See CryptGetDefaultProviderW.
1532 BOOL WINAPI
CryptGetDefaultProviderA (DWORD dwProvType
, DWORD
*pdwReserved
,
1533 DWORD dwFlags
, LPSTR pszProvName
, DWORD
*pcbProvName
)
1539 TRACE("(%d, %p, %08x, %p, %p)\n", dwProvType
, pdwReserved
, dwFlags
, pszProvName
, pcbProvName
);
1541 CryptGetDefaultProviderW(dwProvType
, pdwReserved
, dwFlags
, NULL
, &bufsize
);
1542 if ( pszProvName
&& !(str
= CRYPT_Alloc(bufsize
)) )
1544 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1547 ret
= CryptGetDefaultProviderW(dwProvType
, pdwReserved
, dwFlags
, str
, &bufsize
);
1549 CRYPT_UnicodeToANSI(str
, &pszProvName
, *pcbProvName
);
1550 *pcbProvName
= bufsize
/ sizeof(WCHAR
);
1554 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1556 SetLastError(ERROR_MORE_DATA
);
1563 /******************************************************************************
1564 * CryptGetHashParam (ADVAPI32.@)
1566 * Retrieves data that controls the operations of a hash object.
1569 * hHash [I] Handle of the hash object to question.
1570 * dwParam [I] Query type.
1571 * pbData [O] Buffer that receives the value data.
1572 * pdwDataLen [I/O] Size of the pbData buffer.
1573 * dwFlags [I] Reserved for future use and must be zero.
1580 * If pbData is NULL, pdwDataLen will contain the length required.
1582 BOOL WINAPI
CryptGetHashParam (HCRYPTHASH hHash
, DWORD dwParam
, BYTE
*pbData
,
1583 DWORD
*pdwDataLen
, DWORD dwFlags
)
1586 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1588 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hHash
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1590 if (!hash
|| !pdwDataLen
|| !hash
->pProvider
||
1591 hash
->dwMagic
!= MAGIC_CRYPTHASH
|| hash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1593 SetLastError(ERROR_INVALID_PARAMETER
);
1597 prov
= hash
->pProvider
;
1598 return prov
->pFuncs
->pCPGetHashParam(prov
->hPrivate
, hash
->hPrivate
, dwParam
,
1599 pbData
, pdwDataLen
, dwFlags
);
1602 /******************************************************************************
1603 * CryptGetKeyParam (ADVAPI32.@)
1605 * Retrieves data that controls the operations of a key.
1608 * hKey [I] Handle to they key in question.
1609 * dwParam [I] Specifies query type.
1610 * pbData [O] Sequence of bytes to receive data.
1611 * pdwDataLen [I/O] Size of pbData.
1612 * dwFlags [I] Reserved for future use and must be zero.
1619 * If pbData is NULL, pdwDataLen is set to the needed length of the buffer.
1621 BOOL WINAPI
CryptGetKeyParam (HCRYPTKEY hKey
, DWORD dwParam
, BYTE
*pbData
,
1622 DWORD
*pdwDataLen
, DWORD dwFlags
)
1625 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
1627 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hKey
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1629 if (!key
|| !pdwDataLen
|| !key
->pProvider
||
1630 key
->dwMagic
!= MAGIC_CRYPTKEY
|| key
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1632 SetLastError(ERROR_INVALID_PARAMETER
);
1636 prov
= key
->pProvider
;
1637 return prov
->pFuncs
->pCPGetKeyParam(prov
->hPrivate
, key
->hPrivate
, dwParam
,
1638 pbData
, pdwDataLen
, dwFlags
);
1641 /******************************************************************************
1642 * CryptGetProvParam (ADVAPI32.@)
1644 * Retrieves parameters that control the operations of a CSP.
1647 * hProv [I] Handle of the CSP in question.
1648 * dwParam [I] Specifies query type.
1649 * pbData [O] Buffer to receive the data.
1650 * pdwDataLen [I/O] Size of pbData.
1651 * dwFlags [I] see MSDN Docs.
1658 * If pbData is NULL, pdwDataLen is set to the needed buffer length.
1660 BOOL WINAPI
CryptGetProvParam (HCRYPTPROV hProv
, DWORD dwParam
, BYTE
*pbData
,
1661 DWORD
*pdwDataLen
, DWORD dwFlags
)
1663 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1665 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hProv
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1667 if (!prov
|| prov
->dwMagic
!= MAGIC_CRYPTPROV
)
1669 SetLastError(ERROR_INVALID_PARAMETER
);
1673 return prov
->pFuncs
->pCPGetProvParam(prov
->hPrivate
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1676 /******************************************************************************
1677 * CryptGetUserKey (ADVAPI32.@)
1679 * Gets a handle of one of a user's two public/private key pairs.
1682 * hProv [I] Handle of a CSP.
1683 * dwKeySpec [I] Private key to use.
1684 * phUserKey [O] Pointer to the handle of the retrieved keys.
1690 BOOL WINAPI
CryptGetUserKey (HCRYPTPROV hProv
, DWORD dwKeySpec
, HCRYPTKEY
*phUserKey
)
1692 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1695 TRACE("(0x%lx, %d, %p)\n", hProv
, dwKeySpec
, phUserKey
);
1699 SetLastError(ERROR_INVALID_HANDLE
);
1702 if (!phUserKey
|| prov
->dwMagic
!= MAGIC_CRYPTPROV
)
1704 SetLastError(ERROR_INVALID_PARAMETER
);
1707 if ( !(key
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
1709 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1713 key
->pProvider
= prov
;
1714 key
->dwMagic
= MAGIC_CRYPTKEY
;
1715 if (prov
->pFuncs
->pCPGetUserKey(prov
->hPrivate
, dwKeySpec
, &key
->hPrivate
))
1717 *phUserKey
= (HCRYPTKEY
)key
;
1728 /******************************************************************************
1729 * CryptHashData (ADVAPI32.@)
1731 * Adds data to a hash object.
1734 * hHash [I] Handle of the hash object.
1735 * pbData [I] Buffer of data to be hashed.
1736 * dwDataLen [I] Number of bytes to add.
1737 * dwFlags [I] Can be CRYPT_USERDATA
1743 BOOL WINAPI
CryptHashData (HCRYPTHASH hHash
, const BYTE
*pbData
, DWORD dwDataLen
, DWORD dwFlags
)
1745 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1748 TRACE("(0x%lx, %p, %d, %08x)\n", hHash
, pbData
, dwDataLen
, dwFlags
);
1752 SetLastError(ERROR_INVALID_HANDLE
);
1755 if (!hash
->pProvider
|| hash
->dwMagic
!= MAGIC_CRYPTHASH
||
1756 hash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1758 SetLastError(ERROR_INVALID_PARAMETER
);
1762 prov
= hash
->pProvider
;
1763 return prov
->pFuncs
->pCPHashData(prov
->hPrivate
, hash
->hPrivate
, pbData
, dwDataLen
, dwFlags
);
1766 /******************************************************************************
1767 * CryptHashSessionKey (ADVAPI32.@)
1769 * Compute the cryptographic hash of a session key object.
1772 * hHash [I] Handle to the hash object.
1773 * hKey [I] Handle to the key to be hashed.
1774 * dwFlags [I] Can be CRYPT_LITTLE_ENDIAN.
1780 BOOL WINAPI
CryptHashSessionKey (HCRYPTHASH hHash
, HCRYPTKEY hKey
, DWORD dwFlags
)
1782 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1783 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
1786 TRACE("(0x%lx, 0x%lx, %08x)\n", hHash
, hKey
, dwFlags
);
1790 SetLastError(ERROR_INVALID_HANDLE
);
1794 if (!hash
->pProvider
|| hash
->dwMagic
!= MAGIC_CRYPTHASH
||
1795 hash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
|| key
->dwMagic
!= MAGIC_CRYPTKEY
)
1797 SetLastError(ERROR_INVALID_PARAMETER
);
1801 prov
= hash
->pProvider
;
1802 return prov
->pFuncs
->pCPHashSessionKey(prov
->hPrivate
, hash
->hPrivate
, key
->hPrivate
, dwFlags
);
1805 /******************************************************************************
1806 * CryptImportKey (ADVAPI32.@)
1808 * Transfer a cryptographic key from a key BLOB into a cryptographic service provider (CSP).
1811 * hProv [I] Handle of a CSP.
1812 * pbData [I] Contains the key to be imported.
1813 * dwDataLen [I] Length of the key.
1814 * hPubKey [I] Cryptographic key that decrypts pdData
1815 * dwFlags [I] Used only with a public/private key pair.
1816 * phKey [O] Imported key.
1822 BOOL WINAPI
CryptImportKey (HCRYPTPROV hProv
, CONST BYTE
*pbData
, DWORD dwDataLen
,
1823 HCRYPTKEY hPubKey
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
1825 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1826 PCRYPTKEY pubkey
= (PCRYPTKEY
)hPubKey
, importkey
;
1828 TRACE("(0x%lx, %p, %d, 0x%lx, %08x, %p)\n", hProv
, pbData
, dwDataLen
, hPubKey
, dwFlags
, phKey
);
1830 if (!prov
|| !pbData
|| !dwDataLen
|| !phKey
||
1831 prov
->dwMagic
!= MAGIC_CRYPTPROV
||
1832 (pubkey
&& pubkey
->dwMagic
!= MAGIC_CRYPTKEY
))
1834 SetLastError(ERROR_INVALID_PARAMETER
);
1838 if ( !(importkey
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
1840 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1844 importkey
->pProvider
= prov
;
1845 importkey
->dwMagic
= MAGIC_CRYPTKEY
;
1846 if (prov
->pFuncs
->pCPImportKey(prov
->hPrivate
, pbData
, dwDataLen
,
1847 pubkey
? pubkey
->hPrivate
: 0, dwFlags
, &importkey
->hPrivate
))
1849 *phKey
= (HCRYPTKEY
)importkey
;
1853 importkey
->dwMagic
= 0;
1854 CRYPT_Free(importkey
);
1858 /******************************************************************************
1859 * CryptSignHashW (ADVAPI32.@)
1864 * hHash [I] Handle of the hash object to be signed.
1865 * dwKeySpec [I] Private key to use.
1866 * sDescription [I] Should be NULL.
1867 * dwFlags [I] CRYPT_NOHASHOID/X931_FORMAT.
1868 * pbSignature [O] Buffer of the signature data.
1869 * pdwSigLen [I/O] Size of the pbSignature buffer.
1876 * Because of security flaws sDescription should not be used and should thus be
1877 * NULL. It is supported only for compatibility with Microsoft's Cryptographic
1880 BOOL WINAPI
CryptSignHashW (HCRYPTHASH hHash
, DWORD dwKeySpec
, LPCWSTR sDescription
,
1881 DWORD dwFlags
, BYTE
*pbSignature
, DWORD
*pdwSigLen
)
1883 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1886 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n",
1887 hHash
, dwKeySpec
, debugstr_w(sDescription
), dwFlags
, pbSignature
, pdwSigLen
);
1891 SetLastError(ERROR_INVALID_HANDLE
);
1894 if (!pdwSigLen
|| !hash
->pProvider
|| hash
->dwMagic
!= MAGIC_CRYPTHASH
||
1895 hash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1897 SetLastError(ERROR_INVALID_PARAMETER
);
1901 prov
= hash
->pProvider
;
1902 return prov
->pFuncs
->pCPSignHash(prov
->hPrivate
, hash
->hPrivate
, dwKeySpec
, sDescription
,
1903 dwFlags
, pbSignature
, pdwSigLen
);
1906 /******************************************************************************
1907 * CryptSignHashA (ADVAPI32.@)
1909 * See CryptSignHashW.
1911 BOOL WINAPI
CryptSignHashA (HCRYPTHASH hHash
, DWORD dwKeySpec
, LPCSTR sDescription
,
1912 DWORD dwFlags
, BYTE
*pbSignature
, DWORD
*pdwSigLen
)
1914 LPWSTR wsDescription
;
1917 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n",
1918 hHash
, dwKeySpec
, debugstr_a(sDescription
), dwFlags
, pbSignature
, pdwSigLen
);
1920 CRYPT_ANSIToUnicode(sDescription
, &wsDescription
, -1);
1921 result
= CryptSignHashW(hHash
, dwKeySpec
, wsDescription
, dwFlags
, pbSignature
, pdwSigLen
);
1922 CRYPT_Free(wsDescription
);
1927 /******************************************************************************
1928 * CryptSetHashParam (ADVAPI32.@)
1930 * Customizes the operations of a hash object.
1933 * hHash [I] Handle of the hash object to set parameters.
1934 * dwParam [I] HP_HMAC_INFO/HASHVAL.
1935 * pbData [I] Value data buffer.
1936 * dwFlags [I] Reserved for future use and must be zero.
1942 BOOL WINAPI
CryptSetHashParam (HCRYPTHASH hHash
, DWORD dwParam
, CONST BYTE
*pbData
, DWORD dwFlags
)
1945 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1947 TRACE("(0x%lx, %d, %p, %08x)\n", hHash
, dwParam
, pbData
, dwFlags
);
1949 if (!hash
|| !pbData
|| !hash
->pProvider
||
1950 hash
->dwMagic
!= MAGIC_CRYPTHASH
|| hash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1952 SetLastError(ERROR_INVALID_PARAMETER
);
1956 prov
= hash
->pProvider
;
1957 return prov
->pFuncs
->pCPSetHashParam(prov
->hPrivate
, hash
->hPrivate
,
1958 dwParam
, pbData
, dwFlags
);
1961 /******************************************************************************
1962 * CryptSetKeyParam (ADVAPI32.@)
1964 * Customizes a session key's operations.
1967 * hKey [I] Handle to the key to set values.
1968 * dwParam [I] See MSDN Doc.
1969 * pbData [I] Buffer of values to set.
1970 * dwFlags [I] Only used when dwParam == KP_ALGID.
1976 BOOL WINAPI
CryptSetKeyParam (HCRYPTKEY hKey
, DWORD dwParam
, CONST BYTE
*pbData
, DWORD dwFlags
)
1979 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
1981 TRACE("(0x%lx, %d, %p, %08x)\n", hKey
, dwParam
, pbData
, dwFlags
);
1983 if (!key
|| !pbData
|| !key
->pProvider
||
1984 key
->dwMagic
!= MAGIC_CRYPTKEY
|| key
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
1986 SetLastError(ERROR_INVALID_PARAMETER
);
1990 prov
= key
->pProvider
;
1991 return prov
->pFuncs
->pCPSetKeyParam(prov
->hPrivate
, key
->hPrivate
,
1992 dwParam
, pbData
, dwFlags
);
1995 /******************************************************************************
1996 * CryptSetProviderA (ADVAPI32.@)
1998 * Specifies the current user's default CSP.
2001 * pszProvName [I] Name of the new default CSP.
2002 * dwProvType [I] Provider type of the CSP.
2008 BOOL WINAPI
CryptSetProviderA (LPCSTR pszProvName
, DWORD dwProvType
)
2010 TRACE("(%s, %d)\n", pszProvName
, dwProvType
);
2011 return CryptSetProviderExA(pszProvName
, dwProvType
, NULL
, CRYPT_USER_DEFAULT
);
2014 /******************************************************************************
2015 * CryptSetProviderW (ADVAPI32.@)
2017 * See CryptSetProviderA.
2019 BOOL WINAPI
CryptSetProviderW (LPCWSTR pszProvName
, DWORD dwProvType
)
2021 TRACE("(%s, %d)\n", debugstr_w(pszProvName
), dwProvType
);
2022 return CryptSetProviderExW(pszProvName
, dwProvType
, NULL
, CRYPT_USER_DEFAULT
);
2025 /******************************************************************************
2026 * CryptSetProviderExW (ADVAPI32.@)
2028 * Specifies the default CSP.
2031 * pszProvName [I] Name of the new default CSP.
2032 * dwProvType [I] Provider type of the CSP.
2033 * pdwReserved [I] Reserved for future use and must be NULL.
2034 * dwFlags [I] See MSDN Doc.
2040 BOOL WINAPI
CryptSetProviderExW (LPCWSTR pszProvName
, DWORD dwProvType
, DWORD
*pdwReserved
, DWORD dwFlags
)
2042 HKEY hProvKey
, hTypeKey
;
2044 static const WCHAR nameW
[] = {'N','a','m','e',0};
2046 TRACE("(%s, %d, %p, %08x)\n", debugstr_w(pszProvName
), dwProvType
, pdwReserved
, dwFlags
);
2048 if (!pszProvName
|| pdwReserved
)
2050 SetLastError(ERROR_INVALID_PARAMETER
);
2053 if (dwProvType
> MAXPROVTYPES
)
2055 SetLastError(NTE_BAD_PROV_TYPE
);
2058 if (dwFlags
& ~(CRYPT_MACHINE_DEFAULT
| CRYPT_USER_DEFAULT
| CRYPT_DELETE_DEFAULT
)
2059 || dwFlags
== CRYPT_DELETE_DEFAULT
)
2061 SetLastError(NTE_BAD_FLAGS
);
2065 if (!(keyname
= CRYPT_GetTypeKeyName(dwProvType
, dwFlags
& CRYPT_USER_DEFAULT
)))
2067 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2070 if (RegOpenKeyW((dwFlags
& CRYPT_USER_DEFAULT
) ? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
,
2071 keyname
, &hTypeKey
))
2073 CRYPT_Free(keyname
);
2074 SetLastError(NTE_BAD_PROVIDER
);
2077 CRYPT_Free(keyname
);
2079 if (dwFlags
& CRYPT_DELETE_DEFAULT
)
2081 RegDeleteValueW(hTypeKey
, nameW
);
2085 if (!(keyname
= CRYPT_GetProvKeyName(pszProvName
)))
2087 RegCloseKey(hTypeKey
);
2088 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2091 if (RegOpenKeyW((dwFlags
& CRYPT_USER_DEFAULT
) ? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
,
2092 keyname
, &hProvKey
))
2094 CRYPT_Free(keyname
);
2095 RegCloseKey(hTypeKey
);
2096 SetLastError(NTE_BAD_PROVIDER
);
2099 CRYPT_Free(keyname
);
2101 if (RegSetValueExW(hTypeKey
, nameW
, 0, REG_SZ
, (const BYTE
*)pszProvName
,
2102 (strlenW(pszProvName
) + 1)*sizeof(WCHAR
)))
2104 RegCloseKey(hTypeKey
);
2105 RegCloseKey(hProvKey
);
2109 RegCloseKey(hProvKey
);
2111 RegCloseKey(hTypeKey
);
2116 /******************************************************************************
2117 * CryptSetProviderExA (ADVAPI32.@)
2119 * See CryptSetProviderExW.
2121 BOOL WINAPI
CryptSetProviderExA (LPCSTR pszProvName
, DWORD dwProvType
, DWORD
*pdwReserved
, DWORD dwFlags
)
2126 TRACE("(%s, %d, %p, %08x)\n", pszProvName
, dwProvType
, pdwReserved
, dwFlags
);
2128 if (CRYPT_ANSIToUnicode(pszProvName
, &str
, -1))
2130 ret
= CryptSetProviderExW(str
, dwProvType
, pdwReserved
, dwFlags
);
2136 /******************************************************************************
2137 * CryptSetProvParam (ADVAPI32.@)
2139 * Customizes the operations of a CSP.
2142 * hProv [I] Handle of a CSP.
2143 * dwParam [I] See MSDN Doc.
2144 * pbData [I] Buffer that contains a value to set as a parameter.
2145 * dwFlags [I] if dwParam is PP_USE_HARDWARE_RNG, dwFlags must be zero.
2151 BOOL WINAPI
CryptSetProvParam (HCRYPTPROV hProv
, DWORD dwParam
, CONST BYTE
*pbData
, DWORD dwFlags
)
2153 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
2155 TRACE("(0x%lx, %d, %p, %08x)\n", hProv
, dwParam
, pbData
, dwFlags
);
2159 SetLastError(ERROR_INVALID_HANDLE
);
2162 if (prov
->dwMagic
!= MAGIC_CRYPTPROV
)
2164 SetLastError(ERROR_INVALID_PARAMETER
);
2167 if (dwFlags
& PP_USE_HARDWARE_RNG
)
2169 FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n");
2170 FIXME("\tLetting the CSP decide.\n");
2172 if (dwFlags
& PP_CLIENT_HWND
)
2174 /* FIXME: Should verify the parameter */
2175 if (pbData
/* && IsWindow((HWND)pbData) */)
2177 crypt_hWindow
= (HWND
)(pbData
);
2180 SetLastError(ERROR_INVALID_PARAMETER
);
2184 /* All other flags go to the CSP */
2185 return prov
->pFuncs
->pCPSetProvParam(prov
->hPrivate
, dwParam
, pbData
, dwFlags
);
2188 /******************************************************************************
2189 * CryptVerifySignatureW (ADVAPI32.@)
2191 * Verifies the signature of a hash object.
2194 * hHash [I] Handle of the hash object to verify.
2195 * pbSignature [I] Signature data to verify.
2196 * dwSigLen [I] Size of pbSignature.
2197 * hPubKey [I] Handle to the public key to authenticate signature.
2198 * sDescription [I] Should be NULL.
2199 * dwFlags [I] See MSDN doc.
2206 * Because of security flaws sDescription should not be used and should thus be
2207 * NULL. It is supported only for compatibility with Microsoft's Cryptographic
2210 BOOL WINAPI
CryptVerifySignatureW (HCRYPTHASH hHash
, CONST BYTE
*pbSignature
, DWORD dwSigLen
,
2211 HCRYPTKEY hPubKey
, LPCWSTR sDescription
, DWORD dwFlags
)
2213 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
2214 PCRYPTKEY key
= (PCRYPTKEY
)hPubKey
;
2217 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash
, pbSignature
,
2218 dwSigLen
, hPubKey
, debugstr_w(sDescription
), dwFlags
);
2220 if (!hash
|| !key
|| key
->dwMagic
!= MAGIC_CRYPTKEY
|| hash
->dwMagic
!= MAGIC_CRYPTHASH
||
2221 !hash
->pProvider
|| hash
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
||
2222 !key
->pProvider
|| key
->pProvider
->dwMagic
!= MAGIC_CRYPTPROV
)
2224 SetLastError(ERROR_INVALID_PARAMETER
);
2228 prov
= hash
->pProvider
;
2229 return prov
->pFuncs
->pCPVerifySignature(prov
->hPrivate
, hash
->hPrivate
, pbSignature
, dwSigLen
,
2230 key
->hPrivate
, sDescription
, dwFlags
);
2233 /******************************************************************************
2234 * CryptVerifySignatureA (ADVAPI32.@)
2236 * See CryptVerifySignatureW.
2238 BOOL WINAPI
CryptVerifySignatureA (HCRYPTHASH hHash
, CONST BYTE
*pbSignature
, DWORD dwSigLen
,
2239 HCRYPTKEY hPubKey
, LPCSTR sDescription
, DWORD dwFlags
)
2241 LPWSTR wsDescription
;
2244 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash
, pbSignature
,
2245 dwSigLen
, hPubKey
, debugstr_a(sDescription
), dwFlags
);
2247 CRYPT_ANSIToUnicode(sDescription
, &wsDescription
, -1);
2248 result
= CryptVerifySignatureW(hHash
, pbSignature
, dwSigLen
, hPubKey
, wsDescription
, dwFlags
);
2249 CRYPT_Free(wsDescription
);
2255 /******************************************************************************
2256 * SystemFunction030 (ADVAPI32.@)
2258 * Tests if two blocks of 16 bytes are equal
2261 * b1,b2 [I] block of 16 bytes
2264 * TRUE if blocks are the same
2265 * FALSE if blocks are different
2267 BOOL WINAPI
SystemFunction030(LPCVOID b1
, LPCVOID b2
)
2269 return !memcmp(b1
, b2
, 0x10);
2272 /******************************************************************************
2273 * SystemFunction035 (ADVAPI32.@)
2276 http://disc.server.com/discussion.cgi?disc=148775;article=942;title=Coding%2FASM%2FSystem
2279 * Stub, always return TRUE.
2281 BOOL WINAPI
SystemFunction035(LPCSTR lpszDllFilePath
)
2283 FIXME("%s: stub\n", debugstr_a(lpszDllFilePath
));
2287 /******************************************************************************
2288 * SystemFunction036 (ADVAPI32.@)
2290 * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h
2293 * pbBufer [O] Pointer to memory to receive random bytes.
2294 * dwLen [I] Number of random bytes to fetch.
2301 BOOLEAN WINAPI
SystemFunction036(PVOID pbBuffer
, ULONG dwLen
)
2305 dev_random
= open("/dev/urandom", O_RDONLY
);
2306 if (dev_random
!= -1)
2308 if (read(dev_random
, pbBuffer
, dwLen
) == (ssize_t
)dwLen
)
2316 FIXME("couldn't open /dev/urandom\n");
2317 SetLastError(NTE_FAIL
);
2322 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
2326 /******************************************************************************
2327 * SystemFunction040 (ADVAPI32.@)
2329 * MSDN documents this function as RtlEncryptMemory and declares it in ntsecapi.h.
2332 * memory [I/O] Pointer to memory to encrypt.
2333 * length [I] Length of region to encrypt in bytes.
2334 * flags [I] Control whether other processes are able to decrypt the memory.
2335 * RTL_ENCRYPT_OPTION_SAME_PROCESS
2336 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
2337 * RTL_ENCRYPT_OPTION_SAME_LOGON
2340 * Success: STATUS_SUCCESS
2341 * Failure: NTSTATUS error code
2344 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
2345 * If flags are specified when encrypting, the same flag value must be given
2346 * when decrypting the memory.
2348 NTSTATUS WINAPI
SystemFunction040(PVOID memory
, ULONG length
, ULONG flags
)
2350 FIXME("(%p, %x, %x): stub [RtlEncryptMemory]\n", memory
, length
, flags
);
2351 return STATUS_SUCCESS
;
2354 /******************************************************************************
2355 * SystemFunction041 (ADVAPI32.@)
2357 * MSDN documents this function as RtlDecryptMemory and declares it in ntsecapi.h.
2360 * memory [I/O] Pointer to memory to decrypt.
2361 * length [I] Length of region to decrypt in bytes.
2362 * flags [I] Control whether other processes are able to decrypt the memory.
2363 * RTL_ENCRYPT_OPTION_SAME_PROCESS
2364 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
2365 * RTL_ENCRYPT_OPTION_SAME_LOGON
2368 * Success: STATUS_SUCCESS
2369 * Failure: NTSTATUS error code
2372 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
2373 * If flags are specified when encrypting, the same flag value must be given
2374 * when decrypting the memory.
2376 NTSTATUS WINAPI
SystemFunction041(PVOID memory
, ULONG length
, ULONG flags
)
2378 FIXME("(%p, %x, %x): stub [RtlDecryptMemory]\n", memory
, length
, flags
);
2379 return STATUS_SUCCESS
;
2381 #endif /* !__REACTOS __ */