Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencrypt.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 1999 Ian Schmidt 00003 * Copyright 2001 Travis Michielsen 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 /*********************************************************************** 00021 * 00022 * TODO: 00023 * - Reference counting 00024 * - Thread-safing 00025 */ 00026 00027 #include <advapi32.h> 00028 WINE_DEFAULT_DEBUG_CHANNEL(crypt); 00029 00030 00031 /* 00032 * Note: this code is harmless on little-endian machines. 00033 */ 00034 VOID byteReverse(unsigned char *buf, unsigned longs) 00035 { 00036 unsigned int t; 00037 00038 do 00039 { 00040 t = (unsigned int)((unsigned)buf[3] << 8 | buf[2]) << 16 | 00041 ((unsigned)buf[1] << 8 | buf[0]); 00042 *(unsigned int *)buf = t; 00043 buf += 4; 00044 } while (--longs); 00045 } 00046 00047 static HWND crypt_hWindow ; 00048 00049 #define CRYPT_Alloc(size) (LocalAlloc(LMEM_ZEROINIT, size)) 00050 #define CRYPT_Free(buffer) (LocalFree(buffer)) 00051 00052 static inline PWSTR CRYPT_GetProvKeyName(PCWSTR pProvName) 00053 { 00054 static const WCHAR KEYSTR[] = { 00055 'S','o','f','t','w','a','r','e','\\', 00056 'M','i','c','r','o','s','o','f','t','\\', 00057 'C','r','y','p','t','o','g','r','a','p','h','y','\\', 00058 'D','e','f','a','u','l','t','s','\\', 00059 'P','r','o','v','i','d','e','r','\\',0 00060 }; 00061 PWSTR keyname; 00062 00063 keyname = CRYPT_Alloc((strlenW(KEYSTR) + strlenW(pProvName) +1)*sizeof(WCHAR)); 00064 if (keyname) 00065 { 00066 strcpyW(keyname, KEYSTR); 00067 strcpyW(keyname + strlenW(KEYSTR), pProvName); 00068 } else 00069 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00070 return keyname; 00071 } 00072 00073 static inline PWSTR CRYPT_GetTypeKeyName(DWORD dwType, BOOL user) 00074 { 00075 static const WCHAR MACHINESTR[] = { 00076 'S','o','f','t','w','a','r','e','\\', 00077 'M','i','c','r','o','s','o','f','t','\\', 00078 'C','r','y','p','t','o','g','r','a','p','h','y','\\', 00079 'D','e','f','a','u','l','t','s','\\', 00080 'P','r','o','v','i','d','e','r',' ','T','y','p','e','s','\\', 00081 'T','y','p','e',' ','X','X','X',0 00082 }; 00083 static const WCHAR USERSTR[] = { 00084 'S','o','f','t','w','a','r','e','\\', 00085 'M','i','c','r','o','s','o','f','t','\\', 00086 'C','r','y','p','t','o','g','r','a','p','h','y','\\', 00087 'P','r','o','v','i','d','e','r',' ','T','y','p','e',' ','X','X','X',0 00088 }; 00089 PWSTR keyname; 00090 PWSTR ptr; 00091 00092 keyname = CRYPT_Alloc( ((user ? strlenW(USERSTR) : strlenW(MACHINESTR)) +1)*sizeof(WCHAR)); 00093 if (keyname) 00094 { 00095 user ? strcpyW(keyname, USERSTR) : strcpyW(keyname, MACHINESTR); 00096 ptr = keyname + strlenW(keyname); 00097 *(--ptr) = (dwType % 10) + '0'; 00098 *(--ptr) = ((dwType / 10) % 10) + '0'; 00099 *(--ptr) = (dwType / 100) + '0'; 00100 } else 00101 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00102 return keyname; 00103 } 00104 00105 /* CRYPT_UnicodeTOANSI 00106 * wstr - unicode string 00107 * str - pointer to ANSI string 00108 * strsize - size of buffer pointed to by str or -1 if we have to do the allocation 00109 * 00110 * returns TRUE if unsuccessful, FALSE otherwise. 00111 * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call 00112 */ 00113 static inline BOOL CRYPT_UnicodeToANSI(LPCWSTR wstr, LPSTR* str, int strsize) 00114 { 00115 int count; 00116 00117 if (!wstr) 00118 { 00119 *str = NULL; 00120 return TRUE; 00121 } 00122 count = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); 00123 if (strsize == -1) 00124 *str = CRYPT_Alloc(count * sizeof(CHAR)); 00125 else 00126 count = min( count, strsize ); 00127 if (*str) 00128 { 00129 WideCharToMultiByte(CP_ACP, 0, wstr, -1, *str, count, NULL, NULL); 00130 return TRUE; 00131 } 00132 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00133 return FALSE; 00134 } 00135 00136 /* CRYPT_ANSITOUnicode 00137 * str - ANSI string 00138 * wstr - pointer to unicode string 00139 * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation 00140 */ 00141 static inline BOOL CRYPT_ANSIToUnicode(LPCSTR str, LPWSTR* wstr, int wstrsize) 00142 { 00143 unsigned int wcount; 00144 00145 if (!str) 00146 { 00147 *wstr = NULL; 00148 return TRUE; 00149 } 00150 wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); 00151 if (wstrsize == -1) 00152 *wstr = CRYPT_Alloc(wcount * sizeof(WCHAR)); 00153 else 00154 wcount = min( wcount, wstrsize/sizeof(WCHAR) ); 00155 if (*wstr) 00156 { 00157 MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount); 00158 return TRUE; 00159 } 00160 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00161 return FALSE; 00162 } 00163 00164 /* These next 2 functions are used by the VTableProvStruc structure */ 00165 static BOOL CALLBACK CRYPT_VerifyImage(LPCSTR lpszImage, BYTE* pData) 00166 { 00167 if (!lpszImage || !pData) 00168 { 00169 SetLastError(ERROR_INVALID_PARAMETER); 00170 return FALSE; 00171 } 00172 00173 FIXME("(%s, %p): not verifying image\n", lpszImage, pData); 00174 00175 return TRUE; 00176 } 00177 00178 static BOOL CALLBACK CRYPT_ReturnhWnd(HWND *phWnd) 00179 { 00180 if (!phWnd) 00181 return FALSE; 00182 *phWnd = crypt_hWindow; 00183 return TRUE; 00184 } 00185 00186 #define CRYPT_GetProvFunc(name) \ 00187 if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error 00188 #define CRYPT_GetProvFuncOpt(name) \ 00189 provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name) 00190 static PCRYPTPROV CRYPT_LoadProvider(PCWSTR pImage) 00191 { 00192 PCRYPTPROV provider; 00193 DWORD errorcode = ERROR_NOT_ENOUGH_MEMORY; 00194 00195 if ( !(provider = CRYPT_Alloc(sizeof(CRYPTPROV))) ) goto error; 00196 if ( !(provider->pFuncs = CRYPT_Alloc(sizeof(PROVFUNCS))) ) goto error; 00197 if ( !(provider->pVTable = CRYPT_Alloc(sizeof(VTableProvStruc))) ) goto error; 00198 if ( !(provider->hModule = LoadLibraryW(pImage)) ) 00199 { 00200 errorcode = (GetLastError() == ERROR_FILE_NOT_FOUND) ? NTE_PROV_DLL_NOT_FOUND : NTE_PROVIDER_DLL_FAIL; 00201 FIXME("Failed to load dll %s\n", debugstr_w(pImage)); 00202 goto error; 00203 } 00204 provider->dwMagic = MAGIC_CRYPTPROV; 00205 provider->refcount = 1; 00206 00207 errorcode = NTE_PROVIDER_DLL_FAIL; 00208 CRYPT_GetProvFunc(CPAcquireContext); 00209 CRYPT_GetProvFunc(CPCreateHash); 00210 CRYPT_GetProvFunc(CPDecrypt); 00211 CRYPT_GetProvFunc(CPDeriveKey); 00212 CRYPT_GetProvFunc(CPDestroyHash); 00213 CRYPT_GetProvFunc(CPDestroyKey); 00214 CRYPT_GetProvFuncOpt(CPDuplicateHash); 00215 CRYPT_GetProvFuncOpt(CPDuplicateKey); 00216 CRYPT_GetProvFunc(CPEncrypt); 00217 CRYPT_GetProvFunc(CPExportKey); 00218 CRYPT_GetProvFunc(CPGenKey); 00219 CRYPT_GetProvFunc(CPGenRandom); 00220 CRYPT_GetProvFunc(CPGetHashParam); 00221 CRYPT_GetProvFunc(CPGetKeyParam); 00222 CRYPT_GetProvFunc(CPGetProvParam); 00223 CRYPT_GetProvFunc(CPGetUserKey); 00224 CRYPT_GetProvFunc(CPHashData); 00225 CRYPT_GetProvFunc(CPHashSessionKey); 00226 CRYPT_GetProvFunc(CPImportKey); 00227 CRYPT_GetProvFunc(CPReleaseContext); 00228 CRYPT_GetProvFunc(CPSetHashParam); 00229 CRYPT_GetProvFunc(CPSetKeyParam); 00230 CRYPT_GetProvFunc(CPSetProvParam); 00231 CRYPT_GetProvFunc(CPSignHash); 00232 CRYPT_GetProvFunc(CPVerifySignature); 00233 00234 /* FIXME: Not sure what the pbContextInfo field is for. 00235 * Does it need memory allocation? 00236 */ 00237 provider->pVTable->Version = 3; 00238 provider->pVTable->FuncVerifyImage = CRYPT_VerifyImage; 00239 provider->pVTable->FuncReturnhWnd = CRYPT_ReturnhWnd; 00240 provider->pVTable->dwProvType = 0; 00241 provider->pVTable->pbContextInfo = NULL; 00242 provider->pVTable->cbContextInfo = 0; 00243 provider->pVTable->pszProvName = NULL; 00244 return provider; 00245 00246 error: 00247 SetLastError(errorcode); 00248 if (provider) 00249 { 00250 provider->dwMagic = 0; 00251 if (provider->hModule) 00252 FreeLibrary(provider->hModule); 00253 CRYPT_Free(provider->pVTable); 00254 CRYPT_Free(provider->pFuncs); 00255 CRYPT_Free(provider); 00256 } 00257 return NULL; 00258 } 00259 #undef CRYPT_GetProvFunc 00260 #undef CRYPT_GetProvFuncOpt 00261 00262 00263 static void CRYPT_CreateMachineGuid(void) 00264 { 00265 static const WCHAR cryptographyW[] = { 00266 'S','o','f','t','w','a','r','e','\\', 00267 'M','i','c','r','o','s','o','f','t','\\', 00268 'C','r','y','p','t','o','g','r','a','p','h','y',0 }; 00269 static const WCHAR machineGuidW[] = { 00270 'M','a','c','h','i','n','e','G','u','i','d',0 }; 00271 LONG r; 00272 HKEY key; 00273 00274 r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, cryptographyW, 0, KEY_ALL_ACCESS, 00275 &key); 00276 if (!r) 00277 { 00278 DWORD size; 00279 00280 r = RegQueryValueExW(key, machineGuidW, NULL, NULL, NULL, &size); 00281 if (r == ERROR_FILE_NOT_FOUND) 00282 { 00283 UUID uuid; 00284 WCHAR buf[37]; 00285 RPC_STATUS rs; 00286 static const WCHAR uuidFmt[] = { 00287 '%','0','8','x','-','%','0','4','x','-', 00288 '%','0','4','x','-','%','0','2','x', 00289 '%','0','2','x','-','%','0','2','x', 00290 '%','0','2','x','%','0','2','x', 00291 '%','0','2','x','%','0','2','x', 00292 '%','0','2','x',0 }; 00293 00294 rs = UuidCreate(&uuid); 00295 if (rs == S_OK) 00296 { 00297 sprintfW(buf, uuidFmt, 00298 uuid.Data1, uuid.Data2, uuid.Data3, 00299 uuid.Data4[0], uuid.Data4[1], 00300 uuid.Data4[2], uuid.Data4[3], 00301 uuid.Data4[4], uuid.Data4[5], 00302 uuid.Data4[6], uuid.Data4[7] ); 00303 RegSetValueExW(key, machineGuidW, 0, REG_SZ, 00304 (const BYTE *)buf, 00305 (lstrlenW(buf)+1)*sizeof(WCHAR)); 00306 } 00307 } 00308 RegCloseKey(key); 00309 } 00310 } 00311 00312 /****************************************************************************** 00313 * CryptAcquireContextW (ADVAPI32.@) 00314 * 00315 * Acquire a crypto provider context handle. 00316 * 00317 * PARAMS 00318 * phProv [O] Pointer to HCRYPTPROV for the output. 00319 * pszContainer [I] Key Container Name 00320 * pszProvider [I] Cryptographic Service Provider Name 00321 * dwProvType [I] Crypto provider type to get a handle. 00322 * dwFlags [I] flags for the operation 00323 * 00324 * RETURNS 00325 * TRUE on success, FALSE on failure. 00326 */ 00327 BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer, 00328 LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags) 00329 { 00330 PCRYPTPROV pProv = NULL; 00331 HKEY key; 00332 PWSTR imagepath = NULL, keyname = NULL, provname = NULL, temp = NULL; 00333 PSTR provnameA = NULL, pszContainerA = NULL; 00334 DWORD keytype, type, len; 00335 ULONG r; 00336 static const WCHAR nameW[] = {'N','a','m','e',0}; 00337 static const WCHAR typeW[] = {'T','y','p','e',0}; 00338 static const WCHAR imagepathW[] = {'I','m','a','g','e',' ','P','a','t','h',0}; 00339 00340 TRACE("(%p, %s, %s, %d, %08x)\n", phProv, debugstr_w(pszContainer), 00341 debugstr_w(pszProvider), dwProvType, dwFlags); 00342 00343 if (dwProvType < 1 || dwProvType > MAXPROVTYPES) 00344 { 00345 SetLastError(NTE_BAD_PROV_TYPE); 00346 return FALSE; 00347 } 00348 00349 if (!phProv) 00350 { 00351 SetLastError(ERROR_INVALID_PARAMETER); 00352 return FALSE; 00353 } 00354 00355 /* Make sure the MachineGuid value exists */ 00356 CRYPT_CreateMachineGuid(); 00357 00358 if (!pszProvider || !*pszProvider) 00359 { 00360 /* No CSP name specified so try the user default CSP first 00361 * then try the machine default CSP 00362 */ 00363 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, TRUE)) ) { 00364 TRACE("No provider registered for crypto provider type %d.\n", dwProvType); 00365 SetLastError(NTE_PROV_TYPE_NOT_DEF); 00366 return FALSE; 00367 } 00368 if (RegOpenKeyW(HKEY_CURRENT_USER, keyname, &key)) 00369 { 00370 CRYPT_Free(keyname); 00371 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, FALSE)) ) { 00372 TRACE("No type registered for crypto provider type %d.\n", dwProvType); 00373 RegCloseKey(key); 00374 SetLastError(NTE_PROV_TYPE_NOT_DEF); 00375 goto error; 00376 } 00377 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, keyname, &key)) { 00378 TRACE("Did not find registry entry of crypto provider for %s.\n", debugstr_w(keyname)); 00379 CRYPT_Free(keyname); 00380 RegCloseKey(key); 00381 SetLastError(NTE_PROV_TYPE_NOT_DEF); 00382 goto error; 00383 } 00384 } 00385 CRYPT_Free(keyname); 00386 r = RegQueryValueExW(key, nameW, NULL, &keytype, NULL, &len); 00387 if( r != ERROR_SUCCESS || !len || keytype != REG_SZ) 00388 { 00389 TRACE("error %d reading size of 'Name' from registry\n", r ); 00390 RegCloseKey(key); 00391 SetLastError(NTE_PROV_TYPE_ENTRY_BAD); 00392 goto error; 00393 } 00394 if(!(provname = CRYPT_Alloc(len))) 00395 { 00396 RegCloseKey(key); 00397 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00398 goto error; 00399 } 00400 r = RegQueryValueExW(key, nameW, NULL, NULL, (LPBYTE)provname, &len); 00401 if( r != ERROR_SUCCESS ) 00402 { 00403 TRACE("error %d reading 'Name' from registry\n", r ); 00404 RegCloseKey(key); 00405 SetLastError(NTE_PROV_TYPE_ENTRY_BAD); 00406 goto error; 00407 } 00408 RegCloseKey(key); 00409 } else { 00410 if ( !(provname = CRYPT_Alloc((strlenW(pszProvider) +1)*sizeof(WCHAR))) ) 00411 { 00412 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00413 goto error; 00414 } 00415 strcpyW(provname, pszProvider); 00416 } 00417 00418 keyname = CRYPT_GetProvKeyName(provname); 00419 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, keyname, &key); 00420 CRYPT_Free(keyname); 00421 if (r != ERROR_SUCCESS) 00422 { 00423 SetLastError(NTE_KEYSET_NOT_DEF); 00424 goto error; 00425 } 00426 len = sizeof(DWORD); 00427 r = RegQueryValueExW(key, typeW, NULL, NULL, (BYTE*)&type, &len); 00428 if (r != ERROR_SUCCESS) 00429 { 00430 SetLastError(NTE_PROV_TYPE_ENTRY_BAD); 00431 goto error; 00432 } 00433 if (type != dwProvType) 00434 { 00435 TRACE("Crypto provider has wrong type (%d vs expected %d).\n", type, dwProvType); 00436 SetLastError(NTE_PROV_TYPE_NO_MATCH); 00437 goto error; 00438 } 00439 00440 r = RegQueryValueExW(key, imagepathW, NULL, &keytype, NULL, &len); 00441 if ( r != ERROR_SUCCESS || keytype != REG_SZ) 00442 { 00443 TRACE("error %d reading size of 'Image Path' from registry\n", r ); 00444 RegCloseKey(key); 00445 SetLastError(NTE_PROV_TYPE_ENTRY_BAD); 00446 goto error; 00447 } 00448 if (!(temp = CRYPT_Alloc(len))) 00449 { 00450 RegCloseKey(key); 00451 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00452 goto error; 00453 } 00454 r = RegQueryValueExW(key, imagepathW, NULL, NULL, (LPBYTE)temp, &len); 00455 if( r != ERROR_SUCCESS ) 00456 { 00457 TRACE("error %d reading 'Image Path' from registry\n", r ); 00458 RegCloseKey(key); 00459 SetLastError(NTE_PROV_TYPE_ENTRY_BAD); 00460 goto error; 00461 } 00462 RegCloseKey(key); 00463 len = ExpandEnvironmentStringsW(temp, NULL, 0); 00464 if ( !(imagepath = CRYPT_Alloc(len*sizeof(WCHAR))) ) 00465 { 00466 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00467 goto error; 00468 } 00469 if (!ExpandEnvironmentStringsW(temp, imagepath, len)) 00470 { 00471 /* ExpandEnvironmentStrings will call SetLastError */ 00472 goto error; 00473 } 00474 pProv = CRYPT_LoadProvider(imagepath); 00475 if (!pProv) { 00476 /* CRYPT_LoadProvider calls SetLastError */ 00477 goto error; 00478 } 00479 pProv->pVTable->dwProvType = dwProvType; 00480 if(!CRYPT_UnicodeToANSI(provname, &provnameA, -1)) 00481 { 00482 /* CRYPT_UnicodeToANSI calls SetLastError */ 00483 goto error; 00484 } 00485 pProv->pVTable->pszProvName = provnameA; 00486 if(!CRYPT_UnicodeToANSI(pszContainer, &pszContainerA, -1)) 00487 { 00488 /* CRYPT_UnicodeToANSI calls SetLastError */ 00489 goto error; 00490 } 00491 if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, pszContainerA, dwFlags, pProv->pVTable)) 00492 { 00493 /* MSDN: When this flag is set, the value returned in phProv is undefined, 00494 * and thus, the CryptReleaseContext function need not be called afterwards. 00495 * Therefore, we must clean up everything now. 00496 */ 00497 if (dwFlags & CRYPT_DELETEKEYSET) 00498 { 00499 pProv->dwMagic = 0; 00500 FreeLibrary(pProv->hModule); 00501 CRYPT_Free(provnameA); 00502 CRYPT_Free(pProv->pVTable); 00503 CRYPT_Free(pProv->pFuncs); 00504 CRYPT_Free(pProv); 00505 } else { 00506 *phProv = (HCRYPTPROV)pProv; 00507 } 00508 CRYPT_Free(pszContainerA); 00509 CRYPT_Free(provname); 00510 CRYPT_Free(temp); 00511 CRYPT_Free(imagepath); 00512 return TRUE; 00513 } 00514 /* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */ 00515 error: 00516 if (pProv) 00517 { 00518 pProv->dwMagic = 0; 00519 if (pProv->hModule) 00520 FreeLibrary(pProv->hModule); 00521 CRYPT_Free(pProv->pVTable); 00522 CRYPT_Free(pProv->pFuncs); 00523 CRYPT_Free(pProv); 00524 } 00525 CRYPT_Free(pszContainerA); 00526 CRYPT_Free(provnameA); 00527 CRYPT_Free(provname); 00528 CRYPT_Free(temp); 00529 CRYPT_Free(imagepath); 00530 return FALSE; 00531 } 00532 00533 /****************************************************************************** 00534 * CryptAcquireContextA (ADVAPI32.@) 00535 * 00536 * See CryptAcquireContextW. 00537 */ 00538 BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer, 00539 LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags) 00540 { 00541 PWSTR pProvider = NULL, pContainer = NULL; 00542 BOOL ret = FALSE; 00543 00544 TRACE("(%p, %s, %s, %d, %08x)\n", phProv, pszContainer, 00545 pszProvider, dwProvType, dwFlags); 00546 00547 if ( !CRYPT_ANSIToUnicode(pszContainer, &pContainer, -1) ) 00548 { 00549 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00550 return FALSE; 00551 } 00552 if ( !CRYPT_ANSIToUnicode(pszProvider, &pProvider, -1) ) 00553 { 00554 CRYPT_Free(pContainer); 00555 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00556 return FALSE; 00557 } 00558 00559 ret = CryptAcquireContextW(phProv, pContainer, pProvider, dwProvType, dwFlags); 00560 00561 CRYPT_Free(pContainer); 00562 CRYPT_Free(pProvider); 00563 00564 return ret; 00565 } 00566 00567 /****************************************************************************** 00568 * CryptContextAddRef (ADVAPI32.@) 00569 * 00570 * Increases reference count of a cryptographic service provider handle 00571 * by one. 00572 * 00573 * PARAMS 00574 * hProv [I] Handle to the CSP whose reference is being incremented. 00575 * pdwReserved [IN] Reserved for future use and must be NULL. 00576 * dwFlags [I] Reserved for future use and must be NULL. 00577 * 00578 * RETURNS 00579 * Success: TRUE 00580 * Failure: FALSE 00581 */ 00582 BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags) 00583 { 00584 PCRYPTPROV pProv = (PCRYPTPROV)hProv; 00585 00586 TRACE("(0x%lx, %p, %08x)\n", hProv, pdwReserved, dwFlags); 00587 00588 if (!pProv) 00589 { 00590 SetLastError(NTE_BAD_UID); 00591 return FALSE; 00592 } 00593 00594 if (pProv->dwMagic != MAGIC_CRYPTPROV) 00595 { 00596 SetLastError(ERROR_INVALID_PARAMETER); 00597 return FALSE; 00598 } 00599 00600 pProv->refcount++; 00601 return TRUE; 00602 } 00603 00604 /****************************************************************************** 00605 * CryptReleaseContext (ADVAPI32.@) 00606 * 00607 * Releases the handle of a CSP. Reference count is decreased. 00608 * 00609 * PARAMS 00610 * hProv [I] Handle of a CSP. 00611 * dwFlags [I] Reserved for future use and must be NULL. 00612 * 00613 * RETURNS 00614 * Success: TRUE 00615 * Failure: FALSE 00616 */ 00617 BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags) 00618 { 00619 PCRYPTPROV pProv = (PCRYPTPROV)hProv; 00620 BOOL ret = TRUE; 00621 00622 TRACE("(0x%lx, %08lx)\n", hProv, dwFlags); 00623 00624 if (!pProv) 00625 { 00626 SetLastError(NTE_BAD_UID); 00627 return FALSE; 00628 } 00629 00630 if (pProv->dwMagic != MAGIC_CRYPTPROV) 00631 { 00632 SetLastError(ERROR_INVALID_PARAMETER); 00633 return FALSE; 00634 } 00635 00636 pProv->refcount--; 00637 if (pProv->refcount <= 0) 00638 { 00639 ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags); 00640 pProv->dwMagic = 0; 00641 FreeLibrary(pProv->hModule); 00642 #if 0 00643 CRYPT_Free(pProv->pVTable->pContextInfo); 00644 #endif 00645 CRYPT_Free(pProv->pVTable->pszProvName); 00646 CRYPT_Free(pProv->pVTable); 00647 CRYPT_Free(pProv->pFuncs); 00648 CRYPT_Free(pProv); 00649 } 00650 return ret; 00651 } 00652 00653 /****************************************************************************** 00654 * CryptGenRandom (ADVAPI32.@) 00655 * 00656 * Fills a buffer with cryptographically random bytes. 00657 * 00658 * PARAMS 00659 * hProv [I] Handle of a CSP. 00660 * dwLen [I] Number of bytes to generate. 00661 * pbBuffer [I/O] Buffer to contain random bytes. 00662 * 00663 * RETURNS 00664 * Success: TRUE 00665 * Failure: FALSE 00666 * 00667 * NOTES 00668 * pdBuffer must be at least dwLen bytes long. 00669 */ 00670 BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) 00671 { 00672 PCRYPTPROV prov = (PCRYPTPROV)hProv; 00673 00674 TRACE("(0x%lx, %d, %p)\n", hProv, dwLen, pbBuffer); 00675 00676 if (!hProv) 00677 { 00678 SetLastError(ERROR_INVALID_HANDLE); 00679 return FALSE; 00680 } 00681 00682 if (prov->dwMagic != MAGIC_CRYPTPROV) 00683 { 00684 SetLastError(ERROR_INVALID_PARAMETER); 00685 return FALSE; 00686 } 00687 00688 return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer); 00689 } 00690 00691 /****************************************************************************** 00692 * CryptCreateHash (ADVAPI32.@) 00693 * 00694 * Initiates the hashing of a stream of data. 00695 * 00696 * PARAMS 00697 * hProv [I] Handle of a CSP. 00698 * Algid [I] Identifies the hash algorithm to use. 00699 * hKey [I] Key for the hash (if required). 00700 * dwFlags [I] Reserved for future use and must be NULL. 00701 * phHash [O] Address of the future handle to the new hash object. 00702 * 00703 * RETURNS 00704 * Success: TRUE 00705 * Failure: FALSE 00706 * 00707 * NOTES 00708 * If the algorithm is a keyed hash, hKey is the key. 00709 */ 00710 BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, 00711 DWORD dwFlags, HCRYPTHASH *phHash) 00712 { 00713 PCRYPTPROV prov = (PCRYPTPROV)hProv; 00714 PCRYPTKEY key = (PCRYPTKEY)hKey; 00715 PCRYPTHASH hash; 00716 00717 TRACE("(0x%lx, 0x%x, 0x%lx, %08x, %p)\n", hProv, Algid, hKey, dwFlags, phHash); 00718 00719 if (!prov) 00720 { 00721 SetLastError(ERROR_INVALID_HANDLE); 00722 return FALSE; 00723 } 00724 if (!phHash || prov->dwMagic != MAGIC_CRYPTPROV) 00725 { 00726 SetLastError(ERROR_INVALID_PARAMETER); 00727 return FALSE; 00728 } 00729 if (dwFlags) 00730 { 00731 SetLastError(NTE_BAD_FLAGS); 00732 return FALSE; 00733 } 00734 if ( !(hash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) 00735 { 00736 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00737 return FALSE; 00738 } 00739 00740 hash->pProvider = prov; 00741 00742 if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid, 00743 key ? key->hPrivate : 0, 0, &hash->hPrivate)) 00744 { 00745 *phHash = (HCRYPTHASH)hash; 00746 return TRUE; 00747 } 00748 00749 /* CSP error! */ 00750 CRYPT_Free(hash); 00751 *phHash = 0; 00752 return FALSE; 00753 } 00754 00755 /****************************************************************************** 00756 * CryptDecrypt (ADVAPI32.@) 00757 * 00758 * Decrypts data encrypted by CryptEncrypt. 00759 * 00760 * PARAMS 00761 * hKey [I] Handle to the decryption key. 00762 * hHash [I] Handle to a hash object. 00763 * Final [I] TRUE if this is the last section to be decrypted. 00764 * dwFlags [I] Reserved for future use. Can be CRYPT_OAEP. 00765 * pbData [I/O] Buffer that holds the encrypted data. Holds decrypted 00766 * data on return 00767 * pdwDataLen [I/O] Length of pbData before and after the call. 00768 * 00769 * RETURNS 00770 * Success: TRUE 00771 * Failure: FALSE 00772 */ 00773 BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, 00774 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) 00775 { 00776 PCRYPTPROV prov; 00777 PCRYPTKEY key = (PCRYPTKEY)hKey; 00778 PCRYPTHASH hash = (PCRYPTHASH)hHash; 00779 00780 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen); 00781 00782 if (!key || !pbData || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 00783 { 00784 SetLastError(ERROR_INVALID_PARAMETER); 00785 return FALSE; 00786 } 00787 00788 prov = key->pProvider; 00789 return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, 00790 Final, dwFlags, pbData, pdwDataLen); 00791 } 00792 00793 /****************************************************************************** 00794 * CryptDeriveKey (ADVAPI32.@) 00795 * 00796 * Generates session keys derived from a base data value. 00797 * 00798 * PARAMS 00799 * hProv [I] Handle to a CSP. 00800 * Algid [I] Identifies the symmetric encryption algorithm to use. 00801 * hBaseData [I] Handle to a hash object. 00802 * dwFlags [I] Type of key to generate. 00803 * phKey [I/O] Address of the newly generated key. 00804 * 00805 * RETURNS 00806 * Success: TRUE 00807 * Failure: FALSE 00808 */ 00809 BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, 00810 DWORD dwFlags, HCRYPTKEY *phKey) 00811 { 00812 PCRYPTPROV prov = (PCRYPTPROV)hProv; 00813 PCRYPTHASH hash = (PCRYPTHASH)hBaseData; 00814 PCRYPTKEY key; 00815 00816 TRACE("(0x%lx, 0x%08x, 0x%lx, 0x%08x, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey); 00817 00818 if (!prov || !hash) 00819 { 00820 SetLastError(ERROR_INVALID_HANDLE); 00821 return FALSE; 00822 } 00823 if (!phKey || prov->dwMagic != MAGIC_CRYPTPROV) 00824 { 00825 SetLastError(ERROR_INVALID_PARAMETER); 00826 return FALSE; 00827 } 00828 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 00829 { 00830 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00831 return FALSE; 00832 } 00833 00834 key->pProvider = prov; 00835 if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate)) 00836 { 00837 *phKey = (HCRYPTKEY)key; 00838 return TRUE; 00839 } 00840 00841 /* CSP error! */ 00842 CRYPT_Free(key); 00843 *phKey = 0; 00844 return FALSE; 00845 } 00846 00847 /****************************************************************************** 00848 * CryptDestroyHash (ADVAPI32.@) 00849 * 00850 * Destroys the hash object referenced by hHash. 00851 * 00852 * PARAMS 00853 * hHash [I] Handle of the hash object to be destroyed. 00854 * 00855 * RETURNS 00856 * Success: TRUE 00857 * Failure: FALSE 00858 */ 00859 BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash) 00860 { 00861 PCRYPTHASH hash = (PCRYPTHASH)hHash; 00862 PCRYPTPROV prov; 00863 BOOL ret; 00864 00865 TRACE("(0x%lx)\n", hHash); 00866 00867 if (!hash) 00868 { 00869 SetLastError(ERROR_INVALID_HANDLE); 00870 return FALSE; 00871 } 00872 00873 if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 00874 { 00875 SetLastError(ERROR_INVALID_PARAMETER); 00876 return FALSE; 00877 } 00878 00879 prov = hash->pProvider; 00880 ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate); 00881 CRYPT_Free(hash); 00882 return ret; 00883 } 00884 00885 /****************************************************************************** 00886 * CryptDestroyKey (ADVAPI32.@) 00887 * 00888 * Releases the handle referenced by hKey. 00889 * 00890 * PARAMS 00891 * hKey [I] Handle of the key to be destroyed. 00892 * 00893 * RETURNS 00894 * Success: TRUE 00895 * Failure: FALSE 00896 */ 00897 BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey) 00898 { 00899 PCRYPTKEY key = (PCRYPTKEY)hKey; 00900 PCRYPTPROV prov; 00901 BOOL ret; 00902 00903 TRACE("(0x%lx)\n", hKey); 00904 00905 if (!key) 00906 { 00907 SetLastError(ERROR_INVALID_HANDLE); 00908 return FALSE; 00909 } 00910 00911 if (!key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 00912 { 00913 SetLastError(ERROR_INVALID_PARAMETER); 00914 return FALSE; 00915 } 00916 00917 prov = key->pProvider; 00918 ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate); 00919 CRYPT_Free(key); 00920 return ret; 00921 } 00922 00923 /****************************************************************************** 00924 * CryptDuplicateHash (ADVAPI32.@) 00925 * 00926 * Duplicates a hash. 00927 * 00928 * PARAMS 00929 * hHash [I] Handle to the hash to be copied. 00930 * pdwReserved [I] Reserved for future use and must be zero. 00931 * dwFlags [I] Reserved for future use and must be zero. 00932 * phHash [O] Address of the handle to receive the copy. 00933 * 00934 * RETURNS 00935 * Success: TRUE 00936 * Failure: FALSE 00937 */ 00938 BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved, 00939 DWORD dwFlags, HCRYPTHASH *phHash) 00940 { 00941 PCRYPTPROV prov; 00942 PCRYPTHASH orghash, newhash; 00943 00944 TRACE("(0x%lx, %p, %08x, %p)\n", hHash, pdwReserved, dwFlags, phHash); 00945 00946 orghash = (PCRYPTHASH)hHash; 00947 if (!orghash || pdwReserved || !phHash || !orghash->pProvider || 00948 orghash->pProvider->dwMagic != MAGIC_CRYPTPROV) 00949 { 00950 SetLastError(ERROR_INVALID_PARAMETER); 00951 return FALSE; 00952 } 00953 00954 prov = orghash->pProvider; 00955 if (!prov->pFuncs->pCPDuplicateHash) 00956 { 00957 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00958 return FALSE; 00959 } 00960 00961 if ( !(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))) ) 00962 { 00963 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00964 return FALSE; 00965 } 00966 00967 newhash->pProvider = prov; 00968 if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate)) 00969 { 00970 *phHash = (HCRYPTHASH)newhash; 00971 return TRUE; 00972 } 00973 CRYPT_Free(newhash); 00974 return FALSE; 00975 } 00976 00977 /****************************************************************************** 00978 * CryptDuplicateKey (ADVAPI32.@) 00979 * 00980 * Duplicate a key and the key's state. 00981 * 00982 * PARAMS 00983 * hKey [I] Handle of the key to copy. 00984 * pdwReserved [I] Reserved for future use and must be NULL. 00985 * dwFlags [I] Reserved for future use and must be zero. 00986 * phKey [I] Address of the handle to the duplicated key. 00987 * 00988 * RETURNS 00989 * Success: TRUE 00990 * Failure: FALSE 00991 */ 00992 BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey) 00993 { 00994 PCRYPTPROV prov; 00995 PCRYPTKEY orgkey, newkey; 00996 00997 TRACE("(0x%lx, %p, %08x, %p)\n", hKey, pdwReserved, dwFlags, phKey); 00998 00999 orgkey = (PCRYPTKEY)hKey; 01000 if (!orgkey || pdwReserved || !phKey || !orgkey->pProvider || 01001 orgkey->pProvider->dwMagic != MAGIC_CRYPTPROV) 01002 { 01003 SetLastError(ERROR_INVALID_PARAMETER); 01004 return FALSE; 01005 } 01006 01007 prov = orgkey->pProvider; 01008 if (!prov->pFuncs->pCPDuplicateKey) 01009 { 01010 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 01011 return FALSE; 01012 } 01013 01014 if ( !(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 01015 { 01016 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01017 return FALSE; 01018 } 01019 01020 newkey->pProvider = prov; 01021 if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate)) 01022 { 01023 *phKey = (HCRYPTKEY)newkey; 01024 return TRUE; 01025 } 01026 CRYPT_Free(newkey); 01027 return FALSE; 01028 } 01029 01030 /****************************************************************************** 01031 * CryptEncrypt (ADVAPI32.@) 01032 * 01033 * Encrypts data. 01034 * 01035 * PARAMS 01036 * hKey [I] Handle to the encryption key. 01037 * hHash [I] Handle to a hash object. 01038 * Final [I] TRUE if this is the last section to encrypt. 01039 * dwFlags [I] Can be CRYPT_OAEP. 01040 * pbData [I/O] Data to be encrypted. Contains encrypted data after call. 01041 * pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the 01042 * encrypted data after call. 01043 * dwBufLen [I] Length of the input pbData buffer. 01044 * 01045 * RETURNS 01046 * Success: TRUE 01047 * Failure: FALSE 01048 * 01049 * NOTES 01050 * If pbData is NULL, CryptEncrypt determines stores the number of bytes 01051 * required for the returned data in pdwDataLen. 01052 */ 01053 BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, 01054 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) 01055 { 01056 PCRYPTPROV prov; 01057 PCRYPTKEY key = (PCRYPTKEY)hKey; 01058 PCRYPTHASH hash = (PCRYPTHASH)hHash; 01059 01060 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p, %d)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen); 01061 01062 if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 01063 { 01064 SetLastError(ERROR_INVALID_PARAMETER); 01065 return FALSE; 01066 } 01067 01068 prov = key->pProvider; 01069 return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0, 01070 Final, dwFlags, pbData, pdwDataLen, dwBufLen); 01071 } 01072 01073 /****************************************************************************** 01074 * CryptEnumProvidersW (ADVAPI32.@) 01075 * 01076 * Returns the next available CSP. 01077 * 01078 * PARAMS 01079 * dwIndex [I] Index of the next provider to be enumerated. 01080 * pdwReserved [I] Reserved for future use and must be NULL. 01081 * dwFlags [I] Reserved for future use and must be zero. 01082 * pdwProvType [O] DWORD designating the type of the provider. 01083 * pszProvName [O] Buffer that receives data from the provider. 01084 * pcbProvName [I/O] Specifies the size of pszProvName. Contains the number 01085 * of bytes stored in the buffer on return. 01086 * 01087 * RETURNS 01088 * Success: TRUE 01089 * Failure: FALSE 01090 * 01091 * NOTES 01092 * If pszProvName is NULL, CryptEnumProvidersW sets the size of the name 01093 * for memory allocation purposes. 01094 */ 01095 BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved, 01096 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName) 01097 { 01098 HKEY hKey; 01099 static const WCHAR providerW[] = { 01100 'S','o','f','t','w','a','r','e','\\', 01101 'M','i','c','r','o','s','o','f','t','\\', 01102 'C','r','y','p','t','o','g','r','a','p','h','y','\\', 01103 'D','e','f','a','u','l','t','s','\\', 01104 'P','r','o','v','i','d','e','r',0 01105 }; 01106 static const WCHAR typeW[] = {'T','y','p','e',0}; 01107 BOOL ret; 01108 01109 TRACE("(%d, %p, %d, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, 01110 pdwProvType, pszProvName, pcbProvName); 01111 01112 if (pdwReserved || !pcbProvName) 01113 { 01114 SetLastError(ERROR_INVALID_PARAMETER); 01115 return FALSE; 01116 } 01117 if (dwFlags) 01118 { 01119 SetLastError(NTE_BAD_FLAGS); 01120 return FALSE; 01121 } 01122 01123 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, providerW, &hKey)) 01124 { 01125 SetLastError(NTE_FAIL); 01126 return FALSE; 01127 } 01128 01129 ret = TRUE; 01130 if (!pszProvName) 01131 { 01132 DWORD numkeys; 01133 WCHAR *provNameW; 01134 01135 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, pcbProvName, 01136 NULL, NULL, NULL, NULL, NULL, NULL); 01137 01138 if (!(provNameW = CRYPT_Alloc(*pcbProvName * sizeof(WCHAR)))) 01139 { 01140 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01141 RegCloseKey(hKey); 01142 return FALSE; 01143 } 01144 01145 RegEnumKeyExW(hKey, dwIndex, provNameW, pcbProvName, NULL, NULL, NULL, NULL); 01146 CRYPT_Free(provNameW); 01147 (*pcbProvName)++; 01148 *pcbProvName *= sizeof(WCHAR); 01149 01150 if (dwIndex >= numkeys) 01151 { 01152 SetLastError(ERROR_NO_MORE_ITEMS); 01153 ret = FALSE; 01154 } 01155 } else { 01156 DWORD size = sizeof(DWORD); 01157 DWORD result; 01158 HKEY subkey; 01159 01160 result = RegEnumKeyW(hKey, dwIndex, pszProvName, *pcbProvName / sizeof(WCHAR)); 01161 if (result) 01162 { 01163 SetLastError(result); 01164 RegCloseKey(hKey); 01165 return FALSE; 01166 } 01167 if (RegOpenKeyW(hKey, pszProvName, &subkey)) 01168 { 01169 RegCloseKey(hKey); 01170 return FALSE; 01171 } 01172 01173 if (RegQueryValueExW(subkey, typeW, NULL, NULL, (BYTE*)pdwProvType, &size)) 01174 ret = FALSE; 01175 01176 RegCloseKey(subkey); 01177 } 01178 RegCloseKey(hKey); 01179 return ret; 01180 } 01181 01182 /****************************************************************************** 01183 * CryptEnumProvidersA (ADVAPI32.@) 01184 * 01185 * See CryptEnumProvidersW. 01186 */ 01187 BOOL WINAPI CryptEnumProvidersA (DWORD dwIndex, DWORD *pdwReserved, 01188 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszProvName, DWORD *pcbProvName) 01189 { 01190 PWSTR str = NULL; 01191 DWORD bufsize; 01192 BOOL ret; /* = FALSE; */ 01193 01194 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, 01195 pdwProvType, pszProvName, pcbProvName); 01196 01197 if(!CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, NULL, &bufsize)) 01198 return FALSE; 01199 if ( pszProvName && !(str = CRYPT_Alloc(bufsize)) ) 01200 { 01201 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01202 return FALSE; 01203 } 01204 ret = CryptEnumProvidersW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &bufsize); 01205 if (str) 01206 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName); 01207 *pcbProvName = bufsize / sizeof(WCHAR); /* FIXME: not correct */ 01208 if (str) 01209 { 01210 CRYPT_Free(str); 01211 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 01212 { 01213 SetLastError(ERROR_MORE_DATA); 01214 return FALSE; 01215 } 01216 } 01217 return ret; 01218 } 01219 01220 /****************************************************************************** 01221 * CryptEnumProviderTypesW (ADVAPI32.@) 01222 * 01223 * Retrieves the next type of CSP supported. 01224 * 01225 * PARAMS 01226 * dwIndex [I] Index of the next provider to be enumerated. 01227 * pdwReserved [I] Reserved for future use and must be NULL. 01228 * dwFlags [I] Reserved for future use and must be zero. 01229 * pdwProvType [O] DWORD designating the type of the provider. 01230 * pszTypeName [O] Buffer that receives data from the provider type. 01231 * pcbTypeName [I/O] Specifies the size of pszTypeName. Contains the number 01232 * of bytes stored in the buffer on return. 01233 * 01234 * RETURNS 01235 * Success: TRUE 01236 * Failure: FALSE 01237 * 01238 * NOTES 01239 * If pszTypeName is NULL, CryptEnumProviderTypesW sets the size of the name 01240 * for memory allocation purposes. 01241 */ 01242 BOOL WINAPI CryptEnumProviderTypesW (DWORD dwIndex, DWORD *pdwReserved, 01243 DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszTypeName, DWORD *pcbTypeName) 01244 { 01245 HKEY hKey, hSubkey; 01246 DWORD keylen, numkeys, dwType; 01247 PWSTR keyname, ch; 01248 DWORD result; 01249 static const WCHAR KEYSTR[] = { 01250 'S','o','f','t','w','a','r','e','\\', 01251 'M','i','c','r','o','s','o','f','t','\\', 01252 'C','r','y','p','t','o','g','r','a','p','h','y','\\', 01253 'D','e','f','a','u','l','t','s','\\', 01254 'P','r','o','v','i','d','e','r',' ','T','y','p','e','s',0 01255 }; 01256 static const WCHAR typenameW[] = {'T','y','p','e','N','a','m','e',0}; 01257 01258 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, 01259 dwFlags, pdwProvType, pszTypeName, pcbTypeName); 01260 01261 if (pdwReserved || !pdwProvType || !pcbTypeName) 01262 { 01263 SetLastError(ERROR_INVALID_PARAMETER); 01264 return FALSE; 01265 } 01266 if (dwFlags) 01267 { 01268 SetLastError(NTE_BAD_FLAGS); 01269 return FALSE; 01270 } 01271 01272 if (RegOpenKeyW(HKEY_LOCAL_MACHINE, KEYSTR, &hKey)) 01273 return FALSE; 01274 01275 RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &numkeys, &keylen, NULL, NULL, NULL, NULL, NULL, NULL); 01276 if (dwIndex >= numkeys) 01277 { 01278 SetLastError(ERROR_NO_MORE_ITEMS); 01279 return FALSE; 01280 } 01281 keylen++; 01282 if ( !(keyname = CRYPT_Alloc(keylen*sizeof(WCHAR))) ) 01283 { 01284 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01285 return FALSE; 01286 } 01287 if ( RegEnumKeyW(hKey, dwIndex, keyname, keylen) ) { 01288 CRYPT_Free(keyname); 01289 return FALSE; 01290 } 01291 RegOpenKeyW(hKey, keyname, &hSubkey); 01292 ch = keyname + strlenW(keyname); 01293 /* Convert "Type 000" to 0, etc/ */ 01294 *pdwProvType = *(--ch) - '0'; 01295 *pdwProvType += (*(--ch) - '0') * 10; 01296 *pdwProvType += (*(--ch) - '0') * 100; 01297 CRYPT_Free(keyname); 01298 01299 result = RegQueryValueExW(hSubkey, typenameW, NULL, &dwType, (LPBYTE)pszTypeName, pcbTypeName); 01300 if (result) 01301 { 01302 SetLastError(result); 01303 return FALSE; 01304 } 01305 01306 RegCloseKey(hSubkey); 01307 RegCloseKey(hKey); 01308 return TRUE; 01309 } 01310 01311 /****************************************************************************** 01312 * CryptEnumProviderTypesA (ADVAPI32.@) 01313 * 01314 * See CryptEnumProviderTypesW. 01315 */ 01316 BOOL WINAPI CryptEnumProviderTypesA (DWORD dwIndex, DWORD *pdwReserved, 01317 DWORD dwFlags, DWORD *pdwProvType, LPSTR pszTypeName, DWORD *pcbTypeName) 01318 { 01319 PWSTR str = NULL; 01320 DWORD bufsize; 01321 BOOL ret; 01322 01323 TRACE("(%d, %p, %08x, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags, 01324 pdwProvType, pszTypeName, pcbTypeName); 01325 01326 if(!CryptEnumProviderTypesW(dwIndex, pdwReserved, dwFlags, pdwProvType, NULL, &bufsize)) 01327 return FALSE; 01328 if ( pszTypeName && !(str = CRYPT_Alloc(bufsize)) ) 01329 { 01330 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01331 return FALSE; 01332 } 01333 ret = CryptEnumProviderTypesW(dwIndex, pdwReserved, dwFlags, pdwProvType, str, &bufsize); 01334 if (str) 01335 CRYPT_UnicodeToANSI(str, &pszTypeName, *pcbTypeName); 01336 *pcbTypeName = bufsize / sizeof(WCHAR); 01337 if (str) 01338 { 01339 CRYPT_Free(str); 01340 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 01341 { 01342 SetLastError(ERROR_MORE_DATA); 01343 return FALSE; 01344 } 01345 } 01346 return ret; 01347 } 01348 01349 /****************************************************************************** 01350 * CryptExportKey (ADVAPI32.@) 01351 * 01352 * Exports a cryptographic key from a CSP. 01353 * 01354 * PARAMS 01355 * hKey [I] Handle to the key to export. 01356 * hExpKey [I] Handle to a cryptographic key of the end user. 01357 * dwBlobType [I] Type of BLOB to be exported. 01358 * dwFlags [I] CRYPT_DESTROYKEY/SSL2_FALLBACK/OAEP. 01359 * pbData [O] Buffer to receive BLOB data. 01360 * pdwDataLen [I/O] Specifies the size of pbData. 01361 * 01362 * RETURNS 01363 * Success: TRUE 01364 * Failure: FALSE 01365 * 01366 * NOTES 01367 * if pbData is NULL, CryptExportKey sets pdwDataLen as the size of the 01368 * buffer needed to hold the BLOB. 01369 */ 01370 BOOL WINAPI CryptExportKey (HCRYPTKEY hKey, HCRYPTKEY hExpKey, DWORD dwBlobType, 01371 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) 01372 { 01373 PCRYPTPROV prov; 01374 PCRYPTKEY key = (PCRYPTKEY)hKey, expkey = (PCRYPTKEY)hExpKey; 01375 01376 TRACE("(0x%lx, 0x%lx, %d, %08x, %p, %p)\n", hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen); 01377 01378 if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 01379 { 01380 SetLastError(ERROR_INVALID_PARAMETER); 01381 return FALSE; 01382 } 01383 01384 prov = key->pProvider; 01385 return prov->pFuncs->pCPExportKey(prov->hPrivate, key->hPrivate, expkey ? expkey->hPrivate : 0, 01386 dwBlobType, dwFlags, pbData, pdwDataLen); 01387 } 01388 01389 /****************************************************************************** 01390 * CryptGenKey (ADVAPI32.@) 01391 * 01392 * Generates a random cryptographic session key or a pub/priv key pair. 01393 * 01394 * PARAMS 01395 * hProv [I] Handle to a CSP. 01396 * Algid [I] Algorithm to use to make key. 01397 * dwFlags [I] Specifies type of key to make. 01398 * phKey [I] Address of the handle to which the new key is copied. 01399 * 01400 * RETURNS 01401 * Success: TRUE 01402 * Failure: FALSE 01403 */ 01404 BOOL WINAPI CryptGenKey (HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey) 01405 { 01406 PCRYPTPROV prov = (PCRYPTPROV)hProv; 01407 PCRYPTKEY key; 01408 01409 TRACE("(0x%lx, %d, %08x, %p)\n", hProv, Algid, dwFlags, phKey); 01410 01411 if (!prov) 01412 { 01413 SetLastError(ERROR_INVALID_HANDLE); 01414 return FALSE; 01415 } 01416 if (!phKey || !prov || prov->dwMagic != MAGIC_CRYPTPROV) 01417 { 01418 SetLastError(ERROR_INVALID_PARAMETER); 01419 return FALSE; 01420 } 01421 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 01422 { 01423 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01424 return FALSE; 01425 } 01426 01427 key->pProvider = prov; 01428 01429 if (prov->pFuncs->pCPGenKey(prov->hPrivate, Algid, dwFlags, &key->hPrivate)) 01430 { 01431 *phKey = (HCRYPTKEY)key; 01432 return TRUE; 01433 } 01434 01435 /* CSP error! */ 01436 CRYPT_Free(key); 01437 return FALSE; 01438 } 01439 01440 /****************************************************************************** 01441 * CryptGetDefaultProviderW (ADVAPI32.@) 01442 * 01443 * Finds the default CSP of a certain provider type. 01444 * 01445 * PARAMS 01446 * dwProvType [I] Provider type to look for. 01447 * pdwReserved [I] Reserved for future use and must be NULL. 01448 * dwFlags [I] CRYPT_MACHINE_DEFAULT/USER_DEFAULT 01449 * pszProvName [O] Name of the default CSP. 01450 * pcbProvName [I/O] Size of pszProvName 01451 * 01452 * RETURNS 01453 * Success: TRUE 01454 * Failure: FALSE 01455 * 01456 * NOTES 01457 * If pszProvName is NULL, pcbProvName will hold the size of the buffer for 01458 * memory allocation purposes on return. 01459 */ 01460 BOOL WINAPI CryptGetDefaultProviderW (DWORD dwProvType, DWORD *pdwReserved, 01461 DWORD dwFlags, LPWSTR pszProvName, DWORD *pcbProvName) 01462 { 01463 HKEY hKey; 01464 PWSTR keyname; 01465 DWORD result; 01466 static const WCHAR nameW[] = {'N','a','m','e',0}; 01467 01468 if (pdwReserved || !pcbProvName) 01469 { 01470 SetLastError(ERROR_INVALID_PARAMETER); 01471 return FALSE; 01472 } 01473 if (dwFlags & ~(CRYPT_USER_DEFAULT | CRYPT_MACHINE_DEFAULT)) 01474 { 01475 SetLastError(NTE_BAD_FLAGS); 01476 return FALSE; 01477 } 01478 if (dwProvType > 999) 01479 { 01480 SetLastError(NTE_BAD_PROV_TYPE); 01481 return FALSE; 01482 } 01483 if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) ) 01484 { 01485 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01486 return FALSE; 01487 } 01488 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey)) 01489 { 01490 CRYPT_Free(keyname); 01491 SetLastError(NTE_PROV_TYPE_NOT_DEF); 01492 return FALSE; 01493 } 01494 CRYPT_Free(keyname); 01495 01496 result = RegQueryValueExW(hKey, nameW, NULL, NULL, (LPBYTE)pszProvName, pcbProvName); 01497 if (result) 01498 { 01499 if (result != ERROR_MORE_DATA) 01500 SetLastError(NTE_PROV_TYPE_ENTRY_BAD); 01501 else 01502 SetLastError(result); 01503 01504 return FALSE; 01505 } 01506 01507 RegCloseKey(hKey); 01508 return TRUE; 01509 } 01510 01511 /****************************************************************************** 01512 * CryptGetDefaultProviderA (ADVAPI32.@) 01513 * 01514 * See CryptGetDefaultProviderW. 01515 */ 01516 BOOL WINAPI CryptGetDefaultProviderA (DWORD dwProvType, DWORD *pdwReserved, 01517 DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName) 01518 { 01519 PWSTR str = NULL; 01520 DWORD bufsize; 01521 BOOL ret = FALSE; 01522 01523 TRACE("(%d, %p, %08x, %p, %p)\n", dwProvType, pdwReserved, dwFlags, pszProvName, pcbProvName); 01524 01525 CryptGetDefaultProviderW(dwProvType, pdwReserved, dwFlags, NULL, &bufsize); 01526 if ( pszProvName && !(str = CRYPT_Alloc(bufsize)) ) 01527 { 01528 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01529 return FALSE; 01530 } 01531 ret = CryptGetDefaultProviderW(dwProvType, pdwReserved, dwFlags, str, &bufsize); 01532 if (str) 01533 CRYPT_UnicodeToANSI(str, &pszProvName, *pcbProvName); 01534 *pcbProvName = bufsize / sizeof(WCHAR); 01535 if (str) 01536 { 01537 CRYPT_Free(str); 01538 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 01539 { 01540 SetLastError(ERROR_MORE_DATA); 01541 return FALSE; 01542 } 01543 } 01544 return ret; 01545 } 01546 01547 /****************************************************************************** 01548 * CryptGetHashParam (ADVAPI32.@) 01549 * 01550 * Retrieves data that controls the operations of a hash object. 01551 * 01552 * PARAMS 01553 * hHash [I] Handle of the hash object to question. 01554 * dwParam [I] Query type. 01555 * pbData [O] Buffer that receives the value data. 01556 * pdwDataLen [I/O] Size of the pbData buffer. 01557 * dwFlags [I] Reserved for future use and must be zero. 01558 * 01559 * RETURNS 01560 * Success: TRUE 01561 * Failure: FALSE 01562 * 01563 * NOTES 01564 * If pbData is NULL, pdwDataLen will contain the length required. 01565 */ 01566 BOOL WINAPI CryptGetHashParam (HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, 01567 DWORD *pdwDataLen, DWORD dwFlags) 01568 { 01569 PCRYPTPROV prov; 01570 PCRYPTHASH hash = (PCRYPTHASH)hHash; 01571 01572 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hHash, dwParam, pbData, pdwDataLen, dwFlags); 01573 01574 if (!hash || !pdwDataLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 01575 { 01576 SetLastError(ERROR_INVALID_PARAMETER); 01577 return FALSE; 01578 } 01579 01580 prov = hash->pProvider; 01581 return prov->pFuncs->pCPGetHashParam(prov->hPrivate, hash->hPrivate, dwParam, 01582 pbData, pdwDataLen, dwFlags); 01583 } 01584 01585 /****************************************************************************** 01586 * CryptGetKeyParam (ADVAPI32.@) 01587 * 01588 * Retrieves data that controls the operations of a key. 01589 * 01590 * PARAMS 01591 * hKey [I] Handle to they key in question. 01592 * dwParam [I] Specifies query type. 01593 * pbData [O] Sequence of bytes to receive data. 01594 * pdwDataLen [I/O] Size of pbData. 01595 * dwFlags [I] Reserved for future use and must be zero. 01596 * 01597 * RETURNS 01598 * Success: TRUE 01599 * Failure: FALSE 01600 * 01601 * NOTES 01602 * If pbData is NULL, pdwDataLen is set to the needed length of the buffer. 01603 */ 01604 BOOL WINAPI CryptGetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, 01605 DWORD *pdwDataLen, DWORD dwFlags) 01606 { 01607 PCRYPTPROV prov; 01608 PCRYPTKEY key = (PCRYPTKEY)hKey; 01609 01610 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hKey, dwParam, pbData, pdwDataLen, dwFlags); 01611 01612 if (!key || !pdwDataLen || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 01613 { 01614 SetLastError(ERROR_INVALID_PARAMETER); 01615 return FALSE; 01616 } 01617 01618 prov = key->pProvider; 01619 return prov->pFuncs->pCPGetKeyParam(prov->hPrivate, key->hPrivate, dwParam, 01620 pbData, pdwDataLen, dwFlags); 01621 } 01622 01623 /****************************************************************************** 01624 * CryptGetProvParam (ADVAPI32.@) 01625 * 01626 * Retrieves parameters that control the operations of a CSP. 01627 * 01628 * PARAMS 01629 * hProv [I] Handle of the CSP in question. 01630 * dwParam [I] Specifies query type. 01631 * pbData [O] Buffer to receive the data. 01632 * pdwDataLen [I/O] Size of pbData. 01633 * dwFlags [I] see MSDN Docs. 01634 * 01635 * RETURNS 01636 * Success: TRUE 01637 * Failure: FALSE 01638 * 01639 * NOTES 01640 * If pbData is NULL, pdwDataLen is set to the needed buffer length. 01641 */ 01642 BOOL WINAPI CryptGetProvParam (HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, 01643 DWORD *pdwDataLen, DWORD dwFlags) 01644 { 01645 PCRYPTPROV prov = (PCRYPTPROV)hProv; 01646 01647 TRACE("(0x%lx, %d, %p, %p, %08x)\n", hProv, dwParam, pbData, pdwDataLen, dwFlags); 01648 01649 if (!prov || prov->dwMagic != MAGIC_CRYPTPROV) 01650 { 01651 SetLastError(ERROR_INVALID_PARAMETER); 01652 return FALSE; 01653 } 01654 01655 return prov->pFuncs->pCPGetProvParam(prov->hPrivate, dwParam, pbData, pdwDataLen, dwFlags); 01656 } 01657 01658 /****************************************************************************** 01659 * CryptGetUserKey (ADVAPI32.@) 01660 * 01661 * Gets a handle of one of a user's two public/private key pairs. 01662 * 01663 * PARAMS 01664 * hProv [I] Handle of a CSP. 01665 * dwKeySpec [I] Private key to use. 01666 * phUserKey [O] Pointer to the handle of the retrieved keys. 01667 * 01668 * RETURNS 01669 * Success: TRUE 01670 * Failure: FALSE 01671 */ 01672 BOOL WINAPI CryptGetUserKey (HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey) 01673 { 01674 PCRYPTPROV prov = (PCRYPTPROV)hProv; 01675 PCRYPTKEY key; 01676 01677 TRACE("(0x%lx, %d, %p)\n", hProv, dwKeySpec, phUserKey); 01678 01679 if (!prov) 01680 { 01681 SetLastError(ERROR_INVALID_HANDLE); 01682 return FALSE; 01683 } 01684 if (!phUserKey || prov->dwMagic != MAGIC_CRYPTPROV) 01685 { 01686 SetLastError(ERROR_INVALID_PARAMETER); 01687 return FALSE; 01688 } 01689 if ( !(key = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 01690 { 01691 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01692 return FALSE; 01693 } 01694 01695 key->pProvider = prov; 01696 01697 if (prov->pFuncs->pCPGetUserKey(prov->hPrivate, dwKeySpec, &key->hPrivate)) 01698 { 01699 *phUserKey = (HCRYPTKEY)key; 01700 return TRUE; 01701 } 01702 01703 /* CSP Error */ 01704 CRYPT_Free(key); 01705 *phUserKey = 0; 01706 return FALSE; 01707 } 01708 01709 /****************************************************************************** 01710 * CryptHashData (ADVAPI32.@) 01711 * 01712 * Adds data to a hash object. 01713 * 01714 * PARAMS 01715 * hHash [I] Handle of the hash object. 01716 * pbData [I] Buffer of data to be hashed. 01717 * dwDataLen [I] Number of bytes to add. 01718 * dwFlags [I] Can be CRYPT_USERDATA 01719 * 01720 * RETURNS 01721 * Success: TRUE 01722 * Failure: FALSE 01723 */ 01724 BOOL WINAPI CryptHashData (HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags) 01725 { 01726 PCRYPTHASH hash = (PCRYPTHASH)hHash; 01727 PCRYPTPROV prov; 01728 01729 TRACE("(0x%lx, %p, %d, %08x)\n", hHash, pbData, dwDataLen, dwFlags); 01730 01731 if (!hash) 01732 { 01733 SetLastError(ERROR_INVALID_HANDLE); 01734 return FALSE; 01735 } 01736 if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 01737 { 01738 SetLastError(ERROR_INVALID_PARAMETER); 01739 return FALSE; 01740 } 01741 01742 prov = hash->pProvider; 01743 return prov->pFuncs->pCPHashData(prov->hPrivate, hash->hPrivate, pbData, dwDataLen, dwFlags); 01744 } 01745 01746 /****************************************************************************** 01747 * CryptHashSessionKey (ADVAPI32.@) 01748 * 01749 * Compute the cryptographic hash of a session key object. 01750 * 01751 * PARAMS 01752 * hHash [I] Handle to the hash object. 01753 * hKey [I] Handle to the key to be hashed. 01754 * dwFlags [I] Can be CRYPT_LITTLE_ENDIAN. 01755 * 01756 * RETURNS 01757 * Success: TRUE 01758 * Failure: FALSE 01759 */ 01760 BOOL WINAPI CryptHashSessionKey (HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags) 01761 { 01762 PCRYPTHASH hash = (PCRYPTHASH)hHash; 01763 PCRYPTKEY key = (PCRYPTKEY)hKey; 01764 PCRYPTPROV prov; 01765 01766 TRACE("(0x%lx, 0x%lx, %08x)\n", hHash, hKey, dwFlags); 01767 01768 if (!hash || !key) 01769 { 01770 SetLastError(ERROR_INVALID_HANDLE); 01771 return FALSE; 01772 } 01773 01774 if (!hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 01775 { 01776 SetLastError(ERROR_INVALID_PARAMETER); 01777 return FALSE; 01778 } 01779 01780 prov = hash->pProvider; 01781 return prov->pFuncs->pCPHashSessionKey(prov->hPrivate, hash->hPrivate, key->hPrivate, dwFlags); 01782 } 01783 01784 /****************************************************************************** 01785 * CryptImportKey (ADVAPI32.@) 01786 * 01787 * Transfer a cryptographic key from a key BLOB into a cryptographic service provider (CSP). 01788 * 01789 * PARAMS 01790 * hProv [I] Handle of a CSP. 01791 * pbData [I] Contains the key to be imported. 01792 * dwDataLen [I] Length of the key. 01793 * hPubKey [I] Cryptographic key that decrypts pdData 01794 * dwFlags [I] Used only with a public/private key pair. 01795 * phKey [O] Imported key. 01796 * 01797 * RETURNS 01798 * Success: TRUE 01799 * Failure: FALSE 01800 */ 01801 BOOL WINAPI CryptImportKey (HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, 01802 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) 01803 { 01804 PCRYPTPROV prov = (PCRYPTPROV)hProv; 01805 PCRYPTKEY pubkey = (PCRYPTKEY)hPubKey, importkey; 01806 01807 TRACE("(0x%lx, %p, %d, 0x%lx, %08x, %p)\n", hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); 01808 01809 if (!prov || !pbData || !dwDataLen || !phKey || prov->dwMagic != MAGIC_CRYPTPROV) 01810 { 01811 SetLastError(ERROR_INVALID_PARAMETER); 01812 return FALSE; 01813 } 01814 01815 if ( !(importkey = CRYPT_Alloc(sizeof(CRYPTKEY))) ) 01816 { 01817 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01818 return FALSE; 01819 } 01820 01821 importkey->pProvider = prov; 01822 if (prov->pFuncs->pCPImportKey(prov->hPrivate, pbData, dwDataLen, 01823 pubkey ? pubkey->hPrivate : 0, dwFlags, &importkey->hPrivate)) 01824 { 01825 *phKey = (HCRYPTKEY)importkey; 01826 return TRUE; 01827 } 01828 01829 CRYPT_Free(importkey); 01830 return FALSE; 01831 } 01832 01833 /****************************************************************************** 01834 * CryptSignHashW (ADVAPI32.@) 01835 * 01836 * Signs data. 01837 * 01838 * PARAMS 01839 * hHash [I] Handle of the hash object to be signed. 01840 * dwKeySpec [I] Private key to use. 01841 * sDescription [I] Should be NULL. 01842 * dwFlags [I] CRYPT_NOHASHOID/X931_FORMAT. 01843 * pbSignature [O] Buffer of the signature data. 01844 * pdwSigLen [I/O] Size of the pbSignature buffer. 01845 * 01846 * RETURNS 01847 * Success: TRUE 01848 * Failure: FALSE 01849 * 01850 * NOTES 01851 * Because of security flaws sDescription should not be used and should thus be 01852 * NULL. It is supported only for compatibility with Microsoft's Cryptographic 01853 * Providers. 01854 */ 01855 BOOL WINAPI CryptSignHashW (HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, 01856 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) 01857 { 01858 PCRYPTHASH hash = (PCRYPTHASH)hHash; 01859 PCRYPTPROV prov; 01860 01861 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n", 01862 hHash, dwKeySpec, debugstr_w(sDescription), dwFlags, pbSignature, pdwSigLen); 01863 01864 if (!hash) 01865 { 01866 SetLastError(ERROR_INVALID_HANDLE); 01867 return FALSE; 01868 } 01869 if (!pdwSigLen || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 01870 { 01871 SetLastError(ERROR_INVALID_PARAMETER); 01872 return FALSE; 01873 } 01874 01875 prov = hash->pProvider; 01876 return prov->pFuncs->pCPSignHash(prov->hPrivate, hash->hPrivate, dwKeySpec, sDescription, 01877 dwFlags, pbSignature, pdwSigLen); 01878 } 01879 01880 /****************************************************************************** 01881 * CryptSignHashA (ADVAPI32.@) 01882 * 01883 * See CryptSignHashW. 01884 */ 01885 BOOL WINAPI CryptSignHashA (HCRYPTHASH hHash, DWORD dwKeySpec, LPCSTR sDescription, 01886 DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen) 01887 { 01888 LPWSTR wsDescription; 01889 BOOL result; 01890 01891 TRACE("(0x%lx, %d, %s, %08x, %p, %p)\n", 01892 hHash, dwKeySpec, debugstr_a(sDescription), dwFlags, pbSignature, pdwSigLen); 01893 01894 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1); 01895 result = CryptSignHashW(hHash, dwKeySpec, wsDescription, dwFlags, pbSignature, pdwSigLen); 01896 CRYPT_Free(wsDescription); 01897 01898 return result; 01899 } 01900 01901 /****************************************************************************** 01902 * CryptSetHashParam (ADVAPI32.@) 01903 * 01904 * Customizes the operations of a hash object. 01905 * 01906 * PARAMS 01907 * hHash [I] Handle of the hash object to set parameters. 01908 * dwParam [I] HP_HMAC_INFO/HASHVAL. 01909 * pbData [I] Value data buffer. 01910 * dwFlags [I] Reserved for future use and must be zero. 01911 * 01912 * RETURNS 01913 * Success: TRUE 01914 * Failure: FALSE 01915 */ 01916 BOOL WINAPI CryptSetHashParam (HCRYPTHASH hHash, DWORD dwParam, CONST BYTE *pbData, DWORD dwFlags) 01917 { 01918 PCRYPTPROV prov; 01919 PCRYPTHASH hash = (PCRYPTHASH)hHash; 01920 01921 TRACE("(0x%lx, %d, %p, %08x)\n", hHash, dwParam, pbData, dwFlags); 01922 01923 if (!hash || !pbData || !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV) 01924 { 01925 SetLastError(ERROR_INVALID_PARAMETER); 01926 return FALSE; 01927 } 01928 01929 prov = hash->pProvider; 01930 return prov->pFuncs->pCPSetHashParam(prov->hPrivate, hash->hPrivate, 01931 dwParam, pbData, dwFlags); 01932 } 01933 01934 /****************************************************************************** 01935 * CryptSetKeyParam (ADVAPI32.@) 01936 * 01937 * Customizes a session key's operations. 01938 * 01939 * PARAMS 01940 * hKey [I] Handle to the key to set values. 01941 * dwParam [I] See MSDN Doc. 01942 * pbData [I] Buffer of values to set. 01943 * dwFlags [I] Only used when dwParam == KP_ALGID. 01944 * 01945 * RETURNS 01946 * Success: TRUE 01947 * Failure: FALSE 01948 */ 01949 BOOL WINAPI CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, CONST BYTE *pbData, DWORD dwFlags) 01950 { 01951 PCRYPTPROV prov; 01952 PCRYPTKEY key = (PCRYPTKEY)hKey; 01953 01954 TRACE("(0x%lx, %d, %p, %08x)\n", hKey, dwParam, pbData, dwFlags); 01955 01956 if (!key || !pbData || !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 01957 { 01958 SetLastError(ERROR_INVALID_PARAMETER); 01959 return FALSE; 01960 } 01961 01962 prov = key->pProvider; 01963 return prov->pFuncs->pCPSetKeyParam(prov->hPrivate, key->hPrivate, 01964 dwParam, pbData, dwFlags); 01965 } 01966 01967 /****************************************************************************** 01968 * CryptSetProviderA (ADVAPI32.@) 01969 * 01970 * Specifies the current user's default CSP. 01971 * 01972 * PARAMS 01973 * pszProvName [I] Name of the new default CSP. 01974 * dwProvType [I] Provider type of the CSP. 01975 * 01976 * RETURNS 01977 * Success: TRUE 01978 * Failure: FALSE 01979 */ 01980 BOOL WINAPI CryptSetProviderA (LPCSTR pszProvName, DWORD dwProvType) 01981 { 01982 TRACE("(%s, %d)\n", pszProvName, dwProvType); 01983 return CryptSetProviderExA(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT); 01984 } 01985 01986 /****************************************************************************** 01987 * CryptSetProviderW (ADVAPI32.@) 01988 * 01989 * See CryptSetProviderA. 01990 */ 01991 BOOL WINAPI CryptSetProviderW (LPCWSTR pszProvName, DWORD dwProvType) 01992 { 01993 TRACE("(%s, %d)\n", debugstr_w(pszProvName), dwProvType); 01994 return CryptSetProviderExW(pszProvName, dwProvType, NULL, CRYPT_USER_DEFAULT); 01995 } 01996 01997 /****************************************************************************** 01998 * CryptSetProviderExW (ADVAPI32.@) 01999 * 02000 * Specifies the default CSP. 02001 * 02002 * PARAMS 02003 * pszProvName [I] Name of the new default CSP. 02004 * dwProvType [I] Provider type of the CSP. 02005 * pdwReserved [I] Reserved for future use and must be NULL. 02006 * dwFlags [I] See MSDN Doc. 02007 * 02008 * RETURNS 02009 * Success: TRUE 02010 * Failure: FALSE 02011 */ 02012 BOOL WINAPI CryptSetProviderExW (LPCWSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags) 02013 { 02014 HKEY hProvKey, hTypeKey; 02015 PWSTR keyname; 02016 static const WCHAR nameW[] = {'N','a','m','e',0}; 02017 02018 TRACE("(%s, %d, %p, %08x)\n", debugstr_w(pszProvName), dwProvType, pdwReserved, dwFlags); 02019 02020 if (!pszProvName || pdwReserved) 02021 { 02022 SetLastError(ERROR_INVALID_PARAMETER); 02023 return FALSE; 02024 } 02025 if (dwProvType > MAXPROVTYPES) 02026 { 02027 SetLastError(NTE_BAD_PROV_TYPE); 02028 return FALSE; 02029 } 02030 if (dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT) 02031 || dwFlags == CRYPT_DELETE_DEFAULT) 02032 { 02033 SetLastError(NTE_BAD_FLAGS); 02034 return FALSE; 02035 } 02036 02037 if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT))) 02038 { 02039 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 02040 return FALSE; 02041 } 02042 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, 02043 keyname, &hTypeKey)) 02044 { 02045 CRYPT_Free(keyname); 02046 SetLastError(NTE_BAD_PROVIDER); 02047 return FALSE; 02048 } 02049 CRYPT_Free(keyname); 02050 02051 if (dwFlags & CRYPT_DELETE_DEFAULT) 02052 { 02053 RegDeleteValueW(hTypeKey, nameW); 02054 } 02055 else 02056 { 02057 if (!(keyname = CRYPT_GetProvKeyName(pszProvName))) 02058 { 02059 RegCloseKey(hTypeKey); 02060 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 02061 return FALSE; 02062 } 02063 if (RegOpenKeyW((dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, 02064 keyname, &hProvKey)) 02065 { 02066 CRYPT_Free(keyname); 02067 RegCloseKey(hTypeKey); 02068 SetLastError(NTE_BAD_PROVIDER); 02069 return FALSE; 02070 } 02071 CRYPT_Free(keyname); 02072 02073 if (RegSetValueExW(hTypeKey, nameW, 0, REG_SZ, (const BYTE *)pszProvName, 02074 (strlenW(pszProvName) + 1)*sizeof(WCHAR))) 02075 { 02076 RegCloseKey(hTypeKey); 02077 RegCloseKey(hProvKey); 02078 return FALSE; 02079 } 02080 02081 RegCloseKey(hProvKey); 02082 } 02083 RegCloseKey(hTypeKey); 02084 02085 return TRUE; 02086 } 02087 02088 /****************************************************************************** 02089 * CryptSetProviderExA (ADVAPI32.@) 02090 * 02091 * See CryptSetProviderExW. 02092 */ 02093 BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags) 02094 { 02095 BOOL ret = FALSE; 02096 PWSTR str = NULL; 02097 02098 TRACE("(%s, %d, %p, %08x)\n", pszProvName, dwProvType, pdwReserved, dwFlags); 02099 02100 if (CRYPT_ANSIToUnicode(pszProvName, &str, -1)) 02101 { 02102 ret = CryptSetProviderExW(str, dwProvType, pdwReserved, dwFlags); 02103 CRYPT_Free(str); 02104 } 02105 return ret; 02106 } 02107 02108 /****************************************************************************** 02109 * CryptSetProvParam (ADVAPI32.@) 02110 * 02111 * Customizes the operations of a CSP. 02112 * 02113 * PARAMS 02114 * hProv [I] Handle of a CSP. 02115 * dwParam [I] See MSDN Doc. 02116 * pbData [I] Buffer that contains a value to set as a parameter. 02117 * dwFlags [I] if dwParam is PP_USE_HARDWARE_RNG, dwFlags must be zero. 02118 * 02119 * RETURNS 02120 * Success: TRUE 02121 * Failure: FALSE 02122 */ 02123 BOOL WINAPI CryptSetProvParam (HCRYPTPROV hProv, DWORD dwParam, CONST BYTE *pbData, DWORD dwFlags) 02124 { 02125 PCRYPTPROV prov = (PCRYPTPROV)hProv; 02126 02127 TRACE("(0x%lx, %d, %p, %08x)\n", hProv, dwParam, pbData, dwFlags); 02128 02129 if (!prov) 02130 { 02131 SetLastError(ERROR_INVALID_HANDLE); 02132 return FALSE; 02133 } 02134 if (prov->dwMagic != MAGIC_CRYPTPROV) 02135 { 02136 SetLastError(ERROR_INVALID_PARAMETER); 02137 return FALSE; 02138 } 02139 if (dwFlags & PP_USE_HARDWARE_RNG) 02140 { 02141 FIXME("PP_USE_HARDWARE_RNG: What do I do with this?\n"); 02142 FIXME("\tLetting the CSP decide.\n"); 02143 } 02144 if (dwFlags & PP_CLIENT_HWND) 02145 { 02146 /* FIXME: Should verify the parameter */ 02147 if (pbData /* && IsWindow((HWND)pbData) */) 02148 { 02149 crypt_hWindow = (HWND)(pbData); 02150 return TRUE; 02151 } else { 02152 SetLastError(ERROR_INVALID_PARAMETER); 02153 return FALSE; 02154 } 02155 } 02156 /* All other flags go to the CSP */ 02157 return prov->pFuncs->pCPSetProvParam(prov->hPrivate, dwParam, pbData, dwFlags); 02158 } 02159 02160 /****************************************************************************** 02161 * CryptVerifySignatureW (ADVAPI32.@) 02162 * 02163 * Verifies the signature of a hash object. 02164 * 02165 * PARAMS 02166 * hHash [I] Handle of the hash object to verify. 02167 * pbSignature [I] Signature data to verify. 02168 * dwSigLen [I] Size of pbSignature. 02169 * hPubKey [I] Handle to the public key to authenticate signature. 02170 * sDescription [I] Should be NULL. 02171 * dwFlags [I] See MSDN doc. 02172 * 02173 * RETURNS 02174 * Success: TRUE 02175 * Failure: FALSE 02176 * 02177 * NOTES 02178 * Because of security flaws sDescription should not be used and should thus be 02179 * NULL. It is supported only for compatibility with Microsoft's Cryptographic 02180 * Providers. 02181 */ 02182 BOOL WINAPI CryptVerifySignatureW (HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, 02183 HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags) 02184 { 02185 PCRYPTHASH hash = (PCRYPTHASH)hHash; 02186 PCRYPTKEY key = (PCRYPTKEY)hPubKey; 02187 PCRYPTPROV prov; 02188 02189 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature, 02190 dwSigLen, hPubKey, debugstr_w(sDescription), dwFlags); 02191 02192 if (!hash || !key || 02193 !hash->pProvider || hash->pProvider->dwMagic != MAGIC_CRYPTPROV || 02194 !key->pProvider || key->pProvider->dwMagic != MAGIC_CRYPTPROV) 02195 { 02196 SetLastError(ERROR_INVALID_PARAMETER); 02197 return FALSE; 02198 } 02199 02200 prov = hash->pProvider; 02201 return prov->pFuncs->pCPVerifySignature(prov->hPrivate, hash->hPrivate, pbSignature, dwSigLen, 02202 key->hPrivate, sDescription, dwFlags); 02203 } 02204 02205 /****************************************************************************** 02206 * CryptVerifySignatureA (ADVAPI32.@) 02207 * 02208 * See CryptVerifySignatureW. 02209 */ 02210 BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, 02211 HCRYPTKEY hPubKey, LPCSTR sDescription, DWORD dwFlags) 02212 { 02213 LPWSTR wsDescription; 02214 BOOL result; 02215 02216 TRACE("(0x%lx, %p, %d, 0x%lx, %s, %08x)\n", hHash, pbSignature, 02217 dwSigLen, hPubKey, debugstr_a(sDescription), dwFlags); 02218 02219 CRYPT_ANSIToUnicode(sDescription, &wsDescription, -1); 02220 result = CryptVerifySignatureW(hHash, pbSignature, dwSigLen, hPubKey, wsDescription, dwFlags); 02221 CRYPT_Free(wsDescription); 02222 02223 return result; 02224 } Generated on Sat May 26 2012 04:21:08 for ReactOS by
1.7.6.1
|