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 NULL. 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 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 NULL. 643 * 644 * RETURNS 645 * Success: TRUE 646 * Failure: FALSE 647 */ 648 #ifdef __REACTOS__ 649 BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags) 650 #else 651 BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, ULONG_PTR dwFlags) 652 #endif 653 { 654 PCRYPTPROV pProv = (PCRYPTPROV)hProv; 655 BOOL ret = TRUE; 656 657 TRACE("(0x%lx, %08lx)\n", hProv, dwFlags); 658 659 if (!pProv) 660 { 661 SetLastError(NTE_BAD_UID); 662 return FALSE; 663 } 664 665 if (pProv->dwMagic != MAGIC_CRYPTPROV) 666 { 667 SetLastError(ERROR_INVALID_PARAMETER); 668 return FALSE; 669 } 670 671 pProv->refcount--; 672 if (pProv->refcount <= 0) 673 { 674 ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags); 675 pProv->dwMagic = 0; 676 FreeLibrary(pProv->hModule); 677 #if 0 678 CRYPT_Free(pProv->pVTable->pContextInfo); 679 #endif 680 CRYPT_Free(pProv->pVTable->pszProvName); 681 CRYPT_Free(pProv->pVTable); 682 CRYPT_Free(pProv->pFuncs); 683 CRYPT_Free(pProv); 684 } 685 return ret; 686 } 687 688 /****************************************************************************** 689 * CryptGenRandom (ADVAPI32.@) 690 * 691 * Fills a buffer with cryptographically random bytes. 692 * 693 * PARAMS 694 * hProv [I] Handle of a CSP. 695 * dwLen [I] Number of bytes to generate. 696 * pbBuffer [I/O] Buffer to contain random bytes. 697 * 698 * RETURNS 699 * Success: TRUE 700 * Failure: FALSE 701 * 702 * NOTES 703 * pdBuffer must be at least dwLen bytes long. 704 */ 705 BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) 706 { 707 PCRYPTPROV prov = (PCRYPTPROV)hProv; 708 709 TRACE("(0x%lx, %d, %p)\n", hProv, dwLen, pbBuffer); 710 711 if (!hProv) 712 { 713 SetLastError(ERROR_INVALID_HANDLE); 714 return FALSE; 715 } 716 717 if (prov->dwMagic != MAGIC_CRYPTPROV) 718 { 719 SetLastError(ERROR_INVALID_PARAMETER); 720 return FALSE; 721 } 722 723 return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer); 724 } 725 726 /****************************************************************************** 727 * CryptCreateHash (ADVAPI32.@) 728 * 729 * Initiates the hashing of a stream of data. 730 * 731 * PARAMS 732 * hProv [I] Handle of a CSP. 733 * Algid [I] Identifies the hash algorithm to use. 734 * hKey [I] Key for the hash (if required). 735 * dwFlags [I] Reserved for future use and must be NULL. 736 * phHash [O] Address of the future handle to the new hash object. 737 * 738 * RETURNS 739 * Success: TRUE 740 * Failure: FALSE 741 * 742 * NOTES 743 * If the algorithm is a keyed hash, hKey is the key. 744 */ 745 BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, 746 DWORD dwFlags, HCRYPTHASH *phHash) 747 { 748 PCRYPTPROV prov = (PCRYPTPROV)hProv; 749 PCRYPTKEY key = (PCRYPTKEY)hKey; 750 PCRYPTHASH hash; 751 752 TRACE("(0x%lx, 0x%x, 0x%lx, %08x, %p)\n", hProv, Algid, hKey, dwFlags, phHash); 753 754 if (!prov || !phHash || prov->dwMagic != MAGIC_CRYPTPROV || 755 (key && key->dwMagic != MAGIC_CRYPTKEY)) 756 { 757 SetLastError(ERROR_INVALID_PARAMETER); 758 return FALSE; 759 } 760 if (dwFlags) 761 { 762 SetLastError(NTE_BAD_FLAGS); 763 return FALSE; 764 } 765 if ( !(hash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) 766 { 767 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 768 return FALSE; 769 } 770 771 hash->pProvider = prov; 772 hash->dwMagic = MAGIC_CRYPTHASH; 773 if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid, 774 key ? key->hPrivate : 0, 0, &hash->hPrivate)) 775 { 776 *phHash = (HCRYPTHASH)hash; 777 return TRUE; 778 } 779 780 /* CSP error! */ 781 hash->dwMagic = 0; 782 CRYPT_Free(hash); 783 *phHash = 0; 784 return FALSE; 785 } 786 787 /****************************************************************************** 788 * CryptDecrypt (ADVAPI32.@) 789 * 790 * Decrypts data encrypted by CryptEncrypt. 791 * 792 * PARAMS 793 * hKey [I] Handle to the decryption key. 794 * hHash [I] Handle to a hash object. 795 * Final [I] TRUE if this is the last section to be decrypted. 796 * dwFlags [I] Reserved for future use. Can be CRYPT_OAEP. 797 * pbData [I/O] Buffer that holds the encrypted data. Holds decrypted 798 * data on return 799 * pdwDataLen [I/O] Length of pbData before and after the call. 800 * 801 * RETURNS 802 * Success: TRUE 803 * Failure: FALSE 804 */ 805 BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, 806 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) 807 { 808 PCRYPTPROV prov; 809 PCRYPTKEY key = (PCRYPTKEY)hKey; 810 PCRYPTHASH hash = (PCRYPTHASH)hHash; 811 812 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen); 813 814 if (!key || !pbData || !pdwDataLen || 815 !key->pProvider || key->dwMagic != MAGIC_CRYPTKEY || 816 key->pProvider->dwMagic != MAGIC_CRYPTPROV) 817 { 818 SetLastError(ERROR_INVALID_PARAMETER); 819 return FALSE; 820 } 821 822 prov = key->pProvider; 823 return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, 824 Final, dwFlags, pbData, pdwDataLen); 825 } 826 827 /****************************************************************************** 828 * CryptDeriveKey (ADVAPI32.@) 829 * 830 * Generates session keys derived from a base data value. 831 * 832 * PARAMS 833 * hProv [I] Handle to a CSP. 834 * Algid [I] Identifies the symmetric encryption algorithm to use. 835 * hBaseData [I] Handle to a hash object. 836 * dwFlags [I] Type of key to generate. 837 * phKey [I/O] Address of the newly generated key. 838 * 839 * RETURNS 840 * Success: TRUE 841 * Failure: FALSE 842 */ 843 BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, 844 DWORD dwFlags, HCRYPTKEY *phKey) 845 { 846 PCRYPTPROV prov = (PCRYPTPROV)hProv; 847 PCRYPTHASH hash = (PCRYPTHASH)hBaseData; 848 PCRYPTKEY key; 849 850 TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08x, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey); 851 852 if (!prov || !hash) 853 { 854 SetLastError(ERROR_INVALID_HANDLE); 855 return FALSE; 856 } 857 if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV || hash->dwMagic != MAGIC_CRYPTHASH) 858 { 859 SetLastError(ERROR_INVALID_PARAMETER); 860 return FALSE; 861 } 862 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 863 { 864 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 865 return FALSE; 866 } 867 868 key->pProvider = prov; 869 key->dwMagic = MAGIC_CRYPTKEY; 870 if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate)) 871 { 872 *phKey = (HCRYPTKEY)key; 873 return TRUE; 874 } 875 876 /* CSP error! */ 877 key->dwMagic = 0; 878 CRYPT_Free(key); 879 *phKey = 0; 880 return FALSE; 881 } 882 883 /****************************************************************************** 884 * CryptDestroyHash (ADVAPI32.@) 885 * 886 * Destroys the hash object referenced by hHash. 887 * 888 * PARAMS 889 * hHash [I] Handle of the hash object to be destroyed. 890 * 891 * RETURNS 892 * Success: TRUE 893 * Failure: FALSE 894 */ 895 BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash) 896 { 897 PCRYPTHASH hash = (PCRYPTHASH)hHash; 898 PCRYPTPROV prov; 899 BOOL ret; 900 901 TRACE("(0x%lx)\n", hHash); 902 903 if (!hash) 904 { 905 SetLastError(ERROR_INVALID_HANDLE); 906 return FALSE; 907 } 908 909 if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || 910 hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 911 { 912 SetLastError(ERROR_INVALID_PARAMETER); 913 return FALSE; 914 } 915 916 prov = hash->pProvider; 917 ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate); 918 hash->dwMagic = 0; 919 CRYPT_Free(hash); 920 return ret; 921 } 922 923 /****************************************************************************** 924 * CryptDestroyKey (ADVAPI32.@) 925 * 926 * Releases the handle referenced by hKey. 927 * 928 * PARAMS 929 * hKey [I] Handle of the key to be destroyed. 930 * 931 * RETURNS 932 * Success: TRUE 933 * Failure: FALSE 934 */ 935 BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey) 936 { 937 PCRYPTKEY key = (PCRYPTKEY)hKey; 938 PCRYPTPROV prov; 939 BOOL ret; 940 941 TRACE("(0x%lx)\n", hKey); 942 943 if (!key) 944 { 945 SetLastError(ERROR_INVALID_HANDLE); 946 return FALSE; 947 } 948 949 if (!key->pProvider || key->dwMagic != MAGIC_CRYPTKEY || 950 key->pProvider->dwMagic != MAGIC_CRYPTPROV) 951 { 952 SetLastError(ERROR_INVALID_PARAMETER); 953 return FALSE; 954 } 955 956 prov = key->pProvider; 957 ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate); 958 key->dwMagic = 0; 959 CRYPT_Free(key); 960 return ret; 961 } 962 963 /****************************************************************************** 964 * CryptDuplicateHash (ADVAPI32.@) 965 * 966 * Duplicates a hash. 967 * 968 * PARAMS 969 * hHash [I] Handle to the hash to be copied. 970 * pdwReserved [I] Reserved for future use and must be zero. 971 * dwFlags [I] Reserved for future use and must be zero. 972 * phHash [O] Address of the handle to receive the copy. 973 * 974 * RETURNS 975 * Success: TRUE 976 * Failure: FALSE 977 */ 978 BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved, 979 DWORD dwFlags, HCRYPTHASH *phHash) 980 { 981 PCRYPTPROV prov; 982 PCRYPTHASH orghash, newhash; 983 984 TRACE("(0x%lx, %p, %08x, %p)\n", hHash, pdwReserved, dwFlags, phHash); 985 986 orghash = (PCRYPTHASH)hHash; 987 if (!orghash || pdwReserved || !phHash || !orghash->pProvider || 988 orghash->dwMagic != MAGIC_CRYPTHASH || orghash->pProvider->dwMagic != MAGIC_CRYPTPROV) 989 { 990 SetLastError(ERROR_INVALID_PARAMETER); 991 return FALSE; 992 } 993 994 prov = orghash->pProvider; 995 if (!prov->pFuncs->pCPDuplicateHash) 996 { 997 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 998 return FALSE; 999 } 1000 1001 if ( !(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) 1002 { 1003 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1004 return FALSE; 1005 } 1006 1007 newhash->pProvider = prov; 1008 newhash->dwMagic = MAGIC_CRYPTHASH; 1009 if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate)) 1010 { 1011 *phHash = (HCRYPTHASH)newhash; 1012 return TRUE; 1013 } 1014 newhash->dwMagic = 0; 1015 CRYPT_Free(newhash); 1016 return FALSE; 1017 } 1018 1019 /****************************************************************************** 1020 * CryptDuplicateKey (ADVAPI32.@) 1021 * 1022 * Duplicate a key and the key's state. 1023 * 1024 * PARAMS 1025 * hKey [I] Handle of the key to copy. 1026 * pdwReserved [I] Reserved for future use and must be NULL. 1027 * dwFlags [I] Reserved for future use and must be zero. 1028 * phKey [I] Address of the handle to the duplicated key. 1029 * 1030 * RETURNS 1031 * Success: TRUE 1032 * Failure: FALSE 1033 */ 1034 BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey) 1035 { 1036 PCRYPTPROV prov; 1037 PCRYPTKEY orgkey, newkey; 1038 1039 TRACE("(0x%lx, %p, %08x, %p)\n", hKey, pdwReserved, dwFlags, phKey); 1040 1041 orgkey = (PCRYPTKEY)hKey; 1042 if (!orgkey || pdwReserved || !phKey || !orgkey->pProvider || 1043 orgkey->dwMagic != MAGIC_CRYPTKEY || 1044 orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV) 1045 { 1046 SetLastError(ERROR_INVALID_PARAMETER); 1047 return FALSE; 1048 } 1049 1050 prov = orgkey->pProvider; 1051 if (!prov->pFuncs->pCPDuplicateKey) 1052 { 1053 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1054 return FALSE; 1055 } 1056 1057 if ( !(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 1058 { 1059 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1060 return FALSE; 1061 } 1062 1063 newkey->pProvider = prov; 1064 newkey->dwMagic = MAGIC_CRYPTKEY; 1065 if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate)) 1066 { 1067 *phKey = (HCRYPTKEY)newkey; 1068 return TRUE; 1069 } 1070 newkey->dwMagic = 0; 1071 CRYPT_Free(newkey); 1072 return FALSE; 1073 } 1074 1075 /****************************************************************************** 1076 * CryptEncrypt (ADVAPI32.@) 1077 * 1078 * Encrypts data. 1079 * 1080 * PARAMS 1081 * hKey [I] Handle to the encryption key. 1082 * hHash [I] Handle to a hash object. 1083 * Final [I] TRUE if this is the last section to encrypt. 1084 * dwFlags [I] Can be CRYPT_OAEP. 1085 * pbData [I/O] Data to be encrypted. Contains encrypted data after call. 1086 * pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the 1087 * encrypted data after call. 1088 * dwBufLen [I] Length of the input pbData buffer. 1089 * 1090 * RETURNS 1091 * Success: TRUE 1092 * Failure: FALSE 1093 * 1094 * NOTES 1095 * If pbData is NULL, CryptEncrypt determines stores the number of bytes 1096 * required for the returned data in pdwDataLen. 1097 */ 1098 BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, 1099 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) 1100 { 1101 PCRYPTPROV prov; 1102 PCRYPTKEY key = (PCRYPTKEY)hKey; 1103 PCRYPTHASH hash = (PCRYPTHASH)hHash; 1104 1105 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p, %d)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen); 1106 1107 if (!key || !pdwDataLen || !key->pProvider || 1108 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 1109 { 1110 SetLastError(ERROR_INVALID_PARAMETER); 1111 return FALSE; 1112 } 1113 1114 prov = key->pProvider; 1115 return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, 1116 Final, dwFlags, pbData, pdwDataLen, dwBufLen); 1117 } 1118 1119 /****************************************************************************** 1120 * CryptEnumProvidersW (ADVAPI32.@) 1121 * 1122 * Returns the next available CSP. 1123 * 1124 * PARAMS 1125 * dwIndex [I] Index of the next provider to be enumerated. 1126 * pdwReserved [I] Reserved for future use and must be NULL. 1127 * dwFlags [I] Reserved for future use and must be zero. 1128 * pdwProvType [O] DWORD designating the type of the provider. 1129 * pszProvName [O] Buffer that receives data from the provider. 1130 * pcbProvName [I/O] Specifies the size of pszProvName. Contains the number 1131 * of bytes stored in the buffer on return. 1132 * 1133 * RETURNS 1134 * Success: TRUE 1135 * Failure: FALSE 1136 * 1137 * NOTES 1138 * If pszProvName is NULL, CryptEnumProvidersW sets the size of the name 1139 * for memory allocation purposes. 1140 */ 1141 BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved, 1142 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName) 1143 { 1144 HKEY hKey; 1145 static const WCHAR providerW[] = { 1146 'S','o','f','t','w','a','r','e','\\', 1147 'M','i','c','r','o','s','o','f','t','\\', 1148 'C','r','y','p','t','o','g','r','a','p','h','y','\\', 1149 'D','e','f','a','u','l','t','s','\\', 1150 'P','r','o','v','i','d','e','r',0 1151 }; 1152 static const WCHAR typeW[] = {'T','y','p','e',0}; 1153 BOOL ret; 1154 1155 TRACE("(%d, %p, %d, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, 1156 pdwProvType, pszProvName, pcbProvName); 1157 1158 if (pdwReserved || !pcbProvName) 1159 { 1160 SetLastError(ERROR_INVALID_PARAMETER); 1161 return FALSE; 1162 } 1163 if (dwFlags) 1164 { 1165 SetLastError(NTE_BAD_FLAGS); 1166 return FALSE; 1167 } 1168 1169 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, providerW, &hKey)) 1170 { 1171 SetLastError(NTE_FAIL); 1172 return FALSE; 1173 } 1174 1175 ret = TRUE; 1176 if (!pszProvName) 1177 { 1178 DWORD numkeys; 1179 WCHAR *provNameW; 1180 1181 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, pcbProvName, 1182 NULL, NULL, NULL, NULL, NULL, NULL); 1183 1184 if (!(provNameW = CRYPT_Alloc(*pcbProvName * sizeof(WCHAR)))) 1185 { 1186 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1187 RegCloseKey(hKey); 1188 return FALSE; 1189 } 1190 1191 RegEnumKeyExW(hKey, dwIndex, provNameW, pcbProvName, NULL, NULL, NULL, NULL); 1192 CRYPT_Free(provNameW); 1193 (*pcbProvName)++; 1194 *pcbProvName *= sizeof(WCHAR); 1195 1196 if (dwIndex >= numkeys) 1197 { 1198 SetLastError(ERROR_NO_MORE_ITEMS); 1199 ret = FALSE; 1200 } 1201 } else { 1202 DWORD size = sizeof(DWORD); 1203 DWORD result; 1204 HKEY subkey; 1205 1206 result = RegEnumKeyW(hKey, dwIndex, pszProvName, *pcbProvName / sizeof(WCHAR)); 1207 if (result) 1208 { 1209 SetLastError(result); 1210 RegCloseKey(hKey); 1211 return FALSE; 1212 } 1213 if (RegOpenKeyW(hKey, pszProvName, &subkey)) 1214 { 1215 RegCloseKey(hKey); 1216 return FALSE; 1217 } 1218 1219 if (RegQueryValueExW(subkey, typeW, NULL, NULL, (BYTE*)pdwProvType, &size)) 1220 ret = FALSE; 1221 1222 RegCloseKey(subkey); 1223 } 1224 RegCloseKey(hKey); 1225 return ret; 1226 } 1227 1228 /****************************************************************************** 1229 * CryptEnumProvidersA (ADVAPI32.@) 1230 * 1231 * See CryptEnumProvidersW. 1232 */ 1233 BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved, 1234 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName) 1235 { 1236 PWSTR str = NULL; 1237 DWORD bufsize; 1238 BOOL ret; 1239 1240 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, 1241 pdwProvType, pszProvName, pcbProvName); 1242 1243 if(!CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, NULL, &bufsize)) 1244 return FALSE; 1245 if ( pszProvName && !(str = CRYPT_Alloc(bufsize)) ) 1246 { 1247 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1248 return FALSE; 1249 } 1250 ret = CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &bufsize); 1251 if (str) 1252 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName); 1253 *pcbProvName = bufsize / sizeof(WCHAR); /* FIXME: not correct */ 1254 if (str) 1255 { 1256 CRYPT_Free(str); 1257 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1258 { 1259 SetLastError(ERROR_MORE_DATA); 1260 return FALSE; 1261 } 1262 } 1263 return ret; 1264 } 1265 1266 /****************************************************************************** 1267 * CryptEnumProviderTypesW (ADVAPI32.@) 1268 * 1269 * Retrieves the next type of CSP supported. 1270 * 1271 * PARAMS 1272 * dwIndex [I] Index of the next provider to be enumerated. 1273 * pdwReserved [I] Reserved for future use and must be NULL. 1274 * dwFlags [I] Reserved for future use and must be zero. 1275 * pdwProvType [O] DWORD designating the type of the provider. 1276 * pszTypeName [O] Buffer that receives data from the provider type. 1277 * pcbTypeName [I/O] Specifies the size of pszTypeName. Contains the number 1278 * of bytes stored in the buffer on return. 1279 * 1280 * RETURNS 1281 * Success: TRUE 1282 * Failure: FALSE 1283 * 1284 * NOTES 1285 * If pszTypeName is NULL, CryptEnumProviderTypesW sets the size of the name 1286 * for memory allocation purposes. 1287 */ 1288 BOOL WINAPI CryptEnumProviderTypesW (DWORD dwIndex, DWORD *pdwReserved, 1289 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszTypeName, DWORD *pcbTypeName) 1290 { 1291 HKEY hKey, hSubkey; 1292 DWORD keylen, numkeys, dwType; 1293 PWSTR keyname, ch; 1294 DWORD result; 1295 static const WCHAR KEYSTR[] = { 1296 'S','o','f','t','w','a','r','e','\\', 1297 'M','i','c','r','o','s','o','f','t','\\', 1298 'C','r','y','p','t','o','g','r','a','p','h','y','\\', 1299 'D','e','f','a','u','l','t','s','\\', 1300 'P','r','o','v','i','d','e','r',' ','T','y','p','e','s',0 1301 }; 1302 static const WCHAR typenameW[] = {'T','y','p','e','N','a','m','e',0}; 1303 1304 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, 1305 dwFlags, pdwProvType, pszTypeName, pcbTypeName); 1306 1307 if (pdwReserved || !pdwProvType || !pcbTypeName) 1308 { 1309 SetLastError(ERROR_INVALID_PARAMETER); 1310 return FALSE; 1311 } 1312 if (dwFlags) 1313 { 1314 SetLastError(NTE_BAD_FLAGS); 1315 return FALSE; 1316 } 1317 1318 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, KEYSTR, &hKey)) 1319 return FALSE; 1320 1321 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, &keylen, NULL, NULL, NULL, NULL, NULL, NULL); 1322 if (dwIndex >= numkeys) 1323 { 1324 SetLastError(ERROR_NO_MORE_ITEMS); 1325 RegCloseKey(hKey); 1326 return FALSE; 1327 } 1328 keylen++; 1329 if ( !(keyname = CRYPT_Alloc(keylen*sizeof(WCHAR))) ) 1330 { 1331 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1332 RegCloseKey(hKey); 1333 return FALSE; 1334 } 1335 if ( RegEnumKeyW(hKey, dwIndex, keyname, keylen) ) { 1336 CRYPT_Free(keyname); 1337 RegCloseKey(hKey); 1338 return FALSE; 1339 } 1340 RegOpenKeyW(hKey, keyname, &hSubkey); 1341 RegCloseKey(hKey); 1342 1343 ch = keyname + strlenW(keyname); 1344 /* Convert "Type 000" to 0, etc/ */ 1345 *pdwProvType = *(--ch) - '0'; 1346 *pdwProvType += (*(--ch) - '0') * 10; 1347 *pdwProvType += (*(--ch) - '0') * 100; 1348 CRYPT_Free(keyname); 1349 1350 result = RegQueryValueExW(hSubkey, typenameW, NULL, &dwType, (LPBYTE)pszTypeName, pcbTypeName); 1351 if (result) 1352 { 1353 SetLastError(result); 1354 RegCloseKey(hSubkey); 1355 return FALSE; 1356 } 1357 1358 RegCloseKey(hSubkey); 1359 return TRUE; 1360 } 1361 1362 /****************************************************************************** 1363 * CryptEnumProviderTypesA (ADVAPI32.@) 1364 * 1365 * See CryptEnumProviderTypesW. 1366 */ 1367 BOOL WINAPI CryptEnumProviderTypesA (DWORD dwIndex, DWORD *pdwReserved, 1368 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszTypeName, DWORD *pcbTypeName) 1369 { 1370 PWSTR str = NULL; 1371 DWORD bufsize; 1372 BOOL ret; 1373 1374 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, 1375 pdwProvType, pszTypeName, pcbTypeName); 1376 1377 if(!CryptEnumProviderTypesW(dwIndex, pdwReserved, dwFlags, pdwProvType, NULL, &bufsize)) 1378 return FALSE; 1379 if ( pszTypeName && !(str = CRYPT_Alloc(bufsize)) ) 1380 { 1381 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1382 return FALSE; 1383 } 1384 ret = CryptEnumProviderTypesW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &bufsize); 1385 if (str) 1386 CRYPT_UnicodeToANSI(str, &pszTypeName, *pcbTypeName); 1387 *pcbTypeName = bufsize / sizeof(WCHAR); 1388 if (str) 1389 { 1390 CRYPT_Free(str); 1391 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1392 { 1393 SetLastError(ERROR_MORE_DATA); 1394 return FALSE; 1395 } 1396 } 1397 return ret; 1398 } 1399 1400 /****************************************************************************** 1401 * CryptExportKey (ADVAPI32.@) 1402 * 1403 * Exports a cryptographic key from a CSP. 1404 * 1405 * PARAMS 1406 * hKey [I] Handle to the key to export. 1407 * hExpKey [I] Handle to a cryptographic key of the end user. 1408 * dwBlobType [I] Type of BLOB to be exported. 1409 * dwFlags [I] CRYPT_DESTROYKEY/SSL2_FALLBACK/OAEP. 1410 * pbData [O] Buffer to receive BLOB data. 1411 * pdwDataLen [I/O] Specifies the size of pbData. 1412 * 1413 * RETURNS 1414 * Success: TRUE 1415 * Failure: FALSE 1416 * 1417 * NOTES 1418 * if pbData is NULL, CryptExportKey sets pdwDataLen as the size of the 1419 * buffer needed to hold the BLOB. 1420 */ 1421 BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, 1422 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) 1423 { 1424 PCRYPTPROV prov; 1425 PCRYPTKEY key = (PCRYPTKEY)hKey, expkey = (PCRYPTKEY)hExpKey; 1426 1427 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen); 1428 1429 if (!key || !pdwDataLen || !key->pProvider || 1430 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 1431 { 1432 SetLastError(ERROR_INVALID_PARAMETER); 1433 return FALSE; 1434 } 1435 1436 prov = key->pProvider; 1437 return prov->pFuncs->pCPExportKey(prov->hPrivate, key->hPrivate, expkey ? expkey->hPrivate : 0, 1438 dwBlobType, dwFlags, pbData, pdwDataLen); 1439 } 1440 1441 /****************************************************************************** 1442 * CryptGenKey (ADVAPI32.@) 1443 * 1444 * Generates a random cryptographic session key or a pub/priv key pair. 1445 * 1446 * PARAMS 1447 * hProv [I] Handle to a CSP. 1448 * Algid [I] Algorithm to use to make key. 1449 * dwFlags [I] Specifies type of key to make. 1450 * phKey [I] Address of the handle to which the new key is copied. 1451 * 1452 * RETURNS 1453 * Success: TRUE 1454 * Failure: FALSE 1455 */ 1456 BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey) 1457 { 1458 PCRYPTPROV prov = (PCRYPTPROV)hProv; 1459 PCRYPTKEY key; 1460 1461 TRACE("(0x%lx, %d, %08x, %p)\n", hProv, Algid, dwFlags, phKey); 1462 1463 if (!phKey || !prov || prov->dwMagic != MAGIC_CRYPTPROV) 1464 { 1465 SetLastError(ERROR_INVALID_PARAMETER); 1466 return FALSE; 1467 } 1468 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 1469 { 1470 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1471 return FALSE; 1472 } 1473 1474 key->pProvider = prov; 1475 key->dwMagic = MAGIC_CRYPTKEY; 1476 if (prov->pFuncs->pCPGenKey(prov->hPrivate, Algid, dwFlags, &key->hPrivate)) 1477 { 1478 *phKey = (HCRYPTKEY)key; 1479 return TRUE; 1480 } 1481 1482 /* CSP error! */ 1483 key->dwMagic = 0; 1484 CRYPT_Free(key); 1485 return FALSE; 1486 } 1487 1488 /****************************************************************************** 1489 * CryptGetDefaultProviderW (ADVAPI32.@) 1490 * 1491 * Finds the default CSP of a certain provider type. 1492 * 1493 * PARAMS 1494 * dwProvType [I] Provider type to look for. 1495 * pdwReserved [I] Reserved for future use and must be NULL. 1496 * dwFlags [I] CRYPT_MACHINE_DEFAULT/USER_DEFAULT 1497 * pszProvName [O] Name of the default CSP. 1498 * pcbProvName [I/O] Size of pszProvName 1499 * 1500 * RETURNS 1501 * Success: TRUE 1502 * Failure: FALSE 1503 * 1504 * NOTES 1505 * If pszProvName is NULL, pcbProvName will hold the size of the buffer for 1506 * memory allocation purposes on return. 1507 */ 1508 BOOL WINAPI CryptGetDefaultProviderW (DWORD dwProvType, DWORD *pdwReserved, 1509 DWORD dwFlags, LPWSTR pszProvName, DWORD *pcbProvName) 1510 { 1511 HKEY hKey; 1512 PWSTR keyname; 1513 DWORD result; 1514 static const WCHAR nameW[] = {'N','a','m','e',0}; 1515 1516 if (pdwReserved || !pcbProvName) 1517 { 1518 SetLastError(ERROR_INVALID_PARAMETER); 1519 return FALSE; 1520 } 1521 if (dwFlags & ~(CRYPT_USER_DEFAULT | CRYPT_MACHINE_DEFAULT)) 1522 { 1523 SetLastError(NTE_BAD_FLAGS); 1524 return FALSE; 1525 } 1526 if (dwProvType > 999) 1527 { 1528 SetLastError(NTE_BAD_PROV_TYPE); 1529 return FALSE; 1530 } 1531 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) ) 1532 { 1533 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1534 return FALSE; 1535 } 1536 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey)) 1537 { 1538 CRYPT_Free(keyname); 1539 SetLastError(NTE_PROV_TYPE_NOT_DEF); 1540 return FALSE; 1541 } 1542 CRYPT_Free(keyname); 1543 1544 result = RegQueryValueExW(hKey, nameW, NULL, NULL, (LPBYTE)pszProvName, pcbProvName); 1545 RegCloseKey(hKey); 1546 1547 if (result) 1548 { 1549 if (result != ERROR_MORE_DATA) 1550 SetLastError(NTE_PROV_TYPE_ENTRY_BAD); 1551 else 1552 SetLastError(result); 1553 1554 return FALSE; 1555 } 1556 1557 return TRUE; 1558 } 1559 1560 /****************************************************************************** 1561 * CryptGetDefaultProviderA (ADVAPI32.@) 1562 * 1563 * See CryptGetDefaultProviderW. 1564 */ 1565 BOOL WINAPI CryptGetDefaultProviderA (DWORD dwProvType, DWORD *pdwReserved, 1566 DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName) 1567 { 1568 PWSTR str = NULL; 1569 DWORD bufsize; 1570 BOOL ret; 1571 1572 TRACE("(%d, %p, %08x, %p, %p)\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName); 1573 1574 CryptGetDefaultProviderW(dwProvType, pdwReserved, dwFlags, NULL, &bufsize); 1575 if ( pszProvName && !(str = CRYPT_Alloc(bufsize)) ) 1576 { 1577 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1578 return FALSE; 1579 } 1580 ret = CryptGetDefaultProviderW(dwProvType, pdwReserved, dwFlags, str, &bufsize); 1581 if (str) 1582 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName); 1583 *pcbProvName = bufsize / sizeof(WCHAR); 1584 if (str) 1585 { 1586 CRYPT_Free(str); 1587 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1588 { 1589 SetLastError(ERROR_MORE_DATA); 1590 return FALSE; 1591 } 1592 } 1593 return ret; 1594 } 1595 1596 /****************************************************************************** 1597 * CryptGetHashParam (ADVAPI32.@) 1598 * 1599 * Retrieves data that controls the operations of a hash object. 1600 * 1601 * PARAMS 1602 * hHash [I] Handle of the hash object to question. 1603 * dwParam [I] Query type. 1604 * pbData [O] Buffer that receives the value data. 1605 * pdwDataLen [I/O] Size of the pbData buffer. 1606 * dwFlags [I] Reserved for future use and must be zero. 1607 * 1608 * RETURNS 1609 * Success: TRUE 1610 * Failure: FALSE 1611 * 1612 * NOTES 1613 * If pbData is NULL, pdwDataLen will contain the length required. 1614 */ 1615 BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, 1616 DWORD *pdwDataLen, DWORD dwFlags) 1617 { 1618 PCRYPTPROV prov; 1619 PCRYPTHASH hash = (PCRYPTHASH)hHash; 1620 1621 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags); 1622 1623 if (!hash || !pdwDataLen || !hash->pProvider || 1624 hash->dwMagic != MAGIC_CRYPTHASH || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 1625 { 1626 SetLastError(ERROR_INVALID_PARAMETER); 1627 return FALSE; 1628 } 1629 1630 prov = hash->pProvider; 1631 return prov->pFuncs->pCPGetHashParam(prov->hPrivate, hash->hPrivate, dwParam, 1632 pbData, pdwDataLen, dwFlags); 1633 } 1634 1635 /****************************************************************************** 1636 * CryptGetKeyParam (ADVAPI32.@) 1637 * 1638 * Retrieves data that controls the operations of a key. 1639 * 1640 * PARAMS 1641 * hKey [I] Handle to they key in question. 1642 * dwParam [I] Specifies query type. 1643 * pbData [O] Sequence of bytes to receive data. 1644 * pdwDataLen [I/O] Size of pbData. 1645 * dwFlags [I] Reserved for future use and must be zero. 1646 * 1647 * RETURNS 1648 * Success: TRUE 1649 * Failure: FALSE 1650 * 1651 * NOTES 1652 * If pbData is NULL, pdwDataLen is set to the needed length of the buffer. 1653 */ 1654 BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, 1655 DWORD *pdwDataLen, DWORD dwFlags) 1656 { 1657 PCRYPTPROV prov; 1658 PCRYPTKEY key = (PCRYPTKEY)hKey; 1659 1660 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags); 1661 1662 if (!key || !pdwDataLen || !key->pProvider || 1663 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 1664 { 1665 SetLastError(ERROR_INVALID_PARAMETER); 1666 return FALSE; 1667 } 1668 1669 prov = key->pProvider; 1670 return prov->pFuncs->pCPGetKeyParam(prov->hPrivate, key->hPrivate, dwParam, 1671 pbData, pdwDataLen, dwFlags); 1672 } 1673 1674 /****************************************************************************** 1675 * CryptGetProvParam (ADVAPI32.@) 1676 * 1677 * Retrieves parameters that control the operations of a CSP. 1678 * 1679 * PARAMS 1680 * hProv [I] Handle of the CSP in question. 1681 * dwParam [I] Specifies query type. 1682 * pbData [O] Buffer to receive the data. 1683 * pdwDataLen [I/O] Size of pbData. 1684 * dwFlags [I] see MSDN Docs. 1685 * 1686 * RETURNS 1687 * Success: TRUE 1688 * Failure: FALSE 1689 * 1690 * NOTES 1691 * If pbData is NULL, pdwDataLen is set to the needed buffer length. 1692 */ 1693 BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, 1694 DWORD *pdwDataLen, DWORD dwFlags) 1695 { 1696 PCRYPTPROV prov = (PCRYPTPROV)hProv; 1697 1698 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags); 1699 1700 if (!prov || prov->dwMagic != MAGIC_CRYPTPROV) 1701 { 1702 SetLastError(ERROR_INVALID_PARAMETER); 1703 return FALSE; 1704 } 1705 1706 return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags); 1707 } 1708 1709 /****************************************************************************** 1710 * CryptGetUserKey (ADVAPI32.@) 1711 * 1712 * Gets a handle of one of a user's two public/private key pairs. 1713 * 1714 * PARAMS 1715 * hProv [I] Handle of a CSP. 1716 * dwKeySpec [I] Private key to use. 1717 * phUserKey [O] Pointer to the handle of the retrieved keys. 1718 * 1719 * RETURNS 1720 * Success: TRUE 1721 * Failure: FALSE 1722 */ 1723 BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey) 1724 { 1725 PCRYPTPROV prov = (PCRYPTPROV)hProv; 1726 PCRYPTKEY key; 1727 1728 TRACE("(0x%lx, %d, %p)\n", hProv, dwKeySpec, phUserKey); 1729 1730 if (!prov) 1731 { 1732 SetLastError(ERROR_INVALID_HANDLE); 1733 return FALSE; 1734 } 1735 if (!phUserKey || prov->dwMagic != MAGIC_CRYPTPROV) 1736 { 1737 SetLastError(ERROR_INVALID_PARAMETER); 1738 return FALSE; 1739 } 1740 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 1741 { 1742 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1743 return FALSE; 1744 } 1745 1746 key->pProvider = prov; 1747 key->dwMagic = MAGIC_CRYPTKEY; 1748 if (prov->pFuncs->pCPGetUserKey(prov->hPrivate, dwKeySpec, &key->hPrivate)) 1749 { 1750 *phUserKey = (HCRYPTKEY)key; 1751 return TRUE; 1752 } 1753 1754 /* CSP Error */ 1755 key->dwMagic = 0; 1756 CRYPT_Free(key); 1757 *phUserKey = 0; 1758 return FALSE; 1759 } 1760 1761 /****************************************************************************** 1762 * CryptHashData (ADVAPI32.@) 1763 * 1764 * Adds data to a hash object. 1765 * 1766 * PARAMS 1767 * hHash [I] Handle of the hash object. 1768 * pbData [I] Buffer of data to be hashed. 1769 * dwDataLen [I] Number of bytes to add. 1770 * dwFlags [I] Can be CRYPT_USERDATA 1771 * 1772 * RETURNS 1773 * Success: TRUE 1774 * Failure: FALSE 1775 */ 1776 BOOL WINAPI CryptHashData (HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags) 1777 { 1778 PCRYPTHASH hash = (PCRYPTHASH)hHash; 1779 PCRYPTPROV prov; 1780 1781 TRACE("(0x%lx, %p, %d, %08x)\n", hHash, pbData, dwDataLen, dwFlags); 1782 1783 if (!hash) 1784 { 1785 SetLastError(ERROR_INVALID_HANDLE); 1786 return FALSE; 1787 } 1788 if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || 1789 hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 1790 { 1791 SetLastError(ERROR_INVALID_PARAMETER); 1792 return FALSE; 1793 } 1794 1795 prov = hash->pProvider; 1796 return prov->pFuncs->pCPHashData(prov->hPrivate, hash->hPrivate, pbData, dwDataLen, dwFlags); 1797 } 1798 1799 /****************************************************************************** 1800 * CryptHashSessionKey (ADVAPI32.@) 1801 * 1802 * Compute the cryptographic hash of a session key object. 1803 * 1804 * PARAMS 1805 * hHash [I] Handle to the hash object. 1806 * hKey [I] Handle to the key to be hashed. 1807 * dwFlags [I] Can be CRYPT_LITTLE_ENDIAN. 1808 * 1809 * RETURNS 1810 * Success: TRUE 1811 * Failure: FALSE 1812 */ 1813 BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags) 1814 { 1815 PCRYPTHASH hash = (PCRYPTHASH)hHash; 1816 PCRYPTKEY key = (PCRYPTKEY)hKey; 1817 PCRYPTPROV prov; 1818 1819 TRACE("(0x%lx, 0x%lx, %08x)\n", hHash, hKey, dwFlags); 1820 1821 if (!hash || !key) 1822 { 1823 SetLastError(ERROR_INVALID_HANDLE); 1824 return FALSE; 1825 } 1826 1827 if (!hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || 1828 hash->pProvider->dwMagic != MAGIC_CRYPTPROV || key->dwMagic != MAGIC_CRYPTKEY) 1829 { 1830 SetLastError(ERROR_INVALID_PARAMETER); 1831 return FALSE; 1832 } 1833 1834 prov = hash->pProvider; 1835 return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags); 1836 } 1837 1838 /****************************************************************************** 1839 * CryptImportKey (ADVAPI32.@) 1840 * 1841 * Transfer a cryptographic key from a key BLOB into a cryptographic service provider (CSP). 1842 * 1843 * PARAMS 1844 * hProv [I] Handle of a CSP. 1845 * pbData [I] Contains the key to be imported. 1846 * dwDataLen [I] Length of the key. 1847 * hPubKey [I] Cryptographic key that decrypts pdData 1848 * dwFlags [I] Used only with a public/private key pair. 1849 * phKey [O] Imported key. 1850 * 1851 * RETURNS 1852 * Success: TRUE 1853 * Failure: FALSE 1854 */ 1855 BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, 1856 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) 1857 { 1858 PCRYPTPROV prov = (PCRYPTPROV)hProv; 1859 PCRYPTKEY pubkey = (PCRYPTKEY)hPubKey, importkey; 1860 1861 TRACE("(0x%lx, %p, %d, 0x%lx, %08x, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); 1862 1863 if (!prov || !pbData || !dwDataLen || !phKey || 1864 prov->dwMagic != MAGIC_CRYPTPROV || 1865 (pubkey && pubkey->dwMagic != MAGIC_CRYPTKEY)) 1866 { 1867 SetLastError(ERROR_INVALID_PARAMETER); 1868 return FALSE; 1869 } 1870 1871 if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 1872 { 1873 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1874 return FALSE; 1875 } 1876 1877 importkey->pProvider = prov; 1878 importkey->dwMagic = MAGIC_CRYPTKEY; 1879 if (prov->pFuncs->pCPImportKey(prov->hPrivate, pbData, dwDataLen, 1880 pubkey ? pubkey->hPrivate : 0, dwFlags, &importkey->hPrivate)) 1881 { 1882 *phKey = (HCRYPTKEY)importkey; 1883 return TRUE; 1884 } 1885 1886 importkey->dwMagic = 0; 1887 CRYPT_Free(importkey); 1888 return FALSE; 1889 } 1890 1891 /****************************************************************************** 1892 * CryptSignHashW (ADVAPI32.@) 1893 * 1894 * Signs data. 1895 * 1896 * PARAMS 1897 * hHash [I] Handle of the hash object to be signed. 1898 * dwKeySpec [I] Private key to use. 1899 * sDescription [I] Should be NULL. 1900 * dwFlags [I] CRYPT_NOHASHOID/X931_FORMAT. 1901 * pbSignature [O] Buffer of the signature data. 1902 * pdwSigLen [I/O] Size of the pbSignature buffer. 1903 * 1904 * RETURNS 1905 * Success: TRUE 1906 * Failure: FALSE 1907 * 1908 * NOTES 1909 * Because of security flaws sDescription should not be used and should thus be 1910 * NULL. It is supported only for compatibility with Microsoft's Cryptographic 1911 * Providers. 1912 */ 1913 BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, 1914 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) 1915 { 1916 PCRYPTHASH hash = (PCRYPTHASH)hHash; 1917 PCRYPTPROV prov; 1918 1919 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n", 1920 hHash, dwKeySpec, debugstr_w(sDescription), dwFlags, pbSignature, pdwSigLen); 1921 1922 if (!hash) 1923 { 1924 SetLastError(ERROR_INVALID_HANDLE); 1925 return FALSE; 1926 } 1927 if (!pdwSigLen || !hash->pProvider || hash->dwMagic != MAGIC_CRYPTHASH || 1928 hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 1929 { 1930 SetLastError(ERROR_INVALID_PARAMETER); 1931 return FALSE; 1932 } 1933 1934 prov = hash->pProvider; 1935 return prov->pFuncs->pCPSignHash(prov->hPrivate, hash->hPrivate, dwKeySpec, sDescription, 1936 dwFlags, pbSignature, pdwSigLen); 1937 } 1938 1939 /****************************************************************************** 1940 * CryptSignHashA (ADVAPI32.@) 1941 * 1942 * See CryptSignHashW. 1943 */ 1944 BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription, 1945 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) 1946 { 1947 LPWSTR wsDescription; 1948 BOOL result; 1949 1950 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n", 1951 hHash, dwKeySpec, debugstr_a(sDescription), dwFlags, pbSignature, pdwSigLen); 1952 1953 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1); 1954 result = CryptSignHashW(hHash, dwKeySpec, wsDescription, dwFlags, pbSignature, pdwSigLen); 1955 CRYPT_Free(wsDescription); 1956 1957 return result; 1958 } 1959 1960 /****************************************************************************** 1961 * CryptSetHashParam (ADVAPI32.@) 1962 * 1963 * Customizes the operations of a hash object. 1964 * 1965 * PARAMS 1966 * hHash [I] Handle of the hash object to set parameters. 1967 * dwParam [I] HP_HMAC_INFO/HASHVAL. 1968 * pbData [I] Value data buffer. 1969 * dwFlags [I] Reserved for future use and must be zero. 1970 * 1971 * RETURNS 1972 * Success: TRUE 1973 * Failure: FALSE 1974 */ 1975 BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, const BYTE *pbData, DWORD dwFlags) 1976 { 1977 PCRYPTPROV prov; 1978 PCRYPTHASH hash = (PCRYPTHASH)hHash; 1979 1980 TRACE("(0x%lx, %d, %p, %08x)\n", hHash, dwParam, pbData, dwFlags); 1981 1982 if (!hash || !pbData || !hash->pProvider || 1983 hash->dwMagic != MAGIC_CRYPTHASH || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 1984 { 1985 SetLastError(ERROR_INVALID_PARAMETER); 1986 return FALSE; 1987 } 1988 1989 prov = hash->pProvider; 1990 return prov->pFuncs->pCPSetHashParam(prov->hPrivate, hash->hPrivate, 1991 dwParam, pbData, dwFlags); 1992 } 1993 1994 /****************************************************************************** 1995 * CryptSetKeyParam (ADVAPI32.@) 1996 * 1997 * Customizes a session key's operations. 1998 * 1999 * PARAMS 2000 * hKey [I] Handle to the key to set values. 2001 * dwParam [I] See MSDN Doc. 2002 * pbData [I] Buffer of values to set. 2003 * dwFlags [I] Only used when dwParam == KP_ALGID. 2004 * 2005 * RETURNS 2006 * Success: TRUE 2007 * Failure: FALSE 2008 */ 2009 BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, const BYTE *pbData, DWORD dwFlags) 2010 { 2011 PCRYPTPROV prov; 2012 PCRYPTKEY key = (PCRYPTKEY)hKey; 2013 2014 TRACE("(0x%lx, %d, %p, %08x)\n", hKey, dwParam, pbData, dwFlags); 2015 2016 if (!key || !pbData || !key->pProvider || 2017 key->dwMagic != MAGIC_CRYPTKEY || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 2018 { 2019 SetLastError(ERROR_INVALID_PARAMETER); 2020 return FALSE; 2021 } 2022 2023 prov = key->pProvider; 2024 return prov->pFuncs->pCPSetKeyParam(prov->hPrivate, key->hPrivate, 2025 dwParam, pbData, dwFlags); 2026 } 2027 2028 /****************************************************************************** 2029 * CryptSetProviderA (ADVAPI32.@) 2030 * 2031 * Specifies the current user's default CSP. 2032 * 2033 * PARAMS 2034 * pszProvName [I] Name of the new default CSP. 2035 * dwProvType [I] Provider type of the CSP. 2036 * 2037 * RETURNS 2038 * Success: TRUE 2039 * Failure: FALSE 2040 */ 2041 BOOL WINAPI CryptSetProviderA (LPCSTR pszProvName, DWORD dwProvType) 2042 { 2043 TRACE("(%s, %d)\n", pszProvName, dwProvType); 2044 return CryptSetProviderExA(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT); 2045 } 2046 2047 /****************************************************************************** 2048 * CryptSetProviderW (ADVAPI32.@) 2049 * 2050 * See CryptSetProviderA. 2051 */ 2052 BOOL WINAPI CryptSetProviderW (LPCWSTR pszProvName, DWORD dwProvType) 2053 { 2054 TRACE("(%s, %d)\n", debugstr_w(pszProvName), dwProvType); 2055 return CryptSetProviderExW(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT); 2056 } 2057 2058 /****************************************************************************** 2059 * CryptSetProviderExW (ADVAPI32.@) 2060 * 2061 * Specifies the default CSP. 2062 * 2063 * PARAMS 2064 * pszProvName [I] Name of the new default CSP. 2065 * dwProvType [I] Provider type of the CSP. 2066 * pdwReserved [I] Reserved for future use and must be NULL. 2067 * dwFlags [I] See MSDN Doc. 2068 * 2069 * RETURNS 2070 * Success: TRUE 2071 * Failure: FALSE 2072 */ 2073 BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags) 2074 { 2075 HKEY hProvKey, hTypeKey; 2076 PWSTR keyname; 2077 static const WCHAR nameW[] = {'N','a','m','e',0}; 2078 2079 TRACE("(%s, %d, %p, %08x)\n", debugstr_w(pszProvName), dwProvType, pdwReserved, dwFlags); 2080 2081 if (!pszProvName || pdwReserved) 2082 { 2083 SetLastError(ERROR_INVALID_PARAMETER); 2084 return FALSE; 2085 } 2086 if (dwProvType > MAXPROVTYPES) 2087 { 2088 SetLastError(NTE_BAD_PROV_TYPE); 2089 return FALSE; 2090 } 2091 if (dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT) 2092 || dwFlags == CRYPT_DELETE_DEFAULT) 2093 { 2094 SetLastError(NTE_BAD_FLAGS); 2095 return FALSE; 2096 } 2097 2098 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT))) 2099 { 2100 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2101 return FALSE; 2102 } 2103 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, 2104 keyname, &hTypeKey)) 2105 { 2106 CRYPT_Free(keyname); 2107 SetLastError(NTE_BAD_PROVIDER); 2108 return FALSE; 2109 } 2110 CRYPT_Free(keyname); 2111 2112 if (dwFlags & CRYPT_DELETE_DEFAULT) 2113 { 2114 RegDeleteValueW(hTypeKey, nameW); 2115 } 2116 else 2117 { 2118 if (!(keyname = CRYPT_GetProvKeyName(pszProvName))) 2119 { 2120 RegCloseKey(hTypeKey); 2121 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2122 return FALSE; 2123 } 2124 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, 2125 keyname, &hProvKey)) 2126 { 2127 CRYPT_Free(keyname); 2128 RegCloseKey(hTypeKey); 2129 SetLastError(NTE_BAD_PROVIDER); 2130 return FALSE; 2131 } 2132 CRYPT_Free(keyname); 2133 2134 if (RegSetValueExW(hTypeKey, nameW, 0, REG_SZ, (const BYTE *)pszProvName, 2135 (strlenW(pszProvName) + 1)*sizeof(WCHAR))) 2136 { 2137 RegCloseKey(hTypeKey); 2138 RegCloseKey(hProvKey); 2139 return FALSE; 2140 } 2141 2142 RegCloseKey(hProvKey); 2143 } 2144 RegCloseKey(hTypeKey); 2145 2146 return TRUE; 2147 } 2148 2149 /****************************************************************************** 2150 * CryptSetProviderExA (ADVAPI32.@) 2151 * 2152 * See CryptSetProviderExW. 2153 */ 2154 BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags) 2155 { 2156 BOOL ret = FALSE; 2157 PWSTR str = NULL; 2158 2159 TRACE("(%s, %d, %p, %08x)\n", pszProvName, dwProvType, pdwReserved, dwFlags); 2160 2161 if (CRYPT_ANSIToUnicode(pszProvName, &str, -1)) 2162 { 2163 ret = CryptSetProviderExW(str, dwProvType, pdwReserved, dwFlags); 2164 CRYPT_Free(str); 2165 } 2166 return ret; 2167 } 2168 2169 /****************************************************************************** 2170 * CryptSetProvParam (ADVAPI32.@) 2171 * 2172 * Customizes the operations of a CSP. 2173 * 2174 * PARAMS 2175 * hProv [I] Handle of a CSP. 2176 * dwParam [I] See MSDN Doc. 2177 * pbData [I] Buffer that contains a value to set as a parameter. 2178 * dwFlags [I] if dwParam is PP_USE_HARDWARE_RNG, dwFlags must be zero. 2179 * 2180 * RETURNS 2181 * Success: TRUE 2182 * Failure: FALSE 2183 */ 2184 BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, const BYTE *pbData, DWORD dwFlags) 2185 { 2186 PCRYPTPROV prov = (PCRYPTPROV)hProv; 2187 2188 TRACE("(0x%lx, %d, %p, %08x)\n", hProv, dwParam, pbData, dwFlags); 2189 2190 if (!prov) 2191 { 2192 SetLastError(ERROR_INVALID_HANDLE); 2193 return FALSE; 2194 } 2195 if (prov->dwMagic != MAGIC_CRYPTPROV) 2196 { 2197 SetLastError(ERROR_INVALID_PARAMETER); 2198 return FALSE; 2199 } 2200 if (dwParam == PP_USE_HARDWARE_RNG) 2201 { 2202 FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n"); 2203 FIXME("\tLetting the CSP decide.\n"); 2204 } 2205 if (dwFlags & PP_CLIENT_HWND) 2206 { 2207 /* FIXME: Should verify the parameter */ 2208 if (pbData /* && IsWindow((HWND)pbData) */) 2209 { 2210 crypt_hWindow = (HWND)(pbData); 2211 return TRUE; 2212 } else { 2213 SetLastError(ERROR_INVALID_PARAMETER); 2214 return FALSE; 2215 } 2216 } 2217 /* All other flags go to the CSP */ 2218 return prov->pFuncs->pCPSetProvParam(prov->hPrivate, dwParam, pbData, dwFlags); 2219 } 2220 2221 /****************************************************************************** 2222 * CryptVerifySignatureW (ADVAPI32.@) 2223 * 2224 * Verifies the signature of a hash object. 2225 * 2226 * PARAMS 2227 * hHash [I] Handle of the hash object to verify. 2228 * pbSignature [I] Signature data to verify. 2229 * dwSigLen [I] Size of pbSignature. 2230 * hPubKey [I] Handle to the public key to authenticate signature. 2231 * sDescription [I] Should be NULL. 2232 * dwFlags [I] See MSDN doc. 2233 * 2234 * RETURNS 2235 * Success: TRUE 2236 * Failure: FALSE 2237 * 2238 * NOTES 2239 * Because of security flaws sDescription should not be used and should thus be 2240 * NULL. It is supported only for compatibility with Microsoft's Cryptographic 2241 * Providers. 2242 */ 2243 BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, 2244 HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags) 2245 { 2246 PCRYPTHASH hash = (PCRYPTHASH)hHash; 2247 PCRYPTKEY key = (PCRYPTKEY)hPubKey; 2248 PCRYPTPROV prov; 2249 2250 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature, 2251 dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags); 2252 2253 if (!hash || !key || key->dwMagic != MAGIC_CRYPTKEY || hash->dwMagic != MAGIC_CRYPTHASH || 2254 !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV || 2255 !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 2256 { 2257 SetLastError(ERROR_INVALID_PARAMETER); 2258 return FALSE; 2259 } 2260 2261 prov = hash->pProvider; 2262 return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen, 2263 key->hPrivate, sDescription, dwFlags); 2264 } 2265 2266 /****************************************************************************** 2267 * CryptVerifySignatureA (ADVAPI32.@) 2268 * 2269 * See CryptVerifySignatureW. 2270 */ 2271 BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, 2272 HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags) 2273 { 2274 LPWSTR wsDescription; 2275 BOOL result; 2276 2277 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature, 2278 dwSigLen, hPubKey, debugstr_a(sDescription), dwFlags); 2279 2280 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1); 2281 result = CryptVerifySignatureW(hHash, pbSignature, dwSigLen, hPubKey, wsDescription, dwFlags); 2282 CRYPT_Free(wsDescription); 2283 2284 return result; 2285 } 2286 2287 /****************************************************************************** 2288 * OpenEncryptedFileRawA (ADVAPI32.@) 2289 * 2290 * See OpenEncryptedFileRawW 2291 */ 2292 DWORD WINAPI OpenEncryptedFileRawA(LPCSTR filename, ULONG flags, PVOID *context) 2293 { 2294 FIXME("(%s, %x, %p): stub\n", debugstr_a(filename), flags, context); 2295 return ERROR_CALL_NOT_IMPLEMENTED; 2296 } 2297 2298 /****************************************************************************** 2299 * OpenEncryptedFileRawW (ADVAPI32.@) 2300 * 2301 * Opens an EFS encrypted file for backup/restore 2302 * 2303 * PARAMS 2304 * filename [I] Filename to operate on 2305 * flags [I] Operation to perform 2306 * context [I] Handle to the context (out) 2307 * RETURNS 2308 * Success: ERROR_SUCCESS 2309 * Failure: NTSTATUS error code 2310 */ 2311 DWORD WINAPI OpenEncryptedFileRawW(LPCWSTR filename, ULONG flags, PVOID *context) 2312 { 2313 FIXME("(%s, %x, %p): stub\n", debugstr_w(filename), flags, context); 2314 return ERROR_CALL_NOT_IMPLEMENTED; 2315 } 2316 2317 /****************************************************************************** 2318 * ReadEncryptedFileRaw (ADVAPI32.@) 2319 * 2320 * Export encrypted files 2321 * 2322 * PARAMS 2323 * export [I] pointer to the export callback function 2324 * callback [I] pointer to the application defined context 2325 * context [I] pointer to the system context 2326 * RETURNS 2327 * Success: ERROR_SUCCESS 2328 * Failure: NTSTATUS error code 2329 */ 2330 DWORD WINAPI ReadEncryptedFileRaw(PFE_EXPORT_FUNC export, PVOID callback, PVOID context) 2331 { 2332 FIXME("(%p, %p, %p): stub\n", export, callback, context); 2333 return ERROR_CALL_NOT_IMPLEMENTED; 2334 } 2335 2336 #ifndef __REACTOS__ 2337 /****************************************************************************** 2338 * SystemFunction030 (ADVAPI32.@) 2339 * 2340 * Tests if two blocks of 16 bytes are equal 2341 * 2342 * PARAMS 2343 * b1,b2 [I] block of 16 bytes 2344 * 2345 * RETURNS 2346 * TRUE if blocks are the same 2347 * FALSE if blocks are different 2348 */ 2349 BOOL WINAPI SystemFunction030(LPCVOID b1, LPCVOID b2) 2350 { 2351 return !memcmp(b1, b2, 0x10); 2352 } 2353 2354 /****************************************************************************** 2355 * SystemFunction035 (ADVAPI32.@) 2356 * 2357 * Described here: 2358 http://disc.server.com/discussion.cgi?disc=148775;article=942;title=Coding%2FASM%2FSystem 2359 * 2360 * NOTES 2361 * Stub, always return TRUE. 2362 */ 2363 BOOL WINAPI SystemFunction035(LPCSTR lpszDllFilePath) 2364 { 2365 FIXME("%s: stub\n", debugstr_a(lpszDllFilePath)); 2366 return TRUE; 2367 } 2368 2369 /****************************************************************************** 2370 * SystemFunction036 (ADVAPI32.@) 2371 * 2372 * MSDN documents this function as RtlGenRandom and declares it in ntsecapi.h 2373 * 2374 * PARAMS 2375 * pbBuffer [O] Pointer to memory to receive random bytes. 2376 * dwLen [I] Number of random bytes to fetch. 2377 * 2378 * RETURNS 2379 * Success: TRUE 2380 * Failure: FALSE 2381 */ 2382 2383 BOOLEAN WINAPI SystemFunction036(PVOID pbBuffer, ULONG dwLen) 2384 { 2385 int dev_random; 2386 2387 dev_random = open("/dev/urandom", O_RDONLY); 2388 if (dev_random != -1) 2389 { 2390 if (!IsBadWritePtr( pbBuffer, dwLen ) && 2391 read(dev_random, pbBuffer, dwLen) == (ssize_t)dwLen) 2392 { 2393 close(dev_random); 2394 return TRUE; 2395 } 2396 close(dev_random); 2397 } 2398 else 2399 FIXME("couldn't open /dev/urandom\n"); 2400 SetLastError(NTE_FAIL); 2401 return FALSE; 2402 } 2403 2404 /* 2405 These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory, 2406 in crypt32.dll. 2407 */ 2408 2409 /****************************************************************************** 2410 * SystemFunction040 (ADVAPI32.@) 2411 * 2412 * MSDN documents this function as RtlEncryptMemory and declares it in ntsecapi.h. 2413 * 2414 * PARAMS 2415 * memory [I/O] Pointer to memory to encrypt. 2416 * length [I] Length of region to encrypt in bytes. 2417 * flags [I] Control whether other processes are able to decrypt the memory. 2418 * RTL_ENCRYPT_OPTION_SAME_PROCESS 2419 * RTL_ENCRYPT_OPTION_CROSS_PROCESS 2420 * RTL_ENCRYPT_OPTION_SAME_LOGON 2421 * 2422 * RETURNS 2423 * Success: STATUS_SUCCESS 2424 * Failure: NTSTATUS error code 2425 * 2426 * NOTES 2427 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE. 2428 * If flags are specified when encrypting, the same flag value must be given 2429 * when decrypting the memory. 2430 */ 2431 NTSTATUS WINAPI SystemFunction040(PVOID memory, ULONG length, ULONG flags) 2432 { 2433 FIXME("(%p, %x, %x): stub [RtlEncryptMemory]\n", memory, length, flags); 2434 return STATUS_SUCCESS; 2435 } 2436 2437 /****************************************************************************** 2438 * SystemFunction041 (ADVAPI32.@) 2439 * 2440 * MSDN documents this function as RtlDecryptMemory and declares it in ntsecapi.h. 2441 * 2442 * PARAMS 2443 * memory [I/O] Pointer to memory to decrypt. 2444 * length [I] Length of region to decrypt in bytes. 2445 * flags [I] Control whether other processes are able to decrypt the memory. 2446 * RTL_ENCRYPT_OPTION_SAME_PROCESS 2447 * RTL_ENCRYPT_OPTION_CROSS_PROCESS 2448 * RTL_ENCRYPT_OPTION_SAME_LOGON 2449 * 2450 * RETURNS 2451 * Success: STATUS_SUCCESS 2452 * Failure: NTSTATUS error code 2453 * 2454 * NOTES 2455 * length must be a multiple of RTL_ENCRYPT_MEMORY_SIZE. 2456 * If flags are specified when encrypting, the same flag value must be given 2457 * when decrypting the memory. 2458 */ 2459 NTSTATUS WINAPI SystemFunction041(PVOID memory, ULONG length, ULONG flags) 2460 { 2461 FIXME("(%p, %x, %x): stub [RtlDecryptMemory]\n", memory, length, flags); 2462 return STATUS_SUCCESS; 2463 } 2464 #endif /* !__REACTOS __ */ 2465 2466 /****************************************************************************** 2467 * WriteEncryptedFileRaw (ADVAPI32.@) 2468 * 2469 * Import encrypted files 2470 * 2471 * PARAMS 2472 * import [I] pointer to the import callback function 2473 * callback [I] pointer to the application defined context 2474 * context [I] pointer to the system context 2475 * RETURNS 2476 * Success: ERROR_SUCCESS 2477 * Failure: NTSTATUS error code 2478 */ 2479 DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC import, PVOID callback, PVOID context) 2480 { 2481 FIXME("(%p, %p, %p): stub\n", import, callback, context); 2482 return ERROR_CALL_NOT_IMPLEMENTED; 2483 } 2484