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