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