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
35 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
41 HWND crypt_hWindow = 0;
43 #define CRYPT_ReturnLastError(err) {SetLastError(err); return FALSE;}
45 #define CRYPT_Alloc(size) ((LPVOID)LocalAlloc(LMEM_ZEROINIT, size))
46 #define CRYPT_Free(buffer) (LocalFree((HLOCAL)buffer))
48 static inline PSTR CRYPT_GetProvKeyName(PCSTR pProvName)
50 PCSTR KEYSTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\";
53 keyname = CRYPT_Alloc(strlen(KEYSTR) + strlen(pProvName) +1);
56 strcpy(keyname, KEYSTR);
57 strcpy(keyname + strlen(KEYSTR), pProvName);
59 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
63 static inline PSTR CRYPT_GetTypeKeyName(DWORD dwType, BOOL user)
65 PCSTR MACHINESTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
66 PCSTR USERSTR = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
70 keyname = CRYPT_Alloc( (user ? strlen(USERSTR) : strlen(MACHINESTR)) +1);
73 user ? strcpy(keyname, USERSTR) : strcpy(keyname, MACHINESTR);
74 ptr = keyname + strlen(keyname);
75 *(--ptr) = (dwType % 10) + '0';
76 *(--ptr) = ((dwType / 10) % 10) + '0';
77 *(--ptr) = (dwType / 100) + '0';
79 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
83 /* CRYPT_UnicodeTOANSI
84 * wstr - unicode string
85 * str - pointer to ANSI string
86 * strsize - size of buffer pointed to by str or -1 if we have to do the allocation
88 * returns TRUE if unsuccessfull, FALSE otherwise.
89 * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call
91 static inline BOOL CRYPT_UnicodeToANSI(LPCWSTR wstr, LPSTR* str, int strsize)
100 count = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
102 *str = CRYPT_Alloc(count * sizeof(CHAR));
104 count = min( count, strsize );
107 WideCharToMultiByte(CP_ACP, 0, wstr, -1, *str, count, NULL, NULL);
110 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
114 /* CRYPT_ANSITOUnicode
116 * wstr - pointer to unicode string
117 * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation
119 static inline BOOL CRYPT_ANSIToUnicode(LPCSTR str, LPWSTR* wstr, int wstrsize)
128 wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
130 *wstr = CRYPT_Alloc(wcount * sizeof(WCHAR));
132 wcount = min( wcount, wstrsize/sizeof(WCHAR) );
135 MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount);
138 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
142 /* These next 2 functions are used by the VTableProvStruc structure */
143 static BOOL CALLBACK CRYPT_VerifyImage(LPCSTR lpszImage, BYTE* pData)
145 if (!lpszImage || !pData)
147 SetLastError(ERROR_INVALID_PARAMETER);
151 FIXME("(%s, %p): not verifying image\n", lpszImage, pData);
156 static BOOL CALLBACK CRYPT_ReturnhWnd(HWND *phWnd)
160 *phWnd = crypt_hWindow;
164 #define CRYPT_GetProvFunc(name) \
165 if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error
166 #define CRYPT_GetProvFuncOpt(name) \
167 provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)
168 PCRYPTPROV CRYPT_LoadProvider(PSTR pImage)
171 DWORD errorcode = ERROR_NOT_ENOUGH_MEMORY;
173 if ( !(provider = CRYPT_Alloc(sizeof(CRYPTPROV))) ) goto error;
174 if ( !(provider->pFuncs = CRYPT_Alloc(sizeof(PROVFUNCS))) ) goto error;
175 if ( !(provider->pVTable = CRYPT_Alloc(sizeof(VTableProvStruc))) ) goto error;
176 if ( !(provider->hModule = LoadLibraryA(pImage)) )
178 errorcode = (GetLastError() == ERROR_FILE_NOT_FOUND) ? NTE_PROV_DLL_NOT_FOUND : NTE_PROVIDER_DLL_FAIL;
179 FIXME("Failed to load dll %s\n", debugstr_a(pImage));
182 provider->refcount = 1;
184 errorcode = NTE_PROVIDER_DLL_FAIL;
185 CRYPT_GetProvFunc(CPAcquireContext);
186 CRYPT_GetProvFunc(CPCreateHash);
187 CRYPT_GetProvFunc(CPDecrypt);
188 CRYPT_GetProvFunc(CPDeriveKey);
189 CRYPT_GetProvFunc(CPDestroyHash);
190 CRYPT_GetProvFunc(CPDestroyKey);
191 CRYPT_GetProvFuncOpt(CPDuplicateHash);
192 CRYPT_GetProvFuncOpt(CPDuplicateKey);
193 CRYPT_GetProvFunc(CPEncrypt);
194 CRYPT_GetProvFunc(CPExportKey);
195 CRYPT_GetProvFunc(CPGenKey);
196 CRYPT_GetProvFunc(CPGenRandom);
197 CRYPT_GetProvFunc(CPGetHashParam);
198 CRYPT_GetProvFunc(CPGetKeyParam);
199 CRYPT_GetProvFunc(CPGetProvParam);
200 CRYPT_GetProvFunc(CPGetUserKey);
201 CRYPT_GetProvFunc(CPHashData);
202 CRYPT_GetProvFunc(CPHashSessionKey);
203 CRYPT_GetProvFunc(CPImportKey);
204 CRYPT_GetProvFunc(CPReleaseContext);
205 CRYPT_GetProvFunc(CPSetHashParam);
206 CRYPT_GetProvFunc(CPSetKeyParam);
207 CRYPT_GetProvFunc(CPSetProvParam);
208 CRYPT_GetProvFunc(CPSignHash);
209 CRYPT_GetProvFunc(CPVerifySignature);
211 /* FIXME: Not sure what the pbContextInfo field is for.
212 * Does it need memory allocation?
214 provider->pVTable->Version = 3;
215 provider->pVTable->pFuncVerifyImage = (FARPROC)CRYPT_VerifyImage;
216 provider->pVTable->pFuncReturnhWnd = (FARPROC)CRYPT_ReturnhWnd;
217 provider->pVTable->dwProvType = 0;
218 provider->pVTable->pbContextInfo = NULL;
219 provider->pVTable->cbContextInfo = 0;
220 provider->pVTable->pszProvName = NULL;
224 SetLastError(errorcode);
227 if (provider->hModule)
228 FreeLibrary(provider->hModule);
229 CRYPT_Free(provider->pVTable);
230 CRYPT_Free(provider->pFuncs);
231 CRYPT_Free(provider);
235 #undef CRYPT_GetProvFunc
236 #undef CRYPT_GetProvFuncOpt
239 /******************************************************************************
240 * CryptAcquireContextA (ADVAPI32.@)
241 * Acquire a crypto provider context handle.
244 * phProv: Pointer to HCRYPTPROV for the output.
245 * pszContainer: Key Container Name
246 * pszProvider: Cryptographic Service Provider Name
247 * dwProvType: Crypto provider type to get a handle.
248 * dwFlags: flags for the operation
250 * RETURNS TRUE on success, FALSE on failure.
252 BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer,
253 LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
255 PCRYPTPROV pProv = NULL;
257 PSTR imagepath = NULL, keyname = NULL, provname = NULL, temp = NULL;
259 DWORD keytype, type, len;
262 TRACE("(%p, %s, %s, %ld, %08lx)\n", phProv, pszContainer,
263 pszProvider, dwProvType, dwFlags);
265 if (dwProvType < 1 || dwProvType > MAXPROVTYPES)
267 SetLastError(NTE_BAD_PROV_TYPE);
273 SetLastError(ERROR_INVALID_PARAMETER);
277 if (!pszProvider || !*pszProvider)
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 TRACE("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 TRACE("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 TRACE("Did not find registry entry of crypto provider for %s.\n", debugstr_a(keyname));
300 SetLastError(NTE_PROV_TYPE_NOT_DEF);
305 r = RegQueryValueExA(key, "Name", NULL, &keytype, NULL, &len);
306 if( r != ERROR_SUCCESS || !len || keytype != REG_SZ)
308 TRACE("error %ld reading size of 'Name' from registry\n", r );
310 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
313 if(!(provname = CRYPT_Alloc(len)))
316 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
319 r = RegQueryValueExA(key, "Name", NULL, NULL, provname, &len);
320 if( r != ERROR_SUCCESS )
322 TRACE("error %ld reading 'Name' from registry\n", r );
324 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
329 if ( !(provname = CRYPT_Alloc(strlen(pszProvider) +1)) )
331 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
334 strcpy(provname, pszProvider);
337 keyname = CRYPT_GetProvKeyName(provname);
338 r = RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key);
340 if (r != ERROR_SUCCESS)
342 SetLastError(NTE_KEYSET_NOT_DEF);
346 r = RegQueryValueExA(key, "Type", NULL, NULL, (BYTE*)&type, &len);
347 if (r != ERROR_SUCCESS)
349 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
352 if (type != dwProvType)
354 TRACE("Crypto provider has wrong type (%ld vs expected %ld).\n", type, dwProvType);
355 SetLastError(NTE_PROV_TYPE_NO_MATCH);
359 r = RegQueryValueExA(key, "Image Path", NULL, &keytype, NULL, &len);
360 if ( r != ERROR_SUCCESS || keytype != REG_SZ)
362 TRACE("error %ld reading size of 'Image Path' from registry\n", r );
364 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
367 if (!(temp = CRYPT_Alloc(len)))
370 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
373 r = RegQueryValueExA(key, "Image Path", NULL, NULL, temp, &len);
374 if( r != ERROR_SUCCESS )
376 TRACE("error %ld reading 'Image Path' from registry\n", r );
378 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
382 r = RegQueryValueExA(key, "Signature", NULL, &keytype, NULL, &len);
383 if ( r == ERROR_SUCCESS && keytype == REG_BINARY )
385 if (!(signature = CRYPT_Alloc(len)))
388 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
391 r = RegQueryValueExA(key, "Signature", NULL, NULL, signature, &len);
392 if ( r != ERROR_SUCCESS )
394 TRACE("error %ld reading 'Signature'\n", r );
395 CRYPT_Free(signature);
397 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
403 r = RegQueryValueExA(key, "SigInFile", NULL, &keytype, NULL, &len);
404 if (r != ERROR_SUCCESS)
406 TRACE("error %ld reading size of 'SigInFile'\n", r );
408 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
413 /* FIXME: The presence of the SigInFile value indicates the
414 * provider's signature is in its resources, so need to read it.
415 * But since CRYPT_VerifyImage is stubbed, provide any old thing
418 if (!(signature = CRYPT_Alloc(1)))
421 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
427 len = ExpandEnvironmentStringsA(temp, NULL, 0);
428 if ( !(imagepath = CRYPT_Alloc(len)) )
430 CRYPT_Free(signature);
431 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
434 if (!ExpandEnvironmentStringsA(temp, imagepath, len))
436 CRYPT_Free(signature);
437 /* ExpandEnvironmentStrings will call SetLastError */
441 if (!CRYPT_VerifyImage(imagepath, signature))
443 CRYPT_Free(signature);
444 SetLastError(NTE_SIGNATURE_FILE_BAD);
447 pProv = CRYPT_LoadProvider(imagepath);
448 CRYPT_Free(signature);
450 /* CRYPT_LoadProvider calls SetLastError */
453 pProv->pVTable->dwProvType = dwProvType;
454 pProv->pVTable->pszProvName = provname;
455 if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, (CHAR*)pszContainer, dwFlags, pProv->pVTable))
457 /* MSDN: When this flag is set, the value returned in phProv is undefined,
458 * and thus, the CryptReleaseContext function need not be called afterwards.
459 * Therefore, we must clean up everything now.
461 if (dwFlags & CRYPT_DELETEKEYSET)
463 FreeLibrary(pProv->hModule);
464 CRYPT_Free(provname);
465 CRYPT_Free(pProv->pFuncs);
468 *phProv = (HCRYPTPROV)pProv;
471 CRYPT_Free(imagepath);
474 /* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */
479 FreeLibrary(pProv->hModule);
481 CRYPT_Free(pProv->pVTable);
483 CRYPT_Free(pProv->pFuncs);
487 CRYPT_Free(provname);
491 CRYPT_Free(imagepath);
495 /******************************************************************************
496 * CryptAcquireContextW (ADVAPI32.@)
498 * see CryptAcquireContextA
500 BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer,
501 LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
503 PSTR pProvider = NULL, pContainer = NULL;
506 TRACE("(%p, %s, %s, %ld, %08lx)\n", phProv, debugstr_w(pszContainer),
507 debugstr_w(pszProvider), dwProvType, dwFlags);
509 if ( !CRYPT_UnicodeToANSI(pszContainer, &pContainer, -1) )
510 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
511 if ( !CRYPT_UnicodeToANSI(pszProvider, &pProvider, -1) )
513 CRYPT_Free(pContainer);
514 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
517 ret = CryptAcquireContextA(phProv, pContainer, pProvider, dwProvType, dwFlags);
520 CRYPT_Free(pContainer);
522 CRYPT_Free(pProvider);
527 /******************************************************************************
528 * CryptContextAddRef (ADVAPI32.@)
530 * Increases reference count of a cryptographic service provider handle
534 * hProv [I] Handle to the CSP whose reference is being incremented.
535 * pdwReserved [IN] Reserved for future use and must be NULL.
536 * dwFlags [I] Reserved for future use and must be NULL.
542 BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags)
544 PCRYPTPROV pProv = (PCRYPTPROV)hProv;
546 TRACE("(0x%lx, %p, %08lx)\n", hProv, pdwReserved, dwFlags);
550 SetLastError(NTE_BAD_UID);
558 /******************************************************************************
559 * CryptReleaseContext (ADVAPI32.@)
561 * Releases the handle of a CSP. Reference count is decreased.
564 * hProv [I] Handle of a CSP.
565 * dwFlags [I] Reserved for future use and must be NULL.
571 BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags)
573 PCRYPTPROV pProv = (PCRYPTPROV)hProv;
576 TRACE("(0x%lx, %08ld)\n", hProv, dwFlags);
580 SetLastError(NTE_BAD_UID);
585 if (pProv->refcount <= 0)
587 ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
588 FreeLibrary(pProv->hModule);
590 CRYPT_Free(pProv->pVTable->pContextInfo);
592 CRYPT_Free(pProv->pVTable->pszProvName);
593 CRYPT_Free(pProv->pVTable);
594 CRYPT_Free(pProv->pFuncs);
600 /******************************************************************************
601 * CryptGenRandom (ADVAPI32.@)
603 * Fills a buffer with cryptographically random bytes.
606 * hProv [I] Handle of a CSP.
607 * dwLen [I] Number of bytes to generate.
608 * pbBuffer [I/O] Buffer to contain random bytes.
615 * pdBuffer must be at least dwLen bytes long.
617 BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
619 PCRYPTPROV prov = (PCRYPTPROV)hProv;
621 TRACE("(0x%lx, %ld, %p)\n", hProv, dwLen, pbBuffer);
624 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
626 return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer);
629 /******************************************************************************
630 * CryptCreateHash (ADVAPI32.@)
632 * Initiates the hashing of a stream of data.
635 * hProv [I] Handle of a CSP.
636 * Algid [I] Identifies the hash algorithm to use.
637 * hKey [I] Key for the hash (if required).
638 * dwFlags [I] Reserved for future use and must be NULL.
639 * phHash [O] Address of the future handle to the new hash object.
646 * If the algorithm is a keyed hash, hKey is the key.
648 BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
649 DWORD dwFlags, HCRYPTHASH *phHash)
651 PCRYPTPROV prov = (PCRYPTPROV)hProv;
652 PCRYPTKEY key = (PCRYPTKEY)hKey;
655 TRACE("(0x%lx, 0x%x, 0x%lx, %08lx, %p)\n", hProv, Algid, hKey, dwFlags, phHash);
658 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
660 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
662 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
663 if ( !(hash = CRYPT_Alloc(sizeof(CRYPTHASH))) )
664 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
666 hash->pProvider = prov;
668 if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid,
669 key ? key->hPrivate : 0, 0, &hash->hPrivate))
671 *phHash = (HCRYPTHASH)hash;
681 /******************************************************************************
682 * CryptDecrypt (ADVAPI32.@)
684 * Decrypts data encrypted by CryptEncrypt.
687 * hKey [I] Handle to the decryption key.
688 * hHash [I] Handle to a hash object.
689 * Final [I] TRUE if this is the last section to be decrypted.
690 * dwFlags [I] Reserved for future use. Can be CRYPT_OAEP.
691 * pbData [I/O] Buffer that holds the encrypted data. Holds decrypted
693 * pdwDataLen [I/O] Length of pbData before and after the call.
699 BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
700 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
703 PCRYPTKEY key = (PCRYPTKEY)hKey;
704 PCRYPTHASH hash = (PCRYPTHASH)hHash;
706 TRACE("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
708 if (!key || !pbData || !pdwDataLen)
709 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
711 prov = key->pProvider;
712 return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
713 Final, dwFlags, pbData, pdwDataLen);
716 /******************************************************************************
717 * CryptDeriveKey (ADVAPI32.@)
719 * Generates session keys derived from a base data value.
722 * hProv [I] Handle to a CSP.
723 * Algid [I] Identifies the symmetric encryption algorithm to use.
724 * hBaseData [I] Handle to a hash object.
725 * dwFlags [I] Type of key to generate.
726 * phKey [I/O] Address of the newly generated key.
732 BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData,
733 DWORD dwFlags, HCRYPTKEY *phKey)
735 PCRYPTPROV prov = (PCRYPTPROV)hProv;
736 PCRYPTHASH hash = (PCRYPTHASH)hBaseData;
739 TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08lx, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey);
742 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
744 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
745 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
746 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
748 key->pProvider = prov;
749 if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate))
751 *phKey = (HCRYPTKEY)key;
761 /******************************************************************************
762 * CryptDestroyHash (ADVAPI32.@)
764 * Destroys the hash object referenced by hHash.
767 * hHash [I] Handle of the hash object to be destroyed.
773 BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash)
775 PCRYPTHASH hash = (PCRYPTHASH)hHash;
779 TRACE("(0x%lx)\n", hHash);
782 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
784 prov = hash->pProvider;
785 ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate);
790 /******************************************************************************
791 * CryptDestroyKey (ADVAPI32.@)
793 * Releases the handle referenced by hKey.
796 * hKey [I] Handle of the key to be destroyed.
802 BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey)
804 PCRYPTKEY key = (PCRYPTKEY)hKey;
808 TRACE("(0x%lx)\n", hKey);
811 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
813 prov = key->pProvider;
814 ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate);
819 /******************************************************************************
820 * CryptDuplicateHash (ADVAPI32.@)
825 * hHash [I] Handle to the hash to be copied.
826 * pdwReserved [I] Reserved for future use and must be zero.
827 * dwFlags [I] Reserved for future use and must be zero.
828 * phHash [O] Address of the handle to receive the copy.
834 BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved,
835 DWORD dwFlags, HCRYPTHASH *phHash)
838 PCRYPTHASH orghash, newhash;
840 TRACE("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash);
842 orghash = (PCRYPTHASH)hHash;
843 if (!orghash || pdwReserved || !phHash)
844 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
846 prov = orghash->pProvider;
847 if (!prov->pFuncs->pCPDuplicateHash)
848 CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
850 if ( !(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))) )
851 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
853 newhash->pProvider = prov;
854 if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate))
856 *phHash = (HCRYPTHASH)newhash;
863 /******************************************************************************
864 * CryptDuplicateKey (ADVAPI32.@)
866 * Duplicate a key and the key's state.
869 * hKey [I] Handle of the key to copy.
870 * pdwReserved [I] Reserved for future use and must be NULL.
871 * dwFlags [I] Reserved for future use and must be zero.
872 * phKey [I] Address of the handle to the duplicated key.
878 BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
881 PCRYPTKEY orgkey, newkey;
883 TRACE("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey);
885 orgkey = (PCRYPTKEY)hKey;
886 if (!orgkey || pdwReserved || !phKey)
887 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
889 prov = orgkey->pProvider;
890 if (!prov->pFuncs->pCPDuplicateKey)
891 CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
893 if ( !(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))) )
894 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
896 newkey->pProvider = prov;
897 if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate))
899 *phKey = (HCRYPTKEY)newkey;
906 /******************************************************************************
907 * CryptEncrypt (ADVAPI32.@)
912 * hKey [I] Handle to the enryption key.
913 * hHash [I] Handle to a hash object.
914 * Final [I] TRUE if this is the last section to encrypt.
915 * dwFlags [I] Can be CRYPT_OAEP.
916 * pbData [I/O] Data to be encrypted. Contains encrypted data after call.
917 * pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the
918 * encrypted data after call.
919 * dwBufLen [I] Length of the input pbData buffer.
926 * If pbData is NULL, CryptEncrypt determines stores the number of bytes
927 * required for the returned data in pdwDataLen.
929 BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
930 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
933 PCRYPTKEY key = (PCRYPTKEY)hKey;
934 PCRYPTHASH hash = (PCRYPTHASH)hHash;
936 TRACE("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
938 if (!key || !pdwDataLen)
939 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
941 prov = key->pProvider;
942 return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
943 Final, dwFlags, pbData, pdwDataLen, dwBufLen);
946 /******************************************************************************
947 * CryptEnumProvidersW (ADVAPI32.@)
949 * Returns the next availabe CSP.
952 * dwIndex [I] Index of the next provider to be enumerated.
953 * pdwReserved [I] Reserved for future use and must be NULL.
954 * dwFlags [I] Reserved for future use and must be zero.
955 * pdwProvType [O] DWORD designating the type of the provider.
956 * pszProvName [O] Buffer that receives data from the provider.
957 * pcbProvName [I/O] Specifies the size of pszProvName. Contains the number
958 * of bytes stored in the buffer on return.
965 * If pszProvName is NULL, CryptEnumProvidersW sets the size of the name
966 * for memory allocation purposes.
968 BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved,
969 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName)
973 static const WCHAR providerW[] = {
974 'S','o','f','t','w','a','r','e','\\',
975 'M','i','c','r','o','s','o','f','t','\\',
976 'C','r','y','p','t','o','g','r','a','p','h','y','\\',
977 'D','e','f','a','u','l','t','s','\\',
978 'P','r','o','v','i','d','e','r',0
981 static const WCHAR typeW[] = {'T','y','p','e',0};
983 TRACE("(%ld, %p, %ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
984 pdwProvType, pszProvName, pcbProvName);
986 if (pdwReserved || !pcbProvName) CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
987 if (dwFlags) CRYPT_ReturnLastError(NTE_BAD_FLAGS);
989 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, providerW, &hKey))
990 CRYPT_ReturnLastError(NTE_FAIL);
997 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, pcbProvName,
998 NULL, NULL, NULL, NULL, NULL, NULL);
1000 if (!(provNameW = CRYPT_Alloc(*pcbProvName * sizeof(WCHAR))))
1001 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1003 RegEnumKeyExW(hKey, dwIndex, provNameW, pcbProvName, NULL, NULL, NULL, NULL);
1005 *pcbProvName *= sizeof(WCHAR);
1007 CRYPT_Free(provNameW);
1009 if (dwIndex >= numkeys)
1010 CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS);
1012 DWORD size = sizeof(DWORD);
1016 result = RegEnumKeyW(hKey, dwIndex, pszProvName, *pcbProvName / sizeof(WCHAR));
1018 CRYPT_ReturnLastError(result);
1019 if (RegOpenKeyW(hKey, pszProvName, &subkey))
1021 if (RegQueryValueExW(subkey, typeW, NULL, NULL, (BYTE*)pdwProvType, &size))
1023 RegCloseKey(subkey);
1029 /******************************************************************************
1030 * CryptEnumProvidersA (ADVAPI32.@)
1032 * see CryptEnumProvidersW
1034 BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved,
1035 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName)
1039 BOOL ret; /* = FALSE; */
1041 TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
1042 pdwProvType, pszProvName, pcbProvName);
1044 strlen = *pcbProvName * sizeof(WCHAR);
1045 if ( pszProvName && !(str = CRYPT_Alloc(strlen)) )
1046 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1047 ret = CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &strlen);
1050 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName);
1053 *pcbProvName = strlen / sizeof(WCHAR); /* FIXME: not correct */
1057 /******************************************************************************
1058 * CryptEnumProviderTypesA (ADVAPI32i.@)
1060 * Retrieves the next type of CSP supported.
1063 * dwIndex [I] Index of the next provider to be enumerated.
1064 * pdwReserved [I] Reserved for future use and must be NULL.
1065 * dwFlags [I] Reserved for future use and must be zero.
1066 * pdwProvType [O] DWORD designating the type of the provider.
1067 * pszTypeName [O] Buffer that receives data from the provider type.
1068 * pcbTypeName [I/O] Specifies the size of pszTypeName. Contains the number
1069 * of bytes stored in the buffer on return.
1076 * If pszTypeName is NULL, CryptEnumProviderTypesA sets the size of the name
1077 * for memory allocation purposes.
1079 BOOL WINAPI CryptEnumProviderTypesA (DWORD dwIndex, DWORD *pdwReserved,
1080 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszTypeName, DWORD *pcbTypeName)
1083 DWORD keylen, numkeys, dwType;
1087 TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved,
1088 dwFlags, pdwProvType, pszTypeName, pcbTypeName);
1090 if (pdwReserved || !pdwProvType || !pcbTypeName)
1091 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1092 if (dwFlags) CRYPT_ReturnLastError(NTE_BAD_FLAGS);
1094 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
1097 RegQueryInfoKeyA(hKey, NULL, NULL, NULL, &numkeys, &keylen, NULL, NULL, NULL, NULL, NULL, NULL);
1098 if (dwIndex >= numkeys)
1099 CRYPT_ReturnLastError(ERROR_NO_MORE_ITEMS);
1101 if ( !(keyname = CRYPT_Alloc(keylen)) )
1102 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1103 if ( RegEnumKeyA(hKey, dwIndex, keyname, keylen) ) {
1104 CRYPT_Free(keyname);
1107 RegOpenKeyA(hKey, keyname, &hSubkey);
1108 ch = keyname + strlen(keyname);
1109 /* Convert "Type 000" to 0, etc/ */
1110 *pdwProvType = *(--ch) - '0';
1111 *pdwProvType += (*(--ch) - '0') * 10;
1112 *pdwProvType += (*(--ch) - '0') * 100;
1113 CRYPT_Free(keyname);
1115 result = RegQueryValueExA(hSubkey, "TypeName", NULL, &dwType, pszTypeName, pcbTypeName);
1117 CRYPT_ReturnLastError(result);
1119 RegCloseKey(hSubkey);
1124 /******************************************************************************
1125 * CryptEnumProviderTypesW (ADVAPI32.@)
1127 * see CryptEnumProviderTypesA
1129 BOOL WINAPI CryptEnumProviderTypesW (DWORD dwIndex, DWORD *pdwReserved,
1130 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszTypeName, DWORD *pcbTypeName)
1136 TRACE("(%ld, %p, %08ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
1137 pdwProvType, pszTypeName, pcbTypeName);
1138 strlen = *pcbTypeName / sizeof(WCHAR);
1139 if ( pszTypeName && !(str = CRYPT_Alloc(strlen)) )
1140 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1141 ret = CryptEnumProviderTypesA(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &strlen);
1144 CRYPT_ANSIToUnicode(str, &pszTypeName, *pcbTypeName);
1147 *pcbTypeName = strlen * sizeof(WCHAR);
1151 /******************************************************************************
1152 * CryptExportKey (ADVAPI32.@)
1154 * Exports a cryptographic key from a CSP.
1157 * hKey [I] Handle to the key to export.
1158 * hExpKey [I] Handle to a cryptographic key of the end user.
1159 * dwBlobType [I] Type of BLOB to be exported.
1160 * dwFlags [I] CRYPT_DESTROYKEY/SSL2_FALLBACK/OAEP.
1161 * pbData [O] Buffer to receive BLOB data.
1162 * pdwDataLen [I/O] Specifies the size of pbData.
1169 * if pbData is NULL, CryptExportKey sets pdwDataLen as the size of the
1170 * buffer needed to hold the BLOB.
1172 BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType,
1173 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
1176 PCRYPTKEY key = (PCRYPTKEY)hKey, expkey = (PCRYPTKEY)hExpKey;
1178 TRACE("(0x%lx, 0x%lx, %ld, %08ld, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen);
1180 if (!key || !pdwDataLen)
1181 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1183 prov = key->pProvider;
1184 return prov->pFuncs->pCPExportKey(prov->hPrivate, key->hPrivate, expkey ? expkey->hPrivate : 0,
1185 dwBlobType, dwFlags, pbData, pdwDataLen);
1188 /******************************************************************************
1189 * CryptGenKey (ADVAPI32.@)
1191 * Generates a random cryptographic session key or a pub/priv key pair.
1194 * hProv [I] Handle to a CSP.
1195 * Algid [I] Algorithm to use to make key.
1196 * dwFlags [I] Specifies type of key to make.
1197 * phKey [I] Address of the handle to which the new key is copied.
1203 BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey)
1205 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1208 TRACE("(0x%lx, %d, %08ld, %p)\n", hProv, Algid, dwFlags, phKey);
1211 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1213 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1214 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
1215 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1217 key->pProvider = prov;
1219 if (prov->pFuncs->pCPGenKey(prov->hPrivate, Algid, dwFlags, &key->hPrivate))
1221 *phKey = (HCRYPTKEY)key;
1230 /******************************************************************************
1231 * CryptGetDefaultProviderA (ADVAPI32.@)
1233 * Finds the default CSP of a certain provider type.
1236 * dwProvType [I] Provider type to look for.
1237 * pdwReserved [I] Reserved for future use and must be NULL.
1238 * dwFlags [I] CRYPT_MACHINE_DEFAULT/USER_DEFAULT
1239 * pszProvName [O] Name of the default CSP.
1240 * pcbProvName [I/O] Size of pszProvName
1247 * If pszProvName is NULL, pcbProvName will hold the size of the buffer for
1248 * memory allocation purposes on return.
1250 BOOL WINAPI CryptGetDefaultProviderA (DWORD dwProvType, DWORD *pdwReserved,
1251 DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName)
1257 if (pdwReserved || !pcbProvName)
1258 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1259 if (dwFlags & ~(CRYPT_USER_DEFAULT | CRYPT_MACHINE_DEFAULT))
1260 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
1261 if (dwProvType > 999)
1262 CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE);
1263 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) )
1264 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1265 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))
1267 CRYPT_Free(keyname);
1268 CRYPT_ReturnLastError(NTE_PROV_TYPE_NOT_DEF);
1270 CRYPT_Free(keyname);
1272 result = RegQueryValueExA(hKey, "Name", NULL, NULL, pszProvName, pcbProvName);
1275 if (result != ERROR_MORE_DATA)
1276 SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
1278 SetLastError(result);
1287 /******************************************************************************
1288 * CryptGetDefaultProviderW (ADVAPI32.@)
1290 * see CryptGetDefaultProviderA
1292 BOOL WINAPI CryptGetDefaultProviderW (DWORD dwProvType, DWORD *pdwReserved,
1293 DWORD dwFlags, LPWSTR pszProvName, DWORD *pcbProvName)
1299 TRACE("(%ld, %p, %08ld, %p, %p)\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName);
1301 strlen = *pcbProvName / sizeof(WCHAR);
1302 if ( pszProvName && !(str = CRYPT_Alloc(strlen)) )
1303 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1304 ret = CryptGetDefaultProviderA(dwProvType, pdwReserved, dwFlags, str, &strlen);
1307 CRYPT_ANSIToUnicode(str, &pszProvName, *pcbProvName);
1310 *pcbProvName = strlen * sizeof(WCHAR);
1314 /******************************************************************************
1315 * CryptGetHashParam (ADVAPI32.@)
1317 * Retrieves data that controls the operations of a hash object.
1320 * hHash [I] Handle of the hash object to question.
1321 * dwParam [I] Query type.
1322 * pbData [O] Buffer that receives the value data.
1323 * pdwDataLen [I/O] Size of the pbData buffer.
1324 * dwFlags [I] Reserved for future use and must be zero.
1331 * If pbData is NULL, pdwDataLen will contain the length required.
1333 BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData,
1334 DWORD *pdwDataLen, DWORD dwFlags)
1337 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1339 TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags);
1341 if (!hash || !pdwDataLen)
1342 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1344 prov = hash->pProvider;
1345 return prov->pFuncs->pCPGetHashParam(prov->hPrivate, hash->hPrivate, dwParam,
1346 pbData, pdwDataLen, dwFlags);
1349 /******************************************************************************
1350 * CryptGetKeyParam (ADVAPI32.@)
1352 * Retrieves data that controls the operations of a key.
1355 * hKey [I] Handle to they key in question.
1356 * dwParam [I] Specifies query type.
1357 * pbData [O] Sequence of bytes to receive data.
1358 * pdwDataLen [I/O] Size of pbData.
1359 * dwFlags [I] Reserved for future use and must be zero.
1366 * If pbData is NULL, pdwDataLen is set to the needed length of the buffer.
1368 BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData,
1369 DWORD *pdwDataLen, DWORD dwFlags)
1372 PCRYPTKEY key = (PCRYPTKEY)hKey;
1374 TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags);
1376 if (!key || !pdwDataLen)
1377 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1379 prov = key->pProvider;
1380 return prov->pFuncs->pCPGetKeyParam(prov->hPrivate, key->hPrivate, dwParam,
1381 pbData, pdwDataLen, dwFlags);
1384 /******************************************************************************
1385 * CryptGetProvParam (ADVAPI32.@)
1387 * Retrieves parameters that control the operations of a CSP.
1390 * hProv [I] Handle of the CSP in question.
1391 * dwParam [I] Specifies query type.
1392 * pbData [O] Buffer to receive the data.
1393 * pdwDataLen [I/O] Size of pbData.
1394 * dwFlags [I] see MSDN Docs.
1401 * If pbData is NULL, pdwDataLen is set to the needed buffer length.
1403 BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
1404 DWORD *pdwDataLen, DWORD dwFlags)
1406 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1408 TRACE("(0x%lx, %ld, %p, %p, %08ld)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags);
1410 return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags);
1413 /******************************************************************************
1414 * CryptGetUserKey (ADVAPI32.@)
1416 * Gets a handle of one of a user's two public/private key pairs.
1419 * hProv [I] Handle of a CSP.
1420 * dwKeySpec [I] Private key to use.
1421 * phUserKey [O] Pointer to the handle of the retrieved keys.
1427 BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey)
1429 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1432 TRACE("(0x%lx, %ld, %p)\n", hProv, dwKeySpec, phUserKey);
1435 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1437 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1438 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) )
1439 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1441 key->pProvider = prov;
1443 if (prov->pFuncs->pCPGetUserKey(prov->hPrivate, dwKeySpec, &key->hPrivate))
1445 *phUserKey = (HCRYPTKEY)key;
1455 /******************************************************************************
1456 * CryptHashData (ADVAPI32.@)
1458 * Adds data to a hash object.
1461 * hHash [I] Handle of the hash object.
1462 * pbData [I] Buffer of data to be hashed.
1463 * dwDataLen [I] Number of bytes to add.
1464 * dwFlags [I] Can be CRYPT_USERDATA
1470 BOOL WINAPI CryptHashData (HCRYPTHASH hHash, BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
1472 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1475 TRACE("(0x%lx, %p, %ld, %08ld)\n", hHash, pbData, dwDataLen, dwFlags);
1478 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1479 if (!pbData || !dwDataLen)
1480 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1482 prov = hash->pProvider;
1483 return prov->pFuncs->pCPHashData(prov->hPrivate, hash->hPrivate, pbData, dwDataLen, dwFlags);
1486 /******************************************************************************
1487 * CryptHashSessionKey (ADVAPI32.@)
1490 * hHash [I] Handle to the hash object.
1491 * hKey [I] Handle to the key to be hashed.
1492 * dwFlags [I] Can be CRYPT_LITTLE_ENDIAN.
1498 BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags)
1500 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1501 PCRYPTKEY key = (PCRYPTKEY)hKey;
1504 TRACE("(0x%lx, 0x%lx, %08ld)\n", hHash, hKey, dwFlags);
1507 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1509 prov = hash->pProvider;
1510 return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags);
1513 /******************************************************************************
1514 * CryptImportKey (ADVAPI32.@)
1517 * hProv [I] Handle of a CSP.
1518 * pbData [I] Contains the key to be imported.
1519 * dwDataLen [I] Length of the key.
1520 * hPubKey [I] Cryptographic key that decrypts pdData
1521 * dwFlags [I] Used only with a public/private key pair.
1522 * phKey [O] Imported key.
1528 BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, BYTE *pbData, DWORD dwDataLen,
1529 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
1531 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1532 PCRYPTKEY pubkey = (PCRYPTKEY)hPubKey, importkey;
1534 TRACE("(0x%lx, %p, %ld, 0x%lx, %08ld, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
1536 if (!prov || !pbData || !dwDataLen || !phKey)
1537 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1539 if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) )
1540 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1542 importkey->pProvider = prov;
1543 if (prov->pFuncs->pCPImportKey(prov->hPrivate, pbData, dwDataLen,
1544 pubkey ? pubkey->hPrivate : 0, dwFlags, &importkey->hPrivate))
1546 *phKey = (HCRYPTKEY)importkey;
1550 CRYPT_Free(importkey);
1554 /******************************************************************************
1555 * CryptSignHashW (ADVAPI32.@)
1560 * hHash [I] Handle of the hash object to be signed.
1561 * dwKeySpec [I] Private key to use.
1562 * sDescription [I] Should be NULL.
1563 * dwFlags [I] CRYPT_NOHASHOID/X931_FORMAT.
1564 * pbSignature [O] Buffer of the signature data.
1565 * pdwSigLen [I/O] Size of the pbSignature buffer.
1572 * Because of security flaws sDescription should not be used and should thus be
1573 * NULL. It is supported only for compatibility with Microsoft's Cryptographic
1576 BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription,
1577 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
1579 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1582 TRACE("(0x%lx, %ld, %s, %08ld, %p, %p)\n",
1583 hHash, dwKeySpec, debugstr_w(sDescription), dwFlags, pbSignature, pdwSigLen);
1586 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1588 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1590 prov = hash->pProvider;
1591 return prov->pFuncs->pCPSignHash(prov->hPrivate, hash->hPrivate, dwKeySpec, sDescription,
1592 dwFlags, pbSignature, pdwSigLen);
1595 /******************************************************************************
1596 * CryptSignHashA (ADVAPI32.@)
1598 * ASCII version of CryptSignHashW
1600 BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription,
1601 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen)
1603 LPWSTR wsDescription;
1606 TRACE("(0x%lx, %ld, %s, %08ld, %p, %p)\n",
1607 hHash, dwKeySpec, debugstr_a(sDescription), dwFlags, pbSignature, pdwSigLen);
1609 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1);
1610 result = CryptSignHashW(hHash, dwKeySpec, wsDescription, dwFlags, pbSignature, pdwSigLen);
1611 if (wsDescription) CRYPT_Free(wsDescription);
1616 /******************************************************************************
1617 * CryptSetHashParam (ADVAPI32.@)
1619 * Customizes the operations of a hash object.
1622 * hHash [I] Handle of the hash object to set parameters.
1623 * dwParam [I] HP_HMAC_INFO/HASHVAL.
1624 * pbData [I] Value data buffer.
1625 * dwFlags [I] Reserved for future use and must be zero.
1631 BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
1634 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1636 TRACE("(0x%lx, %ld, %p, %08ld)\n", hHash, dwParam, pbData, dwFlags);
1638 if (!hash || !pbData)
1639 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1641 prov = hash->pProvider;
1642 return prov->pFuncs->pCPSetHashParam(prov->hPrivate, hash->hPrivate,
1643 dwParam, pbData, dwFlags);
1646 /******************************************************************************
1647 * CryptSetKeyParam (ADVAPI32.@)
1649 * Customizes a session key's operations.
1652 * hKey [I] Handle to the key to set values.
1653 * dwParam [I] See MSDN Doc.
1654 * pbData [I] Buffer of values to set.
1655 * dwFlags [I] Only used when dwParam == KP_ALGID.
1661 BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
1664 PCRYPTKEY key = (PCRYPTKEY)hKey;
1666 TRACE("(0x%lx, %ld, %p, %08ld)\n", hKey, dwParam, pbData, dwFlags);
1668 if (!key || !pbData)
1669 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1671 prov = key->pProvider;
1672 return prov->pFuncs->pCPSetKeyParam(prov->hPrivate, key->hPrivate,
1673 dwParam, pbData, dwFlags);
1676 /******************************************************************************
1677 * CryptSetProviderA (ADVAPI32.@)
1679 * Specifies the current user's default CSP.
1682 * pszProvName [I] Name of the new default CSP.
1683 * dwProvType [I] Provider type of the CSP.
1689 BOOL WINAPI CryptSetProviderA (LPCSTR pszProvName, DWORD dwProvType)
1691 TRACE("(%s, %ld)\n", pszProvName, dwProvType);
1692 return CryptSetProviderExA(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT);
1695 /******************************************************************************
1696 * CryptSetProviderW (ADVAPI32.@)
1698 * See CryptSetProviderA
1700 BOOL WINAPI CryptSetProviderW (LPCWSTR pszProvName, DWORD dwProvType)
1702 TRACE("(%s, %ld)\n", debugstr_w(pszProvName), dwProvType);
1703 return CryptSetProviderExW(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT);
1706 /******************************************************************************
1707 * CryptSetProviderExA (ADVAPI32.@)
1709 * Specifies the default CSP.
1712 * pszProvName [I] Name of the new default CSP.
1713 * dwProvType [I] Provider type of the CSP.
1714 * pdwReserved [I] Reserved for future use and must be NULL.
1715 * dwFlags [I] See MSDN Doc.
1721 BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags)
1723 HKEY hProvKey, hTypeKey;
1726 TRACE("(%s, %ld, %p, %08ld)\n", pszProvName, dwProvType, pdwReserved, dwFlags);
1728 if (!pszProvName || pdwReserved)
1729 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1730 if (dwProvType > MAXPROVTYPES)
1731 CRYPT_ReturnLastError(NTE_BAD_PROV_TYPE);
1732 if (dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT)
1733 || dwFlags == CRYPT_DELETE_DEFAULT)
1734 CRYPT_ReturnLastError(NTE_BAD_FLAGS);
1736 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)))
1737 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1738 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
1739 keyname, &hTypeKey))
1741 CRYPT_Free(keyname);
1742 CRYPT_ReturnLastError(NTE_BAD_PROVIDER);
1744 CRYPT_Free(keyname);
1746 if (dwFlags & CRYPT_DELETE_DEFAULT)
1748 RegDeleteValueA(hTypeKey, "Name");
1752 if (!(keyname = CRYPT_GetProvKeyName(pszProvName)))
1754 RegCloseKey(hTypeKey);
1755 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
1757 if (RegOpenKeyA((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE,
1758 keyname, &hProvKey))
1760 CRYPT_Free(keyname);
1761 RegCloseKey(hTypeKey);
1762 CRYPT_ReturnLastError(NTE_BAD_PROVIDER);
1764 CRYPT_Free(keyname);
1766 if (RegSetValueExA(hTypeKey, "Name", 0, REG_SZ, pszProvName, strlen(pszProvName) + 1))
1768 RegCloseKey(hTypeKey);
1769 RegCloseKey(hProvKey);
1773 RegCloseKey(hProvKey);
1775 RegCloseKey(hTypeKey);
1780 /******************************************************************************
1781 * CryptSetProviderExW (ADVAPI32.@)
1783 * See CryptSetProviderExA
1785 BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags)
1790 TRACE("(%s, %ld, %p, %08ld)\n", debugstr_w(pszProvName), dwProvType, pdwReserved, dwFlags);
1792 if (CRYPT_UnicodeToANSI(pszProvName, &str, -1))
1794 ret = CryptSetProviderExA(str, dwProvType, pdwReserved, dwFlags);
1800 /******************************************************************************
1801 * CryptSetProvParam (ADVAPI32.@)
1803 * Customizes the operations of a CSP.
1806 * hProv [I] Handle of a CSP.
1807 * dwParam [I] See MSDN Doc.
1808 * pbData [I] Buffer that contains a value to set as a parameter.
1809 * dwFlags [I] if dwParam is PP_USE_HARDWARE_RNG, dwFlags must be zero.
1815 BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
1817 PCRYPTPROV prov = (PCRYPTPROV)hProv;
1819 TRACE("(0x%lx, %ld, %p, %08ld)\n", hProv, dwParam, pbData, dwFlags);
1822 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1823 if (dwFlags & PP_USE_HARDWARE_RNG)
1825 FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n");
1826 FIXME("\tLetting the CSP decide.\n");
1828 if (dwFlags & PP_CLIENT_HWND)
1830 /* FIXME: Should verify the parameter */
1831 if (pbData /* && IsWindow((HWND)pbData) */)
1833 crypt_hWindow = (HWND)(pbData);
1836 SetLastError(ERROR_INVALID_PARAMETER);
1840 /* All other flags go to the CSP */
1841 return prov->pFuncs->pCPSetProvParam(prov->hPrivate, dwParam, pbData, dwFlags);
1844 /******************************************************************************
1845 * CryptVerifySignatureW (ADVAPI32.@)
1847 * Verifies the signature of a hash object.
1850 * hHash [I] Handle of the hash object to verify.
1851 * pbSignature [I] Signature data to verify.
1852 * dwSigLen [I] Size of pbSignature.
1853 * hPubKey [I] Handle to the public key to authenticate signature.
1854 * sDescription [I] Should be NULL.
1855 * dwFlags [I] See MSDN doc.
1862 * Because of security flaws sDescription should not be used and should thus be
1863 * NULL. It is supported only for compatibility with Microsoft's Cryptographic
1866 BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen,
1867 HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags)
1869 PCRYPTHASH hash = (PCRYPTHASH)hHash;
1870 PCRYPTKEY key = (PCRYPTKEY)hPubKey;
1873 TRACE("(0x%lx, %p, %ld, 0x%lx, %s, %08ld)\n", hHash, pbSignature,
1874 dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags);
1877 CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
1878 if (!pbSignature || !dwSigLen)
1879 CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
1881 prov = hash->pProvider;
1882 return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen,
1883 key->hPrivate, sDescription, dwFlags);
1886 /******************************************************************************
1887 * CryptVerifySignatureA (ADVAPI32.@)
1889 * ASCII version of CryptVerifySignatureW
1891 BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dwSigLen,
1892 HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags)
1894 LPWSTR wsDescription;
1897 TRACE("(0x%lx, %p, %ld, 0x%lx, %s, %08ld)\n", hHash, pbSignature,
1898 dwSigLen, hPubKey, debugstr_a(sDescription), dwFlags);
1900 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1);
1901 result = CryptVerifySignatureW(hHash, pbSignature, dwSigLen, hPubKey, wsDescription, dwFlags);
1902 if (wsDescription) CRYPT_Free(wsDescription);
1908 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
1912 /******************************************************************************
1913 * SystemFunction040 (ADVAPI32.@)
1916 * memory [I/O] Pointer to memory to encrypt.
1917 * length [I] Length of region to encrypt in bytes.
1918 * flags [I] Control whether other processes are able to decrypt the memory.
1919 * RTL_ENCRYPT_OPTION_SAME_PROCESS
1920 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
1921 * RTL_ENCRYPT_OPTION_SAME_LOGON
1924 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
1925 * If flags are specified when encrypting, the same flag value must be given
1926 * when decrypting the memory.
1928 NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags) /* RtlEncryptMemory */
1930 FIXME("(%p, %lx, %lx): stub [RtlEncryptMemory]\n", memory, length, flags);
1931 return STATUS_SUCCESS;
1934 /******************************************************************************
1935 * SystemFunction041 (ADVAPI32.@)
1938 * memory [I/O] Pointer to memory to decrypt.
1939 * length [I] Length of region to decrypt in bytes.
1940 * flags [I] Control whether other processes are able to decrypt the memory.
1941 * RTL_ENCRYPT_OPTION_SAME_PROCESS
1942 * RTL_ENCRYPT_OPTION_CROSS_PROCESS
1943 * RTL_ENCRYPT_OPTION_SAME_LOGON
1946 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE.
1947 * If flags are specified when encrypting, the same flag value must be given
1948 * when decrypting the memory.
1950 NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags) /* RtlDecryptMemory */
1952 FIXME("(%p, %lx, %lx): stub [RtlDecryptMemory]\n", memory, length, flags);
1953 return STATUS_SUCCESS;