1 /* 2 * dlls/rsaenh/rsaenh.c 3 * RSAENH - RSA encryption for Wine 4 * 5 * Copyright 2002 TransGaming Technologies (David Hammerton) 6 * Copyright 2004 Mike McCormack for CodeWeavers 7 * Copyright 2004, 2005 Michael Jung 8 * Copyright 2007 Vijay Kiran Kamuju 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 23 */ 24 25 #define WIN32_NO_STATUS 26 #define _INC_WINDOWS 27 #define COM_NO_WINDOWS_H 28 29 #include <config.h> 30 //#include "wine/port.h" 31 #include <wine/library.h> 32 #include <wine/debug.h> 33 34 //#include <stdarg.h> 35 //#include <stdio.h> 36 37 #include <windef.h> 38 //#include "winbase.h" 39 #include <winreg.h> 40 #include <wincrypt.h> 41 #include "handle.h" 42 #include "implglue.h" 43 #include <objbase.h> 44 #include <rpcproxy.h> 45 #include <aclapi.h> 46 #include <strsafe.h> 47 48 WINE_DEFAULT_DEBUG_CHANNEL(crypt); 49 50 static HINSTANCE instance; 51 52 /****************************************************************************** 53 * CRYPTHASH - hash objects 54 */ 55 #define RSAENH_MAGIC_HASH 0x85938417u 56 #define RSAENH_MAX_HASH_SIZE 104 57 #define RSAENH_HASHSTATE_HASHING 1 58 #define RSAENH_HASHSTATE_FINISHED 2 59 typedef struct _RSAENH_TLS1PRF_PARAMS 60 { 61 CRYPT_DATA_BLOB blobLabel; 62 CRYPT_DATA_BLOB blobSeed; 63 } RSAENH_TLS1PRF_PARAMS; 64 65 typedef struct tagCRYPTHASH 66 { 67 OBJECTHDR header; 68 ALG_ID aiAlgid; 69 HCRYPTKEY hKey; 70 HCRYPTPROV hProv; 71 DWORD dwHashSize; 72 DWORD dwState; 73 HASH_CONTEXT context; 74 BYTE abHashValue[RSAENH_MAX_HASH_SIZE]; 75 PHMAC_INFO pHMACInfo; 76 RSAENH_TLS1PRF_PARAMS tpPRFParams; 77 } CRYPTHASH; 78 79 /****************************************************************************** 80 * CRYPTKEY - key objects 81 */ 82 #define RSAENH_MAGIC_KEY 0x73620457u 83 #define RSAENH_MAX_KEY_SIZE 64 84 #define RSAENH_MAX_BLOCK_SIZE 24 85 #define RSAENH_KEYSTATE_IDLE 0 86 #define RSAENH_KEYSTATE_ENCRYPTING 1 87 #define RSAENH_KEYSTATE_MASTERKEY 2 88 typedef struct _RSAENH_SCHANNEL_INFO 89 { 90 SCHANNEL_ALG saEncAlg; 91 SCHANNEL_ALG saMACAlg; 92 CRYPT_DATA_BLOB blobClientRandom; 93 CRYPT_DATA_BLOB blobServerRandom; 94 } RSAENH_SCHANNEL_INFO; 95 96 typedef struct tagCRYPTKEY 97 { 98 OBJECTHDR header; 99 ALG_ID aiAlgid; 100 HCRYPTPROV hProv; 101 DWORD dwMode; 102 DWORD dwModeBits; 103 DWORD dwPermissions; 104 DWORD dwKeyLen; 105 DWORD dwEffectiveKeyLen; 106 DWORD dwSaltLen; 107 DWORD dwBlockLen; 108 DWORD dwState; 109 KEY_CONTEXT context; 110 BYTE abKeyValue[RSAENH_MAX_KEY_SIZE]; 111 BYTE abInitVector[RSAENH_MAX_BLOCK_SIZE]; 112 BYTE abChainVector[RSAENH_MAX_BLOCK_SIZE]; 113 RSAENH_SCHANNEL_INFO siSChannelInfo; 114 CRYPT_DATA_BLOB blobHmacKey; 115 } CRYPTKEY; 116 117 /****************************************************************************** 118 * KEYCONTAINER - key containers 119 */ 120 #define RSAENH_PERSONALITY_BASE 0u 121 #define RSAENH_PERSONALITY_STRONG 1u 122 #define RSAENH_PERSONALITY_ENHANCED 2u 123 #define RSAENH_PERSONALITY_SCHANNEL 3u 124 #define RSAENH_PERSONALITY_AES 4u 125 126 #define RSAENH_MAGIC_CONTAINER 0x26384993u 127 typedef struct tagKEYCONTAINER 128 { 129 OBJECTHDR header; 130 DWORD dwFlags; 131 DWORD dwPersonality; 132 DWORD dwEnumAlgsCtr; 133 DWORD dwEnumContainersCtr; 134 CHAR szName[MAX_PATH]; 135 CHAR szProvName[MAX_PATH]; 136 HCRYPTKEY hKeyExchangeKeyPair; 137 HCRYPTKEY hSignatureKeyPair; 138 } KEYCONTAINER; 139 140 /****************************************************************************** 141 * Some magic constants 142 */ 143 #define RSAENH_ENCRYPT 1 144 #define RSAENH_DECRYPT 0 145 #define RSAENH_HMAC_DEF_IPAD_CHAR 0x36 146 #define RSAENH_HMAC_DEF_OPAD_CHAR 0x5c 147 #define RSAENH_HMAC_DEF_PAD_LEN 64 148 #define RSAENH_HMAC_BLOCK_LEN 64 149 #define RSAENH_DES_EFFECTIVE_KEYLEN 56 150 #define RSAENH_DES_STORAGE_KEYLEN 64 151 #define RSAENH_3DES112_EFFECTIVE_KEYLEN 112 152 #define RSAENH_3DES112_STORAGE_KEYLEN 128 153 #define RSAENH_3DES_EFFECTIVE_KEYLEN 168 154 #define RSAENH_3DES_STORAGE_KEYLEN 192 155 #define RSAENH_MAGIC_RSA2 0x32415352 156 #define RSAENH_MAGIC_RSA1 0x31415352 157 #define RSAENH_PKC_BLOCKTYPE 0x02 158 #define RSAENH_SSL3_VERSION_MAJOR 3 159 #define RSAENH_SSL3_VERSION_MINOR 0 160 #define RSAENH_TLS1_VERSION_MAJOR 3 161 #define RSAENH_TLS1_VERSION_MINOR 1 162 #define RSAENH_REGKEY "Software\\Wine\\Crypto\\RSA\\%s" 163 164 #define RSAENH_MIN(a,b) ((a)<(b)?(a):(b)) 165 /****************************************************************************** 166 * aProvEnumAlgsEx - Defines the capabilities of the CSP personalities. 167 */ 168 #define RSAENH_MAX_ENUMALGS 24 169 #define RSAENH_PCT1_SSL2_SSL3_TLS1 (CRYPT_FLAG_PCT1|CRYPT_FLAG_SSL2|CRYPT_FLAG_SSL3|CRYPT_FLAG_TLS1) 170 static const PROV_ENUMALGS_EX aProvEnumAlgsEx[5][RSAENH_MAX_ENUMALGS+1] = 171 { 172 { 173 {CALG_RC2, 40, 40, 56,0, 4,"RC2", 24,"RSA Data Security's RC2"}, 174 {CALG_RC4, 40, 40, 56,0, 4,"RC4", 24,"RSA Data Security's RC4"}, 175 {CALG_DES, 56, 56, 56,0, 4,"DES", 31,"Data Encryption Standard (DES)"}, 176 {CALG_SHA, 160,160, 160,CRYPT_FLAG_SIGNING, 6,"SHA-1", 30,"Secure Hash Algorithm (SHA-1)"}, 177 {CALG_MD2, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD2", 23,"Message Digest 2 (MD2)"}, 178 {CALG_MD4, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD4", 23,"Message Digest 4 (MD4)"}, 179 {CALG_MD5, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD5", 23,"Message Digest 5 (MD5)"}, 180 {CALG_SSL3_SHAMD5,288,288,288,0, 12,"SSL3 SHAMD5",12,"SSL3 SHAMD5"}, 181 {CALG_MAC, 0, 0, 0,0, 4,"MAC", 28,"Message Authentication Code"}, 182 {CALG_RSA_SIGN, 512,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_SIGN",14,"RSA Signature"}, 183 {CALG_RSA_KEYX, 512,384, 1024,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_KEYX",17,"RSA Key Exchange"}, 184 {CALG_HMAC, 0, 0, 0,0, 5,"HMAC", 18,"Hugo's MAC (HMAC)"}, 185 {0, 0, 0, 0,0, 1,"", 1,""} 186 }, 187 { 188 {CALG_RC2, 128, 40, 128,0, 4,"RC2", 24,"RSA Data Security's RC2"}, 189 {CALG_RC4, 128, 40, 128,0, 4,"RC4", 24,"RSA Data Security's RC4"}, 190 {CALG_DES, 56, 56, 56,0, 4,"DES", 31,"Data Encryption Standard (DES)"}, 191 {CALG_3DES_112, 112,112, 112,0, 13,"3DES TWO KEY",19,"Two Key Triple DES"}, 192 {CALG_3DES, 168,168, 168,0, 5,"3DES", 21,"Three Key Triple DES"}, 193 {CALG_SHA, 160,160, 160,CRYPT_FLAG_SIGNING, 6,"SHA-1", 30,"Secure Hash Algorithm (SHA-1)"}, 194 {CALG_MD2, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD2", 23,"Message Digest 2 (MD2)"}, 195 {CALG_MD4, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD4", 23,"Message Digest 4 (MD4)"}, 196 {CALG_MD5, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD5", 23,"Message Digest 5 (MD5)"}, 197 {CALG_SSL3_SHAMD5,288,288,288,0, 12,"SSL3 SHAMD5",12,"SSL3 SHAMD5"}, 198 {CALG_MAC, 0, 0, 0,0, 4,"MAC", 28,"Message Authentication Code"}, 199 {CALG_RSA_SIGN,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_SIGN",14,"RSA Signature"}, 200 {CALG_RSA_KEYX,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_KEYX",17,"RSA Key Exchange"}, 201 {CALG_HMAC, 0, 0, 0,0, 5,"HMAC", 18,"Hugo's MAC (HMAC)"}, 202 {0, 0, 0, 0,0, 1,"", 1,""} 203 }, 204 { 205 {CALG_RC2, 128, 40, 128,0, 4,"RC2", 24,"RSA Data Security's RC2"}, 206 {CALG_RC4, 128, 40, 128,0, 4,"RC4", 24,"RSA Data Security's RC4"}, 207 {CALG_DES, 56, 56, 56,0, 4,"DES", 31,"Data Encryption Standard (DES)"}, 208 {CALG_3DES_112, 112,112, 112,0, 13,"3DES TWO KEY",19,"Two Key Triple DES"}, 209 {CALG_3DES, 168,168, 168,0, 5,"3DES", 21,"Three Key Triple DES"}, 210 {CALG_SHA, 160,160, 160,CRYPT_FLAG_SIGNING, 6,"SHA-1", 30,"Secure Hash Algorithm (SHA-1)"}, 211 {CALG_MD2, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD2", 23,"Message Digest 2 (MD2)"}, 212 {CALG_MD4, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD4", 23,"Message Digest 4 (MD4)"}, 213 {CALG_MD5, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD5", 23,"Message Digest 5 (MD5)"}, 214 {CALG_SSL3_SHAMD5,288,288,288,0, 12,"SSL3 SHAMD5",12,"SSL3 SHAMD5"}, 215 {CALG_MAC, 0, 0, 0,0, 4,"MAC", 28,"Message Authentication Code"}, 216 {CALG_RSA_SIGN,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_SIGN",14,"RSA Signature"}, 217 {CALG_RSA_KEYX,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_KEYX",17,"RSA Key Exchange"}, 218 {CALG_HMAC, 0, 0, 0,0, 5,"HMAC", 18,"Hugo's MAC (HMAC)"}, 219 {0, 0, 0, 0,0, 1,"", 1,""} 220 }, 221 { 222 {CALG_RC2, 128, 40, 128,RSAENH_PCT1_SSL2_SSL3_TLS1, 4,"RC2", 24,"RSA Data Security's RC2"}, 223 {CALG_RC4, 128, 40, 128,RSAENH_PCT1_SSL2_SSL3_TLS1, 4,"RC4", 24,"RSA Data Security's RC4"}, 224 {CALG_DES, 56, 56, 56,RSAENH_PCT1_SSL2_SSL3_TLS1, 4,"DES", 31,"Data Encryption Standard (DES)"}, 225 {CALG_3DES_112, 112,112, 112,RSAENH_PCT1_SSL2_SSL3_TLS1,13,"3DES TWO KEY",19,"Two Key Triple DES"}, 226 {CALG_3DES, 168,168, 168,RSAENH_PCT1_SSL2_SSL3_TLS1, 5,"3DES", 21,"Three Key Triple DES"}, 227 {CALG_SHA,160,160,160,CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1,6,"SHA-1",30,"Secure Hash Algorithm (SHA-1)"}, 228 {CALG_MD5,128,128,128,CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1,4,"MD5",23,"Message Digest 5 (MD5)"}, 229 {CALG_SSL3_SHAMD5,288,288,288,0, 12,"SSL3 SHAMD5",12,"SSL3 SHAMD5"}, 230 {CALG_MAC, 0, 0, 0,0, 4,"MAC", 28,"Message Authentication Code"}, 231 {CALG_RSA_SIGN,1024,384,16384,CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1,9,"RSA_SIGN",14,"RSA Signature"}, 232 {CALG_RSA_KEYX,1024,384,16384,CRYPT_FLAG_SIGNING|RSAENH_PCT1_SSL2_SSL3_TLS1,9,"RSA_KEYX",17,"RSA Key Exchange"}, 233 {CALG_HMAC, 0, 0, 0,0, 5,"HMAC", 18,"Hugo's MAC (HMAC)"}, 234 {CALG_PCT1_MASTER,128,128,128,CRYPT_FLAG_PCT1, 12,"PCT1 MASTER",12,"PCT1 Master"}, 235 {CALG_SSL2_MASTER,40,40, 192,CRYPT_FLAG_SSL2, 12,"SSL2 MASTER",12,"SSL2 Master"}, 236 {CALG_SSL3_MASTER,384,384,384,CRYPT_FLAG_SSL3, 12,"SSL3 MASTER",12,"SSL3 Master"}, 237 {CALG_TLS1_MASTER,384,384,384,CRYPT_FLAG_TLS1, 12,"TLS1 MASTER",12,"TLS1 Master"}, 238 {CALG_SCHANNEL_MASTER_HASH,0,0,-1,0, 16,"SCH MASTER HASH",21,"SChannel Master Hash"}, 239 {CALG_SCHANNEL_MAC_KEY,0,0,-1,0, 12,"SCH MAC KEY",17,"SChannel MAC Key"}, 240 {CALG_SCHANNEL_ENC_KEY,0,0,-1,0, 12,"SCH ENC KEY",24,"SChannel Encryption Key"}, 241 {CALG_TLS1PRF, 0, 0, -1,0, 9,"TLS1 PRF", 28,"TLS1 Pseudo Random Function"}, 242 {0, 0, 0, 0,0, 1,"", 1,""} 243 }, 244 { 245 {CALG_RC2, 128, 40, 128,0, 4,"RC2", 24,"RSA Data Security's RC2"}, 246 {CALG_RC4, 128, 40, 128,0, 4,"RC4", 24,"RSA Data Security's RC4"}, 247 {CALG_DES, 56, 56, 56,0, 4,"DES", 31,"Data Encryption Standard (DES)"}, 248 {CALG_3DES_112, 112,112, 112,0, 13,"3DES TWO KEY",19,"Two Key Triple DES"}, 249 {CALG_3DES, 168,168, 168,0, 5,"3DES", 21,"Three Key Triple DES"}, 250 {CALG_AES, 128,128, 128,0, 4,"AES", 35,"Advanced Encryption Standard (AES)"}, 251 {CALG_AES_128, 128,128, 128,0, 8,"AES-128", 39,"Advanced Encryption Standard (AES-128)"}, 252 {CALG_AES_192, 192,192, 192,0, 8,"AES-192", 39,"Advanced Encryption Standard (AES-192)"}, 253 {CALG_AES_256, 256,256, 256,0, 8,"AES-256", 39,"Advanced Encryption Standard (AES-256)"}, 254 {CALG_SHA, 160,160, 160,CRYPT_FLAG_SIGNING, 6,"SHA-1", 30,"Secure Hash Algorithm (SHA-1)"}, 255 {CALG_SHA_256, 256,256, 256,CRYPT_FLAG_SIGNING, 6,"SHA-256", 30,"Secure Hash Algorithm (SHA-256)"}, 256 {CALG_SHA_384, 384,384, 384,CRYPT_FLAG_SIGNING, 6,"SHA-384", 30,"Secure Hash Algorithm (SHA-384)"}, 257 {CALG_SHA_512, 512,512, 512,CRYPT_FLAG_SIGNING, 6,"SHA-512", 30,"Secure Hash Algorithm (SHA-512)"}, 258 {CALG_MD2, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD2", 23,"Message Digest 2 (MD2)"}, 259 {CALG_MD4, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD4", 23,"Message Digest 4 (MD4)"}, 260 {CALG_MD5, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD5", 23,"Message Digest 5 (MD5)"}, 261 {CALG_SSL3_SHAMD5,288,288,288,0, 12,"SSL3 SHAMD5",12,"SSL3 SHAMD5"}, 262 {CALG_MAC, 0, 0, 0,0, 4,"MAC", 28,"Message Authentication Code"}, 263 {CALG_RSA_SIGN,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_SIGN",14,"RSA Signature"}, 264 {CALG_RSA_KEYX,1024,384,16384,CRYPT_FLAG_SIGNING|CRYPT_FLAG_IPSEC,9,"RSA_KEYX",17,"RSA Key Exchange"}, 265 {CALG_HMAC, 0, 0, 0,0, 5,"HMAC", 18,"Hugo's MAC (HMAC)"}, 266 {0, 0, 0, 0,0, 1,"", 1,""} 267 } 268 }; 269 270 /****************************************************************************** 271 * API forward declarations 272 */ 273 BOOL WINAPI 274 RSAENH_CPGetKeyParam( 275 HCRYPTPROV hProv, 276 HCRYPTKEY hKey, 277 DWORD dwParam, 278 BYTE *pbData, 279 DWORD *pdwDataLen, 280 DWORD dwFlags 281 ); 282 283 BOOL WINAPI 284 RSAENH_CPEncrypt( 285 HCRYPTPROV hProv, 286 HCRYPTKEY hKey, 287 HCRYPTHASH hHash, 288 BOOL Final, 289 DWORD dwFlags, 290 BYTE *pbData, 291 DWORD *pdwDataLen, 292 DWORD dwBufLen 293 ); 294 295 BOOL WINAPI 296 RSAENH_CPCreateHash( 297 HCRYPTPROV hProv, 298 ALG_ID Algid, 299 HCRYPTKEY hKey, 300 DWORD dwFlags, 301 HCRYPTHASH *phHash 302 ); 303 304 BOOL WINAPI 305 RSAENH_CPSetHashParam( 306 HCRYPTPROV hProv, 307 HCRYPTHASH hHash, 308 DWORD dwParam, 309 BYTE *pbData, DWORD dwFlags 310 ); 311 312 BOOL WINAPI 313 RSAENH_CPGetHashParam( 314 HCRYPTPROV hProv, 315 HCRYPTHASH hHash, 316 DWORD dwParam, 317 BYTE *pbData, 318 DWORD *pdwDataLen, 319 DWORD dwFlags 320 ); 321 322 BOOL WINAPI 323 RSAENH_CPDestroyHash( 324 HCRYPTPROV hProv, 325 HCRYPTHASH hHash 326 ); 327 328 static BOOL crypt_export_key( 329 CRYPTKEY *pCryptKey, 330 HCRYPTKEY hPubKey, 331 DWORD dwBlobType, 332 DWORD dwFlags, 333 BOOL force, 334 BYTE *pbData, 335 DWORD *pdwDataLen 336 ); 337 338 static BOOL import_key( 339 HCRYPTPROV hProv, 340 const BYTE *pbData, 341 DWORD dwDataLen, 342 HCRYPTKEY hPubKey, 343 DWORD dwFlags, 344 BOOL fStoreKey, 345 HCRYPTKEY *phKey 346 ); 347 348 BOOL WINAPI 349 RSAENH_CPHashData( 350 HCRYPTPROV hProv, 351 HCRYPTHASH hHash, 352 const BYTE *pbData, 353 DWORD dwDataLen, 354 DWORD dwFlags 355 ); 356 357 /****************************************************************************** 358 * CSP's handle table (used by all acquired key containers) 359 */ 360 static struct handle_table handle_table; 361 362 /****************************************************************************** 363 * DllMain (RSAENH.@) 364 * 365 * Initializes and destroys the handle table for the CSP's handles. 366 */ 367 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID reserved) 368 { 369 switch (fdwReason) 370 { 371 case DLL_PROCESS_ATTACH: 372 instance = hInstance; 373 DisableThreadLibraryCalls(hInstance); 374 init_handle_table(&handle_table); 375 break; 376 377 case DLL_PROCESS_DETACH: 378 if (reserved) break; 379 destroy_handle_table(&handle_table); 380 break; 381 } 382 return TRUE; 383 } 384 385 /****************************************************************************** 386 * copy_param [Internal] 387 * 388 * Helper function that supports the standard WINAPI protocol for querying data 389 * of dynamic size. 390 * 391 * PARAMS 392 * pbBuffer [O] Buffer where the queried parameter is copied to, if it is large enough. 393 * May be NUL if the required buffer size is to be queried only. 394 * pdwBufferSize [I/O] In: Size of the buffer at pbBuffer 395 * Out: Size of parameter pbParam 396 * pbParam [I] Parameter value. 397 * dwParamSize [I] Size of pbParam 398 * 399 * RETURN 400 * Success: TRUE (pbParam was copied into pbBuffer or pbBuffer is NULL) 401 * Failure: FALSE (pbBuffer is not large enough to hold pbParam). Last error: ERROR_MORE_DATA 402 */ 403 static inline BOOL copy_param(BYTE *pbBuffer, DWORD *pdwBufferSize, const BYTE *pbParam, 404 DWORD dwParamSize) 405 { 406 if (pbBuffer) 407 { 408 if (dwParamSize > *pdwBufferSize) 409 { 410 SetLastError(ERROR_MORE_DATA); 411 *pdwBufferSize = dwParamSize; 412 return FALSE; 413 } 414 memcpy(pbBuffer, pbParam, dwParamSize); 415 } 416 *pdwBufferSize = dwParamSize; 417 return TRUE; 418 } 419 420 static inline KEYCONTAINER* get_key_container(HCRYPTPROV hProv) 421 { 422 KEYCONTAINER *pKeyContainer; 423 424 if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER, 425 (OBJECTHDR**)&pKeyContainer)) 426 { 427 SetLastError(NTE_BAD_UID); 428 return NULL; 429 } 430 return pKeyContainer; 431 } 432 433 /****************************************************************************** 434 * get_algid_info [Internal] 435 * 436 * Query CSP capabilities for a given crypto algorithm. 437 * 438 * PARAMS 439 * hProv [I] Handle to a key container of the CSP whose capabilities are to be queried. 440 * algid [I] Identifier of the crypto algorithm about which information is requested. 441 * 442 * RETURNS 443 * Success: Pointer to a PROV_ENUMALGS_EX struct containing information about the crypto algorithm. 444 * Failure: NULL (algid not supported) 445 */ 446 static inline const PROV_ENUMALGS_EX* get_algid_info(HCRYPTPROV hProv, ALG_ID algid) { 447 const PROV_ENUMALGS_EX *iterator; 448 KEYCONTAINER *pKeyContainer; 449 450 if (!(pKeyContainer = get_key_container(hProv))) return NULL; 451 452 for (iterator = aProvEnumAlgsEx[pKeyContainer->dwPersonality]; iterator->aiAlgid; iterator++) { 453 if (iterator->aiAlgid == algid) return iterator; 454 } 455 456 SetLastError(NTE_BAD_ALGID); 457 return NULL; 458 } 459 460 /****************************************************************************** 461 * copy_data_blob [Internal] 462 * 463 * deeply copies a DATA_BLOB 464 * 465 * PARAMS 466 * dst [O] That's where the blob will be copied to 467 * src [I] Source blob 468 * 469 * RETURNS 470 * Success: TRUE 471 * Failure: FALSE (GetLastError() == NTE_NO_MEMORY 472 * 473 * NOTES 474 * Use free_data_blob to release resources occupied by copy_data_blob. 475 */ 476 static inline BOOL copy_data_blob(PCRYPT_DATA_BLOB dst, const PCRYPT_DATA_BLOB src) 477 { 478 dst->pbData = HeapAlloc(GetProcessHeap(), 0, src->cbData); 479 if (!dst->pbData) { 480 SetLastError(NTE_NO_MEMORY); 481 return FALSE; 482 } 483 dst->cbData = src->cbData; 484 memcpy(dst->pbData, src->pbData, src->cbData); 485 return TRUE; 486 } 487 488 /****************************************************************************** 489 * concat_data_blobs [Internal] 490 * 491 * Concatenates two blobs 492 * 493 * PARAMS 494 * dst [O] The new blob will be copied here 495 * src1 [I] Prefix blob 496 * src2 [I] Appendix blob 497 * 498 * RETURNS 499 * Success: TRUE 500 * Failure: FALSE (GetLastError() == NTE_NO_MEMORY) 501 * 502 * NOTES 503 * Release resources occupied by concat_data_blobs with free_data_blobs 504 */ 505 static inline BOOL concat_data_blobs(PCRYPT_DATA_BLOB dst, const PCRYPT_DATA_BLOB src1, 506 const PCRYPT_DATA_BLOB src2) 507 { 508 dst->cbData = src1->cbData + src2->cbData; 509 dst->pbData = HeapAlloc(GetProcessHeap(), 0, dst->cbData); 510 if (!dst->pbData) { 511 SetLastError(NTE_NO_MEMORY); 512 return FALSE; 513 } 514 memcpy(dst->pbData, src1->pbData, src1->cbData); 515 memcpy(dst->pbData + src1->cbData, src2->pbData, src2->cbData); 516 return TRUE; 517 } 518 519 /****************************************************************************** 520 * free_data_blob [Internal] 521 * 522 * releases resource occupied by a dynamically allocated CRYPT_DATA_BLOB 523 * 524 * PARAMS 525 * pBlob [I] Heap space occupied by pBlob->pbData is released 526 */ 527 static inline void free_data_blob(PCRYPT_DATA_BLOB pBlob) { 528 HeapFree(GetProcessHeap(), 0, pBlob->pbData); 529 } 530 531 /****************************************************************************** 532 * init_data_blob [Internal] 533 */ 534 static inline void init_data_blob(PCRYPT_DATA_BLOB pBlob) { 535 pBlob->pbData = NULL; 536 pBlob->cbData = 0; 537 } 538 539 /****************************************************************************** 540 * free_hmac_info [Internal] 541 * 542 * Deeply free an HMAC_INFO struct. 543 * 544 * PARAMS 545 * hmac_info [I] Pointer to the HMAC_INFO struct to be freed. 546 * 547 * NOTES 548 * See Internet RFC 2104 for details on the HMAC algorithm. 549 */ 550 static inline void free_hmac_info(PHMAC_INFO hmac_info) { 551 if (!hmac_info) return; 552 HeapFree(GetProcessHeap(), 0, hmac_info->pbInnerString); 553 HeapFree(GetProcessHeap(), 0, hmac_info->pbOuterString); 554 HeapFree(GetProcessHeap(), 0, hmac_info); 555 } 556 557 /****************************************************************************** 558 * copy_hmac_info [Internal] 559 * 560 * Deeply copy an HMAC_INFO struct 561 * 562 * PARAMS 563 * dst [O] Pointer to a location where the pointer to the HMAC_INFO copy will be stored. 564 * src [I] Pointer to the HMAC_INFO struct to be copied. 565 * 566 * RETURNS 567 * Success: TRUE 568 * Failure: FALSE 569 * 570 * NOTES 571 * See Internet RFC 2104 for details on the HMAC algorithm. 572 */ 573 static BOOL copy_hmac_info(PHMAC_INFO *dst, const HMAC_INFO *src) { 574 if (!src) return FALSE; 575 *dst = HeapAlloc(GetProcessHeap(), 0, sizeof(HMAC_INFO)); 576 if (!*dst) return FALSE; 577 **dst = *src; 578 (*dst)->pbInnerString = NULL; 579 (*dst)->pbOuterString = NULL; 580 if ((*dst)->cbInnerString == 0) (*dst)->cbInnerString = RSAENH_HMAC_DEF_PAD_LEN; 581 (*dst)->pbInnerString = HeapAlloc(GetProcessHeap(), 0, (*dst)->cbInnerString); 582 if (!(*dst)->pbInnerString) { 583 free_hmac_info(*dst); 584 return FALSE; 585 } 586 if (src->cbInnerString) 587 memcpy((*dst)->pbInnerString, src->pbInnerString, src->cbInnerString); 588 else 589 memset((*dst)->pbInnerString, RSAENH_HMAC_DEF_IPAD_CHAR, RSAENH_HMAC_DEF_PAD_LEN); 590 if ((*dst)->cbOuterString == 0) (*dst)->cbOuterString = RSAENH_HMAC_DEF_PAD_LEN; 591 (*dst)->pbOuterString = HeapAlloc(GetProcessHeap(), 0, (*dst)->cbOuterString); 592 if (!(*dst)->pbOuterString) { 593 free_hmac_info(*dst); 594 return FALSE; 595 } 596 if (src->cbOuterString) 597 memcpy((*dst)->pbOuterString, src->pbOuterString, src->cbOuterString); 598 else 599 memset((*dst)->pbOuterString, RSAENH_HMAC_DEF_OPAD_CHAR, RSAENH_HMAC_DEF_PAD_LEN); 600 return TRUE; 601 } 602 603 /****************************************************************************** 604 * destroy_hash [Internal] 605 * 606 * Destructor for hash objects 607 * 608 * PARAMS 609 * pCryptHash [I] Pointer to the hash object to be destroyed. 610 * Will be invalid after function returns! 611 */ 612 static void destroy_hash(OBJECTHDR *pObject) 613 { 614 CRYPTHASH *pCryptHash = (CRYPTHASH*)pObject; 615 616 free_hmac_info(pCryptHash->pHMACInfo); 617 free_data_blob(&pCryptHash->tpPRFParams.blobLabel); 618 free_data_blob(&pCryptHash->tpPRFParams.blobSeed); 619 HeapFree(GetProcessHeap(), 0, pCryptHash); 620 } 621 622 /****************************************************************************** 623 * init_hash [Internal] 624 * 625 * Initialize (or reset) a hash object 626 * 627 * PARAMS 628 * pCryptHash [I] The hash object to be initialized. 629 */ 630 static inline BOOL init_hash(CRYPTHASH *pCryptHash) { 631 DWORD dwLen; 632 633 switch (pCryptHash->aiAlgid) 634 { 635 case CALG_HMAC: 636 if (pCryptHash->pHMACInfo) { 637 const PROV_ENUMALGS_EX *pAlgInfo; 638 639 pAlgInfo = get_algid_info(pCryptHash->hProv, pCryptHash->pHMACInfo->HashAlgid); 640 if (!pAlgInfo) return FALSE; 641 pCryptHash->dwHashSize = pAlgInfo->dwDefaultLen >> 3; 642 init_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context); 643 update_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context, 644 pCryptHash->pHMACInfo->pbInnerString, 645 pCryptHash->pHMACInfo->cbInnerString); 646 } 647 return TRUE; 648 649 case CALG_MAC: 650 dwLen = sizeof(DWORD); 651 RSAENH_CPGetKeyParam(pCryptHash->hProv, pCryptHash->hKey, KP_BLOCKLEN, 652 (BYTE*)&pCryptHash->dwHashSize, &dwLen, 0); 653 pCryptHash->dwHashSize >>= 3; 654 return TRUE; 655 656 default: 657 return init_hash_impl(pCryptHash->aiAlgid, &pCryptHash->context); 658 } 659 } 660 661 /****************************************************************************** 662 * update_hash [Internal] 663 * 664 * Hashes the given data and updates the hash object's state accordingly 665 * 666 * PARAMS 667 * pCryptHash [I] Hash object to be updated. 668 * pbData [I] Pointer to data stream to be hashed. 669 * dwDataLen [I] Length of data stream. 670 */ 671 static inline void update_hash(CRYPTHASH *pCryptHash, const BYTE *pbData, DWORD dwDataLen) 672 { 673 BYTE *pbTemp; 674 675 switch (pCryptHash->aiAlgid) 676 { 677 case CALG_HMAC: 678 if (pCryptHash->pHMACInfo) 679 update_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context, 680 pbData, dwDataLen); 681 break; 682 683 case CALG_MAC: 684 pbTemp = HeapAlloc(GetProcessHeap(), 0, dwDataLen); 685 if (!pbTemp) return; 686 memcpy(pbTemp, pbData, dwDataLen); 687 RSAENH_CPEncrypt(pCryptHash->hProv, pCryptHash->hKey, 0, FALSE, 0, 688 pbTemp, &dwDataLen, dwDataLen); 689 HeapFree(GetProcessHeap(), 0, pbTemp); 690 break; 691 692 default: 693 update_hash_impl(pCryptHash->aiAlgid, &pCryptHash->context, pbData, dwDataLen); 694 } 695 } 696 697 /****************************************************************************** 698 * finalize_hash [Internal] 699 * 700 * Finalizes the hash, after all data has been hashed with update_hash. 701 * No additional data can be hashed afterwards until the hash gets initialized again. 702 * 703 * PARAMS 704 * pCryptHash [I] Hash object to be finalized. 705 */ 706 static inline void finalize_hash(CRYPTHASH *pCryptHash) { 707 DWORD dwDataLen; 708 709 switch (pCryptHash->aiAlgid) 710 { 711 case CALG_HMAC: 712 if (pCryptHash->pHMACInfo) { 713 BYTE abHashValue[RSAENH_MAX_HASH_SIZE]; 714 715 finalize_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context, 716 pCryptHash->abHashValue); 717 memcpy(abHashValue, pCryptHash->abHashValue, pCryptHash->dwHashSize); 718 init_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context); 719 update_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context, 720 pCryptHash->pHMACInfo->pbOuterString, 721 pCryptHash->pHMACInfo->cbOuterString); 722 update_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context, 723 abHashValue, pCryptHash->dwHashSize); 724 finalize_hash_impl(pCryptHash->pHMACInfo->HashAlgid, &pCryptHash->context, 725 pCryptHash->abHashValue); 726 } 727 break; 728 729 case CALG_MAC: 730 dwDataLen = 0; 731 RSAENH_CPEncrypt(pCryptHash->hProv, pCryptHash->hKey, 0, TRUE, 0, 732 pCryptHash->abHashValue, &dwDataLen, pCryptHash->dwHashSize); 733 break; 734 735 default: 736 finalize_hash_impl(pCryptHash->aiAlgid, &pCryptHash->context, pCryptHash->abHashValue); 737 } 738 } 739 740 /****************************************************************************** 741 * destroy_key [Internal] 742 * 743 * Destructor for key objects 744 * 745 * PARAMS 746 * pCryptKey [I] Pointer to the key object to be destroyed. 747 * Will be invalid after function returns! 748 */ 749 static void destroy_key(OBJECTHDR *pObject) 750 { 751 CRYPTKEY *pCryptKey = (CRYPTKEY*)pObject; 752 753 free_key_impl(pCryptKey->aiAlgid, &pCryptKey->context); 754 free_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom); 755 free_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom); 756 free_data_blob(&pCryptKey->blobHmacKey); 757 HeapFree(GetProcessHeap(), 0, pCryptKey); 758 } 759 760 /****************************************************************************** 761 * setup_key [Internal] 762 * 763 * Initialize (or reset) a key object 764 * 765 * PARAMS 766 * pCryptKey [I] The key object to be initialized. 767 */ 768 static inline void setup_key(CRYPTKEY *pCryptKey) { 769 pCryptKey->dwState = RSAENH_KEYSTATE_IDLE; 770 memcpy(pCryptKey->abChainVector, pCryptKey->abInitVector, sizeof(pCryptKey->abChainVector)); 771 setup_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen, 772 pCryptKey->dwEffectiveKeyLen, pCryptKey->dwSaltLen, 773 pCryptKey->abKeyValue); 774 } 775 776 /****************************************************************************** 777 * new_key [Internal] 778 * 779 * Creates a new key object without assigning the actual binary key value. 780 * This is done by CPDeriveKey, CPGenKey or CPImportKey, which call this function. 781 * 782 * PARAMS 783 * hProv [I] Handle to the provider to which the created key will belong. 784 * aiAlgid [I] The new key shall use the crypto algorithm identified by aiAlgid. 785 * dwFlags [I] Upper 16 bits give the key length. 786 * Lower 16 bits: CRYPT_EXPORTABLE, CRYPT_CREATE_SALT, 787 * CRYPT_NO_SALT 788 * ppCryptKey [O] Pointer to the created key 789 * 790 * RETURNS 791 * Success: Handle to the created key. 792 * Failure: INVALID_HANDLE_VALUE 793 */ 794 static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTKEY **ppCryptKey) 795 { 796 HCRYPTKEY hCryptKey; 797 CRYPTKEY *pCryptKey; 798 DWORD dwKeyLen = HIWORD(dwFlags), bKeyLen = dwKeyLen; 799 const PROV_ENUMALGS_EX *peaAlgidInfo; 800 801 *ppCryptKey = NULL; 802 803 /* 804 * Retrieve the CSP's capabilities for the given ALG_ID value 805 */ 806 peaAlgidInfo = get_algid_info(hProv, aiAlgid); 807 if (!peaAlgidInfo) return (HCRYPTKEY)INVALID_HANDLE_VALUE; 808 809 TRACE("alg = %s, dwKeyLen = %d\n", debugstr_a(peaAlgidInfo->szName), 810 dwKeyLen); 811 /* 812 * Assume the default key length, if none is specified explicitly 813 */ 814 if (dwKeyLen == 0) dwKeyLen = peaAlgidInfo->dwDefaultLen; 815 816 /* 817 * Check if the requested key length is supported by the current CSP. 818 * Adjust key length's for DES algorithms. 819 */ 820 switch (aiAlgid) { 821 case CALG_DES: 822 if (dwKeyLen == RSAENH_DES_EFFECTIVE_KEYLEN) { 823 dwKeyLen = RSAENH_DES_STORAGE_KEYLEN; 824 } 825 if (dwKeyLen != RSAENH_DES_STORAGE_KEYLEN) { 826 SetLastError(NTE_BAD_FLAGS); 827 return (HCRYPTKEY)INVALID_HANDLE_VALUE; 828 } 829 break; 830 831 case CALG_3DES_112: 832 if (dwKeyLen == RSAENH_3DES112_EFFECTIVE_KEYLEN) { 833 dwKeyLen = RSAENH_3DES112_STORAGE_KEYLEN; 834 } 835 if (dwKeyLen != RSAENH_3DES112_STORAGE_KEYLEN) { 836 SetLastError(NTE_BAD_FLAGS); 837 return (HCRYPTKEY)INVALID_HANDLE_VALUE; 838 } 839 break; 840 841 case CALG_3DES: 842 if (dwKeyLen == RSAENH_3DES_EFFECTIVE_KEYLEN) { 843 dwKeyLen = RSAENH_3DES_STORAGE_KEYLEN; 844 } 845 if (dwKeyLen != RSAENH_3DES_STORAGE_KEYLEN) { 846 SetLastError(NTE_BAD_FLAGS); 847 return (HCRYPTKEY)INVALID_HANDLE_VALUE; 848 } 849 break; 850 851 case CALG_HMAC: 852 /* Avoid the key length check for HMAC keys, which have unlimited 853 * length. 854 */ 855 break; 856 857 case CALG_AES: 858 if (!bKeyLen) 859 { 860 TRACE("missing key len for CALG_AES\n"); 861 SetLastError(NTE_BAD_ALGID); 862 return (HCRYPTKEY)INVALID_HANDLE_VALUE; 863 } 864 /* fall through */ 865 default: 866 if (dwKeyLen % 8 || 867 dwKeyLen > peaAlgidInfo->dwMaxLen || 868 dwKeyLen < peaAlgidInfo->dwMinLen) 869 { 870 TRACE("key len %d out of bounds (%d, %d)\n", dwKeyLen, 871 peaAlgidInfo->dwMinLen, peaAlgidInfo->dwMaxLen); 872 SetLastError(NTE_BAD_DATA); 873 return (HCRYPTKEY)INVALID_HANDLE_VALUE; 874 } 875 } 876 877 hCryptKey = new_object(&handle_table, sizeof(CRYPTKEY), RSAENH_MAGIC_KEY, 878 destroy_key, (OBJECTHDR**)&pCryptKey); 879 if (hCryptKey != (HCRYPTKEY)INVALID_HANDLE_VALUE) 880 { 881 KEYCONTAINER *pKeyContainer = get_key_container(hProv); 882 pCryptKey->aiAlgid = aiAlgid; 883 pCryptKey->hProv = hProv; 884 pCryptKey->dwModeBits = 0; 885 pCryptKey->dwPermissions = CRYPT_ENCRYPT | CRYPT_DECRYPT | CRYPT_READ | CRYPT_WRITE | 886 CRYPT_MAC; 887 if (dwFlags & CRYPT_EXPORTABLE) 888 pCryptKey->dwPermissions |= CRYPT_EXPORT; 889 pCryptKey->dwKeyLen = dwKeyLen >> 3; 890 pCryptKey->dwEffectiveKeyLen = 0; 891 892 /* 893 * For compatibility reasons a 40 bit key on the Enhanced 894 * provider will not have salt 895 */ 896 if (pKeyContainer->dwPersonality == RSAENH_PERSONALITY_ENHANCED 897 && (aiAlgid == CALG_RC2 || aiAlgid == CALG_RC4) 898 && (dwFlags & CRYPT_CREATE_SALT) && dwKeyLen == 40) 899 pCryptKey->dwSaltLen = 0; 900 else if ((dwFlags & CRYPT_CREATE_SALT) || (dwKeyLen == 40 && !(dwFlags & CRYPT_NO_SALT))) 901 pCryptKey->dwSaltLen = 16 /*FIXME*/ - pCryptKey->dwKeyLen; 902 else 903 pCryptKey->dwSaltLen = 0; 904 memset(pCryptKey->abKeyValue, 0, sizeof(pCryptKey->abKeyValue)); 905 memset(pCryptKey->abInitVector, 0, sizeof(pCryptKey->abInitVector)); 906 memset(&pCryptKey->siSChannelInfo.saEncAlg, 0, sizeof(pCryptKey->siSChannelInfo.saEncAlg)); 907 memset(&pCryptKey->siSChannelInfo.saMACAlg, 0, sizeof(pCryptKey->siSChannelInfo.saMACAlg)); 908 init_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom); 909 init_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom); 910 init_data_blob(&pCryptKey->blobHmacKey); 911 912 switch(aiAlgid) 913 { 914 case CALG_PCT1_MASTER: 915 case CALG_SSL2_MASTER: 916 case CALG_SSL3_MASTER: 917 case CALG_TLS1_MASTER: 918 case CALG_RC4: 919 pCryptKey->dwBlockLen = 0; 920 pCryptKey->dwMode = 0; 921 break; 922 923 case CALG_RC2: 924 case CALG_DES: 925 case CALG_3DES_112: 926 case CALG_3DES: 927 pCryptKey->dwBlockLen = 8; 928 pCryptKey->dwMode = CRYPT_MODE_CBC; 929 break; 930 931 case CALG_AES: 932 case CALG_AES_128: 933 case CALG_AES_192: 934 case CALG_AES_256: 935 pCryptKey->dwBlockLen = 16; 936 pCryptKey->dwMode = CRYPT_MODE_CBC; 937 break; 938 939 case CALG_RSA_KEYX: 940 case CALG_RSA_SIGN: 941 pCryptKey->dwBlockLen = dwKeyLen >> 3; 942 pCryptKey->dwMode = 0; 943 break; 944 945 case CALG_HMAC: 946 pCryptKey->dwBlockLen = 0; 947 pCryptKey->dwMode = 0; 948 break; 949 } 950 951 *ppCryptKey = pCryptKey; 952 } 953 954 return hCryptKey; 955 } 956 957 /****************************************************************************** 958 * map_key_spec_to_key_pair_name [Internal] 959 * 960 * Returns the name of the registry value associated with a key spec. 961 * 962 * PARAMS 963 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE 964 * 965 * RETURNS 966 * Success: Name of registry value. 967 * Failure: NULL 968 */ 969 static LPCSTR map_key_spec_to_key_pair_name(DWORD dwKeySpec) 970 { 971 LPCSTR szValueName; 972 973 switch (dwKeySpec) 974 { 975 case AT_KEYEXCHANGE: 976 szValueName = "KeyExchangeKeyPair"; 977 break; 978 case AT_SIGNATURE: 979 szValueName = "SignatureKeyPair"; 980 break; 981 default: 982 WARN("invalid key spec %d\n", dwKeySpec); 983 szValueName = NULL; 984 } 985 return szValueName; 986 } 987 988 /****************************************************************************** 989 * store_key_pair [Internal] 990 * 991 * Stores a key pair to the registry 992 * 993 * PARAMS 994 * hCryptKey [I] Handle to the key to be stored 995 * hKey [I] Registry key where the key pair is to be stored 996 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE 997 * dwFlags [I] Flags for protecting the key 998 */ 999 static void store_key_pair(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags) 1000 { 1001 LPCSTR szValueName; 1002 DATA_BLOB blobIn, blobOut; 1003 CRYPTKEY *pKey; 1004 DWORD dwLen; 1005 BYTE *pbKey; 1006 1007 if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec))) 1008 return; 1009 if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, 1010 (OBJECTHDR**)&pKey)) 1011 { 1012 if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, 0, &dwLen)) 1013 { 1014 pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen); 1015 if (pbKey) 1016 { 1017 if (crypt_export_key(pKey, 0, PRIVATEKEYBLOB, 0, TRUE, pbKey, 1018 &dwLen)) 1019 { 1020 blobIn.pbData = pbKey; 1021 blobIn.cbData = dwLen; 1022 1023 if (CryptProtectData(&blobIn, NULL, NULL, NULL, NULL, 1024 dwFlags, &blobOut)) 1025 { 1026 RegSetValueExA(hKey, szValueName, 0, REG_BINARY, 1027 blobOut.pbData, blobOut.cbData); 1028 LocalFree(blobOut.pbData); 1029 } 1030 } 1031 HeapFree(GetProcessHeap(), 0, pbKey); 1032 } 1033 } 1034 } 1035 } 1036 1037 /****************************************************************************** 1038 * map_key_spec_to_permissions_name [Internal] 1039 * 1040 * Returns the name of the registry value associated with the permissions for 1041 * a key spec. 1042 * 1043 * PARAMS 1044 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE 1045 * 1046 * RETURNS 1047 * Success: Name of registry value. 1048 * Failure: NULL 1049 */ 1050 static LPCSTR map_key_spec_to_permissions_name(DWORD dwKeySpec) 1051 { 1052 LPCSTR szValueName; 1053 1054 switch (dwKeySpec) 1055 { 1056 case AT_KEYEXCHANGE: 1057 szValueName = "KeyExchangePermissions"; 1058 break; 1059 case AT_SIGNATURE: 1060 szValueName = "SignaturePermissions"; 1061 break; 1062 default: 1063 WARN("invalid key spec %d\n", dwKeySpec); 1064 szValueName = NULL; 1065 } 1066 return szValueName; 1067 } 1068 1069 /****************************************************************************** 1070 * store_key_permissions [Internal] 1071 * 1072 * Stores a key's permissions to the registry 1073 * 1074 * PARAMS 1075 * hCryptKey [I] Handle to the key whose permissions are to be stored 1076 * hKey [I] Registry key where the key permissions are to be stored 1077 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE 1078 */ 1079 static void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpec) 1080 { 1081 LPCSTR szValueName; 1082 CRYPTKEY *pKey; 1083 1084 if (!(szValueName = map_key_spec_to_permissions_name(dwKeySpec))) 1085 return; 1086 if (lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, 1087 (OBJECTHDR**)&pKey)) 1088 RegSetValueExA(hKey, szValueName, 0, REG_DWORD, 1089 (BYTE *)&pKey->dwPermissions, 1090 sizeof(pKey->dwPermissions)); 1091 } 1092 1093 /****************************************************************************** 1094 * create_container_key [Internal] 1095 * 1096 * Creates the registry key for a key container's persistent storage. 1097 * 1098 * PARAMS 1099 * pKeyContainer [I] Pointer to the key container 1100 * sam [I] Desired registry access 1101 * phKey [O] Returned key 1102 */ 1103 static BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey) 1104 { 1105 CHAR szRSABase[MAX_PATH]; 1106 HKEY hRootKey; 1107 1108 StringCbPrintfA(szRSABase, sizeof(szRSABase), RSAENH_REGKEY, pKeyContainer->szName); 1109 1110 if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) 1111 hRootKey = HKEY_LOCAL_MACHINE; 1112 else 1113 hRootKey = HKEY_CURRENT_USER; 1114 1115 /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA */ 1116 /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */ 1117 return RegCreateKeyExA(hRootKey, szRSABase, 0, NULL, 1118 REG_OPTION_NON_VOLATILE, sam, NULL, phKey, NULL) 1119 == ERROR_SUCCESS; 1120 } 1121 1122 /****************************************************************************** 1123 * open_container_key [Internal] 1124 * 1125 * Opens a key container's persistent storage for reading. 1126 * 1127 * PARAMS 1128 * pszContainerName [I] Name of the container to be opened. May be the empty 1129 * string if the parent key of all containers is to be 1130 * opened. 1131 * dwFlags [I] Flags indicating which keyset to be opened. 1132 * phKey [O] Returned key 1133 */ 1134 static BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, HKEY *phKey) 1135 { 1136 CHAR szRSABase[MAX_PATH]; 1137 HKEY hRootKey; 1138 1139 sprintf(szRSABase, RSAENH_REGKEY, pszContainerName); 1140 1141 if (dwFlags & CRYPT_MACHINE_KEYSET) 1142 hRootKey = HKEY_LOCAL_MACHINE; 1143 else 1144 hRootKey = HKEY_CURRENT_USER; 1145 1146 /* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA */ 1147 /* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */ 1148 return RegOpenKeyExA(hRootKey, szRSABase, 0, access, phKey) == 1149 ERROR_SUCCESS; 1150 } 1151 1152 /****************************************************************************** 1153 * delete_container_key [Internal] 1154 * 1155 * Deletes a key container's persistent storage. 1156 * 1157 * PARAMS 1158 * pszContainerName [I] Name of the container to be opened. 1159 * dwFlags [I] Flags indicating which keyset to be opened. 1160 */ 1161 static BOOL delete_container_key(LPCSTR pszContainerName, DWORD dwFlags) 1162 { 1163 CHAR szRegKey[MAX_PATH]; 1164 1165 if (snprintf(szRegKey, MAX_PATH, RSAENH_REGKEY, pszContainerName) >= MAX_PATH) { 1166 SetLastError(NTE_BAD_KEYSET_PARAM); 1167 return FALSE; 1168 } else { 1169 HKEY hRootKey; 1170 if (dwFlags & CRYPT_MACHINE_KEYSET) 1171 hRootKey = HKEY_LOCAL_MACHINE; 1172 else 1173 hRootKey = HKEY_CURRENT_USER; 1174 if (!RegDeleteKeyA(hRootKey, szRegKey)) { 1175 SetLastError(ERROR_SUCCESS); 1176 return TRUE; 1177 } else { 1178 SetLastError(NTE_BAD_KEYSET); 1179 return FALSE; 1180 } 1181 } 1182 } 1183 1184 /****************************************************************************** 1185 * store_key_container_keys [Internal] 1186 * 1187 * Stores key container's keys in a persistent location. 1188 * 1189 * PARAMS 1190 * pKeyContainer [I] Pointer to the key container whose keys are to be saved 1191 */ 1192 static void store_key_container_keys(KEYCONTAINER *pKeyContainer) 1193 { 1194 HKEY hKey; 1195 DWORD dwFlags; 1196 1197 /* On WinXP, persistent keys are stored in a file located at: 1198 * $AppData$\\Microsoft\\Crypto\\RSA\\$SID$\\some_hex_string 1199 */ 1200 1201 if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) 1202 dwFlags = CRYPTPROTECT_LOCAL_MACHINE; 1203 else 1204 dwFlags = 0; 1205 1206 if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) 1207 { 1208 store_key_pair(pKeyContainer->hKeyExchangeKeyPair, hKey, 1209 AT_KEYEXCHANGE, dwFlags); 1210 store_key_pair(pKeyContainer->hSignatureKeyPair, hKey, 1211 AT_SIGNATURE, dwFlags); 1212 RegCloseKey(hKey); 1213 } 1214 } 1215 1216 /****************************************************************************** 1217 * store_key_container_permissions [Internal] 1218 * 1219 * Stores key container's key permissions in a persistent location. 1220 * 1221 * PARAMS 1222 * pKeyContainer [I] Pointer to the key container whose key permissions are to 1223 * be saved 1224 */ 1225 static void store_key_container_permissions(KEYCONTAINER *pKeyContainer) 1226 { 1227 HKEY hKey; 1228 1229 if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) 1230 { 1231 store_key_permissions(pKeyContainer->hKeyExchangeKeyPair, hKey, 1232 AT_KEYEXCHANGE); 1233 store_key_permissions(pKeyContainer->hSignatureKeyPair, hKey, 1234 AT_SIGNATURE); 1235 RegCloseKey(hKey); 1236 } 1237 } 1238 1239 /****************************************************************************** 1240 * release_key_container_keys [Internal] 1241 * 1242 * Releases key container's keys. 1243 * 1244 * PARAMS 1245 * pKeyContainer [I] Pointer to the key container whose keys are to be released. 1246 */ 1247 static void release_key_container_keys(KEYCONTAINER *pKeyContainer) 1248 { 1249 release_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair, 1250 RSAENH_MAGIC_KEY); 1251 release_handle(&handle_table, pKeyContainer->hSignatureKeyPair, 1252 RSAENH_MAGIC_KEY); 1253 } 1254 1255 /****************************************************************************** 1256 * destroy_key_container [Internal] 1257 * 1258 * Destructor for key containers. 1259 * 1260 * PARAMS 1261 * pObjectHdr [I] Pointer to the key container to be destroyed. 1262 */ 1263 static void destroy_key_container(OBJECTHDR *pObjectHdr) 1264 { 1265 KEYCONTAINER *pKeyContainer = (KEYCONTAINER*)pObjectHdr; 1266 1267 if (!(pKeyContainer->dwFlags & CRYPT_VERIFYCONTEXT)) 1268 { 1269 store_key_container_keys(pKeyContainer); 1270 store_key_container_permissions(pKeyContainer); 1271 release_key_container_keys(pKeyContainer); 1272 } 1273 else 1274 release_key_container_keys(pKeyContainer); 1275 HeapFree( GetProcessHeap(), 0, pKeyContainer ); 1276 } 1277 1278 /****************************************************************************** 1279 * new_key_container [Internal] 1280 * 1281 * Create a new key container. The personality (RSA Base, Strong or Enhanced CP) 1282 * of the CSP is determined via the pVTable->pszProvName string. 1283 * 1284 * PARAMS 1285 * pszContainerName [I] Name of the key container. 1286 * pVTable [I] Callback functions and context info provided by the OS 1287 * 1288 * RETURNS 1289 * Success: Handle to the new key container. 1290 * Failure: INVALID_HANDLE_VALUE 1291 */ 1292 static HCRYPTPROV new_key_container(PCCH pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable) 1293 { 1294 KEYCONTAINER *pKeyContainer; 1295 HCRYPTPROV hKeyContainer; 1296 1297 hKeyContainer = new_object(&handle_table, sizeof(KEYCONTAINER), RSAENH_MAGIC_CONTAINER, 1298 destroy_key_container, (OBJECTHDR**)&pKeyContainer); 1299 if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE) 1300 { 1301 lstrcpynA(pKeyContainer->szName, pszContainerName, MAX_PATH); 1302 pKeyContainer->dwFlags = dwFlags; 1303 pKeyContainer->dwEnumAlgsCtr = 0; 1304 pKeyContainer->hKeyExchangeKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE; 1305 pKeyContainer->hSignatureKeyPair = (HCRYPTKEY)INVALID_HANDLE_VALUE; 1306 if (pVTable && pVTable->pszProvName) { 1307 lstrcpynA(pKeyContainer->szProvName, pVTable->pszProvName, MAX_PATH); 1308 if (!strcmp(pVTable->pszProvName, MS_DEF_PROV_A)) { 1309 pKeyContainer->dwPersonality = RSAENH_PERSONALITY_BASE; 1310 } else if (!strcmp(pVTable->pszProvName, MS_ENHANCED_PROV_A)) { 1311 pKeyContainer->dwPersonality = RSAENH_PERSONALITY_ENHANCED; 1312 } else if (!strcmp(pVTable->pszProvName, MS_DEF_RSA_SCHANNEL_PROV_A)) { 1313 pKeyContainer->dwPersonality = RSAENH_PERSONALITY_SCHANNEL; 1314 } else if (!strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_A) || 1315 !strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_XP_A)) { 1316 pKeyContainer->dwPersonality = RSAENH_PERSONALITY_AES; 1317 } else { 1318 pKeyContainer->dwPersonality = RSAENH_PERSONALITY_STRONG; 1319 } 1320 } 1321 1322 /* The new key container has to be inserted into the CSP immediately 1323 * after creation to be available for CPGetProvParam's PP_ENUMCONTAINERS. */ 1324 if (!(dwFlags & CRYPT_VERIFYCONTEXT)) { 1325 HKEY hKey; 1326 1327 if (create_container_key(pKeyContainer, KEY_WRITE, &hKey)) 1328 RegCloseKey(hKey); 1329 } 1330 } 1331 1332 return hKeyContainer; 1333 } 1334 1335 /****************************************************************************** 1336 * read_key_value [Internal] 1337 * 1338 * Reads a key pair value from the registry 1339 * 1340 * PARAMS 1341 * hKeyContainer [I] Crypt provider to use to import the key 1342 * hKey [I] Registry key from which to read the key pair 1343 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE 1344 * dwFlags [I] Flags for unprotecting the key 1345 * phCryptKey [O] Returned key 1346 */ 1347 static BOOL read_key_value(HCRYPTPROV hKeyContainer, HKEY hKey, DWORD dwKeySpec, DWORD dwFlags, HCRYPTKEY *phCryptKey) 1348 { 1349 LPCSTR szValueName; 1350 DWORD dwValueType, dwLen; 1351 BYTE *pbKey; 1352 DATA_BLOB blobIn, blobOut; 1353 BOOL ret = FALSE; 1354 1355 if (!(szValueName = map_key_spec_to_key_pair_name(dwKeySpec))) 1356 return FALSE; 1357 if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, NULL, &dwLen) == 1358 ERROR_SUCCESS) 1359 { 1360 pbKey = HeapAlloc(GetProcessHeap(), 0, dwLen); 1361 if (pbKey) 1362 { 1363 if (RegQueryValueExA(hKey, szValueName, 0, &dwValueType, pbKey, &dwLen) == 1364 ERROR_SUCCESS) 1365 { 1366 blobIn.pbData = pbKey; 1367 blobIn.cbData = dwLen; 1368 1369 if (CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, 1370 dwFlags, &blobOut)) 1371 { 1372 ret = import_key(hKeyContainer, blobOut.pbData, blobOut.cbData, 0, 0, 1373 FALSE, phCryptKey); 1374 LocalFree(blobOut.pbData); 1375 } 1376 } 1377 HeapFree(GetProcessHeap(), 0, pbKey); 1378 } 1379 } 1380 if (ret) 1381 { 1382 CRYPTKEY *pKey; 1383 1384 if (lookup_handle(&handle_table, *phCryptKey, RSAENH_MAGIC_KEY, 1385 (OBJECTHDR**)&pKey)) 1386 { 1387 if ((szValueName = map_key_spec_to_permissions_name(dwKeySpec))) 1388 { 1389 dwLen = sizeof(pKey->dwPermissions); 1390 RegQueryValueExA(hKey, szValueName, 0, NULL, 1391 (BYTE *)&pKey->dwPermissions, &dwLen); 1392 } 1393 } 1394 } 1395 return ret; 1396 } 1397 1398 /****************************************************************************** 1399 * read_key_container [Internal] 1400 * 1401 * Tries to read the persistent state of the key container (mainly the signature 1402 * and key exchange private keys) given by pszContainerName. 1403 * 1404 * PARAMS 1405 * pszContainerName [I] Name of the key container to read from the registry 1406 * pVTable [I] Pointer to context data provided by the operating system 1407 * 1408 * RETURNS 1409 * Success: Handle to the key container read from the registry 1410 * Failure: INVALID_HANDLE_VALUE 1411 */ 1412 static HCRYPTPROV read_key_container(PCHAR pszContainerName, DWORD dwFlags, const VTableProvStruc *pVTable) 1413 { 1414 HKEY hKey; 1415 KEYCONTAINER *pKeyContainer; 1416 HCRYPTPROV hKeyContainer; 1417 HCRYPTKEY hCryptKey; 1418 1419 if (!open_container_key(pszContainerName, dwFlags, KEY_READ, &hKey)) 1420 { 1421 SetLastError(NTE_BAD_KEYSET); 1422 return (HCRYPTPROV)INVALID_HANDLE_VALUE; 1423 } 1424 1425 hKeyContainer = new_key_container(pszContainerName, dwFlags, pVTable); 1426 if (hKeyContainer != (HCRYPTPROV)INVALID_HANDLE_VALUE) 1427 { 1428 DWORD dwProtectFlags = (dwFlags & CRYPT_MACHINE_KEYSET) ? 1429 CRYPTPROTECT_LOCAL_MACHINE : 0; 1430 1431 if (!lookup_handle(&handle_table, hKeyContainer, RSAENH_MAGIC_CONTAINER, 1432 (OBJECTHDR**)&pKeyContainer)) 1433 return (HCRYPTPROV)INVALID_HANDLE_VALUE; 1434 1435 /* read_key_value calls import_key, which calls import_private_key, 1436 * which implicitly installs the key value into the appropriate key 1437 * container key. Thus the ref count is incremented twice, once for 1438 * the output key value, and once for the implicit install, and needs 1439 * to be decremented to balance the two. 1440 */ 1441 if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE, 1442 dwProtectFlags, &hCryptKey)) 1443 release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); 1444 if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE, 1445 dwProtectFlags, &hCryptKey)) 1446 release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY); 1447 } 1448 1449 return hKeyContainer; 1450 } 1451 1452 /****************************************************************************** 1453 * build_hash_signature [Internal] 1454 * 1455 * Builds a padded version of a hash to match the length of the RSA key modulus. 1456 * 1457 * PARAMS 1458 * pbSignature [O] The padded hash object is stored here. 1459 * dwLen [I] Length of the pbSignature buffer. 1460 * aiAlgid [I] Algorithm identifier of the hash to be padded. 1461 * abHashValue [I] The value of the hash object. 1462 * dwHashLen [I] Length of the hash value. 1463 * dwFlags [I] Selection of padding algorithm. 1464 * 1465 * RETURNS 1466 * Success: TRUE 1467 * Failure: FALSE (NTE_BAD_ALGID) 1468 */ 1469 static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid, 1470 const BYTE *abHashValue, DWORD dwHashLen, DWORD dwFlags) 1471 { 1472 /* These prefixes are meant to be concatenated with hash values of the 1473 * respective kind to form a PKCS #7 DigestInfo. */ 1474 static const struct tagOIDDescriptor { 1475 ALG_ID aiAlgid; 1476 DWORD dwLen; 1477 const BYTE abOID[19]; 1478 } aOIDDescriptor[] = { 1479 { CALG_MD2, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 1480 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 } }, 1481 { CALG_MD4, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 1482 0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 } }, 1483 { CALG_MD5, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 1484 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 } }, 1485 { CALG_SHA, 15, { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 1486 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 } }, 1487 { CALG_SHA_256, 19, { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 1488 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 1489 0x05, 0x00, 0x04, 0x20 } }, 1490 { CALG_SHA_384, 19, { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 1491 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 1492 0x05, 0x00, 0x04, 0x30 } }, 1493 { CALG_SHA_512, 19, { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 1494 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 1495 0x05, 0x00, 0x04, 0x40 } }, 1496 { CALG_SSL3_SHAMD5, 0, { 0 } }, 1497 { 0, 0, { 0 } } 1498 }; 1499 DWORD dwIdxOID, i, j; 1500 1501 for (dwIdxOID = 0; aOIDDescriptor[dwIdxOID].aiAlgid; dwIdxOID++) { 1502 if (aOIDDescriptor[dwIdxOID].aiAlgid == aiAlgid) break; 1503 } 1504 1505 if (!aOIDDescriptor[dwIdxOID].aiAlgid) { 1506 SetLastError(NTE_BAD_ALGID); 1507 return FALSE; 1508 } 1509 1510 /* Build the padded signature */ 1511 if (dwFlags & CRYPT_X931_FORMAT) { 1512 pbSignature[0] = 0x6b; 1513 for (i=1; i < dwLen - dwHashLen - 3; i++) { 1514 pbSignature[i] = 0xbb; 1515 } 1516 pbSignature[i++] = 0xba; 1517 for (j=0; j < dwHashLen; j++, i++) { 1518 pbSignature[i] = abHashValue[j]; 1519 } 1520 pbSignature[i++] = 0x33; 1521 pbSignature[i++] = 0xcc; 1522 } else { 1523 pbSignature[0] = 0x00; 1524 pbSignature[1] = 0x01; 1525 if (dwFlags & CRYPT_NOHASHOID) { 1526 for (i=2; i < dwLen - 1 - dwHashLen; i++) { 1527 pbSignature[i] = 0xff; 1528 } 1529 pbSignature[i++] = 0x00; 1530 } else { 1531 for (i=2; i < dwLen - 1 - aOIDDescriptor[dwIdxOID].dwLen - dwHashLen; i++) { 1532 pbSignature[i] = 0xff; 1533 } 1534 pbSignature[i++] = 0x00; 1535 for (j=0; j < aOIDDescriptor[dwIdxOID].dwLen; j++) { 1536 pbSignature[i++] = aOIDDescriptor[dwIdxOID].abOID[j]; 1537 } 1538 } 1539 for (j=0; j < dwHashLen; j++) { 1540 pbSignature[i++] = abHashValue[j]; 1541 } 1542 } 1543 1544 return TRUE; 1545 } 1546 1547 /****************************************************************************** 1548 * tls1_p [Internal] 1549 * 1550 * This is an implementation of the 'P_hash' helper function for TLS1's PRF. 1551 * It is used exclusively by tls1_prf. For details see RFC 2246, chapter 5. 1552 * The pseudo random stream generated by this function is exclusive or'ed with 1553 * the data in pbBuffer. 1554 * 1555 * PARAMS 1556 * hHMAC [I] HMAC object, which will be used in pseudo random generation 1557 * pblobSeed [I] Seed value 1558 * pbBuffer [I/O] Pseudo random stream will be xor'ed to the provided data 1559 * dwBufferLen [I] Number of pseudo random bytes desired 1560 * 1561 * RETURNS 1562 * Success: TRUE 1563 * Failure: FALSE 1564 */ 1565 static BOOL tls1_p(HCRYPTHASH hHMAC, const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer, 1566 DWORD dwBufferLen) 1567 { 1568 CRYPTHASH *pHMAC; 1569 BYTE abAi[RSAENH_MAX_HASH_SIZE]; 1570 DWORD i = 0; 1571 1572 if (!lookup_handle(&handle_table, hHMAC, RSAENH_MAGIC_HASH, (OBJECTHDR**)&pHMAC)) { 1573 SetLastError(NTE_BAD_HASH); 1574 return FALSE; 1575 } 1576 1577 /* compute A_1 = HMAC(seed) */ 1578 init_hash(pHMAC); 1579 update_hash(pHMAC, pblobSeed->pbData, pblobSeed->cbData); 1580 finalize_hash(pHMAC); 1581 memcpy(abAi, pHMAC->abHashValue, pHMAC->dwHashSize); 1582 1583 do { 1584 /* compute HMAC(A_i + seed) */ 1585 init_hash(pHMAC); 1586 update_hash(pHMAC, abAi, pHMAC->dwHashSize); 1587 update_hash(pHMAC, pblobSeed->pbData, pblobSeed->cbData); 1588 finalize_hash(pHMAC); 1589 1590 /* pseudo random stream := CONCAT_{i=1..n} ( HMAC(A_i + seed) ) */ 1591 do { 1592 if (i >= dwBufferLen) break; 1593 pbBuffer[i] ^= pHMAC->abHashValue[i % pHMAC->dwHashSize]; 1594 i++; 1595 } while (i % pHMAC->dwHashSize); 1596 1597 /* compute A_{i+1} = HMAC(A_i) */ 1598 init_hash(pHMAC); 1599 update_hash(pHMAC, abAi, pHMAC->dwHashSize); 1600 finalize_hash(pHMAC); 1601 memcpy(abAi, pHMAC->abHashValue, pHMAC->dwHashSize); 1602 } while (i < dwBufferLen); 1603 1604 return TRUE; 1605 } 1606 1607 /****************************************************************************** 1608 * tls1_prf [Internal] 1609 * 1610 * TLS1 pseudo random function as specified in RFC 2246, chapter 5 1611 * 1612 * PARAMS 1613 * hProv [I] Key container used to compute the pseudo random stream 1614 * hSecret [I] Key that holds the (pre-)master secret 1615 * pblobLabel [I] Descriptive label 1616 * pblobSeed [I] Seed value 1617 * pbBuffer [O] Pseudo random numbers will be stored here 1618 * dwBufferLen [I] Number of pseudo random bytes desired 1619 * 1620 * RETURNS 1621 * Success: TRUE 1622 * Failure: FALSE 1623 */ 1624 static BOOL tls1_prf(HCRYPTPROV hProv, HCRYPTPROV hSecret, const PCRYPT_DATA_BLOB pblobLabel, 1625 const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer, DWORD dwBufferLen) 1626 { 1627 HMAC_INFO hmacInfo = { 0, NULL, 0, NULL, 0 }; 1628 HCRYPTHASH hHMAC = (HCRYPTHASH)INVALID_HANDLE_VALUE; 1629 HCRYPTKEY hHalfSecret = (HCRYPTKEY)INVALID_HANDLE_VALUE; 1630 CRYPTKEY *pHalfSecret, *pSecret; 1631 DWORD dwHalfSecretLen; 1632 BOOL result = FALSE; 1633 CRYPT_DATA_BLOB blobLabelSeed; 1634 1635 TRACE("(hProv=%08lx, hSecret=%08lx, pblobLabel=%p, pblobSeed=%p, pbBuffer=%p, dwBufferLen=%d)\n", 1636 hProv, hSecret, pblobLabel, pblobSeed, pbBuffer, dwBufferLen); 1637 1638 if (!lookup_handle(&handle_table, hSecret, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pSecret)) { 1639 SetLastError(NTE_FAIL); 1640 return FALSE; 1641 } 1642 1643 dwHalfSecretLen = (pSecret->dwKeyLen+1)/2; 1644 1645 /* concatenation of the label and the seed */ 1646 if (!concat_data_blobs(&blobLabelSeed, pblobLabel, pblobSeed)) goto exit; 1647 1648 /* zero out the buffer, since two random streams will be xor'ed into it. */ 1649 memset(pbBuffer, 0, dwBufferLen); 1650 1651 /* build a 'fake' key, to hold the secret. CALG_SSL2_MASTER is used since it provides 1652 * the biggest range of valid key lengths. */ 1653 hHalfSecret = new_key(hProv, CALG_SSL2_MASTER, MAKELONG(0,dwHalfSecretLen*8), &pHalfSecret); 1654 if (hHalfSecret == (HCRYPTKEY)INVALID_HANDLE_VALUE) goto exit; 1655 1656 /* Derive an HMAC_MD5 hash and call the helper function. */ 1657 memcpy(pHalfSecret->abKeyValue, pSecret->abKeyValue, dwHalfSecretLen); 1658 if (!RSAENH_CPCreateHash(hProv, CALG_HMAC, hHalfSecret, 0, &hHMAC)) goto exit; 1659 hmacInfo.HashAlgid = CALG_MD5; 1660 if (!RSAENH_CPSetHashParam(hProv, hHMAC, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0)) goto exit; 1661 if (!tls1_p(hHMAC, &blobLabelSeed, pbBuffer, dwBufferLen)) goto exit; 1662 1663 /* Reconfigure to HMAC_SHA hash and call helper function again. */ 1664 memcpy(pHalfSecret->abKeyValue, pSecret->abKeyValue + (pSecret->dwKeyLen/2), dwHalfSecretLen); 1665 hmacInfo.HashAlgid = CALG_SHA; 1666 if (!RSAENH_CPSetHashParam(hProv, hHMAC, HP_HMAC_INFO, (BYTE*)&hmacInfo, 0)) goto exit; 1667 if (!tls1_p(hHMAC, &blobLabelSeed, pbBuffer, dwBufferLen)) goto exit; 1668 1669 result = TRUE; 1670 exit: 1671 release_handle(&handle_table, hHalfSecret, RSAENH_MAGIC_KEY); 1672 if (hHMAC != (HCRYPTHASH)INVALID_HANDLE_VALUE) RSAENH_CPDestroyHash(hProv, hHMAC); 1673 free_data_blob(&blobLabelSeed); 1674 return result; 1675 } 1676 1677 /****************************************************************************** 1678 * pad_data [Internal] 1679 * 1680 * Helper function for data padding according to PKCS1 #2 1681 * 1682 * PARAMS 1683 * abData [I] The data to be padded 1684 * dwDataLen [I] Length of the data 1685 * abBuffer [O] Padded data will be stored here 1686 * dwBufferLen [I] Length of the buffer (also length of padded data) 1687 * dwFlags [I] Padding format (CRYPT_SSL2_FALLBACK) 1688 * 1689 * RETURN 1690 * Success: TRUE 1691 * Failure: FALSE (NTE_BAD_LEN, too much data to pad) 1692 */ 1693 static BOOL pad_data(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen, 1694 DWORD dwFlags) 1695 { 1696 DWORD i; 1697 1698 /* Ensure there is enough space for PKCS1 #2 padding */ 1699 if (dwDataLen > dwBufferLen-11) { 1700 SetLastError(NTE_BAD_LEN); 1701 return FALSE; 1702 } 1703 1704 memmove(abBuffer + dwBufferLen - dwDataLen, abData, dwDataLen); 1705 1706 abBuffer[0] = 0x00; 1707 abBuffer[1] = RSAENH_PKC_BLOCKTYPE; 1708 for (i=2; i < dwBufferLen - dwDataLen - 1; i++) 1709 do gen_rand_impl(&abBuffer[i], 1); while (!abBuffer[i]); 1710 if (dwFlags & CRYPT_SSL2_FALLBACK) 1711 for (i-=8; i < dwBufferLen - dwDataLen - 1; i++) 1712 abBuffer[i] = 0x03; 1713 abBuffer[i] = 0x00; 1714 1715 return TRUE; 1716 } 1717 1718 /****************************************************************************** 1719 * unpad_data [Internal] 1720 * 1721 * Remove the PKCS1 padding from RSA decrypted data 1722 * 1723 * PARAMS 1724 * abData [I] The padded data 1725 * dwDataLen [I] Length of the padded data 1726 * abBuffer [O] Data without padding will be stored here 1727 * dwBufferLen [I/O] I: Length of the buffer, O: Length of unpadded data 1728 * dwFlags [I] Currently none defined 1729 * 1730 * RETURNS 1731 * Success: TRUE 1732 * Failure: FALSE, (NTE_BAD_DATA, no valid PKCS1 padding or buffer too small) 1733 */ 1734 static BOOL unpad_data(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen, 1735 DWORD dwFlags) 1736 { 1737 DWORD i; 1738 1739 if (dwDataLen < 3) 1740 { 1741 SetLastError(NTE_BAD_DATA); 1742 return FALSE; 1743 } 1744 for (i=2; i<dwDataLen; i++) 1745 if (!abData[i]) 1746 break; 1747 1748 if ((i == dwDataLen) || (*dwBufferLen < dwDataLen - i - 1) || 1749 (abData[0] != 0x00) || (abData[1] != RSAENH_PKC_BLOCKTYPE)) 1750 { 1751 SetLastError(NTE_BAD_DATA); 1752 return FALSE; 1753 } 1754 1755 *dwBufferLen = dwDataLen - i - 1; 1756 memmove(abBuffer, abData + i + 1, *dwBufferLen); 1757 return TRUE; 1758 } 1759 1760 /****************************************************************************** 1761 * CPAcquireContext (RSAENH.@) 1762 * 1763 * Acquire a handle to the key container specified by pszContainer 1764 * 1765 * PARAMS 1766 * phProv [O] Pointer to the location the acquired handle will be written to. 1767 * pszContainer [I] Name of the desired key container. See Notes 1768 * dwFlags [I] Flags. See Notes. 1769 * pVTable [I] Pointer to a PVTableProvStruct containing callbacks. 1770 * 1771 * RETURNS 1772 * Success: TRUE 1773 * Failure: FALSE 1774 * 1775 * NOTES 1776 * If pszContainer is NULL or points to a zero length string the user's login 1777 * name will be used as the key container name. 1778 * 1779 * If the CRYPT_NEW_KEYSET flag is set in dwFlags a new keyset will be created. 1780 * If a keyset with the given name already exists, the function fails and sets 1781 * last error to NTE_EXISTS. If CRYPT_NEW_KEYSET is not set and the specified 1782 * key container does not exist, function fails and sets last error to 1783 * NTE_BAD_KEYSET. 1784 */ 1785 BOOL WINAPI RSAENH_CPAcquireContext(HCRYPTPROV *phProv, LPSTR pszContainer, 1786 DWORD dwFlags, PVTableProvStruc pVTable) 1787 { 1788 CHAR szKeyContainerName[MAX_PATH]; 1789 1790 TRACE("(phProv=%p, pszContainer=%s, dwFlags=%08x, pVTable=%p)\n", phProv, 1791 debugstr_a(pszContainer), dwFlags, pVTable); 1792 1793 if (pszContainer && *pszContainer) 1794 { 1795 lstrcpynA(szKeyContainerName, pszContainer, MAX_PATH); 1796 } 1797 else 1798 { 1799 DWORD dwLen = sizeof(szKeyContainerName); 1800 if (!GetUserNameA(szKeyContainerName, &dwLen)) return FALSE; 1801 } 1802 1803 switch (dwFlags & (CRYPT_NEWKEYSET|CRYPT_VERIFYCONTEXT|CRYPT_DELETEKEYSET)) 1804 { 1805 case 0: 1806 *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable); 1807 break; 1808 1809 case CRYPT_DELETEKEYSET: 1810 return delete_container_key(szKeyContainerName, dwFlags); 1811 1812 case CRYPT_NEWKEYSET: 1813 *phProv = read_key_container(szKeyContainerName, dwFlags, pVTable); 1814 if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE) 1815 { 1816 release_handle(&handle_table, *phProv, RSAENH_MAGIC_CONTAINER); 1817 TRACE("Can't create new keyset, already exists\n"); 1818 SetLastError(NTE_EXISTS); 1819 return FALSE; 1820 } 1821 *phProv = new_key_container(szKeyContainerName, dwFlags, pVTable); 1822 break; 1823 1824 case CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET: 1825 case CRYPT_VERIFYCONTEXT: 1826 if (pszContainer && *pszContainer) { 1827 TRACE("pszContainer should be empty\n"); 1828 SetLastError(NTE_BAD_FLAGS); 1829 return FALSE; 1830 } 1831 *phProv = new_key_container("", dwFlags, pVTable); 1832 break; 1833 1834 default: 1835 *phProv = (HCRYPTPROV)INVALID_HANDLE_VALUE; 1836 SetLastError(NTE_BAD_FLAGS); 1837 return FALSE; 1838 } 1839 1840 if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE) { 1841 SetLastError(ERROR_SUCCESS); 1842 return TRUE; 1843 } else { 1844 return FALSE; 1845 } 1846 } 1847 1848 /****************************************************************************** 1849 * CPCreateHash (RSAENH.@) 1850 * 1851 * CPCreateHash creates and initializes a new hash object. 1852 * 1853 * PARAMS 1854 * hProv [I] Handle to the key container to which the new hash will belong. 1855 * Algid [I] Identifies the hash algorithm, which will be used for the hash. 1856 * hKey [I] Handle to a session key applied for keyed hashes. 1857 * dwFlags [I] Currently no flags defined. Must be zero. 1858 * phHash [O] Points to the location where a handle to the new hash will be stored. 1859 * 1860 * RETURNS 1861 * Success: TRUE 1862 * Failure: FALSE 1863 * 1864 * NOTES 1865 * hKey is a handle to a session key applied in keyed hashes like MAC and HMAC. 1866 * If a normal hash object is to be created (like e.g. MD2 or SHA1) hKey must be zero. 1867 */ 1868 BOOL WINAPI RSAENH_CPCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, 1869 HCRYPTHASH *phHash) 1870 { 1871 CRYPTKEY *pCryptKey; 1872 CRYPTHASH *pCryptHash; 1873 const PROV_ENUMALGS_EX *peaAlgidInfo; 1874 1875 TRACE("(hProv=%08lx, Algid=%08x, hKey=%08lx, dwFlags=%08x, phHash=%p)\n", hProv, Algid, hKey, 1876 dwFlags, phHash); 1877 1878 peaAlgidInfo = get_algid_info(hProv, Algid); 1879 if (!peaAlgidInfo) return FALSE; 1880 1881 if (dwFlags) 1882 { 1883 SetLastError(NTE_BAD_FLAGS); 1884 return FALSE; 1885 } 1886 1887 if (Algid == CALG_MAC || Algid == CALG_HMAC || Algid == CALG_SCHANNEL_MASTER_HASH || 1888 Algid == CALG_TLS1PRF) 1889 { 1890 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) { 1891 SetLastError(NTE_BAD_KEY); 1892 return FALSE; 1893 } 1894 1895 if ((Algid == CALG_MAC) && (GET_ALG_TYPE(pCryptKey->aiAlgid) != ALG_TYPE_BLOCK)) { 1896 SetLastError(NTE_BAD_KEY); 1897 return FALSE; 1898 } 1899 1900 if ((Algid == CALG_SCHANNEL_MASTER_HASH || Algid == CALG_TLS1PRF) && 1901 (pCryptKey->aiAlgid != CALG_TLS1_MASTER)) 1902 { 1903 SetLastError(NTE_BAD_KEY); 1904 return FALSE; 1905 } 1906 if (Algid == CALG_SCHANNEL_MASTER_HASH && 1907 ((!pCryptKey->siSChannelInfo.blobClientRandom.cbData) || 1908 (!pCryptKey->siSChannelInfo.blobServerRandom.cbData))) 1909 { 1910 SetLastError(ERROR_INVALID_PARAMETER); 1911 return FALSE; 1912 } 1913 1914 if ((Algid == CALG_TLS1PRF) && (pCryptKey->dwState != RSAENH_KEYSTATE_MASTERKEY)) { 1915 SetLastError(NTE_BAD_KEY_STATE); 1916 return FALSE; 1917 } 1918 } 1919 1920 *phHash = new_object(&handle_table, sizeof(CRYPTHASH), RSAENH_MAGIC_HASH, 1921 destroy_hash, (OBJECTHDR**)&pCryptHash); 1922 if (!pCryptHash) return FALSE; 1923 1924 pCryptHash->aiAlgid = Algid; 1925 pCryptHash->hKey = hKey; 1926 pCryptHash->hProv = hProv; 1927 pCryptHash->dwState = RSAENH_HASHSTATE_HASHING; 1928 pCryptHash->pHMACInfo = NULL; 1929 pCryptHash->dwHashSize = peaAlgidInfo->dwDefaultLen >> 3; 1930 init_data_blob(&pCryptHash->tpPRFParams.blobLabel); 1931 init_data_blob(&pCryptHash->tpPRFParams.blobSeed); 1932 1933 if (Algid == CALG_SCHANNEL_MASTER_HASH) { 1934 static const char keyex[] = "key expansion"; 1935 BYTE key_expansion[sizeof keyex]; 1936 CRYPT_DATA_BLOB blobRandom, blobKeyExpansion = { 13, key_expansion }; 1937 1938 memcpy( key_expansion, keyex, sizeof keyex ); 1939 1940 if (pCryptKey->dwState != RSAENH_KEYSTATE_MASTERKEY) { 1941 static const char msec[] = "master secret"; 1942 BYTE master_secret[sizeof msec]; 1943 CRYPT_DATA_BLOB blobLabel = { 13, master_secret }; 1944 BYTE abKeyValue[48]; 1945 1946 memcpy( master_secret, msec, sizeof msec ); 1947 1948 /* See RFC 2246, chapter 8.1 */ 1949 if (!concat_data_blobs(&blobRandom, 1950 &pCryptKey->siSChannelInfo.blobClientRandom, 1951 &pCryptKey->siSChannelInfo.blobServerRandom)) 1952 { 1953 return FALSE; 1954 } 1955 tls1_prf(hProv, hKey, &blobLabel, &blobRandom, abKeyValue, 48); 1956 pCryptKey->dwState = RSAENH_KEYSTATE_MASTERKEY; 1957 memcpy(pCryptKey->abKeyValue, abKeyValue, 48); 1958 free_data_blob(&blobRandom); 1959 } 1960 1961 /* See RFC 2246, chapter 6.3 */ 1962 if (!concat_data_blobs(&blobRandom, 1963 &pCryptKey->siSChannelInfo.blobServerRandom, 1964 &pCryptKey->siSChannelInfo.blobClientRandom)) 1965 { 1966 return FALSE; 1967 } 1968 tls1_prf(hProv, hKey, &blobKeyExpansion, &blobRandom, pCryptHash->abHashValue, 1969 RSAENH_MAX_HASH_SIZE); 1970 free_data_blob(&blobRandom); 1971 } 1972 1973 return init_hash(pCryptHash); 1974 } 1975 1976 /****************************************************************************** 1977 * CPDestroyHash (RSAENH.@) 1978 * 1979 * Releases the handle to a hash object. The object is destroyed if its reference 1980 * count reaches zero. 1981 * 1982 * PARAMS 1983 * hProv [I] Handle to the key container to which the hash object belongs. 1984 * hHash [I] Handle to the hash object to be released. 1985 * 1986 * RETURNS 1987 * Success: TRUE 1988 * Failure: FALSE 1989 */ 1990 BOOL WINAPI RSAENH_CPDestroyHash(HCRYPTPROV hProv, HCRYPTHASH hHash) 1991 { 1992 TRACE("(hProv=%08lx, hHash=%08lx)\n", hProv, hHash); 1993 1994 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 1995 { 1996 SetLastError(NTE_BAD_UID); 1997 return FALSE; 1998 } 1999 2000 if (!release_handle(&handle_table, hHash, RSAENH_MAGIC_HASH)) 2001 { 2002 SetLastError(NTE_BAD_HASH); 2003 return FALSE; 2004 } 2005 2006 return TRUE; 2007 } 2008 2009 /****************************************************************************** 2010 * CPDestroyKey (RSAENH.@) 2011 * 2012 * Releases the handle to a key object. The object is destroyed if its reference 2013 * count reaches zero. 2014 * 2015 * PARAMS 2016 * hProv [I] Handle to the key container to which the key object belongs. 2017 * hKey [I] Handle to the key object to be released. 2018 * 2019 * RETURNS 2020 * Success: TRUE 2021 * Failure: FALSE 2022 */ 2023 BOOL WINAPI RSAENH_CPDestroyKey(HCRYPTPROV hProv, HCRYPTKEY hKey) 2024 { 2025 TRACE("(hProv=%08lx, hKey=%08lx)\n", hProv, hKey); 2026 2027 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 2028 { 2029 SetLastError(NTE_BAD_UID); 2030 return FALSE; 2031 } 2032 2033 if (!release_handle(&handle_table, hKey, RSAENH_MAGIC_KEY)) 2034 { 2035 SetLastError(NTE_BAD_KEY); 2036 return FALSE; 2037 } 2038 2039 return TRUE; 2040 } 2041 2042 /****************************************************************************** 2043 * CPDuplicateHash (RSAENH.@) 2044 * 2045 * Clones a hash object including its current state. 2046 * 2047 * PARAMS 2048 * hUID [I] Handle to the key container the hash belongs to. 2049 * hHash [I] Handle to the hash object to be cloned. 2050 * pdwReserved [I] Reserved. Must be NULL. 2051 * dwFlags [I] No flags are currently defined. Must be 0. 2052 * phHash [O] Handle to the cloned hash object. 2053 * 2054 * RETURNS 2055 * Success: TRUE. 2056 * Failure: FALSE. 2057 */ 2058 BOOL WINAPI RSAENH_CPDuplicateHash(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, 2059 DWORD dwFlags, HCRYPTHASH *phHash) 2060 { 2061 CRYPTHASH *pSrcHash, *pDestHash; 2062 2063 TRACE("(hUID=%08lx, hHash=%08lx, pdwReserved=%p, dwFlags=%08x, phHash=%p)\n", hUID, hHash, 2064 pdwReserved, dwFlags, phHash); 2065 2066 if (!is_valid_handle(&handle_table, hUID, RSAENH_MAGIC_CONTAINER)) 2067 { 2068 SetLastError(NTE_BAD_UID); 2069 return FALSE; 2070 } 2071 2072 if (!lookup_handle(&handle_table, hHash, RSAENH_MAGIC_HASH, (OBJECTHDR**)&pSrcHash)) 2073 { 2074 SetLastError(NTE_BAD_HASH); 2075 return FALSE; 2076 } 2077 2078 if (!phHash || pdwReserved || dwFlags) 2079 { 2080 SetLastError(ERROR_INVALID_PARAMETER); 2081 return FALSE; 2082 } 2083 2084 *phHash = new_object(&handle_table, sizeof(CRYPTHASH), RSAENH_MAGIC_HASH, 2085 destroy_hash, (OBJECTHDR**)&pDestHash); 2086 if (*phHash != (HCRYPTHASH)INVALID_HANDLE_VALUE) 2087 { 2088 *pDestHash = *pSrcHash; 2089 duplicate_hash_impl(pSrcHash->aiAlgid, &pSrcHash->context, &pDestHash->context); 2090 copy_hmac_info(&pDestHash->pHMACInfo, pSrcHash->pHMACInfo); 2091 copy_data_blob(&pDestHash->tpPRFParams.blobLabel, &pSrcHash->tpPRFParams.blobLabel); 2092 copy_data_blob(&pDestHash->tpPRFParams.blobSeed, &pSrcHash->tpPRFParams.blobSeed); 2093 } 2094 2095 return *phHash != (HCRYPTHASH)INVALID_HANDLE_VALUE; 2096 } 2097 2098 /****************************************************************************** 2099 * CPDuplicateKey (RSAENH.@) 2100 * 2101 * Clones a key object including its current state. 2102 * 2103 * PARAMS 2104 * hUID [I] Handle to the key container the hash belongs to. 2105 * hKey [I] Handle to the key object to be cloned. 2106 * pdwReserved [I] Reserved. Must be NULL. 2107 * dwFlags [I] No flags are currently defined. Must be 0. 2108 * phHash [O] Handle to the cloned key object. 2109 * 2110 * RETURNS 2111 * Success: TRUE. 2112 * Failure: FALSE. 2113 */ 2114 BOOL WINAPI RSAENH_CPDuplicateKey(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, 2115 DWORD dwFlags, HCRYPTKEY *phKey) 2116 { 2117 CRYPTKEY *pSrcKey, *pDestKey; 2118 2119 TRACE("(hUID=%08lx, hKey=%08lx, pdwReserved=%p, dwFlags=%08x, phKey=%p)\n", hUID, hKey, 2120 pdwReserved, dwFlags, phKey); 2121 2122 if (!is_valid_handle(&handle_table, hUID, RSAENH_MAGIC_CONTAINER)) 2123 { 2124 SetLastError(NTE_BAD_UID); 2125 return FALSE; 2126 } 2127 2128 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pSrcKey)) 2129 { 2130 SetLastError(NTE_BAD_KEY); 2131 return FALSE; 2132 } 2133 2134 if (!phKey || pdwReserved || dwFlags) 2135 { 2136 SetLastError(ERROR_INVALID_PARAMETER); 2137 return FALSE; 2138 } 2139 2140 *phKey = new_object(&handle_table, sizeof(CRYPTKEY), RSAENH_MAGIC_KEY, destroy_key, 2141 (OBJECTHDR**)&pDestKey); 2142 if (*phKey != (HCRYPTKEY)INVALID_HANDLE_VALUE) 2143 { 2144 *pDestKey = *pSrcKey; 2145 copy_data_blob(&pDestKey->siSChannelInfo.blobServerRandom, 2146 &pSrcKey->siSChannelInfo.blobServerRandom); 2147 copy_data_blob(&pDestKey->siSChannelInfo.blobClientRandom, 2148 &pSrcKey->siSChannelInfo.blobClientRandom); 2149 duplicate_key_impl(pSrcKey->aiAlgid, &pSrcKey->context, &pDestKey->context); 2150 return TRUE; 2151 } 2152 else 2153 { 2154 return FALSE; 2155 } 2156 } 2157 2158 /****************************************************************************** 2159 * CPEncrypt (RSAENH.@) 2160 * 2161 * Encrypt data. 2162 * 2163 * PARAMS 2164 * hProv [I] The key container hKey and hHash belong to. 2165 * hKey [I] The key used to encrypt the data. 2166 * hHash [I] An optional hash object for parallel hashing. See notes. 2167 * Final [I] Indicates if this is the last block of data to encrypt. 2168 * dwFlags [I] Currently no flags defined. Must be zero. 2169 * pbData [I/O] Pointer to the data to encrypt. Encrypted data will also be stored there. 2170 * pdwDataLen [I/O] I: Length of data to encrypt, O: Length of encrypted data. 2171 * dwBufLen [I] Size of the buffer at pbData. 2172 * 2173 * RETURNS 2174 * Success: TRUE. 2175 * Failure: FALSE. 2176 * 2177 * NOTES 2178 * If a hash object handle is provided in hHash, it will be updated with the plaintext. 2179 * This is useful for message signatures. 2180 * 2181 * This function uses the standard WINAPI protocol for querying data of dynamic length. 2182 */ 2183 BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, 2184 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen) 2185 { 2186 CRYPTKEY *pCryptKey; 2187 BYTE *in, out[RSAENH_MAX_BLOCK_SIZE], o[RSAENH_MAX_BLOCK_SIZE]; 2188 DWORD dwEncryptedLen, i, j, k; 2189 2190 TRACE("(hProv=%08lx, hKey=%08lx, hHash=%08lx, Final=%d, dwFlags=%08x, pbData=%p, " 2191 "pdwDataLen=%p, dwBufLen=%d)\n", hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen, 2192 dwBufLen); 2193 2194 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 2195 { 2196 SetLastError(NTE_BAD_UID); 2197 return FALSE; 2198 } 2199 2200 if (dwFlags) 2201 { 2202 SetLastError(NTE_BAD_FLAGS); 2203 return FALSE; 2204 } 2205 2206 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) 2207 { 2208 SetLastError(NTE_BAD_KEY); 2209 return FALSE; 2210 } 2211 2212 if (pCryptKey->dwState == RSAENH_KEYSTATE_IDLE) 2213 pCryptKey->dwState = RSAENH_KEYSTATE_ENCRYPTING; 2214 2215 if (pCryptKey->dwState != RSAENH_KEYSTATE_ENCRYPTING) 2216 { 2217 SetLastError(NTE_BAD_DATA); 2218 return FALSE; 2219 } 2220 2221 if (is_valid_handle(&handle_table, hHash, RSAENH_MAGIC_HASH)) { 2222 if (!RSAENH_CPHashData(hProv, hHash, pbData, *pdwDataLen, 0)) return FALSE; 2223 } 2224 2225 if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_BLOCK) { 2226 if (!Final && (*pdwDataLen % pCryptKey->dwBlockLen)) { 2227 SetLastError(NTE_BAD_DATA); 2228 return FALSE; 2229 } 2230 2231 dwEncryptedLen = (*pdwDataLen/pCryptKey->dwBlockLen+(Final?1:0))*pCryptKey->dwBlockLen; 2232 2233 if (pbData == NULL) { 2234 *pdwDataLen = dwEncryptedLen; 2235 return TRUE; 2236 } 2237 else if (dwEncryptedLen > dwBufLen) { 2238 *pdwDataLen = dwEncryptedLen; 2239 SetLastError(ERROR_MORE_DATA); 2240 return FALSE; 2241 } 2242 2243 /* Pad final block with length bytes */ 2244 for (i=*pdwDataLen; i<dwEncryptedLen; i++) pbData[i] = dwEncryptedLen - *pdwDataLen; 2245 *pdwDataLen = dwEncryptedLen; 2246 2247 for (i=0, in=pbData; i<*pdwDataLen; i+=pCryptKey->dwBlockLen, in+=pCryptKey->dwBlockLen) { 2248 switch (pCryptKey->dwMode) { 2249 case CRYPT_MODE_ECB: 2250 encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out, 2251 RSAENH_ENCRYPT); 2252 break; 2253 2254 case CRYPT_MODE_CBC: 2255 for (j=0; j<pCryptKey->dwBlockLen; j++) in[j] ^= pCryptKey->abChainVector[j]; 2256 encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out, 2257 RSAENH_ENCRYPT); 2258 memcpy(pCryptKey->abChainVector, out, pCryptKey->dwBlockLen); 2259 break; 2260 2261 case CRYPT_MODE_CFB: 2262 for (j=0; j<pCryptKey->dwBlockLen; j++) { 2263 encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, 2264 pCryptKey->abChainVector, o, RSAENH_ENCRYPT); 2265 out[j] = in[j] ^ o[0]; 2266 for (k=0; k<pCryptKey->dwBlockLen-1; k++) 2267 pCryptKey->abChainVector[k] = pCryptKey->abChainVector[k+1]; 2268 pCryptKey->abChainVector[k] = out[j]; 2269 } 2270 break; 2271 2272 default: 2273 SetLastError(NTE_BAD_ALGID); 2274 return FALSE; 2275 } 2276 memcpy(in, out, pCryptKey->dwBlockLen); 2277 } 2278 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) { 2279 if (pbData == NULL) { 2280 *pdwDataLen = dwBufLen; 2281 return TRUE; 2282 } 2283 encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen); 2284 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) { 2285 if (pCryptKey->aiAlgid == CALG_RSA_SIGN) { 2286 SetLastError(NTE_BAD_KEY); 2287 return FALSE; 2288 } 2289 if (!pbData) { 2290 *pdwDataLen = pCryptKey->dwBlockLen; 2291 return TRUE; 2292 } 2293 if (dwBufLen < pCryptKey->dwBlockLen) { 2294 SetLastError(ERROR_MORE_DATA); 2295 return FALSE; 2296 } 2297 if (!pad_data(pbData, *pdwDataLen, pbData, pCryptKey->dwBlockLen, dwFlags)) return FALSE; 2298 encrypt_block_impl(pCryptKey->aiAlgid, PK_PUBLIC, &pCryptKey->context, pbData, pbData, RSAENH_ENCRYPT); 2299 *pdwDataLen = pCryptKey->dwBlockLen; 2300 Final = TRUE; 2301 } else { 2302 SetLastError(NTE_BAD_TYPE); 2303 return FALSE; 2304 } 2305 2306 if (Final) setup_key(pCryptKey); 2307 2308 return TRUE; 2309 } 2310 2311 /****************************************************************************** 2312 * CPDecrypt (RSAENH.@) 2313 * 2314 * Decrypt data. 2315 * 2316 * PARAMS 2317 * hProv [I] The key container hKey and hHash belong to. 2318 * hKey [I] The key used to decrypt the data. 2319 * hHash [I] An optional hash object for parallel hashing. See notes. 2320 * Final [I] Indicates if this is the last block of data to decrypt. 2321 * dwFlags [I] Currently no flags defined. Must be zero. 2322 * pbData [I/O] Pointer to the data to decrypt. Plaintext will also be stored there. 2323 * pdwDataLen [I/O] I: Length of ciphertext, O: Length of plaintext. 2324 * 2325 * RETURNS 2326 * Success: TRUE. 2327 * Failure: FALSE. 2328 * 2329 * NOTES 2330 * If a hash object handle is provided in hHash, it will be updated with the plaintext. 2331 * This is useful for message signatures. 2332 * 2333 * This function uses the standard WINAPI protocol for querying data of dynamic length. 2334 */ 2335 BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, 2336 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) 2337 { 2338 CRYPTKEY *pCryptKey; 2339 BYTE *in, out[RSAENH_MAX_BLOCK_SIZE], o[RSAENH_MAX_BLOCK_SIZE]; 2340 DWORD i, j, k; 2341 DWORD dwMax; 2342 2343 TRACE("(hProv=%08lx, hKey=%08lx, hHash=%08lx, Final=%d, dwFlags=%08x, pbData=%p, " 2344 "pdwDataLen=%p)\n", hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen); 2345 2346 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 2347 { 2348 SetLastError(NTE_BAD_UID); 2349 return FALSE; 2350 } 2351 2352 if (dwFlags) 2353 { 2354 SetLastError(NTE_BAD_FLAGS); 2355 return FALSE; 2356 } 2357 2358 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) 2359 { 2360 SetLastError(NTE_BAD_KEY); 2361 return FALSE; 2362 } 2363 2364 if (pCryptKey->dwState == RSAENH_KEYSTATE_IDLE) 2365 pCryptKey->dwState = RSAENH_KEYSTATE_ENCRYPTING; 2366 2367 if (pCryptKey->dwState != RSAENH_KEYSTATE_ENCRYPTING) 2368 { 2369 SetLastError(NTE_BAD_DATA); 2370 return FALSE; 2371 } 2372 2373 dwMax=*pdwDataLen; 2374 2375 if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_BLOCK) { 2376 for (i=0, in=pbData; i<*pdwDataLen; i+=pCryptKey->dwBlockLen, in+=pCryptKey->dwBlockLen) { 2377 switch (pCryptKey->dwMode) { 2378 case CRYPT_MODE_ECB: 2379 encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out, 2380 RSAENH_DECRYPT); 2381 break; 2382 2383 case CRYPT_MODE_CBC: 2384 encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, in, out, 2385 RSAENH_DECRYPT); 2386 for (j=0; j<pCryptKey->dwBlockLen; j++) out[j] ^= pCryptKey->abChainVector[j]; 2387 memcpy(pCryptKey->abChainVector, in, pCryptKey->dwBlockLen); 2388 break; 2389 2390 case CRYPT_MODE_CFB: 2391 for (j=0; j<pCryptKey->dwBlockLen; j++) { 2392 encrypt_block_impl(pCryptKey->aiAlgid, 0, &pCryptKey->context, 2393 pCryptKey->abChainVector, o, RSAENH_ENCRYPT); 2394 out[j] = in[j] ^ o[0]; 2395 for (k=0; k<pCryptKey->dwBlockLen-1; k++) 2396 pCryptKey->abChainVector[k] = pCryptKey->abChainVector[k+1]; 2397 pCryptKey->abChainVector[k] = in[j]; 2398 } 2399 break; 2400 2401 default: 2402 SetLastError(NTE_BAD_ALGID); 2403 return FALSE; 2404 } 2405 memcpy(in, out, pCryptKey->dwBlockLen); 2406 } 2407 if (Final) { 2408 if (pbData[*pdwDataLen-1] && 2409 pbData[*pdwDataLen-1] <= pCryptKey->dwBlockLen && 2410 pbData[*pdwDataLen-1] <= *pdwDataLen) { 2411 BOOL padOkay = TRUE; 2412 2413 /* check that every bad byte has the same value */ 2414 for (i = 1; padOkay && i < pbData[*pdwDataLen-1]; i++) 2415 if (pbData[*pdwDataLen - i - 1] != pbData[*pdwDataLen - 1]) 2416 padOkay = FALSE; 2417 if (padOkay) 2418 *pdwDataLen -= pbData[*pdwDataLen-1]; 2419 else { 2420 SetLastError(NTE_BAD_DATA); 2421 setup_key(pCryptKey); 2422 return FALSE; 2423 } 2424 } 2425 else { 2426 SetLastError(NTE_BAD_DATA); 2427 setup_key(pCryptKey); 2428 return FALSE; 2429 } 2430 } 2431 2432 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) { 2433 encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen); 2434 } else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) { 2435 if (pCryptKey->aiAlgid == CALG_RSA_SIGN) { 2436 SetLastError(NTE_BAD_KEY); 2437 return FALSE; 2438 } 2439 encrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbData, pbData, RSAENH_DECRYPT); 2440 if (!unpad_data(pbData, pCryptKey->dwBlockLen, pbData, pdwDataLen, dwFlags)) return FALSE; 2441 Final = TRUE; 2442 } else { 2443 SetLastError(NTE_BAD_TYPE); 2444 return FALSE; 2445 } 2446 2447 if (Final) setup_key(pCryptKey); 2448 2449 if (is_valid_handle(&handle_table, hHash, RSAENH_MAGIC_HASH)) { 2450 if (*pdwDataLen>dwMax || 2451 !RSAENH_CPHashData(hProv, hHash, pbData, *pdwDataLen, 0)) return FALSE; 2452 } 2453 2454 return TRUE; 2455 } 2456 2457 static BOOL crypt_export_simple(CRYPTKEY *pCryptKey, CRYPTKEY *pPubKey, 2458 DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) 2459 { 2460 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; 2461 ALG_ID *pAlgid = (ALG_ID*)(pBlobHeader+1); 2462 DWORD dwDataLen; 2463 2464 if (!(GET_ALG_CLASS(pCryptKey->aiAlgid)&(ALG_CLASS_DATA_ENCRYPT|ALG_CLASS_MSG_ENCRYPT))) { 2465 SetLastError(NTE_BAD_KEY); /* FIXME: error code? */ 2466 return FALSE; 2467 } 2468 2469 dwDataLen = sizeof(BLOBHEADER) + sizeof(ALG_ID) + pPubKey->dwBlockLen; 2470 if (pbData) { 2471 if (*pdwDataLen < dwDataLen) { 2472 SetLastError(ERROR_MORE_DATA); 2473 *pdwDataLen = dwDataLen; 2474 return FALSE; 2475 } 2476 2477 pBlobHeader->bType = SIMPLEBLOB; 2478 pBlobHeader->bVersion = CUR_BLOB_VERSION; 2479 pBlobHeader->reserved = 0; 2480 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; 2481 2482 *pAlgid = pPubKey->aiAlgid; 2483 2484 if (!pad_data(pCryptKey->abKeyValue, pCryptKey->dwKeyLen, (BYTE*)(pAlgid+1), 2485 pPubKey->dwBlockLen, dwFlags)) 2486 { 2487 return FALSE; 2488 } 2489 2490 encrypt_block_impl(pPubKey->aiAlgid, PK_PUBLIC, &pPubKey->context, (BYTE*)(pAlgid+1), 2491 (BYTE*)(pAlgid+1), RSAENH_ENCRYPT); 2492 } 2493 *pdwDataLen = dwDataLen; 2494 return TRUE; 2495 } 2496 2497 static BOOL crypt_export_public_key(CRYPTKEY *pCryptKey, BYTE *pbData, 2498 DWORD *pdwDataLen) 2499 { 2500 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; 2501 RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1); 2502 DWORD dwDataLen; 2503 2504 if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) { 2505 SetLastError(NTE_BAD_KEY); 2506 return FALSE; 2507 } 2508 2509 dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + pCryptKey->dwKeyLen; 2510 if (pbData) { 2511 if (*pdwDataLen < dwDataLen) { 2512 SetLastError(ERROR_MORE_DATA); 2513 *pdwDataLen = dwDataLen; 2514 return FALSE; 2515 } 2516 2517 pBlobHeader->bType = PUBLICKEYBLOB; 2518 pBlobHeader->bVersion = CUR_BLOB_VERSION; 2519 pBlobHeader->reserved = 0; 2520 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; 2521 2522 pRSAPubKey->magic = RSAENH_MAGIC_RSA1; 2523 pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; 2524 2525 export_public_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, 2526 pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); 2527 } 2528 *pdwDataLen = dwDataLen; 2529 return TRUE; 2530 } 2531 2532 static BOOL crypt_export_private_key(CRYPTKEY *pCryptKey, BOOL force, 2533 BYTE *pbData, DWORD *pdwDataLen) 2534 { 2535 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; 2536 RSAPUBKEY *pRSAPubKey = (RSAPUBKEY*)(pBlobHeader+1); 2537 DWORD dwDataLen; 2538 2539 if ((pCryptKey->aiAlgid != CALG_RSA_KEYX) && (pCryptKey->aiAlgid != CALG_RSA_SIGN)) { 2540 SetLastError(NTE_BAD_KEY); 2541 return FALSE; 2542 } 2543 if (!force && !(pCryptKey->dwPermissions & CRYPT_EXPORT)) 2544 { 2545 SetLastError(NTE_BAD_KEY_STATE); 2546 return FALSE; 2547 } 2548 2549 dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 2550 2 * pCryptKey->dwKeyLen + 5 * ((pCryptKey->dwKeyLen + 1) >> 1); 2551 if (pbData) { 2552 if (*pdwDataLen < dwDataLen) { 2553 SetLastError(ERROR_MORE_DATA); 2554 *pdwDataLen = dwDataLen; 2555 return FALSE; 2556 } 2557 2558 pBlobHeader->bType = PRIVATEKEYBLOB; 2559 pBlobHeader->bVersion = CUR_BLOB_VERSION; 2560 pBlobHeader->reserved = 0; 2561 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; 2562 2563 pRSAPubKey->magic = RSAENH_MAGIC_RSA2; 2564 pRSAPubKey->bitlen = pCryptKey->dwKeyLen << 3; 2565 2566 export_private_key_impl((BYTE*)(pRSAPubKey+1), &pCryptKey->context, 2567 pCryptKey->dwKeyLen, &pRSAPubKey->pubexp); 2568 } 2569 *pdwDataLen = dwDataLen; 2570 return TRUE; 2571 } 2572 2573 static BOOL crypt_export_plaintext_key(CRYPTKEY *pCryptKey, BYTE *pbData, 2574 DWORD *pdwDataLen) 2575 { 2576 BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData; 2577 DWORD *pKeyLen = (DWORD*)(pBlobHeader+1); 2578 BYTE *pbKey = (BYTE*)(pKeyLen+1); 2579 DWORD dwDataLen; 2580 2581 dwDataLen = sizeof(BLOBHEADER) + sizeof(DWORD) + pCryptKey->dwKeyLen; 2582 if (pbData) { 2583 if (*pdwDataLen < dwDataLen) { 2584 SetLastError(ERROR_MORE_DATA); 2585 *pdwDataLen = dwDataLen; 2586 return FALSE; 2587 } 2588 2589 pBlobHeader->bType = PLAINTEXTKEYBLOB; 2590 pBlobHeader->bVersion = CUR_BLOB_VERSION; 2591 pBlobHeader->reserved = 0; 2592 pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid; 2593 2594 *pKeyLen = pCryptKey->dwKeyLen; 2595 memcpy(pbKey, pCryptKey->abKeyValue, pCryptKey->dwKeyLen); 2596 } 2597 *pdwDataLen = dwDataLen; 2598 return TRUE; 2599 } 2600 /****************************************************************************** 2601 * crypt_export_key [Internal] 2602 * 2603 * Export a key into a binary large object (BLOB). Called by CPExportKey and 2604 * by store_key_pair. 2605 * 2606 * PARAMS 2607 * pCryptKey [I] Key to be exported. 2608 * hPubKey [I] Key used to encrypt sensitive BLOB data. 2609 * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB. 2610 * dwFlags [I] Currently none defined. 2611 * force [I] If TRUE, the key is written no matter what the key's 2612 * permissions are. Otherwise the key's permissions are 2613 * checked before exporting. 2614 * pbData [O] Pointer to a buffer where the BLOB will be written to. 2615 * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB 2616 * 2617 * RETURNS 2618 * Success: TRUE. 2619 * Failure: FALSE. 2620 */ 2621 static BOOL crypt_export_key(CRYPTKEY *pCryptKey, HCRYPTKEY hPubKey, 2622 DWORD dwBlobType, DWORD dwFlags, BOOL force, 2623 BYTE *pbData, DWORD *pdwDataLen) 2624 { 2625 CRYPTKEY *pPubKey; 2626 2627 if (dwFlags & CRYPT_SSL2_FALLBACK) { 2628 if (pCryptKey->aiAlgid != CALG_SSL2_MASTER) { 2629 SetLastError(NTE_BAD_KEY); 2630 return FALSE; 2631 } 2632 } 2633 2634 switch ((BYTE)dwBlobType) 2635 { 2636 case SIMPLEBLOB: 2637 if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey)){ 2638 SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error_code? */ 2639 return FALSE; 2640 } 2641 return crypt_export_simple(pCryptKey, pPubKey, dwFlags, pbData, 2642 pdwDataLen); 2643 2644 case PUBLICKEYBLOB: 2645 if (is_valid_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY)) { 2646 SetLastError(NTE_BAD_KEY); /* FIXME: error code? */ 2647 return FALSE; 2648 } 2649 2650 return crypt_export_public_key(pCryptKey, pbData, pdwDataLen); 2651 2652 case PRIVATEKEYBLOB: 2653 return crypt_export_private_key(pCryptKey, force, pbData, pdwDataLen); 2654 2655 case PLAINTEXTKEYBLOB: 2656 return crypt_export_plaintext_key(pCryptKey, pbData, pdwDataLen); 2657 2658 default: 2659 SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */ 2660 return FALSE; 2661 } 2662 } 2663 2664 /****************************************************************************** 2665 * CPExportKey (RSAENH.@) 2666 * 2667 * Export a key into a binary large object (BLOB). 2668 * 2669 * PARAMS 2670 * hProv [I] Key container from which a key is to be exported. 2671 * hKey [I] Key to be exported. 2672 * hPubKey [I] Key used to encrypt sensitive BLOB data. 2673 * dwBlobType [I] SIMPLEBLOB, PUBLICKEYBLOB or PRIVATEKEYBLOB. 2674 * dwFlags [I] Currently none defined. 2675 * pbData [O] Pointer to a buffer where the BLOB will be written to. 2676 * pdwDataLen [I/O] I: Size of buffer at pbData, O: Size of BLOB 2677 * 2678 * RETURNS 2679 * Success: TRUE. 2680 * Failure: FALSE. 2681 */ 2682 BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, 2683 DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen) 2684 { 2685 CRYPTKEY *pCryptKey; 2686 2687 TRACE("(hProv=%08lx, hKey=%08lx, hPubKey=%08lx, dwBlobType=%08x, dwFlags=%08x, pbData=%p," 2688 "pdwDataLen=%p)\n", hProv, hKey, hPubKey, dwBlobType, dwFlags, pbData, pdwDataLen); 2689 2690 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 2691 { 2692 SetLastError(NTE_BAD_UID); 2693 return FALSE; 2694 } 2695 2696 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) 2697 { 2698 SetLastError(NTE_BAD_KEY); 2699 return FALSE; 2700 } 2701 2702 return crypt_export_key(pCryptKey, hPubKey, dwBlobType, dwFlags, FALSE, 2703 pbData, pdwDataLen); 2704 } 2705 2706 /****************************************************************************** 2707 * release_and_install_key [Internal] 2708 * 2709 * Release an existing key, if present, and replaces it with a new one. 2710 * 2711 * PARAMS 2712 * hProv [I] Key container into which the key is to be imported. 2713 * src [I] Key which will replace *dest 2714 * dest [I] Points to key to be released and replaced with src 2715 * fStoreKey [I] If TRUE, the newly installed key is stored to the registry. 2716 */ 2717 static void release_and_install_key(HCRYPTPROV hProv, HCRYPTKEY src, 2718 HCRYPTKEY *dest, DWORD fStoreKey) 2719 { 2720 RSAENH_CPDestroyKey(hProv, *dest); 2721 copy_handle(&handle_table, src, RSAENH_MAGIC_KEY, dest); 2722 if (fStoreKey) 2723 { 2724 KEYCONTAINER *pKeyContainer; 2725 2726 if ((pKeyContainer = get_key_container(hProv))) 2727 { 2728 store_key_container_keys(pKeyContainer); 2729 store_key_container_permissions(pKeyContainer); 2730 } 2731 } 2732 } 2733 2734 /****************************************************************************** 2735 * import_private_key [Internal] 2736 * 2737 * Import a BLOB'ed private key into a key container. 2738 * 2739 * PARAMS 2740 * hProv [I] Key container into which the private key is to be imported. 2741 * pbData [I] Pointer to a buffer which holds the private key BLOB. 2742 * dwDataLen [I] Length of data in buffer at pbData. 2743 * dwFlags [I] One of: 2744 * CRYPT_EXPORTABLE: the imported key is marked exportable 2745 * fStoreKey [I] If TRUE, the imported key is stored to the registry. 2746 * phKey [O] Handle to the imported key. 2747 * 2748 * 2749 * NOTES 2750 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure 2751 * it's a PRIVATEKEYBLOB. 2752 * 2753 * RETURNS 2754 * Success: TRUE. 2755 * Failure: FALSE. 2756 */ 2757 static BOOL import_private_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, 2758 DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey) 2759 { 2760 KEYCONTAINER *pKeyContainer; 2761 CRYPTKEY *pCryptKey; 2762 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData; 2763 const RSAPUBKEY *pRSAPubKey = (const RSAPUBKEY*)(pBlobHeader+1); 2764 BOOL ret; 2765 2766 if (dwFlags & CRYPT_IPSEC_HMAC_KEY) 2767 { 2768 FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n"); 2769 SetLastError(NTE_BAD_FLAGS); 2770 return FALSE; 2771 } 2772 if (!(pKeyContainer = get_key_container(hProv))) 2773 return FALSE; 2774 2775 if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY))) 2776 { 2777 ERR("datalen %d not long enough for a BLOBHEADER + RSAPUBKEY\n", 2778 dwDataLen); 2779 SetLastError(NTE_BAD_DATA); 2780 return FALSE; 2781 } 2782 if (pRSAPubKey->magic != RSAENH_MAGIC_RSA2) 2783 { 2784 ERR("unexpected magic %08x\n", pRSAPubKey->magic); 2785 SetLastError(NTE_BAD_DATA); 2786 return FALSE; 2787 } 2788 if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 2789 (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4)))) 2790 { 2791 DWORD expectedLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 2792 (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4)); 2793 2794 ERR("blob too short for pub key: expect %d, got %d\n", 2795 expectedLen, dwDataLen); 2796 SetLastError(NTE_BAD_DATA); 2797 return FALSE; 2798 } 2799 2800 *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); 2801 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; 2802 setup_key(pCryptKey); 2803 ret = import_private_key_impl((const BYTE*)(pRSAPubKey+1), &pCryptKey->context, 2804 pRSAPubKey->bitlen/8, dwDataLen, pRSAPubKey->pubexp); 2805 if (ret) { 2806 if (dwFlags & CRYPT_EXPORTABLE) 2807 pCryptKey->dwPermissions |= CRYPT_EXPORT; 2808 switch (pBlobHeader->aiKeyAlg) 2809 { 2810 case AT_SIGNATURE: 2811 case CALG_RSA_SIGN: 2812 TRACE("installing signing key\n"); 2813 release_and_install_key(hProv, *phKey, &pKeyContainer->hSignatureKeyPair, 2814 fStoreKey); 2815 break; 2816 case AT_KEYEXCHANGE: 2817 case CALG_RSA_KEYX: 2818 TRACE("installing key exchange key\n"); 2819 release_and_install_key(hProv, *phKey, &pKeyContainer->hKeyExchangeKeyPair, 2820 fStoreKey); 2821 break; 2822 } 2823 } 2824 return ret; 2825 } 2826 2827 /****************************************************************************** 2828 * import_public_key [Internal] 2829 * 2830 * Import a BLOB'ed public key. 2831 * 2832 * PARAMS 2833 * hProv [I] A CSP. 2834 * pbData [I] Pointer to a buffer which holds the public key BLOB. 2835 * dwDataLen [I] Length of data in buffer at pbData. 2836 * dwFlags [I] One of: 2837 * CRYPT_EXPORTABLE: the imported key is marked exportable 2838 * phKey [O] Handle to the imported key. 2839 * 2840 * 2841 * NOTES 2842 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure 2843 * it's a PUBLICKEYBLOB. 2844 * 2845 * RETURNS 2846 * Success: TRUE. 2847 * Failure: FALSE. 2848 */ 2849 static BOOL import_public_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, 2850 DWORD dwFlags, HCRYPTKEY *phKey) 2851 { 2852 CRYPTKEY *pCryptKey; 2853 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData; 2854 const RSAPUBKEY *pRSAPubKey = (const RSAPUBKEY*)(pBlobHeader+1); 2855 ALG_ID algID; 2856 BOOL ret; 2857 2858 if (dwFlags & CRYPT_IPSEC_HMAC_KEY) 2859 { 2860 FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n"); 2861 SetLastError(NTE_BAD_FLAGS); 2862 return FALSE; 2863 } 2864 2865 if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) || 2866 (pRSAPubKey->magic != RSAENH_MAGIC_RSA1) || 2867 (dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + (pRSAPubKey->bitlen >> 3))) 2868 { 2869 SetLastError(NTE_BAD_DATA); 2870 return FALSE; 2871 } 2872 2873 /* Since this is a public key blob, only the public key is 2874 * available, so only signature verification is possible. 2875 */ 2876 algID = pBlobHeader->aiKeyAlg; 2877 *phKey = new_key(hProv, algID, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey); 2878 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; 2879 setup_key(pCryptKey); 2880 ret = import_public_key_impl((const BYTE*)(pRSAPubKey+1), &pCryptKey->context, 2881 pRSAPubKey->bitlen >> 3, pRSAPubKey->pubexp); 2882 if (ret) { 2883 if (dwFlags & CRYPT_EXPORTABLE) 2884 pCryptKey->dwPermissions |= CRYPT_EXPORT; 2885 } 2886 return ret; 2887 } 2888 2889 /****************************************************************************** 2890 * import_symmetric_key [Internal] 2891 * 2892 * Import a BLOB'ed symmetric key into a key container. 2893 * 2894 * PARAMS 2895 * hProv [I] Key container into which the symmetric key is to be imported. 2896 * pbData [I] Pointer to a buffer which holds the symmetric key BLOB. 2897 * dwDataLen [I] Length of data in buffer at pbData. 2898 * hPubKey [I] Key used to decrypt sensitive BLOB data. 2899 * dwFlags [I] One of: 2900 * CRYPT_EXPORTABLE: the imported key is marked exportable 2901 * phKey [O] Handle to the imported key. 2902 * 2903 * 2904 * NOTES 2905 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure 2906 * it's a SIMPLEBLOB. 2907 * 2908 * RETURNS 2909 * Success: TRUE. 2910 * Failure: FALSE. 2911 */ 2912 static BOOL import_symmetric_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, 2913 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) 2914 { 2915 CRYPTKEY *pCryptKey, *pPubKey; 2916 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData; 2917 const ALG_ID *pAlgid = (const ALG_ID*)(pBlobHeader+1); 2918 const BYTE *pbKeyStream = (const BYTE*)(pAlgid + 1); 2919 BYTE *pbDecrypted; 2920 DWORD dwKeyLen; 2921 2922 if (dwFlags & CRYPT_IPSEC_HMAC_KEY) 2923 { 2924 FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n"); 2925 SetLastError(NTE_BAD_FLAGS); 2926 return FALSE; 2927 } 2928 if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey) || 2929 pPubKey->aiAlgid != CALG_RSA_KEYX) 2930 { 2931 SetLastError(NTE_BAD_PUBLIC_KEY); /* FIXME: error code? */ 2932 return FALSE; 2933 } 2934 2935 if (dwDataLen < sizeof(BLOBHEADER)+sizeof(ALG_ID)+pPubKey->dwBlockLen) 2936 { 2937 SetLastError(NTE_BAD_DATA); /* FIXME: error code */ 2938 return FALSE; 2939 } 2940 2941 pbDecrypted = HeapAlloc(GetProcessHeap(), 0, pPubKey->dwBlockLen); 2942 if (!pbDecrypted) return FALSE; 2943 encrypt_block_impl(pPubKey->aiAlgid, PK_PRIVATE, &pPubKey->context, pbKeyStream, pbDecrypted, 2944 RSAENH_DECRYPT); 2945 2946 dwKeyLen = RSAENH_MAX_KEY_SIZE; 2947 if (!unpad_data(pbDecrypted, pPubKey->dwBlockLen, pbDecrypted, &dwKeyLen, dwFlags)) { 2948 HeapFree(GetProcessHeap(), 0, pbDecrypted); 2949 return FALSE; 2950 } 2951 2952 *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, dwKeyLen<<19, &pCryptKey); 2953 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) 2954 { 2955 HeapFree(GetProcessHeap(), 0, pbDecrypted); 2956 return FALSE; 2957 } 2958 memcpy(pCryptKey->abKeyValue, pbDecrypted, dwKeyLen); 2959 HeapFree(GetProcessHeap(), 0, pbDecrypted); 2960 setup_key(pCryptKey); 2961 if (dwFlags & CRYPT_EXPORTABLE) 2962 pCryptKey->dwPermissions |= CRYPT_EXPORT; 2963 return TRUE; 2964 } 2965 2966 /****************************************************************************** 2967 * import_plaintext_key [Internal] 2968 * 2969 * Import a plaintext key into a key container. 2970 * 2971 * PARAMS 2972 * hProv [I] Key container into which the symmetric key is to be imported. 2973 * pbData [I] Pointer to a buffer which holds the plaintext key BLOB. 2974 * dwDataLen [I] Length of data in buffer at pbData. 2975 * dwFlags [I] One of: 2976 * CRYPT_EXPORTABLE: the imported key is marked exportable 2977 * phKey [O] Handle to the imported key. 2978 * 2979 * 2980 * NOTES 2981 * Assumes the caller has already checked the BLOBHEADER at pbData to ensure 2982 * it's a PLAINTEXTKEYBLOB. 2983 * 2984 * RETURNS 2985 * Success: TRUE. 2986 * Failure: FALSE. 2987 */ 2988 static BOOL import_plaintext_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, 2989 DWORD dwFlags, HCRYPTKEY *phKey) 2990 { 2991 CRYPTKEY *pCryptKey; 2992 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData; 2993 const DWORD *pKeyLen = (const DWORD *)(pBlobHeader + 1); 2994 const BYTE *pbKeyStream = (const BYTE*)(pKeyLen + 1); 2995 2996 if (dwDataLen < sizeof(BLOBHEADER)+sizeof(DWORD)+*pKeyLen) 2997 { 2998 SetLastError(NTE_BAD_DATA); /* FIXME: error code */ 2999 return FALSE; 3000 } 3001 3002 if (dwFlags & CRYPT_IPSEC_HMAC_KEY) 3003 { 3004 *phKey = new_key(hProv, CALG_HMAC, 0, &pCryptKey); 3005 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) 3006 return FALSE; 3007 if (*pKeyLen <= RSAENH_MIN(sizeof(pCryptKey->abKeyValue), RSAENH_HMAC_BLOCK_LEN)) 3008 { 3009 memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen); 3010 pCryptKey->dwKeyLen = *pKeyLen; 3011 } 3012 else 3013 { 3014 CRYPT_DATA_BLOB blobHmacKey = { *pKeyLen, (BYTE *)pbKeyStream }; 3015 3016 /* In order to initialize an HMAC key, the key material is hashed, 3017 * and the output of the hash function is used as the key material. 3018 * Unfortunately, the way the Crypto API is designed, we don't know 3019 * the hash algorithm yet, so we have to copy the entire key 3020 * material. 3021 */ 3022 if (!copy_data_blob(&pCryptKey->blobHmacKey, &blobHmacKey)) 3023 { 3024 release_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY); 3025 *phKey = (HCRYPTKEY)INVALID_HANDLE_VALUE; 3026 return FALSE; 3027 } 3028 } 3029 setup_key(pCryptKey); 3030 if (dwFlags & CRYPT_EXPORTABLE) 3031 pCryptKey->dwPermissions |= CRYPT_EXPORT; 3032 } 3033 else 3034 { 3035 *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, *pKeyLen<<19, &pCryptKey); 3036 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) 3037 return FALSE; 3038 memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen); 3039 setup_key(pCryptKey); 3040 if (dwFlags & CRYPT_EXPORTABLE) 3041 pCryptKey->dwPermissions |= CRYPT_EXPORT; 3042 } 3043 return TRUE; 3044 } 3045 3046 /****************************************************************************** 3047 * import_key [Internal] 3048 * 3049 * Import a BLOB'ed key into a key container, optionally storing the key's 3050 * value to the registry. 3051 * 3052 * PARAMS 3053 * hProv [I] Key container into which the key is to be imported. 3054 * pbData [I] Pointer to a buffer which holds the BLOB. 3055 * dwDataLen [I] Length of data in buffer at pbData. 3056 * hPubKey [I] Key used to decrypt sensitive BLOB data. 3057 * dwFlags [I] One of: 3058 * CRYPT_EXPORTABLE: the imported key is marked exportable 3059 * fStoreKey [I] If TRUE, the imported key is stored to the registry. 3060 * phKey [O] Handle to the imported key. 3061 * 3062 * RETURNS 3063 * Success: TRUE. 3064 * Failure: FALSE. 3065 */ 3066 static BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, 3067 DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey) 3068 { 3069 KEYCONTAINER *pKeyContainer; 3070 const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData; 3071 3072 if (!(pKeyContainer = get_key_container(hProv))) 3073 return FALSE; 3074 3075 if (dwDataLen < sizeof(BLOBHEADER) || 3076 pBlobHeader->bVersion != CUR_BLOB_VERSION || 3077 pBlobHeader->reserved != 0) 3078 { 3079 TRACE("bVersion = %d, reserved = %d\n", pBlobHeader->bVersion, 3080 pBlobHeader->reserved); 3081 SetLastError(NTE_BAD_DATA); 3082 return FALSE; 3083 } 3084 3085 /* If this is a verify-only context, the key is not persisted regardless of 3086 * fStoreKey's original value. 3087 */ 3088 fStoreKey = fStoreKey && !(dwFlags & CRYPT_VERIFYCONTEXT); 3089 TRACE("blob type: %x\n", pBlobHeader->bType); 3090 switch (pBlobHeader->bType) 3091 { 3092 case PRIVATEKEYBLOB: 3093 return import_private_key(hProv, pbData, dwDataLen, dwFlags, 3094 fStoreKey, phKey); 3095 3096 case PUBLICKEYBLOB: 3097 return import_public_key(hProv, pbData, dwDataLen, dwFlags, 3098 phKey); 3099 3100 case SIMPLEBLOB: 3101 return import_symmetric_key(hProv, pbData, dwDataLen, hPubKey, 3102 dwFlags, phKey); 3103 3104 case PLAINTEXTKEYBLOB: 3105 return import_plaintext_key(hProv, pbData, dwDataLen, dwFlags, 3106 phKey); 3107 3108 default: 3109 SetLastError(NTE_BAD_TYPE); /* FIXME: error code? */ 3110 return FALSE; 3111 } 3112 } 3113 3114 /****************************************************************************** 3115 * CPImportKey (RSAENH.@) 3116 * 3117 * Import a BLOB'ed key into a key container. 3118 * 3119 * PARAMS 3120 * hProv [I] Key container into which the key is to be imported. 3121 * pbData [I] Pointer to a buffer which holds the BLOB. 3122 * dwDataLen [I] Length of data in buffer at pbData. 3123 * hPubKey [I] Key used to decrypt sensitive BLOB data. 3124 * dwFlags [I] One of: 3125 * CRYPT_EXPORTABLE: the imported key is marked exportable 3126 * phKey [O] Handle to the imported key. 3127 * 3128 * RETURNS 3129 * Success: TRUE. 3130 * Failure: FALSE. 3131 */ 3132 BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, 3133 HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) 3134 { 3135 TRACE("(hProv=%08lx, pbData=%p, dwDataLen=%d, hPubKey=%08lx, dwFlags=%08x, phKey=%p)\n", 3136 hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey); 3137 3138 return import_key(hProv, pbData, dwDataLen, hPubKey, dwFlags, TRUE, phKey); 3139 } 3140 3141 /****************************************************************************** 3142 * CPGenKey (RSAENH.@) 3143 * 3144 * Generate a key in the key container 3145 * 3146 * PARAMS 3147 * hProv [I] Key container for which a key is to be generated. 3148 * Algid [I] Crypto algorithm identifier for the key to be generated. 3149 * dwFlags [I] Upper 16 bits: Binary length of key. Lower 16 bits: Flags. See Notes 3150 * phKey [O] Handle to the generated key. 3151 * 3152 * RETURNS 3153 * Success: TRUE. 3154 * Failure: FALSE. 3155 * 3156 * FIXME 3157 * Flags currently not considered. 3158 * 3159 * NOTES 3160 * Private key-exchange- and signature-keys can be generated with Algid AT_KEYEXCHANGE 3161 * and AT_SIGNATURE values. 3162 */ 3163 BOOL WINAPI RSAENH_CPGenKey(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey) 3164 { 3165 KEYCONTAINER *pKeyContainer; 3166 CRYPTKEY *pCryptKey; 3167 3168 TRACE("(hProv=%08lx, aiAlgid=%d, dwFlags=%08x, phKey=%p)\n", hProv, Algid, dwFlags, phKey); 3169 3170 if (!(pKeyContainer = get_key_container(hProv))) 3171 { 3172 /* MSDN: hProv not containing valid context handle */ 3173 return FALSE; 3174 } 3175 3176 switch (Algid) 3177 { 3178 case AT_SIGNATURE: 3179 case CALG_RSA_SIGN: 3180 *phKey = new_key(hProv, CALG_RSA_SIGN, dwFlags, &pCryptKey); 3181 if (pCryptKey) { 3182 new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen); 3183 setup_key(pCryptKey); 3184 release_and_install_key(hProv, *phKey, 3185 &pKeyContainer->hSignatureKeyPair, 3186 FALSE); 3187 } 3188 break; 3189 3190 case AT_KEYEXCHANGE: 3191 case CALG_RSA_KEYX: 3192 *phKey = new_key(hProv, CALG_RSA_KEYX, dwFlags, &pCryptKey); 3193 if (pCryptKey) { 3194 new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen); 3195 setup_key(pCryptKey); 3196 release_and_install_key(hProv, *phKey, 3197 &pKeyContainer->hKeyExchangeKeyPair, 3198 FALSE); 3199 } 3200 break; 3201 3202 case CALG_RC2: 3203 case CALG_RC4: 3204 case CALG_DES: 3205 case CALG_3DES_112: 3206 case CALG_3DES: 3207 case CALG_AES: 3208 case CALG_AES_128: 3209 case CALG_AES_192: 3210 case CALG_AES_256: 3211 case CALG_PCT1_MASTER: 3212 case CALG_SSL2_MASTER: 3213 case CALG_SSL3_MASTER: 3214 case CALG_TLS1_MASTER: 3215 *phKey = new_key(hProv, Algid, dwFlags, &pCryptKey); 3216 if (pCryptKey) { 3217 gen_rand_impl(pCryptKey->abKeyValue, RSAENH_MAX_KEY_SIZE); 3218 switch (Algid) { 3219 case CALG_SSL3_MASTER: 3220 pCryptKey->abKeyValue[0] = RSAENH_SSL3_VERSION_MAJOR; 3221 pCryptKey->abKeyValue[1] = RSAENH_SSL3_VERSION_MINOR; 3222 break; 3223 3224 case CALG_TLS1_MASTER: 3225 pCryptKey->abKeyValue[0] = RSAENH_TLS1_VERSION_MAJOR; 3226 pCryptKey->abKeyValue[1] = RSAENH_TLS1_VERSION_MINOR; 3227 break; 3228 } 3229 setup_key(pCryptKey); 3230 } 3231 break; 3232 3233 default: 3234 /* MSDN: Algorithm not supported specified by Algid */ 3235 SetLastError(NTE_BAD_ALGID); 3236 return FALSE; 3237 } 3238 3239 return *phKey != (HCRYPTKEY)INVALID_HANDLE_VALUE; 3240 } 3241 3242 /****************************************************************************** 3243 * CPGenRandom (RSAENH.@) 3244 * 3245 * Generate a random byte stream. 3246 * 3247 * PARAMS 3248 * hProv [I] Key container that is used to generate random bytes. 3249 * dwLen [I] Specifies the number of requested random data bytes. 3250 * pbBuffer [O] Random bytes will be stored here. 3251 * 3252 * RETURNS 3253 * Success: TRUE 3254 * Failure: FALSE 3255 */ 3256 BOOL WINAPI RSAENH_CPGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) 3257 { 3258 TRACE("(hProv=%08lx, dwLen=%d, pbBuffer=%p)\n", hProv, dwLen, pbBuffer); 3259 3260 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 3261 { 3262 /* MSDN: hProv not containing valid context handle */ 3263 SetLastError(NTE_BAD_UID); 3264 return FALSE; 3265 } 3266 3267 return gen_rand_impl(pbBuffer, dwLen); 3268 } 3269 3270 /****************************************************************************** 3271 * CPGetHashParam (RSAENH.@) 3272 * 3273 * Query parameters of an hash object. 3274 * 3275 * PARAMS 3276 * hProv [I] The kea container, which the hash belongs to. 3277 * hHash [I] The hash object that is to be queried. 3278 * dwParam [I] Specifies the parameter that is to be queried. 3279 * pbData [I] Pointer to the buffer where the parameter value will be stored. 3280 * pdwDataLen [I/O] I: Buffer length at pbData, O: Length of the parameter value. 3281 * dwFlags [I] None currently defined. 3282 * 3283 * RETURNS 3284 * Success: TRUE 3285 * Failure: FALSE 3286 * 3287 * NOTES 3288 * Valid dwParams are: HP_ALGID, HP_HASHSIZE, HP_HASHVALUE. The hash will be 3289 * finalized if HP_HASHVALUE is queried. 3290 */ 3291 BOOL WINAPI RSAENH_CPGetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, 3292 DWORD *pdwDataLen, DWORD dwFlags) 3293 { 3294 CRYPTHASH *pCryptHash; 3295 3296 TRACE("(hProv=%08lx, hHash=%08lx, dwParam=%08x, pbData=%p, pdwDataLen=%p, dwFlags=%08x)\n", 3297 hProv, hHash, dwParam, pbData, pdwDataLen, dwFlags); 3298 3299 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 3300 { 3301 SetLastError(NTE_BAD_UID); 3302 return FALSE; 3303 } 3304 3305 if (dwFlags) 3306 { 3307 SetLastError(NTE_BAD_FLAGS); 3308 return FALSE; 3309 } 3310 3311 if (!lookup_handle(&handle_table, hHash, RSAENH_MAGIC_HASH, 3312 (OBJECTHDR**)&pCryptHash)) 3313 { 3314 SetLastError(NTE_BAD_HASH); 3315 return FALSE; 3316 } 3317 3318 if (!pdwDataLen) 3319 { 3320 SetLastError(ERROR_INVALID_PARAMETER); 3321 return FALSE; 3322 } 3323 3324 switch (dwParam) 3325 { 3326 case HP_ALGID: 3327 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptHash->aiAlgid, 3328 sizeof(ALG_ID)); 3329 3330 case HP_HASHSIZE: 3331 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptHash->dwHashSize, 3332 sizeof(DWORD)); 3333 3334 case HP_HASHVAL: 3335 if (pCryptHash->aiAlgid == CALG_TLS1PRF) { 3336 return tls1_prf(hProv, pCryptHash->hKey, &pCryptHash->tpPRFParams.blobLabel, 3337 &pCryptHash->tpPRFParams.blobSeed, pbData, *pdwDataLen); 3338 } 3339 3340 if ( pbData == NULL ) { 3341 *pdwDataLen = pCryptHash->dwHashSize; 3342 return TRUE; 3343 } 3344 3345 if (pbData && (pCryptHash->dwState != RSAENH_HASHSTATE_FINISHED)) 3346 { 3347 finalize_hash(pCryptHash); 3348 pCryptHash->dwState = RSAENH_HASHSTATE_FINISHED; 3349 } 3350 3351 return copy_param(pbData, pdwDataLen, pCryptHash->abHashValue, 3352 pCryptHash->dwHashSize); 3353 3354 default: 3355 SetLastError(NTE_BAD_TYPE); 3356 return FALSE; 3357 } 3358 } 3359 3360 /****************************************************************************** 3361 * CPSetKeyParam (RSAENH.@) 3362 * 3363 * Set a parameter of a key object 3364 * 3365 * PARAMS 3366 * hProv [I] The key container to which the key belongs. 3367 * hKey [I] The key for which a parameter is to be set. 3368 * dwParam [I] Parameter type. See Notes. 3369 * pbData [I] Pointer to the parameter value. 3370 * dwFlags [I] Currently none defined. 3371 * 3372 * RETURNS 3373 * Success: TRUE. 3374 * Failure: FALSE. 3375 * 3376 * NOTES: 3377 * Defined dwParam types are: 3378 * - KP_MODE: Values MODE_CBC, MODE_ECB, MODE_CFB. 3379 * - KP_MODE_BITS: Shift width for cipher feedback mode. (Currently ignored by MS CSP's) 3380 * - KP_PERMISSIONS: Or'ed combination of CRYPT_ENCRYPT, CRYPT_DECRYPT, 3381 * CRYPT_EXPORT, CRYPT_READ, CRYPT_WRITE, CRYPT_MAC 3382 * - KP_IV: Initialization vector 3383 */ 3384 BOOL WINAPI RSAENH_CPSetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, 3385 DWORD dwFlags) 3386 { 3387 CRYPTKEY *pCryptKey; 3388 3389 TRACE("(hProv=%08lx, hKey=%08lx, dwParam=%08x, pbData=%p, dwFlags=%08x)\n", hProv, hKey, 3390 dwParam, pbData, dwFlags); 3391 3392 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 3393 { 3394 SetLastError(NTE_BAD_UID); 3395 return FALSE; 3396 } 3397 3398 if (dwFlags) { 3399 SetLastError(NTE_BAD_FLAGS); 3400 return FALSE; 3401 } 3402 3403 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) 3404 { 3405 SetLastError(NTE_BAD_KEY); 3406 return FALSE; 3407 } 3408 3409 switch (dwParam) { 3410 case KP_PADDING: 3411 /* The MS providers only support PKCS5_PADDING */ 3412 if (*(DWORD *)pbData != PKCS5_PADDING) { 3413 SetLastError(NTE_BAD_DATA); 3414 return FALSE; 3415 } 3416 return TRUE; 3417 3418 case KP_MODE: 3419 pCryptKey->dwMode = *(DWORD*)pbData; 3420 return TRUE; 3421 3422 case KP_MODE_BITS: 3423 pCryptKey->dwModeBits = *(DWORD*)pbData; 3424 return TRUE; 3425 3426 case KP_PERMISSIONS: 3427 { 3428 DWORD perms = *(DWORD *)pbData; 3429 3430 if ((perms & CRYPT_EXPORT) && 3431 !(pCryptKey->dwPermissions & CRYPT_EXPORT)) 3432 { 3433 SetLastError(NTE_BAD_DATA); 3434 return FALSE; 3435 } 3436 else if (!(perms & CRYPT_EXPORT) && 3437 (pCryptKey->dwPermissions & CRYPT_EXPORT)) 3438 { 3439 /* Clearing the export permission appears to be ignored, 3440 * see tests. 3441 */ 3442 perms |= CRYPT_EXPORT; 3443 } 3444 pCryptKey->dwPermissions = perms; 3445 return TRUE; 3446 } 3447 3448 case KP_IV: 3449 memcpy(pCryptKey->abInitVector, pbData, pCryptKey->dwBlockLen); 3450 setup_key(pCryptKey); 3451 return TRUE; 3452 3453 case KP_SALT: 3454 switch (pCryptKey->aiAlgid) { 3455 case CALG_RC2: 3456 case CALG_RC4: 3457 { 3458 KEYCONTAINER *pKeyContainer = get_key_container(pCryptKey->hProv); 3459 if (!pbData) 3460 { 3461 SetLastError(ERROR_INVALID_PARAMETER); 3462 return FALSE; 3463 } 3464 /* MSDN: the base provider always sets eleven bytes of 3465 * salt value. 3466 */ 3467 memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen, 3468 pbData, 11); 3469 pCryptKey->dwSaltLen = 11; 3470 setup_key(pCryptKey); 3471 /* After setting the salt value if the provider is not base or 3472 * strong the salt length will be reset. */ 3473 if (pKeyContainer->dwPersonality != RSAENH_PERSONALITY_BASE && 3474 pKeyContainer->dwPersonality != RSAENH_PERSONALITY_STRONG) 3475 pCryptKey->dwSaltLen = 0; 3476 break; 3477 } 3478 default: 3479 SetLastError(NTE_BAD_KEY); 3480 return FALSE; 3481 } 3482 return TRUE; 3483 3484 case KP_SALT_EX: 3485 { 3486 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pbData; 3487 3488 /* salt length can't be greater than 184 bits = 24 bytes */ 3489 if (blob->cbData > 24) 3490 { 3491 SetLastError(NTE_BAD_DATA); 3492 return FALSE; 3493 } 3494 memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen, blob->pbData, 3495 blob->cbData); 3496 pCryptKey->dwSaltLen = blob->cbData; 3497 setup_key(pCryptKey); 3498 return TRUE; 3499 } 3500 3501 case KP_EFFECTIVE_KEYLEN: 3502 switch (pCryptKey->aiAlgid) { 3503 case CALG_RC2: 3504 { 3505 DWORD keylen, deflen; 3506 BOOL ret = TRUE; 3507 KEYCONTAINER *pKeyContainer = get_key_container(pCryptKey->hProv); 3508 3509 if (!pbData) 3510 { 3511 SetLastError(ERROR_INVALID_PARAMETER); 3512 return FALSE; 3513 } 3514 keylen = *(DWORD *)pbData; 3515 if (!keylen || keylen > 1024) 3516 { 3517 SetLastError(NTE_BAD_DATA); 3518 return FALSE; 3519 } 3520 3521 /* 3522 * The Base provider will force the key length to default 3523 * and set an error state if a key length different from 3524 * the default is tried. 3525 */ 3526 deflen = aProvEnumAlgsEx[pKeyContainer->dwPersonality]->dwDefaultLen; 3527 if (pKeyContainer->dwPersonality == RSAENH_PERSONALITY_BASE 3528 && keylen != deflen) 3529 { 3530 keylen = deflen; 3531 SetLastError(NTE_BAD_DATA); 3532 ret = FALSE; 3533 } 3534 pCryptKey->dwEffectiveKeyLen = keylen; 3535 setup_key(pCryptKey); 3536 return ret; 3537 } 3538 default: 3539 SetLastError(NTE_BAD_TYPE); 3540 return FALSE; 3541 } 3542 return TRUE; 3543 3544 case KP_SCHANNEL_ALG: 3545 switch (((PSCHANNEL_ALG)pbData)->dwUse) { 3546 case SCHANNEL_ENC_KEY: 3547 memcpy(&pCryptKey->siSChannelInfo.saEncAlg, pbData, sizeof(SCHANNEL_ALG)); 3548 break; 3549 3550 case SCHANNEL_MAC_KEY: 3551 memcpy(&pCryptKey->siSChannelInfo.saMACAlg, pbData, sizeof(SCHANNEL_ALG)); 3552 break; 3553 3554 default: 3555 SetLastError(NTE_FAIL); /* FIXME: error code */ 3556 return FALSE; 3557 } 3558 return TRUE; 3559 3560 case KP_CLIENT_RANDOM: 3561 return copy_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom, (PCRYPT_DATA_BLOB)pbData); 3562 3563 case KP_SERVER_RANDOM: 3564 return copy_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom, (PCRYPT_DATA_BLOB)pbData); 3565 3566 default: 3567 SetLastError(NTE_BAD_TYPE); 3568 return FALSE; 3569 } 3570 } 3571 3572 /****************************************************************************** 3573 * CPGetKeyParam (RSAENH.@) 3574 * 3575 * Query a key parameter. 3576 * 3577 * PARAMS 3578 * hProv [I] The key container, which the key belongs to. 3579 * hHash [I] The key object that is to be queried. 3580 * dwParam [I] Specifies the parameter that is to be queried. 3581 * pbData [I] Pointer to the buffer where the parameter value will be stored. 3582 * pdwDataLen [I/O] I: Buffer length at pbData, O: Length of the parameter value. 3583 * dwFlags [I] None currently defined. 3584 * 3585 * RETURNS 3586 * Success: TRUE 3587 * Failure: FALSE 3588 * 3589 * NOTES 3590 * Defined dwParam types are: 3591 * - KP_MODE: Values MODE_CBC, MODE_ECB, MODE_CFB. 3592 * - KP_MODE_BITS: Shift width for cipher feedback mode. 3593 * (Currently ignored by MS CSP's - always eight) 3594 * - KP_PERMISSIONS: Or'ed combination of CRYPT_ENCRYPT, CRYPT_DECRYPT, 3595 * CRYPT_EXPORT, CRYPT_READ, CRYPT_WRITE, CRYPT_MAC 3596 * - KP_IV: Initialization vector. 3597 * - KP_KEYLEN: Bitwidth of the key. 3598 * - KP_BLOCKLEN: Size of a block cipher block. 3599 * - KP_SALT: Salt value. 3600 */ 3601 BOOL WINAPI RSAENH_CPGetKeyParam(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, 3602 DWORD *pdwDataLen, DWORD dwFlags) 3603 { 3604 CRYPTKEY *pCryptKey; 3605 DWORD dwValue; 3606 3607 TRACE("(hProv=%08lx, hKey=%08lx, dwParam=%08x, pbData=%p, pdwDataLen=%p dwFlags=%08x)\n", 3608 hProv, hKey, dwParam, pbData, pdwDataLen, dwFlags); 3609 3610 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 3611 { 3612 SetLastError(NTE_BAD_UID); 3613 return FALSE; 3614 } 3615 3616 if (dwFlags) { 3617 SetLastError(NTE_BAD_FLAGS); 3618 return FALSE; 3619 } 3620 3621 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey)) 3622 { 3623 SetLastError(NTE_BAD_KEY); 3624 return FALSE; 3625 } 3626 3627 switch (dwParam) 3628 { 3629 case KP_IV: 3630 return copy_param(pbData, pdwDataLen, pCryptKey->abInitVector, 3631 pCryptKey->dwBlockLen); 3632 3633 case KP_SALT: 3634 switch (pCryptKey->aiAlgid) { 3635 case CALG_RC2: 3636 case CALG_RC4: 3637 return copy_param(pbData, pdwDataLen, 3638 &pCryptKey->abKeyValue[pCryptKey->dwKeyLen], 3639 pCryptKey->dwSaltLen); 3640 default: 3641 SetLastError(NTE_BAD_KEY); 3642 return FALSE; 3643 } 3644 3645 case KP_PADDING: 3646 dwValue = PKCS5_PADDING; 3647 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD)); 3648 3649 case KP_KEYLEN: 3650 dwValue = pCryptKey->dwKeyLen << 3; 3651 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD)); 3652 3653 case KP_EFFECTIVE_KEYLEN: 3654 if (pCryptKey->dwEffectiveKeyLen) 3655 dwValue = pCryptKey->dwEffectiveKeyLen; 3656 else 3657 dwValue = pCryptKey->dwKeyLen << 3; 3658 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD)); 3659 3660 case KP_BLOCKLEN: 3661 dwValue = pCryptKey->dwBlockLen << 3; 3662 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD)); 3663 3664 case KP_MODE: 3665 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwMode, sizeof(DWORD)); 3666 3667 case KP_MODE_BITS: 3668 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwModeBits, 3669 sizeof(DWORD)); 3670 3671 case KP_PERMISSIONS: 3672 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwPermissions, 3673 sizeof(DWORD)); 3674 3675 case KP_ALGID: 3676 return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->aiAlgid, sizeof(DWORD)); 3677 3678 default: 3679 SetLastError(NTE_BAD_TYPE); 3680 return FALSE; 3681 } 3682 } 3683 3684 /****************************************************************************** 3685 * CPGetProvParam (RSAENH.@) 3686 * 3687 * Query a CSP parameter. 3688 * 3689 * PARAMS 3690 * hProv [I] The key container that is to be queried. 3691 * dwParam [I] Specifies the parameter that is to be queried. 3692 * pbData [I] Pointer to the buffer where the parameter value will be stored. 3693 * pdwDataLen [I/O] I: Buffer length at pbData, O: Length of the parameter value. 3694 * dwFlags [I] CRYPT_FIRST: Start enumeration (for PP_ENUMALGS{_EX}). 3695 * 3696 * RETURNS 3697 * Success: TRUE 3698 * Failure: FALSE 3699 * NOTES: 3700 * Defined dwParam types: 3701 * - PP_CONTAINER: Name of the key container. 3702 * - PP_NAME: Name of the cryptographic service provider. 3703 * - PP_SIG_KEYSIZE_INC: RSA signature keywidth granularity in bits. 3704 * - PP_KEYX_KEYSIZE_INC: RSA key-exchange keywidth granularity in bits. 3705 * - PP_ENUMALGS{_EX}: Query provider capabilities. 3706 * - PP_KEYSET_SEC_DESCR: Retrieve security descriptor on container. 3707 */ 3708 BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, 3709 DWORD *pdwDataLen, DWORD dwFlags) 3710 { 3711 KEYCONTAINER *pKeyContainer; 3712 PROV_ENUMALGS provEnumalgs; 3713 DWORD dwTemp; 3714 HKEY hKey; 3715 3716 /* This is for dwParam PP_CRYPT_COUNT_KEY_USE. 3717 * IE6 SP1 asks for it in the 'About' dialog. 3718 * Returning this BLOB seems to satisfy IE. The marked 0x00 seem 3719 * to be 'don't care's. If you know anything more specific about 3720 * this provider parameter, please report to wine-devel@winehq.org */ 3721 static const BYTE abWTF[96] = { 3722 0xb0, 0x25, 0x63, 0x86, 0x9c, 0xab, 0xb6, 0x37, 3723 0xe8, 0x82, /**/0x00,/**/ 0x72, 0x06, 0xb2, /**/0x00,/**/ 0x3b, 3724 0x60, 0x35, /**/0x00,/**/ 0x3b, 0x88, 0xce, /**/0x00,/**/ 0x82, 3725 0xbc, 0x7a, /**/0x00,/**/ 0xb7, 0x4f, 0x7e, /**/0x00,/**/ 0xde, 3726 0x92, 0xf1, /**/0x00,/**/ 0x83, 0xea, 0x5e, /**/0x00,/**/ 0xc8, 3727 0x12, 0x1e, 0xd4, 0x06, 0xf7, 0x66, /**/0x00,/**/ 0x01, 3728 0x29, 0xa4, /**/0x00,/**/ 0xf8, 0x24, 0x0c, /**/0x00,/**/ 0x33, 3729 0x06, 0x80, /**/0x00,/**/ 0x02, 0x46, 0x0b, /**/0x00,/**/ 0x6d, 3730 0x5b, 0xca, /**/0x00,/**/ 0x9a, 0x10, 0xf0, /**/0x00,/**/ 0x05, 3731 0x19, 0xd0, /**/0x00,/**/ 0x2c, 0xf6, 0x27, /**/0x00,/**/ 0xaa, 3732 0x7c, 0x6f, /**/0x00,/**/ 0xb9, 0xd8, 0x72, /**/0x00,/**/ 0x03, 3733 0xf3, 0x81, /**/0x00,/**/ 0xfa, 0xe8, 0x26, /**/0x00,/**/ 0xca 3734 }; 3735 3736 TRACE("(hProv=%08lx, dwParam=%08x, pbData=%p, pdwDataLen=%p, dwFlags=%08x)\n", 3737 hProv, dwParam, pbData, pdwDataLen, dwFlags); 3738 3739 if (!pdwDataLen) { 3740 SetLastError(ERROR_INVALID_PARAMETER); 3741 return FALSE; 3742 } 3743 3744 if (!(pKeyContainer = get_key_container(hProv))) 3745 { 3746 /* MSDN: hProv not containing valid context handle */ 3747 return FALSE; 3748 } 3749 3750 switch (dwParam) 3751 { 3752 case PP_CONTAINER: 3753 case PP_UNIQUE_CONTAINER:/* MSDN says we can return the same value as PP_CONTAINER */ 3754 return copy_param(pbData, pdwDataLen, (const BYTE*)pKeyContainer->szName, 3755 strlen(pKeyContainer->szName)+1); 3756 3757 case PP_NAME: 3758 return copy_param(pbData, pdwDataLen, (const BYTE*)pKeyContainer->szProvName, 3759 strlen(pKeyContainer->szProvName)+1); 3760 3761 case PP_PROVTYPE: 3762 dwTemp = PROV_RSA_FULL; 3763 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); 3764 3765 case PP_KEYSPEC: 3766 dwTemp = AT_SIGNATURE | AT_KEYEXCHANGE; 3767 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); 3768 3769 case PP_KEYSET_TYPE: 3770 dwTemp = pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET; 3771 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); 3772 3773 case PP_KEYSTORAGE: 3774 dwTemp = CRYPT_SEC_DESCR; 3775 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); 3776 3777 case PP_SIG_KEYSIZE_INC: 3778 case PP_KEYX_KEYSIZE_INC: 3779 dwTemp = 8; 3780 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); 3781 3782 case PP_IMPTYPE: 3783 dwTemp = CRYPT_IMPL_SOFTWARE; 3784 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); 3785 3786 case PP_VERSION: 3787 dwTemp = 0x00000200; 3788 return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp)); 3789 3790 case PP_ENUMCONTAINERS: 3791 if ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) pKeyContainer->dwEnumContainersCtr = 0; 3792 3793 if (!pbData) { 3794 *pdwDataLen = (DWORD)MAX_PATH + 1; 3795 return TRUE; 3796 } 3797 3798 if (!open_container_key("", dwFlags, KEY_READ, &hKey)) 3799 { 3800 SetLastError(ERROR_NO_MORE_ITEMS); 3801 return FALSE; 3802 } 3803 3804 dwTemp = *pdwDataLen; 3805 switch (RegEnumKeyExA(hKey, pKeyContainer->dwEnumContainersCtr, (LPSTR)pbData, &dwTemp, 3806 NULL, NULL, NULL, NULL)) 3807 { 3808 case ERROR_MORE_DATA: 3809 *pdwDataLen = (DWORD)MAX_PATH + 1; 3810 3811 case ERROR_SUCCESS: 3812 pKeyContainer->dwEnumContainersCtr++; 3813 RegCloseKey(hKey); 3814 return TRUE; 3815 3816 case ERROR_NO_MORE_ITEMS: 3817 default: 3818 SetLastError(ERROR_NO_MORE_ITEMS); 3819 RegCloseKey(hKey); 3820 return FALSE; 3821 } 3822 3823 case PP_ENUMALGS: 3824 case PP_ENUMALGS_EX: 3825 if (((pKeyContainer->dwEnumAlgsCtr >= RSAENH_MAX_ENUMALGS-1) || 3826 (!aProvEnumAlgsEx[pKeyContainer->dwPersonality] 3827 [pKeyContainer->dwEnumAlgsCtr+1].aiAlgid)) && 3828 ((dwFlags & CRYPT_FIRST) != CRYPT_FIRST)) 3829 { 3830 SetLastError(ERROR_NO_MORE_ITEMS); 3831 return FALSE; 3832 } 3833 3834 if (dwParam == PP_ENUMALGS) { 3835 if (pbData && (*pdwDataLen >= sizeof(PROV_ENUMALGS))) 3836 pKeyContainer->dwEnumAlgsCtr = ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) ? 3837 0 : pKeyContainer->dwEnumAlgsCtr+1; 3838 3839 provEnumalgs.aiAlgid = aProvEnumAlgsEx 3840 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].aiAlgid; 3841 provEnumalgs.dwBitLen = aProvEnumAlgsEx 3842 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].dwDefaultLen; 3843 provEnumalgs.dwNameLen = aProvEnumAlgsEx 3844 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].dwNameLen; 3845 memcpy(provEnumalgs.szName, aProvEnumAlgsEx 3846 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].szName, 3847 20*sizeof(CHAR)); 3848 3849 return copy_param(pbData, pdwDataLen, (const BYTE*)&provEnumalgs, 3850 sizeof(PROV_ENUMALGS)); 3851 } else { 3852 if (pbData && (*pdwDataLen >= sizeof(PROV_ENUMALGS_EX))) 3853 pKeyContainer->dwEnumAlgsCtr = ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) ? 3854 0 : pKeyContainer->dwEnumAlgsCtr+1; 3855 3856 return copy_param(pbData, pdwDataLen, 3857 (const BYTE*)&aProvEnumAlgsEx 3858 [pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr], 3859 sizeof(PROV_ENUMALGS_EX)); 3860 } 3861 3862 case PP_CRYPT_COUNT_KEY_USE: /* Asked for by IE About dialog */ 3863 return copy_param(pbData, pdwDataLen, abWTF, sizeof(abWTF)); 3864 3865 case PP_KEYSET_SEC_DESCR: 3866 { 3867 SECURITY_DESCRIPTOR *sd; 3868 DWORD err, len, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET); 3869 3870 if (!open_container_key(pKeyContainer->szName, flags, KEY_READ, &hKey)) 3871 { 3872 SetLastError(NTE_BAD_KEYSET); 3873 return FALSE; 3874 } 3875 3876 err = GetSecurityInfo(hKey, SE_REGISTRY_KEY, dwFlags, NULL, NULL, NULL, NULL, (void **)&sd); 3877 RegCloseKey(hKey); 3878 if (err) 3879 { 3880 SetLastError(err); 3881 return FALSE; 3882 } 3883 3884 len = GetSecurityDescriptorLength(sd); 3885 if (*pdwDataLen >= len) memcpy(pbData, sd, len); 3886 else SetLastError(ERROR_INSUFFICIENT_BUFFER); 3887 *pdwDataLen = len; 3888 3889 LocalFree(sd); 3890 return TRUE; 3891 } 3892 3893 default: 3894 /* MSDN: Unknown parameter number in dwParam */ 3895 SetLastError(NTE_BAD_TYPE); 3896 return FALSE; 3897 } 3898 } 3899 3900 /****************************************************************************** 3901 * CPDeriveKey (RSAENH.@) 3902 * 3903 * Derives a key from a hash value. 3904 * 3905 * PARAMS 3906 * hProv [I] Key container for which a key is to be generated. 3907 * Algid [I] Crypto algorithm identifier for the key to be generated. 3908 * hBaseData [I] Hash from whose value the key will be derived. 3909 * dwFlags [I] See Notes. 3910 * phKey [O] The generated key. 3911 * 3912 * RETURNS 3913 * Success: TRUE 3914 * Failure: FALSE 3915 * 3916 * NOTES 3917 * Defined flags: 3918 * - CRYPT_EXPORTABLE: Key can be exported. 3919 * - CRYPT_NO_SALT: No salt is used for 40 bit keys. 3920 * - CRYPT_CREATE_SALT: Use remaining bits as salt value. 3921 */ 3922 BOOL WINAPI RSAENH_CPDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, 3923 DWORD dwFlags, HCRYPTKEY *phKey) 3924 { 3925 CRYPTKEY *pCryptKey, *pMasterKey; 3926 CRYPTHASH *pCryptHash; 3927 BYTE abHashValue[RSAENH_MAX_HASH_SIZE*2]; 3928 DWORD dwLen; 3929 3930 TRACE("(hProv=%08lx, Algid=%d, hBaseData=%08lx, dwFlags=%08x phKey=%p)\n", hProv, Algid, 3931 hBaseData, dwFlags, phKey); 3932 3933 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 3934 { 3935 SetLastError(NTE_BAD_UID); 3936 return FALSE; 3937 } 3938 3939 if (!lookup_handle(&handle_table, hBaseData, RSAENH_MAGIC_HASH, 3940 (OBJECTHDR**)&pCryptHash)) 3941 { 3942 SetLastError(NTE_BAD_HASH); 3943 return FALSE; 3944 } 3945 3946 if (!phKey) 3947 { 3948 SetLastError(ERROR_INVALID_PARAMETER); 3949 return FALSE; 3950 } 3951 3952 switch (GET_ALG_CLASS(Algid)) 3953 { 3954 case ALG_CLASS_DATA_ENCRYPT: 3955 { 3956 int need_padding, copy_len; 3957 *phKey = new_key(hProv, Algid, dwFlags, &pCryptKey); 3958 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; 3959 3960 /* 3961 * We derive the key material from the hash. 3962 * If the hash value is not large enough for the claimed key, we have to construct 3963 * a larger binary value based on the hash. This is documented in MSDN: CryptDeriveKey. 3964 */ 3965 dwLen = RSAENH_MAX_HASH_SIZE; 3966 RSAENH_CPGetHashParam(pCryptHash->hProv, hBaseData, HP_HASHVAL, abHashValue, &dwLen, 0); 3967 3968 /* 3969 * The usage of padding seems to vary from algorithm to algorithm. 3970 * For now the only different case found was for AES with 128 bit key. 3971 */ 3972 switch(Algid) 3973 { 3974 case CALG_AES_128: 3975 /* To reduce the chance of regressions we will only deviate 3976 * from the old behavior for the tested hash lengths */ 3977 if (dwLen == 16 || dwLen == 20) 3978 { 3979 need_padding = 1; 3980 break; 3981 } 3982 default: 3983 need_padding = dwLen < pCryptKey->dwKeyLen; 3984 } 3985 3986 copy_len = pCryptKey->dwKeyLen; 3987 if (need_padding) 3988 { 3989 BYTE pad1[RSAENH_HMAC_DEF_PAD_LEN], pad2[RSAENH_HMAC_DEF_PAD_LEN]; 3990 BYTE old_hashval[RSAENH_MAX_HASH_SIZE]; 3991 DWORD i; 3992 3993 memcpy(old_hashval, pCryptHash->abHashValue, RSAENH_MAX_HASH_SIZE); 3994 3995 for (i=0; i<RSAENH_HMAC_DEF_PAD_LEN; i++) { 3996 pad1[i] = RSAENH_HMAC_DEF_IPAD_CHAR ^ (i<dwLen ? abHashValue[i] : 0); 3997 pad2[i] = RSAENH_HMAC_DEF_OPAD_CHAR ^ (i<dwLen ? abHashValue[i] : 0); 3998 } 3999 4000 init_hash(pCryptHash); 4001 update_hash(pCryptHash, pad1, RSAENH_HMAC_DEF_PAD_LEN); 4002 finalize_hash(pCryptHash); 4003 memcpy(abHashValue, pCryptHash->abHashValue, pCryptHash->dwHashSize); 4004 4005 init_hash(pCryptHash); 4006 update_hash(pCryptHash, pad2, RSAENH_HMAC_DEF_PAD_LEN); 4007 finalize_hash(pCryptHash); 4008 memcpy(abHashValue+pCryptHash->dwHashSize, pCryptHash->abHashValue, 4009 pCryptHash->dwHashSize); 4010 4011 memcpy(pCryptHash->abHashValue, old_hashval, RSAENH_MAX_HASH_SIZE); 4012 } 4013 /* 4014 * Padding was not required, we have more hash than needed. 4015 * Do we need to use the remaining hash as salt? 4016 */ 4017 else if((dwFlags & CRYPT_CREATE_SALT) && 4018 (Algid == CALG_RC2 || Algid == CALG_RC4)) 4019 { 4020 copy_len += pCryptKey->dwSaltLen; 4021 } 4022 4023 memcpy(pCryptKey->abKeyValue, abHashValue, 4024 RSAENH_MIN(copy_len, sizeof(pCryptKey->abKeyValue))); 4025 break; 4026 } 4027 case ALG_CLASS_MSG_ENCRYPT: 4028 if (!lookup_handle(&handle_table, pCryptHash->hKey, RSAENH_MAGIC_KEY, 4029 (OBJECTHDR**)&pMasterKey)) 4030 { 4031 SetLastError(NTE_FAIL); /* FIXME error code */ 4032 return FALSE; 4033 } 4034 4035 switch (Algid) 4036 { 4037 /* See RFC 2246, chapter 6.3 Key calculation */ 4038 case CALG_SCHANNEL_ENC_KEY: 4039 if (!pMasterKey->siSChannelInfo.saEncAlg.Algid || 4040 !pMasterKey->siSChannelInfo.saEncAlg.cBits) 4041 { 4042 SetLastError(NTE_BAD_FLAGS); 4043 return FALSE; 4044 } 4045 *phKey = new_key(hProv, pMasterKey->siSChannelInfo.saEncAlg.Algid, 4046 MAKELONG(LOWORD(dwFlags),pMasterKey->siSChannelInfo.saEncAlg.cBits), 4047 &pCryptKey); 4048 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; 4049 memcpy(pCryptKey->abKeyValue, 4050 pCryptHash->abHashValue + ( 4051 2 * (pMasterKey->siSChannelInfo.saMACAlg.cBits / 8) + 4052 ((dwFlags & CRYPT_SERVER) ? 4053 (pMasterKey->siSChannelInfo.saEncAlg.cBits / 8) : 0)), 4054 pMasterKey->siSChannelInfo.saEncAlg.cBits / 8); 4055 memcpy(pCryptKey->abInitVector, 4056 pCryptHash->abHashValue + ( 4057 2 * (pMasterKey->siSChannelInfo.saMACAlg.cBits / 8) + 4058 2 * (pMasterKey->siSChannelInfo.saEncAlg.cBits / 8) + 4059 ((dwFlags & CRYPT_SERVER) ? pCryptKey->dwBlockLen : 0)), 4060 pCryptKey->dwBlockLen); 4061 break; 4062 4063 case CALG_SCHANNEL_MAC_KEY: 4064 *phKey = new_key(hProv, Algid, 4065 MAKELONG(LOWORD(dwFlags),pMasterKey->siSChannelInfo.saMACAlg.cBits), 4066 &pCryptKey); 4067 if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE; 4068 memcpy(pCryptKey->abKeyValue, 4069 pCryptHash->abHashValue + ((dwFlags & CRYPT_SERVER) ? 4070 pMasterKey->siSChannelInfo.saMACAlg.cBits / 8 : 0), 4071 pMasterKey->siSChannelInfo.saMACAlg.cBits / 8); 4072 break; 4073 4074 default: 4075 SetLastError(NTE_BAD_ALGID); 4076 return FALSE; 4077 } 4078 break; 4079 4080 default: 4081 SetLastError(NTE_BAD_ALGID); 4082 return FALSE; 4083 } 4084 4085 setup_key(pCryptKey); 4086 return TRUE; 4087 } 4088 4089 /****************************************************************************** 4090 * CPGetUserKey (RSAENH.@) 4091 * 4092 * Returns a handle to the user's private key-exchange- or signature-key. 4093 * 4094 * PARAMS 4095 * hProv [I] The key container from which a user key is requested. 4096 * dwKeySpec [I] AT_KEYEXCHANGE or AT_SIGNATURE 4097 * phUserKey [O] Handle to the requested key or INVALID_HANDLE_VALUE in case of failure. 4098 * 4099 * RETURNS 4100 * Success: TRUE. 4101 * Failure: FALSE. 4102 * 4103 * NOTE 4104 * A newly created key container does not contain private user key. Create them with CPGenKey. 4105 */ 4106 BOOL WINAPI RSAENH_CPGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey) 4107 { 4108 KEYCONTAINER *pKeyContainer; 4109 4110 TRACE("(hProv=%08lx, dwKeySpec=%08x, phUserKey=%p)\n", hProv, dwKeySpec, phUserKey); 4111 4112 if (!(pKeyContainer = get_key_container(hProv))) 4113 { 4114 /* MSDN: hProv not containing valid context handle */ 4115 return FALSE; 4116 } 4117 4118 switch (dwKeySpec) 4119 { 4120 case AT_KEYEXCHANGE: 4121 copy_handle(&handle_table, pKeyContainer->hKeyExchangeKeyPair, RSAENH_MAGIC_KEY, 4122 phUserKey); 4123 break; 4124 4125 case AT_SIGNATURE: 4126 copy_handle(&handle_table, pKeyContainer->hSignatureKeyPair, RSAENH_MAGIC_KEY, 4127 phUserKey); 4128 break; 4129 4130 default: 4131 *phUserKey = (HCRYPTKEY)INVALID_HANDLE_VALUE; 4132 } 4133 4134 if (*phUserKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) 4135 { 4136 /* MSDN: dwKeySpec parameter specifies nonexistent key */ 4137 SetLastError(NTE_NO_KEY); 4138 return FALSE; 4139 } 4140 4141 return TRUE; 4142 } 4143 4144 /****************************************************************************** 4145 * CPHashData (RSAENH.@) 4146 * 4147 * Updates a hash object with the given data. 4148 * 4149 * PARAMS 4150 * hProv [I] Key container to which the hash object belongs. 4151 * hHash [I] Hash object which is to be updated. 4152 * pbData [I] Pointer to data with which the hash object is to be updated. 4153 * dwDataLen [I] Length of the data. 4154 * dwFlags [I] Currently none defined. 4155 * 4156 * RETURNS 4157 * Success: TRUE. 4158 * Failure: FALSE. 4159 * 4160 * NOTES 4161 * The actual hash value is queried with CPGetHashParam, which will finalize 4162 * the hash. Updating a finalized hash will fail with a last error NTE_BAD_HASH_STATE. 4163 */ 4164 BOOL WINAPI RSAENH_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pbData, 4165 DWORD dwDataLen, DWORD dwFlags) 4166 { 4167 CRYPTHASH *pCryptHash; 4168 4169 TRACE("(hProv=%08lx, hHash=%08lx, pbData=%p, dwDataLen=%d, dwFlags=%08x)\n", 4170 hProv, hHash, pbData, dwDataLen, dwFlags); 4171 4172 if (dwFlags & ~CRYPT_USERDATA) 4173 { 4174 SetLastError(NTE_BAD_FLAGS); 4175 return FALSE; 4176 } 4177 4178 if (!lookup_handle(&handle_table, hHash, RSAENH_MAGIC_HASH, 4179 (OBJECTHDR**)&pCryptHash)) 4180 { 4181 SetLastError(NTE_BAD_HASH); 4182 return FALSE; 4183 } 4184 4185 if (!get_algid_info(hProv, pCryptHash->aiAlgid) || pCryptHash->aiAlgid == CALG_SSL3_SHAMD5) 4186 { 4187 SetLastError(NTE_BAD_ALGID); 4188 return FALSE; 4189 } 4190 4191 if (pCryptHash->dwState != RSAENH_HASHSTATE_HASHING) 4192 { 4193 SetLastError(NTE_BAD_HASH_STATE); 4194 return FALSE; 4195 } 4196 4197 update_hash(pCryptHash, pbData, dwDataLen); 4198 return TRUE; 4199 } 4200 4201 /****************************************************************************** 4202 * CPHashSessionKey (RSAENH.@) 4203 * 4204 * Updates a hash object with the binary representation of a symmetric key. 4205 * 4206 * PARAMS 4207 * hProv [I] Key container to which the hash object belongs. 4208 * hHash [I] Hash object which is to be updated. 4209 * hKey [I] The symmetric key, whose binary value will be added to the hash. 4210 * dwFlags [I] CRYPT_LITTLE_ENDIAN, if the binary key value shall be interpreted as little endian. 4211 * 4212 * RETURNS 4213 * Success: TRUE. 4214 * Failure: FALSE. 4215 */ 4216 BOOL WINAPI RSAENH_CPHashSessionKey(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, 4217 DWORD dwFlags) 4218 { 4219 BYTE abKeyValue[RSAENH_MAX_KEY_SIZE], bTemp; 4220 CRYPTKEY *pKey; 4221 DWORD i; 4222 4223 TRACE("(hProv=%08lx, hHash=%08lx, hKey=%08lx, dwFlags=%08x)\n", hProv, hHash, hKey, dwFlags); 4224 4225 if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pKey) || 4226 (GET_ALG_CLASS(pKey->aiAlgid) != ALG_CLASS_DATA_ENCRYPT)) 4227 { 4228 SetLastError(NTE_BAD_KEY); 4229 return FALSE; 4230 } 4231 4232 if (dwFlags & ~CRYPT_LITTLE_ENDIAN) { 4233 SetLastError(NTE_BAD_FLAGS); 4234 return FALSE; 4235 } 4236 4237 memcpy(abKeyValue, pKey->abKeyValue, pKey->dwKeyLen); 4238 if (!(dwFlags & CRYPT_LITTLE_ENDIAN)) { 4239 for (i=0; i<pKey->dwKeyLen/2; i++) { 4240 bTemp = abKeyValue[i]; 4241 abKeyValue[i] = abKeyValue[pKey->dwKeyLen-i-1]; 4242 abKeyValue[pKey->dwKeyLen-i-1] = bTemp; 4243 } 4244 } 4245 4246 return RSAENH_CPHashData(hProv, hHash, abKeyValue, pKey->dwKeyLen, 0); 4247 } 4248 4249 /****************************************************************************** 4250 * CPReleaseContext (RSAENH.@) 4251 * 4252 * Release a key container. 4253 * 4254 * PARAMS 4255 * hProv [I] Key container to be released. 4256 * dwFlags [I] Currently none defined. 4257 * 4258 * RETURNS 4259 * Success: TRUE 4260 * Failure: FALSE 4261 */ 4262 BOOL WINAPI RSAENH_CPReleaseContext(HCRYPTPROV hProv, DWORD dwFlags) 4263 { 4264 TRACE("(hProv=%08lx, dwFlags=%08x)\n", hProv, dwFlags); 4265 4266 if (!release_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 4267 { 4268 /* MSDN: hProv not containing valid context handle */ 4269 SetLastError(NTE_BAD_UID); 4270 return FALSE; 4271 } 4272 4273 if (dwFlags) { 4274 SetLastError(NTE_BAD_FLAGS); 4275 return FALSE; 4276 } 4277 4278 return TRUE; 4279 } 4280 4281 /****************************************************************************** 4282 * CPSetHashParam (RSAENH.@) 4283 * 4284 * Set a parameter of a hash object 4285 * 4286 * PARAMS 4287 * hProv [I] The key container to which the key belongs. 4288 * hHash [I] The hash object for which a parameter is to be set. 4289 * dwParam [I] Parameter type. See Notes. 4290 * pbData [I] Pointer to the parameter value. 4291 * dwFlags [I] Currently none defined. 4292 * 4293 * RETURNS 4294 * Success: TRUE. 4295 * Failure: FALSE. 4296 * 4297 * NOTES 4298 * Currently only the HP_HMAC_INFO dwParam type is defined. 4299 * The HMAC_INFO struct will be deep copied into the hash object. 4300 * See Internet RFC 2104 for details on the HMAC algorithm. 4301 */ 4302 BOOL WINAPI RSAENH_CPSetHashParam(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, 4303 BYTE *pbData, DWORD dwFlags) 4304 { 4305 CRYPTHASH *pCryptHash; 4306 CRYPTKEY *pCryptKey; 4307 DWORD i; 4308 4309 TRACE("(hProv=%08lx, hHash=%08lx, dwParam=%08x, pbData=%p, dwFlags=%08x)\n", 4310 hProv, hHash, dwParam, pbData, dwFlags); 4311 4312 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 4313 { 4314 SetLastError(NTE_BAD_UID); 4315 return FALSE; 4316 } 4317 4318 if (dwFlags) { 4319 SetLastError(NTE_BAD_FLAGS); 4320 return FALSE; 4321 } 4322 4323 if (!lookup_handle(&handle_table, hHash, RSAENH_MAGIC_HASH, 4324 (OBJECTHDR**)&pCryptHash)) 4325 { 4326 SetLastError(NTE_BAD_HASH); 4327 return FALSE; 4328 } 4329 4330 switch (dwParam) { 4331 case HP_HMAC_INFO: 4332 free_hmac_info(pCryptHash->pHMACInfo); 4333 if (!copy_hmac_info(&pCryptHash->pHMACInfo, (PHMAC_INFO)pbData)) return FALSE; 4334 4335 if (!lookup_handle(&handle_table, pCryptHash->hKey, RSAENH_MAGIC_KEY, 4336 (OBJECTHDR**)&pCryptKey)) 4337 { 4338 SetLastError(NTE_FAIL); /* FIXME: correct error code? */ 4339 return FALSE; 4340 } 4341 4342 if (pCryptKey->aiAlgid == CALG_HMAC && !pCryptKey->dwKeyLen) { 4343 HCRYPTHASH hKeyHash; 4344 DWORD keyLen; 4345 4346 if (!RSAENH_CPCreateHash(hProv, ((PHMAC_INFO)pbData)->HashAlgid, 0, 0, 4347 &hKeyHash)) 4348 return FALSE; 4349 if (!RSAENH_CPHashData(hProv, hKeyHash, pCryptKey->blobHmacKey.pbData, 4350 pCryptKey->blobHmacKey.cbData, 0)) 4351 { 4352 RSAENH_CPDestroyHash(hProv, hKeyHash); 4353 return FALSE; 4354 } 4355 keyLen = sizeof(pCryptKey->abKeyValue); 4356 if (!RSAENH_CPGetHashParam(hProv, hKeyHash, HP_HASHVAL, pCryptKey->abKeyValue, 4357 &keyLen, 0)) 4358 { 4359 RSAENH_CPDestroyHash(hProv, hKeyHash); 4360 return FALSE; 4361 } 4362 pCryptKey->dwKeyLen = keyLen; 4363 RSAENH_CPDestroyHash(hProv, hKeyHash); 4364 } 4365 for (i=0; i<RSAENH_MIN(pCryptKey->dwKeyLen,pCryptHash->pHMACInfo->cbInnerString); i++) { 4366 pCryptHash->pHMACInfo->pbInnerString[i] ^= pCryptKey->abKeyValue[i]; 4367 } 4368 for (i=0; i<RSAENH_MIN(pCryptKey->dwKeyLen,pCryptHash->pHMACInfo->cbOuterString); i++) { 4369 pCryptHash->pHMACInfo->pbOuterString[i] ^= pCryptKey->abKeyValue[i]; 4370 } 4371 4372 init_hash(pCryptHash); 4373 return TRUE; 4374 4375 case HP_HASHVAL: 4376 memcpy(pCryptHash->abHashValue, pbData, pCryptHash->dwHashSize); 4377 pCryptHash->dwState = RSAENH_HASHSTATE_FINISHED; 4378 return TRUE; 4379 4380 case HP_TLS1PRF_SEED: 4381 return copy_data_blob(&pCryptHash->tpPRFParams.blobSeed, (PCRYPT_DATA_BLOB)pbData); 4382 4383 case HP_TLS1PRF_LABEL: 4384 return copy_data_blob(&pCryptHash->tpPRFParams.blobLabel, (PCRYPT_DATA_BLOB)pbData); 4385 4386 default: 4387 SetLastError(NTE_BAD_TYPE); 4388 return FALSE; 4389 } 4390 } 4391 4392 /****************************************************************************** 4393 * CPSetProvParam (RSAENH.@) 4394 */ 4395 BOOL WINAPI RSAENH_CPSetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags) 4396 { 4397 KEYCONTAINER *pKeyContainer; 4398 HKEY hKey; 4399 4400 TRACE("(hProv=%08lx, dwParam=%08x, pbData=%p, dwFlags=%08x)\n", hProv, dwParam, pbData, dwFlags); 4401 4402 if (!(pKeyContainer = get_key_container(hProv))) 4403 return FALSE; 4404 4405 switch (dwParam) 4406 { 4407 case PP_KEYSET_SEC_DESCR: 4408 { 4409 SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)pbData; 4410 DWORD err, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET); 4411 BOOL def, present; 4412 REGSAM access = WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY; 4413 PSID owner = NULL, group = NULL; 4414 PACL dacl = NULL, sacl = NULL; 4415 4416 if (!open_container_key(pKeyContainer->szName, flags, access, &hKey)) 4417 { 4418 SetLastError(NTE_BAD_KEYSET); 4419 return FALSE; 4420 } 4421 4422 if ((dwFlags & OWNER_SECURITY_INFORMATION && !GetSecurityDescriptorOwner(sd, &owner, &def)) || 4423 (dwFlags & GROUP_SECURITY_INFORMATION && !GetSecurityDescriptorGroup(sd, &group, &def)) || 4424 (dwFlags & DACL_SECURITY_INFORMATION && !GetSecurityDescriptorDacl(sd, &present, &dacl, &def)) || 4425 (dwFlags & SACL_SECURITY_INFORMATION && !GetSecurityDescriptorSacl(sd, &present, &sacl, &def))) 4426 { 4427 RegCloseKey(hKey); 4428 return FALSE; 4429 } 4430 4431 err = SetSecurityInfo(hKey, SE_REGISTRY_KEY, dwFlags, owner, group, dacl, sacl); 4432 RegCloseKey(hKey); 4433 if (err) 4434 { 4435 SetLastError(err); 4436 return FALSE; 4437 } 4438 return TRUE; 4439 } 4440 default: 4441 FIXME("unimplemented parameter %08x\n", dwParam); 4442 return FALSE; 4443 } 4444 } 4445 4446 /****************************************************************************** 4447 * CPSignHash (RSAENH.@) 4448 * 4449 * Sign a hash object 4450 * 4451 * PARAMS 4452 * hProv [I] The key container, to which the hash object belongs. 4453 * hHash [I] The hash object to be signed. 4454 * dwKeySpec [I] AT_SIGNATURE or AT_KEYEXCHANGE: Key used to generate the signature. 4455 * sDescription [I] Should be NULL for security reasons. 4456 * dwFlags [I] 0, CRYPT_NOHASHOID or CRYPT_X931_FORMAT: Format of the signature. 4457 * pbSignature [O] Buffer, to which the signature will be stored. May be NULL to query SigLen. 4458 * pdwSigLen [I/O] Size of the buffer (in), Length of the signature (out) 4459 * 4460 * RETURNS 4461 * Success: TRUE 4462 * Failure: FALSE 4463 */ 4464 BOOL WINAPI RSAENH_CPSignHash(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, 4465 LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, 4466 DWORD *pdwSigLen) 4467 { 4468 HCRYPTKEY hCryptKey = (HCRYPTKEY)INVALID_HANDLE_VALUE; 4469 CRYPTKEY *pCryptKey; 4470 DWORD dwHashLen; 4471 BYTE abHashValue[RSAENH_MAX_HASH_SIZE]; 4472 ALG_ID aiAlgid; 4473 BOOL ret = FALSE; 4474 4475 TRACE("(hProv=%08lx, hHash=%08lx, dwKeySpec=%08x, sDescription=%s, dwFlags=%08x, " 4476 "pbSignature=%p, pdwSigLen=%p)\n", hProv, hHash, dwKeySpec, debugstr_w(sDescription), 4477 dwFlags, pbSignature, pdwSigLen); 4478 4479 if (dwFlags & ~(CRYPT_NOHASHOID|CRYPT_X931_FORMAT)) { 4480 SetLastError(NTE_BAD_FLAGS); 4481 return FALSE; 4482 } 4483 4484 if (!RSAENH_CPGetUserKey(hProv, dwKeySpec, &hCryptKey)) return FALSE; 4485 4486 if (!lookup_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY, 4487 (OBJECTHDR**)&pCryptKey)) 4488 { 4489 SetLastError(NTE_NO_KEY); 4490 goto out; 4491 } 4492 4493 if (!pbSignature) { 4494 *pdwSigLen = pCryptKey->dwKeyLen; 4495 ret = TRUE; 4496 goto out; 4497 } 4498 if (pCryptKey->dwKeyLen > *pdwSigLen) 4499 { 4500 SetLastError(ERROR_MORE_DATA); 4501 *pdwSigLen = pCryptKey->dwKeyLen; 4502 goto out; 4503 } 4504 *pdwSigLen = pCryptKey->dwKeyLen; 4505 4506 if (sDescription) { 4507 if (!RSAENH_CPHashData(hProv, hHash, (const BYTE*)sDescription, 4508 (DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0)) 4509 { 4510 goto out; 4511 } 4512 } 4513 4514 dwHashLen = sizeof(DWORD); 4515 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) goto out; 4516 4517 dwHashLen = RSAENH_MAX_HASH_SIZE; 4518 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) goto out; 4519 4520 4521 if (!build_hash_signature(pbSignature, *pdwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags)) { 4522 goto out; 4523 } 4524 4525 ret = encrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbSignature, pbSignature, RSAENH_ENCRYPT); 4526 out: 4527 RSAENH_CPDestroyKey(hProv, hCryptKey); 4528 return ret; 4529 } 4530 4531 /****************************************************************************** 4532 * CPVerifySignature (RSAENH.@) 4533 * 4534 * Verify the signature of a hash object. 4535 * 4536 * PARAMS 4537 * hProv [I] The key container, to which the hash belongs. 4538 * hHash [I] The hash for which the signature is verified. 4539 * pbSignature [I] The binary signature. 4540 * dwSigLen [I] Length of the signature BLOB. 4541 * hPubKey [I] Public key used to verify the signature. 4542 * sDescription [I] Should be NULL for security reasons. 4543 * dwFlags [I] 0, CRYPT_NOHASHOID or CRYPT_X931_FORMAT: Format of the signature. 4544 * 4545 * RETURNS 4546 * Success: TRUE (Signature is valid) 4547 * Failure: FALSE (GetLastError() == NTE_BAD_SIGNATURE, if signature is invalid) 4548 */ 4549 BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pbSignature, 4550 DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, 4551 DWORD dwFlags) 4552 { 4553 BYTE *pbConstructed = NULL, *pbDecrypted = NULL; 4554 CRYPTKEY *pCryptKey; 4555 DWORD dwHashLen; 4556 ALG_ID aiAlgid; 4557 BYTE abHashValue[RSAENH_MAX_HASH_SIZE]; 4558 BOOL res = FALSE; 4559 4560 TRACE("(hProv=%08lx, hHash=%08lx, pbSignature=%p, dwSigLen=%d, hPubKey=%08lx, sDescription=%s, " 4561 "dwFlags=%08x)\n", hProv, hHash, pbSignature, dwSigLen, hPubKey, debugstr_w(sDescription), 4562 dwFlags); 4563 4564 if (dwFlags & ~(CRYPT_NOHASHOID|CRYPT_X931_FORMAT)) { 4565 SetLastError(NTE_BAD_FLAGS); 4566 return FALSE; 4567 } 4568 4569 if (!is_valid_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER)) 4570 { 4571 SetLastError(NTE_BAD_UID); 4572 return FALSE; 4573 } 4574 4575 if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, 4576 (OBJECTHDR**)&pCryptKey)) 4577 { 4578 SetLastError(NTE_BAD_KEY); 4579 return FALSE; 4580 } 4581 4582 /* in Microsoft implementation, the signature length is checked before 4583 * the signature pointer. 4584 */ 4585 if (dwSigLen != pCryptKey->dwKeyLen) 4586 { 4587 SetLastError(NTE_BAD_SIGNATURE); 4588 return FALSE; 4589 } 4590 4591 if (!hHash || !pbSignature) 4592 { 4593 SetLastError(ERROR_INVALID_PARAMETER); 4594 return FALSE; 4595 } 4596 4597 if (sDescription) { 4598 if (!RSAENH_CPHashData(hProv, hHash, (const BYTE*)sDescription, 4599 (DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0)) 4600 { 4601 return FALSE; 4602 } 4603 } 4604 4605 dwHashLen = sizeof(DWORD); 4606 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) return FALSE; 4607 4608 dwHashLen = RSAENH_MAX_HASH_SIZE; 4609 if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) return FALSE; 4610 4611 pbConstructed = HeapAlloc(GetProcessHeap(), 0, dwSigLen); 4612 if (!pbConstructed) { 4613 SetLastError(NTE_NO_MEMORY); 4614 goto cleanup; 4615 } 4616 4617 pbDecrypted = HeapAlloc(GetProcessHeap(), 0, dwSigLen); 4618 if (!pbDecrypted) { 4619 SetLastError(NTE_NO_MEMORY); 4620 goto cleanup; 4621 } 4622 4623 if (!encrypt_block_impl(pCryptKey->aiAlgid, PK_PUBLIC, &pCryptKey->context, pbSignature, pbDecrypted, 4624 RSAENH_DECRYPT)) 4625 { 4626 goto cleanup; 4627 } 4628 4629 if (build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags) && 4630 !memcmp(pbDecrypted, pbConstructed, dwSigLen)) { 4631 res = TRUE; 4632 goto cleanup; 4633 } 4634 4635 if (!(dwFlags & CRYPT_NOHASHOID) && 4636 build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags|CRYPT_NOHASHOID) && 4637 !memcmp(pbDecrypted, pbConstructed, dwSigLen)) { 4638 res = TRUE; 4639 goto cleanup; 4640 } 4641 4642 SetLastError(NTE_BAD_SIGNATURE); 4643 4644 cleanup: 4645 HeapFree(GetProcessHeap(), 0, pbConstructed); 4646 HeapFree(GetProcessHeap(), 0, pbDecrypted); 4647 return res; 4648 } 4649 4650 /****************************************************************************** 4651 * DllRegisterServer (RSAENH.@) 4652 */ 4653 HRESULT WINAPI DllRegisterServer(void) 4654 { 4655 return __wine_register_resources( instance ); 4656 } 4657 4658 /****************************************************************************** 4659 * DllUnregisterServer (RSAENH.@) 4660 */ 4661 HRESULT WINAPI DllUnregisterServer(void) 4662 { 4663 return __wine_unregister_resources( instance ); 4664 } 4665