ReactOS  0.4.14-dev-317-g96040ec
rsaenh.c
Go to the documentation of this file.
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 
49 
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 {
64 
65 typedef struct tagCRYPTHASH
66 {
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 {
95 
96 typedef struct tagCRYPTKEY
97 {
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 {
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)
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
275  HCRYPTPROV hProv,
276  HCRYPTKEY hKey,
277  DWORD dwParam,
278  BYTE *pbData,
279  DWORD *pdwDataLen,
280  DWORD dwFlags
281 );
282 
283 BOOL WINAPI
285  HCRYPTPROV hProv,
286  HCRYPTKEY hKey,
287  HCRYPTHASH hHash,
288  BOOL Final,
289  DWORD dwFlags,
290  BYTE *pbData,
291  DWORD *pdwDataLen,
293 );
294 
295 BOOL WINAPI
297  HCRYPTPROV hProv,
298  ALG_ID Algid,
299  HCRYPTKEY hKey,
300  DWORD dwFlags,
301  HCRYPTHASH *phHash
302 );
303 
304 BOOL WINAPI
306  HCRYPTPROV hProv,
307  HCRYPTHASH hHash,
308  DWORD dwParam,
310 );
311 
312 BOOL WINAPI
314  HCRYPTPROV hProv,
315  HCRYPTHASH hHash,
316  DWORD dwParam,
317  BYTE *pbData,
318  DWORD *pdwDataLen,
319  DWORD dwFlags
320 );
321 
322 BOOL WINAPI
324  HCRYPTPROV hProv,
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,
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
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  */
361 
362 /******************************************************************************
363  * DllMain (RSAENH.@)
364  *
365  * Initializes and destroys the handle table for the CSP's handles.
366  */
368 {
369  switch (fdwReason)
370  {
371  case DLL_PROCESS_ATTACH:
375  break;
376 
377  case DLL_PROCESS_DETACH:
378  if (reserved) break;
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  {
411  *pdwBufferSize = dwParamSize;
412  return FALSE;
413  }
414  memcpy(pbBuffer, pbParam, dwParamSize);
415  }
416  *pdwBufferSize = dwParamSize;
417  return TRUE;
418 }
419 
421 {
422  KEYCONTAINER *pKeyContainer;
423 
425  (OBJECTHDR**)&pKeyContainer))
426  {
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 
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  */
477 {
478  dst->pbData = HeapAlloc(GetProcessHeap(), 0, src->cbData);
479  if (!dst->pbData) {
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  */
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) {
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  */
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) {
584  return FALSE;
585  }
586  if (src->cbInnerString)
587  memcpy((*dst)->pbInnerString, src->pbInnerString, src->cbInnerString);
588  else
590  if ((*dst)->cbOuterString == 0) (*dst)->cbOuterString = RSAENH_HMAC_DEF_PAD_LEN;
591  (*dst)->pbOuterString = HeapAlloc(GetProcessHeap(), 0, (*dst)->cbOuterString);
592  if (!(*dst)->pbOuterString) {
594  return FALSE;
595  }
596  if (src->cbOuterString)
597  memcpy((*dst)->pbOuterString, src->pbOuterString, src->cbOuterString);
598  else
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);
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) {
828  }
829  break;
830 
831  case CALG_3DES_112:
832  if (dwKeyLen == RSAENH_3DES112_EFFECTIVE_KEYLEN) {
834  }
835  if (dwKeyLen != RSAENH_3DES112_STORAGE_KEYLEN) {
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) {
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");
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);
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;
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  */
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  */
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 
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) {
1167  return FALSE;
1168  } else {
1169  HKEY hRootKey;
1171  hRootKey = HKEY_LOCAL_MACHINE;
1172  else
1173  hRootKey = HKEY_CURRENT_USER;
1174  if (!RegDeleteKeyA(hRootKey, szRegKey)) {
1176  return TRUE;
1177  } else {
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)
1203  else
1204  dwFlags = 0;
1205 
1206  if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
1207  {
1208  store_key_pair(pKeyContainer->hKeyExchangeKeyPair, hKey,
1210  store_key_pair(pKeyContainer->hSignatureKeyPair, hKey,
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  */
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 {
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) ||
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  {
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) ?
1430 
1431  if (!lookup_handle(&handle_table, hKeyContainer, RSAENH_MAGIC_CONTAINER,
1432  (OBJECTHDR**)&pKeyContainer))
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))
1444  if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE,
1445  dwProtectFlags, &hCryptKey))
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) {
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)) {
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 };
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)) {
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:
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) {
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]);
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  {
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  {
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  */
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 
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  {
1817  TRACE("Can't create new keyset, already exists\n");
1819  return FALSE;
1820  }
1821  *phProv = new_key_container(szKeyContainerName, dwFlags, pVTable);
1822  break;
1823 
1825  case CRYPT_VERIFYCONTEXT:
1826  if (pszContainer && *pszContainer) {
1827  TRACE("pszContainer should be empty\n");
1829  return FALSE;
1830  }
1831  *phProv = new_key_container("", dwFlags, pVTable);
1832  break;
1833 
1834  default:
1835  *phProv = (HCRYPTPROV)INVALID_HANDLE_VALUE;
1837  return FALSE;
1838  }
1839 
1840  if (*phProv != (HCRYPTPROV)INVALID_HANDLE_VALUE) {
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  */
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  {
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)) {
1892  return FALSE;
1893  }
1894 
1895  if ((Algid == CALG_MAC) && (GET_ALG_TYPE(pCryptKey->aiAlgid) != ALG_TYPE_BLOCK)) {
1897  return FALSE;
1898  }
1899 
1900  if ((Algid == CALG_SCHANNEL_MASTER_HASH || Algid == CALG_TLS1PRF) &&
1901  (pCryptKey->aiAlgid != CALG_TLS1_MASTER))
1902  {
1904  return FALSE;
1905  }
1906  if (Algid == CALG_SCHANNEL_MASTER_HASH &&
1907  ((!pCryptKey->siSChannelInfo.blobClientRandom.cbData) ||
1908  (!pCryptKey->siSChannelInfo.blobServerRandom.cbData)))
1909  {
1911  return FALSE;
1912  }
1913 
1914  if ((Algid == CALG_TLS1PRF) && (pCryptKey->dwState != RSAENH_KEYSTATE_MASTERKEY)) {
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,
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  */
1991 {
1992  TRACE("(hProv=%08lx, hHash=%08lx)\n", hProv, hHash);
1993 
1995  {
1997  return FALSE;
1998  }
1999 
2001  {
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  */
2024 {
2025  TRACE("(hProv=%08lx, hKey=%08lx)\n", hProv, hKey);
2026 
2028  {
2030  return FALSE;
2031  }
2032 
2034  {
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  */
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 
2067  {
2069  return FALSE;
2070  }
2071 
2073  {
2075  return FALSE;
2076  }
2077 
2078  if (!phHash || pdwReserved || dwFlags)
2079  {
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  */
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 
2123  {
2125  return FALSE;
2126  }
2127 
2128  if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pSrcKey))
2129  {
2131  return FALSE;
2132  }
2133 
2134  if (!phKey || pdwReserved || dwFlags)
2135  {
2137  return FALSE;
2138  }
2139 
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  */
2185 {
2186  CRYPTKEY *pCryptKey;
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 
2195  {
2197  return FALSE;
2198  }
2199 
2200  if (dwFlags)
2201  {
2203  return FALSE;
2204  }
2205 
2206  if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey))
2207  {
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  {
2218  return FALSE;
2219  }
2220 
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)) {
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;
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:
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) {
2287  return FALSE;
2288  }
2289  if (!pbData) {
2290  *pdwDataLen = pCryptKey->dwBlockLen;
2291  return TRUE;
2292  }
2293  if (dwBufLen < pCryptKey->dwBlockLen) {
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 {
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  */
2337 {
2338  CRYPTKEY *pCryptKey;
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 
2347  {
2349  return FALSE;
2350  }
2351 
2352  if (dwFlags)
2353  {
2355  return FALSE;
2356  }
2357 
2358  if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey))
2359  {
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  {
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:
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 {
2421  setup_key(pCryptKey);
2422  return FALSE;
2423  }
2424  }
2425  else {
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) {
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 {
2444  return FALSE;
2445  }
2446 
2447  if (Final) setup_key(pCryptKey);
2448 
2450  if (*pdwDataLen>dwMax ||
2452  }
2453 
2454  return TRUE;
2455 }
2456 
2457 static BOOL crypt_export_simple(CRYPTKEY *pCryptKey, CRYPTKEY *pPubKey,
2459 {
2460  BLOBHEADER *pBlobHeader = (BLOBHEADER*)pbData;
2461  ALG_ID *pAlgid = (ALG_ID*)(pBlobHeader+1);
2462  DWORD dwDataLen;
2463 
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) {
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 
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)) {
2506  return FALSE;
2507  }
2508 
2509  dwDataLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + pCryptKey->dwKeyLen;
2510  if (pbData) {
2511  if (*pdwDataLen < dwDataLen) {
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,
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)) {
2541  return FALSE;
2542  }
2543  if (!force && !(pCryptKey->dwPermissions & CRYPT_EXPORT))
2544  {
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) {
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 
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) {
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,
2624 {
2625  CRYPTKEY *pPubKey;
2626 
2627  if (dwFlags & CRYPT_SSL2_FALLBACK) {
2628  if (pCryptKey->aiAlgid != CALG_SSL2_MASTER) {
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  */
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 
2691  {
2693  return FALSE;
2694  }
2695 
2696  if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey))
2697  {
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  */
2718  HCRYPTKEY *dest, DWORD fStoreKey)
2719 {
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  */
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 
2767  {
2768  FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
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);
2780  return FALSE;
2781  }
2782  if (pRSAPubKey->magic != RSAENH_MAGIC_RSA2)
2783  {
2784  ERR("unexpected magic %08x\n", pRSAPubKey->magic);
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);
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  */
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 
2859  {
2860  FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
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  {
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  */
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 
2923  {
2924  FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
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  */
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 
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  {
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);
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  */
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  */
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);
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);
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) {
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 */
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  */
3257 {
3258  TRACE("(hProv=%08lx, dwLen=%d, pbBuffer=%p)\n", hProv, dwLen, pbBuffer);
3259 
3261  {
3262  /* MSDN: hProv not containing valid context handle */
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  */
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 
3300  {
3302  return FALSE;
3303  }
3304 
3305  if (dwFlags)
3306  {
3308  return FALSE;
3309  }
3310 
3312  (OBJECTHDR**)&pCryptHash))
3313  {
3315  return FALSE;
3316  }
3317 
3318  if (!pdwDataLen)
3319  {
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:
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  */
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 
3393  {
3395  return FALSE;
3396  }
3397 
3398  if (dwFlags) {
3400  return FALSE;
3401  }
3402 
3403  if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey))
3404  {
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) {
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  {
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  {
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:
3480  return FALSE;
3481  }
3482  return TRUE;
3483 
3484  case KP_SALT_EX:
3485  {
3487 
3488  /* salt length can't be greater than 184 bits = 24 bytes */
3489  if (blob->cbData > 24)
3490  {
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  {
3512  return FALSE;
3513  }
3514  keylen = *(DWORD *)pbData;
3515  if (!keylen || keylen > 1024)
3516  {
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;
3532  ret = FALSE;
3533  }
3534  pCryptKey->dwEffectiveKeyLen = keylen;
3535  setup_key(pCryptKey);
3536  return ret;
3537  }
3538  default:
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:
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  */
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 
3611  {
3613  return FALSE;
3614  }
3615 
3616  if (dwFlags) {
3618  return FALSE;
3619  }
3620 
3621  if (!lookup_handle(&handle_table, hKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pCryptKey))
3622  {
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:
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:
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  */
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) {
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  {
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:
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  {
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  {
3868  DWORD err, len, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET);
3869 
3870  if (!open_container_key(pKeyContainer->szName, flags, KEY_READ, &hKey))
3871  {
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 
3885  if (*pdwDataLen >= len) memcpy(pbData, sd, len);
3887  *pdwDataLen = len;
3888 
3889  LocalFree(sd);
3890  return TRUE;
3891  }
3892 
3893  default:
3894  /* MSDN: Unknown parameter number in dwParam */
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  */
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 
3934  {
3936  return FALSE;
3937  }
3938 
3939  if (!lookup_handle(&handle_table, hBaseData, RSAENH_MAGIC_HASH,
3940  (OBJECTHDR**)&pCryptHash))
3941  {
3943  return FALSE;
3944  }
3945 
3946  if (!phKey)
3947  {
3949  return FALSE;
3950  }
3951 
3952  switch (GET_ALG_CLASS(Algid))
3953  {
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  {
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  {
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:
4076  return FALSE;
4077  }
4078  break;
4079 
4080  default:
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  */
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:
4122  phUserKey);
4123  break;
4124 
4125  case AT_SIGNATURE:
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 */
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  */
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  {
4175  return FALSE;
4176  }
4177 
4179  (OBJECTHDR**)&pCryptHash))
4180  {
4182  return FALSE;
4183  }
4184 
4185  if (!get_algid_info(hProv, pCryptHash->aiAlgid) || pCryptHash->aiAlgid == CALG_SSL3_SHAMD5)
4186  {
4188  return FALSE;
4189  }
4190 
4191  if (pCryptHash->dwState != RSAENH_HASHSTATE_HASHING)
4192  {
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  */
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  {
4229  return FALSE;
4230  }
4231 
4232  if (dwFlags & ~CRYPT_LITTLE_ENDIAN) {
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  */
4263 {
4264  TRACE("(hProv=%08lx, dwFlags=%08x)\n", hProv, dwFlags);
4265 
4267  {
4268  /* MSDN: hProv not containing valid context handle */
4270  return FALSE;
4271  }
4272 
4273  if (dwFlags) {
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  */
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 
4313  {
4315  return FALSE;
4316  }
4317 
4318  if (dwFlags) {
4320  return FALSE;
4321  }
4322 
4324  (OBJECTHDR**)&pCryptHash))
4325  {
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:
4388  return FALSE;
4389  }
4390 }
4391 
4392 /******************************************************************************
4393  * CPSetProvParam (RSAENH.@)
4394  */
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  {
4410  DWORD err, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET);
4411  BOOL def, present;
4413  PSID owner = NULL, group = NULL;
4414  PACL dacl = NULL, sacl = NULL;
4415 
4416  if (!open_container_key(pKeyContainer->szName, flags, access, &hKey))
4417  {
4419  return FALSE;
4420  }
4421 
4422  if ((dwFlags & OWNER_SECURITY_INFORMATION && !GetSecurityDescriptorOwner(sd, &owner, &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  */
4465  LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature,
4466  DWORD *pdwSigLen)
4467 {
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 
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  {
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  {
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  */
4550  DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription,
4551  DWORD dwFlags)
4552 {
4553  BYTE *pbConstructed = NULL, *pbDecrypted = NULL;
4554  CRYPTKEY *pCryptKey;
4555