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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 /***********************************************************************
23 * - Reference counting
25 * - Signature checking
32 #include "wine/unicode.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
45 HWND crypt_hWindow
= 0;
47 #define CRYPT_ReturnLastError(err) {SetLastError(err); return FALSE;}
49 #define CRYPT_Alloc(size) ((LPVOID)LocalAlloc(LMEM_ZEROINIT, size))
50 #define CRYPT_Free(buffer) (LocalFree((HLOCAL)buffer))
52 static inline PSTR
CRYPT_GetProvKeyName(PCSTR pProvName
)
54 PCSTR KEYSTR
= "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\";
57 keyname
= CRYPT_Alloc(strlen(KEYSTR
) + strlen(pProvName
) +1);
60 strcpy(keyname
, KEYSTR
);
61 strcpy(keyname
+ strlen(KEYSTR
), pProvName
);
63 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
67 static inline PSTR
CRYPT_GetTypeKeyName(DWORD dwType
, BOOL user
)
69 PCSTR MACHINESTR
= "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
70 PCSTR USERSTR
= "Software\\Microsoft\\Cryptography\\Provider Type XXX";
74 keyname
= CRYPT_Alloc( (user
? strlen(USERSTR
) : strlen(MACHINESTR
)) +1);
77 user
? strcpy(keyname
, USERSTR
) : strcpy(keyname
, MACHINESTR
);
78 ptr
= keyname
+ strlen(keyname
);
79 *(--ptr
) = (dwType
% 10) + '0';
80 *(--ptr
) = (dwType
/ 10) + '0';
81 *(--ptr
) = (dwType
/ 100) + '0';
83 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
87 /* CRYPT_UnicodeTOANSI
88 * wstr - unicode string
89 * str - pointer to ANSI string
90 * strsize - size of buffer pointed to by str or -1 if we have to do the allocation
92 * returns TRUE if unsuccessfull, FALSE otherwise.
93 * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call
95 static inline BOOL
CRYPT_UnicodeToANSI(LPCWSTR wstr
, LPSTR
* str
, int strsize
)
104 count
= WideCharToMultiByte(CP_ACP
, 0, wstr
, -1, NULL
, 0, NULL
, NULL
);
105 count
= count
< strsize
? count
: strsize
;
107 *str
= CRYPT_Alloc(count
* sizeof(CHAR
));
110 WideCharToMultiByte(CP_ACP
, 0, wstr
, -1, *str
, count
, NULL
, NULL
);
113 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
117 /* CRYPT_ANSITOUnicode
119 * wstr - pointer to unicode string
120 * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation
122 static inline BOOL
CRYPT_ANSIToUnicode(LPCSTR str
, LPWSTR
* wstr
, int wstrsize
)
131 wcount
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
132 wcount
= wcount
< wstrsize
/sizeof(WCHAR
) ? wcount
: wstrsize
/sizeof(WCHAR
);
134 *wstr
= CRYPT_Alloc(wcount
* sizeof(WCHAR
));
137 MultiByteToWideChar(CP_ACP
, 0, str
, -1, *wstr
, wcount
);
140 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
144 /* These next 2 functions are used by the VTableProvStruc structure */
145 static BOOL CALLBACK
CRYPT_VerifyImage(LPCSTR lpszImage
, BYTE
* pData
)
147 if (!lpszImage
|| !pData
)
149 SetLastError(ERROR_INVALID_PARAMETER
);
153 FIXME("(%s, %p): not verifying image", lpszImage
, pData
);
158 static BOOL CALLBACK
CRYPT_ReturnhWnd(HWND
*phWnd
)
162 *phWnd
= crypt_hWindow
;
166 #define CRYPT_GetProvFunc(name) \
167 if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error
168 #define CRYPT_GetProvFuncOpt(name) \
169 provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)
170 PCRYPTPROV
CRYPT_LoadProvider(PSTR pImage
)
173 DWORD errorcode
= ERROR_NOT_ENOUGH_MEMORY
;
175 if ( !(provider
= CRYPT_Alloc(sizeof(CRYPTPROV
))) ) goto error
;
176 if ( !(provider
->pFuncs
= CRYPT_Alloc(sizeof(PROVFUNCS
))) ) goto error
;
177 if ( !(provider
->pVTable
= CRYPT_Alloc(sizeof(VTableProvStruc
))) ) goto error
;
178 if ( !(provider
->hModule
= LoadLibraryA(pImage
)) )
180 errorcode
= (GetLastError() == ERROR_FILE_NOT_FOUND
) ? NTE_PROV_DLL_NOT_FOUND
: NTE_PROVIDER_DLL_FAIL
;
181 FIXME("Failed to load dll %s\n", debugstr_a(pImage
));
185 errorcode
= NTE_PROVIDER_DLL_FAIL
;
186 CRYPT_GetProvFunc(CPAcquireContext
);
187 CRYPT_GetProvFunc(CPCreateHash
);
188 CRYPT_GetProvFunc(CPDecrypt
);
189 CRYPT_GetProvFunc(CPDeriveKey
);
190 CRYPT_GetProvFunc(CPDestroyHash
);
191 CRYPT_GetProvFunc(CPDestroyKey
);
192 CRYPT_GetProvFuncOpt(CPDuplicateHash
);
193 CRYPT_GetProvFuncOpt(CPDuplicateKey
);
194 CRYPT_GetProvFunc(CPEncrypt
);
195 CRYPT_GetProvFunc(CPExportKey
);
196 CRYPT_GetProvFunc(CPGenKey
);
197 CRYPT_GetProvFunc(CPGenRandom
);
198 CRYPT_GetProvFunc(CPGetHashParam
);
199 CRYPT_GetProvFunc(CPGetKeyParam
);
200 CRYPT_GetProvFunc(CPGetProvParam
);
201 CRYPT_GetProvFunc(CPGetUserKey
);
202 CRYPT_GetProvFunc(CPHashData
);
203 CRYPT_GetProvFunc(CPHashSessionKey
);
204 CRYPT_GetProvFunc(CPImportKey
);
205 CRYPT_GetProvFunc(CPReleaseContext
);
206 CRYPT_GetProvFunc(CPSetHashParam
);
207 CRYPT_GetProvFunc(CPSetKeyParam
);
208 CRYPT_GetProvFunc(CPSetProvParam
);
209 CRYPT_GetProvFunc(CPSignHash
);
210 CRYPT_GetProvFunc(CPVerifySignature
);
212 /* FIXME: Not sure what the pbContextInfo field is for.
213 * Does it need memory allocation?
215 provider
->pVTable
->Version
= 3;
216 provider
->pVTable
->pFuncVerifyImage
= (FARPROC
)CRYPT_VerifyImage
;
217 provider
->pVTable
->pFuncReturnhWnd
= (FARPROC
)CRYPT_ReturnhWnd
;
218 provider
->pVTable
->dwProvType
= 0;
219 provider
->pVTable
->pbContextInfo
= NULL
;
220 provider
->pVTable
->cbContextInfo
= 0;
221 provider
->pVTable
->pszProvName
= NULL
;
225 SetLastError(errorcode
);
228 if (provider
->hModule
)
229 FreeLibrary(provider
->hModule
);
230 CRYPT_Free(provider
->pVTable
);
231 CRYPT_Free(provider
->pFuncs
);
232 CRYPT_Free(provider
);
236 #undef CRYPT_GetProvFunc
237 #undef CRYPT_GetProvFuncOpt
240 /******************************************************************************
241 * CryptAcquireContextA (ADVAPI32.@)
242 * Acquire a crypto provider context handle.
245 * phProv: Pointer to HCRYPTPROV for the output.
246 * pszContainer: Key Container Name
247 * pszProvider: Cryptographic Service Provider Name
248 * dwProvType: Crypto provider type to get a handle.
249 * dwFlags: flags for the operation
251 * RETURNS TRUE on success, FALSE on failure.
253 BOOL WINAPI
CryptAcquireContextA (HCRYPTPROV
*phProv
, LPCSTR pszContainer
,
254 LPCSTR pszProvider
, DWORD dwProvType
, DWORD dwFlags
)
256 PCRYPTPROV pProv
= NULL
;
258 PSTR imagepath
= NULL
, keyname
= NULL
, provname
= NULL
, temp
= NULL
;
260 DWORD keytype
, type
, len
;
263 TRACE("(%p, %s, %s, %ld, %08lx)\n", phProv
, pszContainer
,
264 pszProvider
, dwProvType
, dwFlags
);
266 if (!phProv
|| !dwProvType
)
268 SetLastError(ERROR_INVALID_PARAMETER
);
271 if (dwProvType
> MAXPROVTYPES
)
273 SetLastError(NTE_BAD_PROV_TYPE
);
279 /* No CSP name specified so try the user default CSP first
280 * then try the machine default CSP
282 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, TRUE
)) ) {
283 FIXME("No provider registered for crypto provider type %ld.\n", dwProvType
);
284 SetLastError(NTE_PROV_TYPE_NOT_DEF
);
287 if (RegOpenKeyA(HKEY_CURRENT_USER
, keyname
, &key
))
290 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, FALSE
)) ) {
291 FIXME("No type registered for crypto provider type %ld.\n", dwProvType
);
293 SetLastError(NTE_PROV_TYPE_NOT_DEF
);
296 if (RegOpenKeyA(HKEY_LOCAL_MACHINE
, keyname
, &key
)) {
297 FIXME("Did not find registry entry of crypto provider for %s.\n", debugstr_a(keyname
));
299 SetLastError(NTE_PROV_TYPE_NOT_DEF
);
304 r
= RegQueryValueExA(key
, "Name", NULL
, &keytype
, NULL
, &len
);
305 if( r
!= ERROR_SUCCESS
|| !len
|| keytype
!= REG_SZ
)
307 TRACE("error %ld reading size of 'Name' from registry\n", r
);
309 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
312 if(!(provname
= CRYPT_Alloc(len
)))
315 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
318 r
= RegQueryValueExA(key
, "Name", NULL
, NULL
, provname
, &len
);
319 if( r
!= ERROR_SUCCESS
)
321 TRACE("error %ld reading 'Name' from registry\n", r
);
323 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
328 if ( !(provname
= CRYPT_Alloc(strlen(pszProvider
) +1)) )
330 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
333 strcpy(provname
, pszProvider
);
336 keyname
= CRYPT_GetProvKeyName(provname
);
337 if (RegOpenKeyA(HKEY_LOCAL_MACHINE
, keyname
, &key
)) goto error
;
340 r
= RegQueryValueExA(key
, "Type", NULL
, NULL
, (BYTE
*)&type
, &len
);
341 if (r
!= ERROR_SUCCESS
|| type
!= dwProvType
)
343 FIXME("Crypto provider has wrong type (%ld vs expected %ld).\n", type
, dwProvType
);
344 SetLastError(NTE_BAD_PROV_TYPE
);
348 r
= RegQueryValueExA(key
, "Image Path", NULL
, &keytype
, NULL
, &len
);
349 if ( r
!= ERROR_SUCCESS
|| keytype
!= REG_SZ
)
351 TRACE("error %ld reading size of 'Image Path' from registry\n", r
);
353 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
356 if (!(temp
= CRYPT_Alloc(len
)))
359 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
362 r
= RegQueryValueExA(key
, "Image Path", NULL
, NULL
, temp
, &len
);
363 if( r
!= ERROR_SUCCESS
)
365 TRACE("error %ld reading 'Image Path' from registry\n", r
);
367 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
371 r
= RegQueryValueExA(key
, "Signature", NULL
, &keytype
, NULL
, &len
);
372 if ( r
!= ERROR_SUCCESS
|| keytype
!= REG_BINARY
)
374 TRACE("error %ld reading size of 'Signature'\n", r
);
376 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
379 if (!(signature
= CRYPT_Alloc(len
)))
382 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
385 r
= RegQueryValueExA(key
, "Signature", NULL
, NULL
, signature
, &len
);
386 if ( r
!= ERROR_SUCCESS
)
388 TRACE("error %ld reading 'Signature'\n", r
);
390 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
394 len
= ExpandEnvironmentStringsA(temp
, NULL
, 0);
395 if ( !(imagepath
= CRYPT_Alloc(len
)) )
397 CRYPT_Free(signature
);
398 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
401 if (!ExpandEnvironmentStringsA(temp
, imagepath
, len
))
403 CRYPT_Free(signature
);
404 /* ExpandEnvironmentStrings will call SetLastError */
408 if (!CRYPT_VerifyImage(imagepath
, signature
))
410 CRYPT_Free(signature
);
411 SetLastError(NTE_SIGNATURE_FILE_BAD
);
414 pProv
= CRYPT_LoadProvider(imagepath
);
416 CRYPT_Free(imagepath
);
417 CRYPT_Free(signature
);
419 FIXME("Could not load crypto provider from DLL %s\n", debugstr_a(imagepath
));
420 /* CRYPT_LoadProvider calls SetLastError */
423 if (pProv
->pFuncs
->pCPAcquireContext(&pProv
->hPrivate
, (CHAR
*)pszContainer
, dwFlags
, pProv
->pVTable
))
425 /* MSDN: When this flag is set, the value returned in phProv is undefined,
426 * and thus, the CryptReleaseContext function need not be called afterwards.
427 * Therefore, we must clean up everything now.
429 if (dwFlags
& CRYPT_DELETEKEYSET
)
431 FreeLibrary(pProv
->hModule
);
432 CRYPT_Free(provname
);
433 CRYPT_Free(pProv
->pFuncs
);
436 pProv
->pVTable
->pszProvName
= provname
;
437 pProv
->pVTable
->dwProvType
= dwProvType
;
438 *phProv
= (HCRYPTPROV
)pProv
;
442 /* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */
446 FreeLibrary(pProv
->hModule
);
447 CRYPT_Free(pProv
->pVTable
);
448 CRYPT_Free(pProv
->pFuncs
);
451 CRYPT_Free(provname
);
453 CRYPT_Free(imagepath
);
458 /******************************************************************************
459 * CryptAcquireContextW (ADVAPI32.@)
461 BOOL WINAPI
CryptAcquireContextW (HCRYPTPROV
*phProv
, LPCWSTR pszContainer
,
462 LPCWSTR pszProvider
, DWORD dwProvType
, DWORD dwFlags
)
464 PSTR pProvider
= NULL
, pContainer
= NULL
;
467 TRACE("(%p, %s, %s, %ld, %08lx)\n", phProv
, debugstr_w(pszContainer
),
468 debugstr_w(pszProvider
), dwProvType
, dwFlags
);
470 if ( !CRYPT_UnicodeToANSI(pszContainer
, &pContainer
, -1) )
471 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
472 if ( !CRYPT_UnicodeToANSI(pszProvider
, &pProvider
, -1) )
474 CRYPT_Free(pContainer
);
475 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
478 ret
= CryptAcquireContextA(phProv
, pContainer
, pProvider
, dwProvType
, dwFlags
);
481 CRYPT_Free(pContainer
);
483 CRYPT_Free(pProvider
);
488 /******************************************************************************
489 * CryptContextAddRef (ADVAPI32.@)
491 BOOL WINAPI
CryptContextAddRef (HCRYPTPROV hProv
, DWORD
*pdwReserved
, DWORD dwFlags
)
493 FIXME("(0x%lx, %p, %08lx): stub!\n", hProv
, pdwReserved
, dwFlags
);
495 /* InterlockIncrement?? */
498 /******************************************************************************
499 * CryptReleaseContext (ADVAPI32.@)
501 BOOL WINAPI
CryptReleaseContext (HCRYPTPROV hProv
, DWORD dwFlags
)
503 PCRYPTPROV pProv
= (PCRYPTPROV
)hProv
;
506 TRACE("(0x%lx, %08ld)\n", hProv
, dwFlags
);
510 SetLastError(NTE_BAD_UID
);
513 /* FIXME: Decrement the counter here first if possible */
514 ret
= pProv
->pFuncs
->pCPReleaseContext(pProv
->hPrivate
, dwFlags
);
515 FreeLibrary(pProv
->hModule
);
517 CRYPT_Free(pProv
->pVTable
->pContextInfo
);
519 CRYPT_Free(pProv
->pVTable
->pszProvName
);
520 CRYPT_Free(pProv
->pVTable
);
521 CRYPT_Free(pProv
->pFuncs
);
526 /******************************************************************************
527 * CryptGenRandom (ADVAPI32.@)
529 BOOL WINAPI
CryptGenRandom (HCRYPTPROV hProv
, DWORD dwLen
, BYTE
*pbBuffer
)
531 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
533 TRACE("(0x%lx, %ld, %p)\n", hProv
, dwLen
, pbBuffer
);
536 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
538 return prov
->pFuncs
->pCPGenRandom(prov
->hPrivate
, dwLen
, pbBuffer
);
541 /******************************************************************************
542 * CryptCreateHash (ADVAPI32.@)
544 BOOL WINAPI
CryptCreateHash (HCRYPTPROV hProv
, ALG_ID Algid
, HCRYPTKEY hKey
,
545 DWORD dwFlags
, HCRYPTHASH
*phHash
)
547 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
548 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
551 TRACE("(0x%lx, 0x%x, 0x%lx, %08lx, %p)\n", hProv
, Algid
, hKey
, dwFlags
, phHash
);
554 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
556 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
558 CRYPT_ReturnLastError(NTE_BAD_FLAGS
);
559 if ( !(hash
= CRYPT_Alloc(sizeof(CRYPTHASH
))) )
560 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
562 hash
->pProvider
= prov
;
564 if (prov
->pFuncs
->pCPCreateHash(prov
->hPrivate
, Algid
,
565 key
? key
->hPrivate
: 0, 0, &hash
->hPrivate
))
567 *phHash
= (HCRYPTHASH
)hash
;
576 /******************************************************************************
577 * CryptDecrypt (ADVAPI32.@)
579 BOOL WINAPI
CryptDecrypt (HCRYPTKEY hKey
, HCRYPTHASH hHash
, BOOL Final
,
580 DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
)
583 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
584 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
586 TRACE("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey
, hHash
, Final
, dwFlags
, pbData
, pdwDataLen
);
588 if (!key
|| !pbData
|| !pdwDataLen
)
589 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
591 prov
= key
->pProvider
;
592 return prov
->pFuncs
->pCPDecrypt(prov
->hPrivate
, key
->hPrivate
, hash
? hash
->hPrivate
: 0,
593 Final
, dwFlags
, pbData
, pdwDataLen
);
596 /******************************************************************************
597 * CryptDeriveKey (ADVAPI32.@)
599 BOOL WINAPI
CryptDeriveKey (HCRYPTPROV hProv
, ALG_ID Algid
, HCRYPTHASH hBaseData
,
600 DWORD dwFlags
, HCRYPTKEY
*phKey
)
602 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
603 PCRYPTHASH hash
= (PCRYPTHASH
)hBaseData
;
606 TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08lx, %p)\n", hProv
, Algid
, hBaseData
, dwFlags
, phKey
);
609 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
611 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
612 if ( !(key
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
613 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
615 key
->pProvider
= prov
;
616 if (prov
->pFuncs
->pCPDeriveKey(prov
->hPrivate
, Algid
, hash
->hPrivate
, dwFlags
, &key
->hPrivate
))
618 *phKey
= (HCRYPTKEY
)key
;
627 /******************************************************************************
628 * CryptDestroyHash (ADVAPI32.@)
630 BOOL WINAPI
CryptDestroyHash (HCRYPTHASH hHash
)
632 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
636 TRACE("(0x%lx)\n", hHash
);
639 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
641 prov
= hash
->pProvider
;
642 ret
= prov
->pFuncs
->pCPDestroyHash(prov
->hPrivate
, hash
->hPrivate
);
647 /******************************************************************************
648 * CryptDestroyKey (ADVAPI32.@)
650 BOOL WINAPI
CryptDestroyKey (HCRYPTKEY hKey
)
652 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
656 TRACE("(0x%lx)\n", hKey
);
659 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
661 prov
= key
->pProvider
;
662 ret
= prov
->pFuncs
->pCPDestroyKey(prov
->hPrivate
, key
->hPrivate
);
667 /******************************************************************************
668 * CryptDuplicateHash (ADVAPI32.@)
670 BOOL WINAPI
CryptDuplicateHash (HCRYPTHASH hHash
, DWORD
*pdwReserved
,
671 DWORD dwFlags
, HCRYPTHASH
*phHash
)
674 PCRYPTHASH orghash
, newhash
;
676 TRACE("(0x%lx, %p, %08ld, %p)\n", hHash
, pdwReserved
, dwFlags
, phHash
);
678 orghash
= (PCRYPTHASH
)hHash
;
679 if (!orghash
|| pdwReserved
|| !phHash
)
680 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
682 prov
= orghash
->pProvider
;
683 if (!prov
->pFuncs
->pCPDuplicateHash
)
684 CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED
);
686 if ( !(newhash
= CRYPT_Alloc(sizeof(CRYPTHASH
))) )
687 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
689 newhash
->pProvider
= prov
;
690 if (prov
->pFuncs
->pCPDuplicateHash(prov
->hPrivate
, orghash
->hPrivate
, pdwReserved
, dwFlags
, &newhash
->hPrivate
))
692 *phHash
= (HCRYPTHASH
)newhash
;
699 /******************************************************************************
700 * CryptDuplicateKey (ADVAPI32.@)
702 BOOL WINAPI
CryptDuplicateKey (HCRYPTKEY hKey
, DWORD
*pdwReserved
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
705 PCRYPTKEY orgkey
, newkey
;
707 TRACE("(0x%lx, %p, %08ld, %p)\n", hKey
, pdwReserved
, dwFlags
, phKey
);
709 orgkey
= (PCRYPTKEY
)hKey
;
710 if (!orgkey
|| pdwReserved
|| !phKey
)
711 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
713 prov
= orgkey
->pProvider
;
714 if (!prov
->pFuncs
->pCPDuplicateKey
)
715 CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED
);
717 if ( !(newkey
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
718 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
720 newkey
->pProvider
= prov
;
721 if (prov
->pFuncs
->pCPDuplicateKey(prov
->hPrivate
, orgkey
->hPrivate
, pdwReserved
, dwFlags
, &newkey
->hPrivate
))
723 *phKey
= (HCRYPTKEY
)newkey
;
730 /******************************************************************************
731 * CryptEncrypt (ADVAPI32.@)
733 BOOL WINAPI
CryptEncrypt (HCRYPTKEY hKey
, HCRYPTHASH hHash
, BOOL Final
,
734 DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
, DWORD dwBufLen
)
737 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
738 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
740 TRACE("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey
, hHash
, Final
, dwFlags
, pbData
, pdwDataLen
, dwBufLen
);
742 if (!key
|| !pdwDataLen
)
743 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
745 prov
= key
->pProvider
;
746 return prov
->pFuncs
->pCPEncrypt(prov
->hPrivate
, key
->hPrivate
, hash
? hash
->hPrivate
: 0,
747 Final
, dwFlags
, pbData
, pdwDataLen
, dwBufLen
);
750 /******************************************************************************
751 * CryptEnumProvidersA (ADVAPI32.@)
753 BOOL WINAPI
CryptEnumProvidersA (DWORD dwIndex
, DWORD
*pdwReserved
,
754 DWORD dwFlags
, DWORD
*pdwProvType
, LPSTR pszProvName
, DWORD
*pcbProvName
)
758 TRACE("(%ld, %p, %ld, %p, %p, %p)\n", dwIndex
, pdwReserved
, dwFlags
,
759 pdwProvType
, pszProvName
, pcbProvName
);
761 if (pdwReserved
|| !pcbProvName
) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
762 if (dwFlags
) CRYPT_ReturnLastError(NTE_BAD_FLAGS
);
764 if (RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey
))
765 CRYPT_ReturnLastError(NTE_FAIL
);
770 RegQueryInfoKeyA(hKey
, NULL
, NULL
, NULL
, &numkeys
, pcbProvName
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
772 if (dwIndex
>= numkeys
)
773 CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS
);
775 DWORD size
= sizeof(DWORD
);
777 if (RegEnumKeyA(hKey
, dwIndex
, pszProvName
, *pcbProvName
))
779 if (RegOpenKeyA(hKey
, pszProvName
, &subkey
))
781 if (RegQueryValueExA(subkey
, "Type", NULL
, NULL
, (BYTE
*)pdwProvType
, &size
))
789 /******************************************************************************
790 * CryptEnumProvidersW (ADVAPI32.@)
792 BOOL WINAPI
CryptEnumProvidersW (DWORD dwIndex
, DWORD
*pdwReserved
,
793 DWORD dwFlags
, DWORD
*pdwProvType
, LPWSTR pszProvName
, DWORD
*pcbProvName
)
797 BOOL ret
; /* = FALSE; */
799 TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex
, pdwReserved
, dwFlags
,
800 pdwProvType
, pszProvName
, pcbProvName
);
802 strlen
= *pcbProvName
/ sizeof(WCHAR
);
803 if ( pszProvName
&& (str
= CRYPT_Alloc(strlen
)) )
804 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
805 ret
= CryptEnumProvidersA(dwIndex
, pdwReserved
, dwFlags
, pdwProvType
, str
, &strlen
);
808 CRYPT_ANSIToUnicode(str
, &pszProvName
, *pcbProvName
);
811 *pcbProvName
= strlen
* sizeof(WCHAR
);
815 /******************************************************************************
816 * CryptEnumProviderTypesA (ADVAPI32.@)
818 BOOL WINAPI
CryptEnumProviderTypesA (DWORD dwIndex
, DWORD
*pdwReserved
,
819 DWORD dwFlags
, DWORD
*pdwProvType
, LPSTR pszTypeName
, DWORD
*pcbTypeName
)
822 DWORD keylen
, numkeys
;
825 TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex
, pdwReserved
,
826 dwFlags
, pdwProvType
, pszTypeName
, pcbTypeName
);
828 if (pdwReserved
|| !pdwProvType
|| !pcbTypeName
)
829 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
830 if (dwFlags
) CRYPT_ReturnLastError(NTE_BAD_FLAGS
);
832 if (RegOpenKeyA(HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey
))
835 RegQueryInfoKeyA(hKey
, NULL
, NULL
, NULL
, &numkeys
, &keylen
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
836 if (dwIndex
>= numkeys
)
837 CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS
);
839 if ( !(keyname
= CRYPT_Alloc(keylen
)) )
840 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
841 if ( RegEnumKeyA(hKey
, dwIndex
, keyname
, keylen
) ) {
845 RegOpenKeyA(hKey
, keyname
, &hSubkey
);
846 ch
= keyname
+ strlen(keyname
);
847 /* Convert "Type 000" to 0, etc/ */
848 *pdwProvType
= *(--ch
) - '0';
849 *pdwProvType
+= (*(--ch
) - '0') * 10;
850 *pdwProvType
+= (*(--ch
) - '0') * 100;
852 RegQueryValueA(hSubkey
, "TypeName", pszTypeName
, pcbTypeName
);
853 RegCloseKey(hSubkey
);
858 /******************************************************************************
859 * CryptEnumProviderTypesW (ADVAPI32.@)
861 BOOL WINAPI
CryptEnumProviderTypesW (DWORD dwIndex
, DWORD
*pdwReserved
,
862 DWORD dwFlags
, DWORD
*pdwProvType
, LPWSTR pszTypeName
, DWORD
*pcbTypeName
)
868 TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex
, pdwReserved
, dwFlags
,
869 pdwProvType
, pszTypeName
, pcbTypeName
);
870 strlen
= *pcbTypeName
/ sizeof(WCHAR
);
871 if ( pszTypeName
&& (str
= CRYPT_Alloc(strlen
)) )
872 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
873 ret
= CryptEnumProviderTypesA(dwIndex
, pdwReserved
, dwFlags
, pdwProvType
, str
, &strlen
);
876 CRYPT_ANSIToUnicode(str
, &pszTypeName
, *pcbTypeName
);
879 *pcbTypeName
= strlen
* sizeof(WCHAR
);
883 /******************************************************************************
884 * CryptExportKey (ADVAPI32.@)
886 BOOL WINAPI
CryptExportKey (HCRYPTKEY hKey
, HCRYPTKEY hExpKey
, DWORD dwBlobType
,
887 DWORD dwFlags
, BYTE
*pbData
, DWORD
*pdwDataLen
)
890 PCRYPTKEY key
= (PCRYPTKEY
)hKey
, expkey
= (PCRYPTKEY
)hExpKey
;
892 TRACE("(0x%lx, 0x%lx, %ld, %08ld, %p, %p)\n", hKey
, hExpKey
, dwBlobType
, dwFlags
, pbData
, pdwDataLen
);
894 if (!key
|| pdwDataLen
)
895 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
897 prov
= key
->pProvider
;
898 return prov
->pFuncs
->pCPExportKey(prov
->hPrivate
, key
->hPrivate
, expkey
? expkey
->hPrivate
: 0,
899 dwBlobType
, dwFlags
, pbData
, pdwDataLen
);
902 /******************************************************************************
903 * CryptGenKey (ADVAPI32.@)
905 BOOL WINAPI
CryptGenKey (HCRYPTPROV hProv
, ALG_ID Algid
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
907 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
910 TRACE("(0x%lx, %d, %08ld, %p)\n", hProv
, Algid
, dwFlags
, phKey
);
913 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
915 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
916 if ( !(key
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
917 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
919 key
->pProvider
= prov
;
921 if (prov
->pFuncs
->pCPGenKey(prov
->hPrivate
, Algid
, dwFlags
, &key
->hPrivate
))
923 *phKey
= (HCRYPTKEY
)key
;
932 /******************************************************************************
933 * CryptGetDefaultProviderA (ADVAPI32.@)
935 BOOL WINAPI
CryptGetDefaultProviderA (DWORD dwProvType
, DWORD
*pdwReserved
,
936 DWORD dwFlags
, LPSTR pszProvName
, DWORD
*pcbProvName
)
941 if (pdwReserved
|| !pcbProvName
)
942 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
943 if (dwFlags
& ~(CRYPT_USER_DEFAULT
| CRYPT_MACHINE_DEFAULT
))
944 CRYPT_ReturnLastError(NTE_BAD_FLAGS
);
945 if (dwProvType
> 999)
946 CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE
);
947 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, dwFlags
& CRYPT_USER_DEFAULT
)) )
948 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
949 if (RegOpenKeyA((dwFlags
& CRYPT_USER_DEFAULT
) ? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
,keyname
, &hKey
))
952 CRYPT_ReturnLastError(NTE_PROV_TYPE_NOT_DEF
);
955 if (RegQueryValueExA(hKey
, "Name", NULL
, NULL
, pszProvName
, pcbProvName
))
957 if (GetLastError() != ERROR_MORE_DATA
)
958 SetLastError(NTE_PROV_TYPE_ENTRY_BAD
);
965 /******************************************************************************
966 * CryptGetDefaultProviderW (ADVAPI32.@)
968 BOOL WINAPI
CryptGetDefaultProviderW (DWORD dwProvType
, DWORD
*pdwReserved
,
969 DWORD dwFlags
, LPWSTR pszProvName
, DWORD
*pcbProvName
)
975 TRACE("(%ld, %p, %08ld, %p, %p)\n", dwProvType
, pdwReserved
, dwFlags
, pszProvName
, pcbProvName
);
977 strlen
= *pcbProvName
/ sizeof(WCHAR
);
978 if ( pszProvName
&& !(str
= CRYPT_Alloc(strlen
)) )
979 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
980 ret
= CryptGetDefaultProviderA(dwProvType
, pdwReserved
, dwFlags
, str
, &strlen
);
983 CRYPT_ANSIToUnicode(str
, &pszProvName
, *pcbProvName
);
986 *pcbProvName
= strlen
* sizeof(WCHAR
);
990 /******************************************************************************
991 * CryptGetHashParam (ADVAPI32.@)
993 BOOL WINAPI
CryptGetHashParam (HCRYPTHASH hHash
, DWORD dwParam
, BYTE
*pbData
,
994 DWORD
*pdwDataLen
, DWORD dwFlags
)
997 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
999 TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hHash
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1001 if (!hash
|| !pdwDataLen
)
1002 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1004 prov
= hash
->pProvider
;
1005 return prov
->pFuncs
->pCPGetHashParam(prov
->hPrivate
, hash
->hPrivate
, dwParam
,
1006 pbData
, pdwDataLen
, dwFlags
);
1009 /******************************************************************************
1010 * CryptGetKeyParam (ADVAPI32.@)
1012 BOOL WINAPI
CryptGetKeyParam (HCRYPTKEY hKey
, DWORD dwParam
, BYTE
*pbData
,
1013 DWORD
*pdwDataLen
, DWORD dwFlags
)
1016 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
1018 TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hKey
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1020 if (!key
|| !pdwDataLen
)
1021 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1023 prov
= key
->pProvider
;
1024 return prov
->pFuncs
->pCPGetKeyParam(prov
->hPrivate
, key
->hPrivate
, dwParam
,
1025 pbData
, pdwDataLen
, dwFlags
);
1028 /******************************************************************************
1029 * CryptGetProvParam (ADVAPI32.@)
1031 BOOL WINAPI
CryptGetProvParam (HCRYPTPROV hProv
, DWORD dwParam
, BYTE
*pbData
,
1032 DWORD
*pdwDataLen
, DWORD dwFlags
)
1034 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1036 TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hProv
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1038 return prov
->pFuncs
->pCPGetProvParam(prov
->hPrivate
, dwParam
, pbData
, pdwDataLen
, dwFlags
);
1041 /******************************************************************************
1042 * CryptGetUserKey (ADVAPI32.@)
1044 BOOL WINAPI
CryptGetUserKey (HCRYPTPROV hProv
, DWORD dwKeySpec
, HCRYPTKEY
*phUserKey
)
1046 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1049 TRACE("(0x%lx, %ld, %p)\n", hProv
, dwKeySpec
, phUserKey
);
1052 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
1054 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1055 if ( !(key
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
1056 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
1058 key
->pProvider
= prov
;
1060 if (prov
->pFuncs
->pCPGetUserKey(prov
->hPrivate
, dwKeySpec
, &key
->hPrivate
))
1062 *phUserKey
= (HCRYPTKEY
)key
;
1071 /******************************************************************************
1072 * CryptHashData (ADVAPI32.@)
1074 BOOL WINAPI
CryptHashData (HCRYPTHASH hHash
, BYTE
*pbData
, DWORD dwDataLen
, DWORD dwFlags
)
1076 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1079 TRACE("(0x%lx, %p, %ld, %08ld)\n", hHash
, pbData
, dwDataLen
, dwFlags
);
1082 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
1083 if (!pbData
|| !dwDataLen
)
1084 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1086 prov
= hash
->pProvider
;
1087 return prov
->pFuncs
->pCPHashData(prov
->hPrivate
, hash
->hPrivate
, pbData
, dwDataLen
, dwFlags
);
1090 /******************************************************************************
1091 * CryptHashSessionKey (ADVAPI32.@)
1093 BOOL WINAPI
CryptHashSessionKey (HCRYPTHASH hHash
, HCRYPTKEY hKey
, DWORD dwFlags
)
1095 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1096 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
1099 TRACE("(0x%lx, 0x%lx, %08ld)\n", hHash
, hKey
, dwFlags
);
1102 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
1104 prov
= hash
->pProvider
;
1105 return prov
->pFuncs
->pCPHashSessionKey(prov
->hPrivate
, hash
->hPrivate
, key
->hPrivate
, dwFlags
);
1108 /******************************************************************************
1109 * CryptImportKey (ADVAPI32.@)
1111 BOOL WINAPI
CryptImportKey (HCRYPTPROV hProv
, BYTE
*pbData
, DWORD dwDataLen
,
1112 HCRYPTKEY hPubKey
, DWORD dwFlags
, HCRYPTKEY
*phKey
)
1114 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1115 PCRYPTKEY pubkey
= (PCRYPTKEY
)hPubKey
, importkey
;
1117 TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld, %p)\n", hProv
, pbData
, dwDataLen
, hPubKey
, dwFlags
, phKey
);
1119 if (!prov
|| !pbData
|| !dwDataLen
|| !phKey
)
1120 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1122 if ( !(importkey
= CRYPT_Alloc(sizeof(CRYPTKEY
))) )
1123 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
1125 importkey
->pProvider
= prov
;
1126 if (prov
->pFuncs
->pCPImportKey(prov
->hPrivate
, pbData
, dwDataLen
,
1127 pubkey
? pubkey
->hPrivate
: 0, dwFlags
, &importkey
->hPrivate
))
1129 *phKey
= (HCRYPTKEY
)importkey
;
1133 CRYPT_Free(importkey
);
1137 /******************************************************************************
1140 * Note: Since the sDesciption (string) is supposed to be NULL and
1141 * is only retained for compatibility no string conversions are required
1142 * and only one implementation is required for both ANSI and Unicode.
1143 * We still need to export both:
1145 * CryptSignHashA (ADVAPI32.@)
1146 * CryptSignHashW (ADVAPI32.@)
1148 BOOL WINAPI
CryptSignHashA (HCRYPTHASH hHash
, DWORD dwKeySpec
, LPCSTR sDescription
,
1149 DWORD dwFlags
, BYTE
*pbSignature
, DWORD
*pdwSigLen
)
1151 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1154 TRACE("(0x%lx, %ld, %08ld, %p, %p)\n", hHash
, dwKeySpec
, dwFlags
, pbSignature
, pdwSigLen
);
1156 WARN("The sDescription parameter is not supported (and no longer used). Ignoring.\n");
1159 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
1161 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1163 prov
= hash
->pProvider
;
1164 return prov
->pFuncs
->pCPSignHash(prov
->hPrivate
, hash
->hPrivate
, dwKeySpec
, NULL
,
1165 dwFlags
, pbSignature
, pdwSigLen
);
1168 /******************************************************************************
1169 * CryptSetHashParam (ADVAPI32.@)
1171 BOOL WINAPI
CryptSetHashParam (HCRYPTHASH hHash
, DWORD dwParam
, BYTE
*pbData
, DWORD dwFlags
)
1174 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1176 TRACE("(0x%lx, %ld, %p, %08ld)\n", hHash
, dwParam
, pbData
, dwFlags
);
1178 if (!hash
|| !pbData
)
1179 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1181 prov
= hash
->pProvider
;
1182 return prov
->pFuncs
->pCPSetHashParam(prov
->hPrivate
, hash
->hPrivate
,
1183 dwParam
, pbData
, dwFlags
);
1186 /******************************************************************************
1187 * CryptSetKeyParam (ADVAPI32.@)
1189 BOOL WINAPI
CryptSetKeyParam (HCRYPTKEY hKey
, DWORD dwParam
, BYTE
*pbData
, DWORD dwFlags
)
1192 PCRYPTKEY key
= (PCRYPTKEY
)hKey
;
1194 TRACE("(0x%lx, %ld, %p, %08ld)\n", hKey
, dwParam
, pbData
, dwFlags
);
1196 if (!key
|| !pbData
)
1197 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1199 prov
= key
->pProvider
;
1200 return prov
->pFuncs
->pCPSetKeyParam(prov
->hPrivate
, key
->hPrivate
,
1201 dwParam
, pbData
, dwFlags
);
1204 /******************************************************************************
1205 * CryptSetProviderA (ADVAPI32.@)
1207 BOOL WINAPI
CryptSetProviderA (LPCSTR pszProvName
, DWORD dwProvType
)
1209 TRACE("(%s, %ld)\n", pszProvName
, dwProvType
);
1210 return CryptSetProviderExA(pszProvName
, dwProvType
, NULL
, CRYPT_USER_DEFAULT
);
1213 /******************************************************************************
1214 * CryptSetProviderW (ADVAPI32.@)
1216 BOOL WINAPI
CryptSetProviderW (LPCWSTR pszProvName
, DWORD dwProvType
)
1218 TRACE("(%s, %ld)\n", debugstr_w(pszProvName
), dwProvType
);
1219 return CryptSetProviderExW(pszProvName
, dwProvType
, NULL
, CRYPT_USER_DEFAULT
);
1222 /******************************************************************************
1223 * CryptSetProviderExA (ADVAPI32.@)
1225 BOOL WINAPI
CryptSetProviderExA (LPCSTR pszProvName
, DWORD dwProvType
, DWORD
*pdwReserved
, DWORD dwFlags
)
1230 TRACE("(%s, %ld, %p, %08ld)\n", pszProvName
, dwProvType
, pdwReserved
, dwFlags
);
1232 if (!pszProvName
|| pdwReserved
)
1233 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1234 if (dwProvType
> MAXPROVTYPES
)
1235 CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE
);
1236 if (dwFlags
& ~(CRYPT_MACHINE_DEFAULT
| CRYPT_USER_DEFAULT
| CRYPT_DELETE_DEFAULT
)
1237 || dwFlags
== CRYPT_DELETE_DEFAULT
)
1238 CRYPT_ReturnLastError(NTE_BAD_FLAGS
);
1240 if (dwFlags
& CRYPT_DELETE_DEFAULT
)
1242 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, dwFlags
& CRYPT_USER_DEFAULT
)) )
1243 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
1244 RegDeleteKeyA( (dwFlags
& CRYPT_USER_DEFAULT
) ? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
, keyname
);
1245 CRYPT_Free(keyname
);
1249 if ( !(keyname
= CRYPT_GetProvKeyName(pszProvName
)) )
1250 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
1251 if (RegOpenKeyA(HKEY_LOCAL_MACHINE
, keyname
, &hKey
))
1253 CRYPT_Free(keyname
);
1254 CRYPT_ReturnLastError(NTE_BAD_PROVIDER
);
1256 CRYPT_Free(keyname
);
1258 if ( !(keyname
= CRYPT_GetTypeKeyName(dwProvType
, dwFlags
& CRYPT_USER_DEFAULT
)) )
1259 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY
);
1260 RegCreateKeyA( (dwFlags
& CRYPT_USER_DEFAULT
) ? HKEY_CURRENT_USER
: HKEY_LOCAL_MACHINE
, keyname
, &hKey
);
1261 CRYPT_Free(keyname
);
1262 if (RegSetValueExA(hKey
, "Name", 0, REG_SZ
, pszProvName
, strlen(pszProvName
) +1))
1267 /******************************************************************************
1268 * CryptSetProviderExW (ADVAPI32.@)
1270 BOOL WINAPI
CryptSetProviderExW (LPCWSTR pszProvName
, DWORD dwProvType
, DWORD
*pdwReserved
, DWORD dwFlags
)
1275 TRACE("(%s, %ld, %p, %08ld)\n", debugstr_w(pszProvName
), dwProvType
, pdwReserved
, dwFlags
);
1277 if (CRYPT_UnicodeToANSI(pszProvName
, &str
, -1))
1279 ret
= CryptSetProviderExA(str
, dwProvType
, pdwReserved
, dwFlags
);
1285 /******************************************************************************
1286 * CryptSetProvParam (ADVAPI32.@)
1288 BOOL WINAPI
CryptSetProvParam (HCRYPTPROV hProv
, DWORD dwParam
, BYTE
*pbData
, DWORD dwFlags
)
1290 PCRYPTPROV prov
= (PCRYPTPROV
)hProv
;
1292 TRACE("(0x%lx, %ld, %p, %08ld)\n", hProv
, dwParam
, pbData
, dwFlags
);
1295 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
1296 if (dwFlags
& PP_USE_HARDWARE_RNG
)
1298 FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n");
1299 FIXME("\tLetting the CSP decide.\n");
1301 if (dwFlags
& PP_CLIENT_HWND
)
1303 /* FIXME: Should verify the parameter */
1304 if (pbData
/* && IsWindow((HWND)pbData) */)
1306 crypt_hWindow
= (HWND
)(pbData
);
1309 SetLastError(ERROR_INVALID_PARAMETER
);
1313 /* All other flags go to the CSP */
1314 return prov
->pFuncs
->pCPSetProvParam(prov
->hPrivate
, dwParam
, pbData
, dwFlags
);
1317 /******************************************************************************
1318 * CryptVerifySignatureA
1320 * Note: Since the sDesciption (string) is supposed to be NULL and
1321 * is only retained for compatibility no string conversions are required
1322 * and only one implementation is required for both ANSI and Unicode.
1323 * We still need to export both:
1325 * CryptVerifySignatureA (ADVAPI32.@)
1326 * CryptVerifySignatureW (ADVAPI32.@)
1328 BOOL WINAPI
CryptVerifySignatureA (HCRYPTHASH hHash
, BYTE
*pbSignature
, DWORD dwSigLen
,
1329 HCRYPTKEY hPubKey
, LPCSTR sDescription
, DWORD dwFlags
)
1331 PCRYPTHASH hash
= (PCRYPTHASH
)hHash
;
1332 PCRYPTKEY key
= (PCRYPTKEY
)hPubKey
;
1335 TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld)\n", hHash
, pbSignature
,
1336 dwSigLen
, hPubKey
, dwFlags
);
1338 WARN("The sDescription parameter is not supported (and no longer used). Ignoring.\n");
1341 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE
);
1342 if (!pbSignature
|| !dwSigLen
)
1343 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER
);
1345 prov
= hash
->pProvider
;
1346 return prov
->pFuncs
->pCPVerifySignature(prov
->hPrivate
, hash
->hPrivate
, pbSignature
, dwSigLen
,
1347 key
->hPrivate
, NULL
, dwFlags
);