handlecontainer.cpp
上传用户:filter2008
上传日期:2013-02-01
资源大小:101k
文件大小:40k
源码类别:

CA认证

开发平台:

C/C++

  1. /****************************************************************************
  2. * library : pkcs_csp.dll
  3. * Purpose : It is a cryptographic service provider which is an independent 
  4. * software module that actually performs cryptography algorithms for 
  5. * authentication, encoding, and encryption.
  6. * This DLL can be interfaced on any PKCS#11 module.  
  7. *
  8. * Copyright (C) 2003 Ilex Syst鑝es Informatiques
  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. *
  24. * Contact :
  25. * Ilex 
  26. * 51 boulevard Voltaire
  27. * 92600 Asni鑢es-sur-Seine
  28. * pkizy@ilex.fr
  29. *
  30. * Author: Delouvrier Antoine
  31. *
  32. *******************************************************************************/
  33. /*
  34. %----------------------------------------------------------------------------
  35. % PROJECT : CSP_PKCS
  36. %
  37. % MODULE : HandleContainer
  38. %
  39. % VERSION : 1.00
  40. %
  41. % FILE : HandleContainer.cpp
  42. %
  43. % this Class allows to manage a container. When an application obtains a context
  44. % on a container it is this class which deals with thereafter all the entrance
  45. % points of the DLL for this specific container. The entrance points are redirected to 
  46. % PKCS#11 functions or to Microsoft Provider functions.
  47. %----------------------------------------------------------------------------
  48. % Version 1.00
  49. % CPX-31/03/2003-Creation
  50. %----------------------------------------------------------------------------
  51. % You can find wincrypt.h in the CSPDK which is downloadable at the adress :
  52. % http://www.microsoft.com/downloads/details.aspx?FamilyId=0F436C75-2304-42BB-B81A-BA0C2C47BAC2&displaylang=en
  53. */ 
  54. /*
  55. % Libraries ANSI or system
  56. %------------------------------
  57. */
  58. #include <windows.h>
  59. #include <stdio.h>
  60. #include "assert.h"
  61. /*
  62. % HEADER Files include
  63. %-----------------------
  64. */
  65. #include "handlecontainer.h"
  66. #include "csp_pkcs_const.h"
  67. #include "resource.h"
  68. #define CONTAINER_NAME TEXT("PKCS_CSP")
  69. extern "C" extern HINSTANCE g_hModule;
  70. typedef struct SessionKeyHeader
  71. {
  72. BLOBHEADER blobHeader;
  73. ALG_ID algid;
  74. } SessionKeyHeader, *pSessionKeyHeader;
  75. //Initialization of static member variable
  76. TableOfHandle HandleContainer::handles_Container;
  77. /*
  78. %--------------------------------------------------------------------------
  79. % HandleContainer()
  80. %
  81. % R鬺e : HandleContainer() is the constructor of the class handlecontainer
  82. %
  83. %---------------------------------------------------------------------------
  84. */
  85. HandleContainer::HandleContainer() 
  86. {
  87. }
  88. /*
  89. %--------------------------------------------------------------------------
  90. % ~HandleContainer()
  91. %
  92. % destructor 
  93. %---------------------------------------------------------------------------
  94. */
  95. HandleContainer::~HandleContainer()
  96. {
  97. TRACE(__LINE__,"~HandleContainer() ",NULL);
  98. handles_Container.RemoveEntry(this);
  99. }
  100. /*
  101. %--------------------------------------------------------------------------
  102. % Initialize
  103. %
  104. % R鬺e : Initialize est utilis閑 pour initialiser l'objet handlecontainer
  105. %
  106. % Parameters of entry  :
  107. % IN pszContainer Name of the container
  108. % IN dwFlags Value of a flag of the type(CRYPT_VERIFYCONTEXTCRYPT_NEWKEYSET),according to this value one can or not to make certain operations on the container
  109. % IN pVTable Pointer on a VTableProvStruc structure containing a list of functions callback provided by the operating software for the use of the CSP.
  110. %  
  111. % return : TRUE if the operation occurred well, FALSE if not
  112. %---------------------------------------------------------------------------
  113. */
  114. BOOL HandleContainer::CreateHandleContainer(const CHAR IN * const pszContainer,const DWORD IN dwFlags, PVTableProvStruc IN pVTable)
  115. {
  116. TRACE(__LINE__,"HandleContainer::CreateHandleContainer BEGIN : %d %d %d",pszContainer,dwFlags,pVTable);
  117. if(!AcquireMicrosoftContext()){
  118. TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
  119. return FALSE;
  120. }
  121. if((dwFlags & CRYPT_MACHINE_KEYSET) == CRYPT_MACHINE_KEYSET)
  122. {
  123. TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
  124. SetLastError(NTE_BAD_FLAGS);
  125. return FALSE;
  126. }
  127. if((dwFlags & CRYPT_VERIFYCONTEXT) == CRYPT_VERIFYCONTEXT){
  128. if(!handles_Container.AddEntry(this))
  129. {
  130. TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
  131. SetLastError(NTE_NO_MEMORY);
  132. return FALSE;
  133. }
  134. TRACE(__LINE__,"HandleContainer::CreateHandleContainer TRUE : %d %d %d",pszContainer,dwFlags,pVTable);
  135. return TRUE;
  136. }
  137. if((dwFlags & CRYPT_NEWKEYSET) == CRYPT_NEWKEYSET)
  138. {
  139. TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
  140. SetLastError(NTE_EXISTS);
  141. return FALSE;
  142. }
  143. else if((dwFlags&CRYPT_DELETEKEYSET) == CRYPT_DELETEKEYSET)
  144. {
  145. TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
  146. SetLastError(NTE_BAD_KEYSET);
  147. return FALSE;
  148. }
  149. else 
  150. {
  151. currentPContainer = Pkcs::GetContainer(pszContainer);
  152. if(!currentPContainer)
  153. {
  154. /* If the table of the containers do not exist or if it must change to release that of front*/
  155. Pkcs::FreeContainer();
  156. /* recreate a table*/
  157. Pkcs::CreateContainerTable();
  158. currentPContainer = Pkcs::GetContainer(pszContainer);
  159. int ret;
  160. while(!currentPContainer){
  161. ret=MessageBox(NULL,"Please insert the card corresponding to the selected certificate.","Insert your card",MB_OKCANCEL|MB_ICONQUESTION|MB_SYSTEMMODAL);
  162. if(ret==IDCANCEL){
  163. TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
  164. SetLastError(NTE_BAD_KEYSET);
  165. return FALSE;
  166. }
  167. /* If the table of the containers do not exist or if it must change to release that of front*/
  168. Pkcs::FreeContainer();
  169. /* recreate a table*/
  170. Pkcs::CreateContainerTable();
  171. currentPContainer = Pkcs::GetContainer(pszContainer);
  172. }
  173. }
  174. }
  175. if(!handles_Container.AddEntry(this))
  176. {
  177. TRACE(__LINE__,"HandleContainer::CreateHandleContainer ERROR : %d %d %d",pszContainer,dwFlags,pVTable);
  178. SetLastError(NTE_NO_MEMORY);
  179. return FALSE;
  180. }
  181. TRACE(__LINE__,"HandleContainer::CreateHandleContainer TRUE : %d %d %d",pszContainer,dwFlags,pVTable);
  182. return TRUE;
  183. }
  184. /*
  185. %--------------------------------------------------------------------------
  186. % AcquireMicrosoftContext
  187. %
  188. % AcquireMicrosoftContext is used to acquire a context to a microsoft provider 
  189. %  
  190. %
  191. % return : TRUE if the operation occurred well, FALSE if not
  192. %---------------------------------------------------------------------------
  193. */
  194. BOOL HandleContainer::AcquireMicrosoftContext()
  195. {
  196. CHAR szProviderName[MAX_PATH] = {0};
  197. /* Try first with enhanced provider , if it fails , try with base provider */
  198. strcpy(szProviderName,MS_ENHANCED_PROV);
  199. if(CryptAcquireContext(&microsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL, CRYPT_NEWKEYSET))
  200. {
  201. return TRUE;
  202. }
  203. /* if the container already exists, try to open it */
  204. if(NTE_EXISTS == GetLastError())
  205. {
  206. if(CryptAcquireContext(&microsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL,0))
  207. {
  208. return TRUE;
  209. }
  210. }
  211. /* the Enhanded provider is not found , try the base provider    */
  212. strcpy(szProviderName, MS_DEF_PROV);
  213. if(CryptAcquireContext(&microsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL, CRYPT_NEWKEYSET))
  214. {
  215. return TRUE;
  216. }
  217. /* if the container already exists, try to open it */
  218. if(NTE_EXISTS == GetLastError())
  219. {
  220. if(CryptAcquireContext(&microsoft_Provider, CONTAINER_NAME, szProviderName, PROV_RSA_FULL, 0))
  221. {
  222. return TRUE;
  223. }
  224. }
  225. microsoft_Provider = NULL;
  226. return FALSE;
  227. }
  228. /*
  229. %--------------------------------------------------------------------------
  230. % VerifyHandleContainer
  231. %
  232. % VerifyHandleContainer allows to check the existence of a context
  233. %
  234. % Parameters of entry  :
  235. % IN handleContainer handle to verify
  236. %  
  237. % return : TRUE if the operation occurred well, FALSE if not
  238. %---------------------------------------------------------------------------
  239. */
  240. bool HandleContainer::VerifyHandleContainer(HandleContainer* handleContainer)
  241. {
  242. TRACE(__LINE__,"HandleContainer::VerifyHandleContainer : %d ",handleContainer);
  243. return handles_Container.VerifyEntry(handleContainer);
  244. }
  245. /*
  246. %--------------------------------------------------------------------------
  247. % CreateHash
  248. %
  249. % CreateHash is used to return a handle on the creation of a hash object: 
  250. % managed by Provider Microsoft
  251. %
  252. % Parameters of entry  :
  253. % IN Algid - Algorithm used for the hashing
  254. % IN hKey - If the type of hash algorithm is a keyed hash, such as the HMAC or MAC algorithm, the key for the hash is passed in this parameter. For nonkeyed algorithms, this parameter must be set to zero 
  255. % IN dwFlags - not used
  256. % OUT phHash - address to which one copies the handle hashed object
  257. %  
  258. % return : TRUE if the operation occurred well, FALSE if not
  259. %---------------------------------------------------------------------------
  260. */
  261. BOOL HandleContainer::CreateHash(ALG_ID Algid, HCRYPTKEY hCryptKey, DWORD dwFlags, HCRYPTHASH* phHash)
  262. {
  263. TRACE(__LINE__,"HandleContainer::CreateHash ",NULL);
  264. return CryptCreateHash(microsoft_Provider,Algid, hCryptKey, dwFlags, phHash);
  265. }
  266. /*
  267. %--------------------------------------------------------------------------
  268. % DestroyHash
  269. %
  270. % DestroyHash is used to destroy a hash object:  managed by Provider Microsoft
  271. %
  272. % Parameters of entry  :
  273. % IN hHash - Handle on a hash object to be destroyed
  274. %  
  275. % return : TRUE if the operation occurred well, FALSE if not
  276. %---------------------------------------------------------------------------
  277. */
  278. BOOL HandleContainer::DestroyHash(HCRYPTHASH hHash)
  279. {
  280. TRACE(__LINE__,"HandleContainer::DestroyHash ",NULL);
  281. return CryptDestroyHash(hHash);
  282. }
  283. /*
  284. %--------------------------------------------------------------------------
  285. % GetHashParam
  286. %
  287. % GetHashParam seeks data about the operations of a hash object.  The actual
  288. % value of the hashing can be obtained by using this function: 
  289. % managed by Provider Microsoft
  290. %
  291. % Parameters of entry  :
  292. % IN hHash - Handle on a hashed object
  293. % IN ulParametre  - value of the parameter
  294. % IN pulDataLen   - Length of the parameter pucData 
  295. % IN ulFlags - Values of the flag 
  296. %
  297. % Parameters of exit :
  298. % OUT pucData - Address to which the function copies the data corresponding to the ulParametre
  299. %  
  300. % return : TRUE if the operation occurred well, FALSE if not
  301. %---------------------------------------------------------------------------
  302. */
  303. BOOL HandleContainer::GetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE* pbData, DWORD*pdwDataLen, DWORD dwFlags)
  304. {
  305. TRACE(__LINE__,"HandleContainer::GetHashParam ",NULL);
  306. return CryptGetHashParam(hHash, dwParam, pbData, pdwDataLen, dwFlags);
  307. }
  308. /*
  309. %--------------------------------------------------------------------------
  310. % HashData
  311. %
  312. % HashData is used to carry out a hashing starting from a handle on a hash object:
  313. % managed by Provider Microsoft
  314. %
  315. % Parameters of entry  :
  316. % IN hHash - Handle on a hashed object
  317. % IN pbData - address containing the data to be hashed
  318. % IN cbDataLen - length in bytes of the data to be hashed
  319. % IN dwFlags - not used
  320. %  
  321. % return : TRUE if the operation occurred well, FALSE if not
  322. %---------------------------------------------------------------------------
  323. */
  324. BOOL HandleContainer::HashData(HCRYPTHASH hHash, CONST BYTE* pbData, DWORD dwDatalen, DWORD dwFlags)
  325. {
  326. TRACE(__LINE__,"HandleContainer::HashData ",NULL);
  327. return CryptHashData(hHash, pbData, dwDatalen, dwFlags);
  328. }
  329. /*
  330. %--------------------------------------------------------------------------
  331. % SetHashParam
  332. %
  333. % SetHashParam adapts the operations to the customer requirements of the hashed data: 
  334. % managed by Provider Microsoft
  335. %
  336. % Parameters of entry  :
  337. % IN hHash - Handle on a hash object
  338. % IN ulParametre  - value of the parameter
  339. % IN pucData - Pointer on data corresponding to the last ulParametre   
  340. % IN ulFlags - Values of the flag 
  341. %
  342. % return : TRUE if the operation occurred well, FALSE if not
  343. %---------------------------------------------------------------------------
  344. */
  345. BOOL HandleContainer::SetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE*pbData, DWORD dwFlags)
  346. {
  347. TRACE(__LINE__,"HandleContainer::SetHashParam ",NULL);
  348. return CryptSetHashParam(hHash,dwParam,pbData,dwFlags);
  349. }
  350. BOOL HandleContainer::GetProvParam(DWORD dwParam, BYTE* pbData, DWORD* pdwDataLen, DWORD dwFlags)
  351. {
  352. switch(dwParam)
  353. {
  354. case PP_ENUMALGS:
  355. TRACE(__LINE__,"HandleContainer::CryptGetProvParam  PP_ENUMALGS",NULL);
  356. return CryptGetProvParam(microsoft_Provider, PP_ENUMALGS, pbData, pdwDataLen, dwFlags);
  357. case PP_ENUMALGS_EX:
  358. TRACE(__LINE__,"HandleContainer::CryptGetProvParam  PP_ENUMALGS_EX",NULL);
  359. return CryptGetProvParam(microsoft_Provider, PP_ENUMALGS_EX, pbData, pdwDataLen, dwFlags);
  360. case PP_PROVTYPE :
  361. TRACE(__LINE__,"HandleContainer::CryptGetProvParam  PP_PROVTYPE",NULL);
  362. return FALSE;
  363. default:
  364. SetLastError(NTE_BAD_TYPE);
  365. return FALSE;
  366. }
  367. return FALSE;
  368. }
  369. /*
  370. %--------------------------------------------------------------------------
  371. % Encrypt
  372. %
  373. % Encrypt is used to cipher  data:  managed by Provider Microsoft
  374. %
  375. % Parameters of entry  :
  376. %             IN  hKey -  Handle on a key of session used for coding
  377. % IN hHash - Handle on a hash object if one wants to carry out a hash data before coding
  378. % IN Final - Boolean allowing to know if it is the last part to be ciphered
  379. % IN dwFlags - not used
  380. % INOUT pbData - data to be ciphered
  381. % INOUT pdwDataLen - length of  data to be ciphered
  382. % IN dwBufLen - length of the data pbData in bytes
  383. %  
  384. % return : TRUE if the operation occurred well, FALSE if not
  385. %---------------------------------------------------------------------------
  386. */
  387. BOOL HandleContainer::Encrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE* pbData, DWORD*pdwDataLen, DWORD dwBufLen)
  388. {
  389. TRACE(__LINE__,"HandleContainer::Encrypt ",NULL);
  390. return CryptEncrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
  391. }
  392. /*
  393. %--------------------------------------------------------------------------
  394. % Decrypt
  395. %
  396. % Decrypt is used to decipher data:  managed by Provider Microsoft
  397. %
  398. % Parameters of entry  :
  399. %             IN  hKey -  Handle on a key of session used for the deciphering
  400. % IN hHash - Handle on a hash object if one wants to carry out a hash data after the deciphering
  401. % IN Final - Boolean allowing to know if it is the last part to be deciphered
  402. % IN dwFlags - not used
  403. % INOUT pbData -data to be  deciphereddata deciphered
  404. % INOUT pdwDataLen -length of data to be  deciphereddata deciphered
  405. %  
  406. % return : TRUE if the operation occurred well, FALSE if not
  407. %---------------------------------------------------------------------------
  408. */
  409. BOOL HandleContainer::Decrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE*pbData, DWORD*pdwDataLen)
  410. {
  411. TRACE(__LINE__,"HandleContainer::Decrypt ",NULL);
  412. return CryptDecrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
  413. }
  414. /*
  415. %--------------------------------------------------------------------------
  416. % SignHash
  417. %
  418. % SignHash is used to carry out the signature of one starting from a handle on a hash object.
  419. %
  420. % Parameters of entry  :
  421. % IN hHash - Handle on the hash object to be signed
  422. % IN dwKeySpec -type of key to use to sign(AT_KEYEXCHANGEAT_SIGNATURE)
  423. % IN szDescription - not used
  424. % IN dwFlags - not used
  425. % OUT pbSignature - pointer on the signed data
  426. % OUT pdwSigLen - address of a DWORD containing the length of the signed data
  427. %  
  428. % return : TRUE if the operation occurred well, FALSE if not
  429. %---------------------------------------------------------------------------
  430. */
  431. BOOL HandleContainer::SignHash(HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE*pbSignature, DWORD* pdwSigLen)
  432. {
  433. TRACE(__LINE__,"HandleContainer::SignHash BEGIN ",NULL);
  434. ALG_ID algidHash;
  435. unsigned long dwBufferLen;
  436. LPBYTE pbyHash = NULL;
  437. unsigned long dwHashLen;
  438. const BYTE * pbyOID = NULL;
  439. unsigned long dwOIDLen = 0;
  440. BOOL bRet = FALSE;
  441. dwBufferLen = sizeof(algidHash);
  442. if(!CryptGetHashParam(hHash, HP_ALGID, (LPBYTE)&algidHash, &dwBufferLen, 0))
  443. {
  444. TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
  445. SetLastError(NTE_BAD_HASH);
  446. return FALSE;
  447. }
  448. dwBufferLen = sizeof(dwHashLen);
  449. if(!CryptGetHashParam(hHash, HP_HASHSIZE, (LPBYTE)&dwHashLen, &dwBufferLen, 0))
  450. {
  451. TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
  452. SetLastError(NTE_BAD_HASH);
  453. return FALSE;
  454. }
  455. switch(algidHash)
  456. {
  457. case CALG_SSL3_SHAMD5:
  458. dwOIDLen = 0;
  459. break;
  460. case CALG_MD2:
  461. pbyOID = &derEncodedMD2[0];
  462. dwOIDLen = sizeof(derEncodedMD2);
  463. break;
  464. case CALG_MD5:
  465. pbyOID = &derEncodedMD5[0];
  466. dwOIDLen = sizeof(derEncodedMD5);
  467. break;
  468. case CALG_SHA1:
  469. pbyOID = &derEncodedSHA1[0];
  470. dwOIDLen = sizeof(derEncodedSHA1);
  471. break;
  472. default:
  473. SetLastError(NTE_BAD_ALGID);
  474. return FALSE;
  475. }
  476. pbyHash = new BYTE[dwHashLen + dwOIDLen];
  477. if(!pbyHash)
  478. {
  479. TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
  480. SetLastError(NTE_FAIL);
  481. return FALSE;
  482. }
  483. if(pbyOID)
  484. memcpy(pbyHash, pbyOID, dwOIDLen);
  485. if(!CryptGetHashParam(hHash, HP_HASHVAL, pbyHash+dwOIDLen, &dwHashLen, 0))
  486. {
  487. TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
  488. SetLastError(NTE_BAD_HASH);
  489. if(pbyHash)
  490. free(pbyHash);
  491. return FALSE;
  492. }
  493. if(!Pkcs::DoSign(currentPContainer,dwHashLen + dwOIDLen, pbyHash, dwKeySpec,pbSignature,pdwSigLen))
  494. {
  495. TRACE(__LINE__,"HandleContainer::SignHash FALSE ",NULL);
  496. SetLastError(NTE_FAIL);
  497. if(pbyHash)
  498. free(pbyHash);
  499. return FALSE;
  500. }
  501. TRACE(__LINE__,"HandleContainer::SignHash TRUE ",NULL);
  502. return TRUE;
  503. }
  504. /*
  505. %--------------------------------------------------------------------------
  506. % VerifySignature
  507. %
  508. % VerifySignature is used to check a signature: managed by Provider Microsoft
  509. %
  510. % Parameters of entry  :
  511. % IN hHash - Handle on a hash object to be checked
  512. % IN pbSignature - buffer containing the signature
  513. % IN dwSigLen - length in bytes of the signature
  514. % IN hPubKey - Handle on the public key with used to check the signature
  515. % IN sDescription - not used
  516. % IN dwFlags - not used
  517. %  
  518. % return : TRUE if the operation occurred well, FALSE if not
  519. %---------------------------------------------------------------------------
  520. */
  521. BOOL HandleContainer::VerifySignature(HCRYPTHASH hHash, CONST BYTE* pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey,LPCTSTR sDescription, DWORD dwFlags)
  522. {
  523. TRACE(__LINE__,"HandleContainer::VerifySignature ",NULL);
  524. return CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey,sDescription, dwFlags);
  525. }
  526. /*
  527. %--------------------------------------------------------------------------
  528. % DestroyKey
  529. %
  530. % The DestroyKey function releases the handle referred by the parameter hKey:  managed by Provider Microsoft
  531. %
  532. % Parameters of entry  :
  533. % IN phKey - Handle on the key
  534. %  
  535. % return : TRUE if the operation occurred well, FALSE if not
  536. %---------------------------------------------------------------------------
  537. */
  538. BOOL HandleContainer::DestroyKey(HCRYPTKEY hKey)
  539. {
  540. TRACE(__LINE__,"HandleContainer::DestroyKey ",NULL);
  541. return CryptDestroyKey(hKey);
  542. }
  543. /*
  544. %--------------------------------------------------------------------------
  545. % ImportKey
  546. %
  547. % ImportKey import keys of a "Keyblob" towards a container of key
  548. %
  549. % Parameters of entry  :
  550. %             IN  pbData -  data of "Keyblob"
  551. % IN  dwDataLen -  length of data
  552. % IN  hPubKey -  Handle on a key public of exchange of the user recipient
  553. %                 IN  dwFlags -  Flags values
  554. %
  555. % Parameters of exit  :
  556. % OUT phKey - Address to which the function copies the handle key to be imported
  557. %  
  558. % return : TRUE if the operation occurred well, FALSE if not
  559. %---------------------------------------------------------------------------
  560. */
  561. BOOL HandleContainer::ImportKey(BYTE* pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY* phKey)
  562. {
  563. DWORD i,j;
  564. HCRYPTPROV hProv_m = 0;
  565. HCRYPTKEY hPubPrivKey = 0;
  566.     BOOL fResult;
  567. TRACE(__LINE__,"HandleContainer::ImportKey BEGIN ",NULL);
  568.    
  569. if(!pbData)
  570. {
  571. TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
  572. SetLastError(NTE_FAIL);
  573. return FALSE;
  574. }
  575. /*If it's a PUBLICKEYBLOB import it into the base provider.*/
  576. pSessionKeyHeader pskh = (pSessionKeyHeader)pbData;
  577. if(PUBLICKEYBLOB == pskh->blobHeader.bType || !hPubKey)
  578. return CryptImportKey(microsoft_Provider, pbData, dwDataLen, hPubKey, dwFlags, phKey);
  579. /*If it's not a SIMPLEBLOB we don't know what to do with it.*/
  580. if(SIMPLEBLOB != pskh->blobHeader.bType)
  581. {
  582. TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
  583. SetLastError(NTE_BAD_TYPE);
  584. return FALSE;
  585. }
  586. /*We only know how to deal with RSA keys.*/
  587. if(CALG_RSA_KEYX != pskh->algid)
  588. {
  589. TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
  590. SetLastError(NTE_BAD_TYPE);
  591. return FALSE;
  592. }
  593. BOOL bRet = FALSE;
  594. //Wrapped blob size.
  595. DWORD wEncryptedDataLength = (DWORD)(dwDataLen - sizeof(SessionKeyHeader));
  596. BYTE* pKeySource = pbData + sizeof(SessionKeyHeader);
  597. BYTE* pbyDecryptedData = new BYTE[wEncryptedDataLength];
  598. DWORD wDecryptedDataLength = wEncryptedDataLength;
  599. if(!pbyDecryptedData)
  600. {
  601. TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
  602. SetLastError(NTE_FAIL);
  603. if(pbyDecryptedData)
  604. delete [] pbyDecryptedData;
  605. return FALSE;
  606. }
  607. /*reversal of the block pKeySource */
  608. for (i=wEncryptedDataLength-1, j=0; i > j; --i, ++j)
  609. {
  610. BYTE bTmp = pKeySource[i];
  611. pKeySource[i] = pKeySource[j];
  612. pKeySource[j] = bTmp;
  613. }
  614. if(!Pkcs::Decrypt(hPubKey, pKeySource, wEncryptedDataLength, pbyDecryptedData, &wDecryptedDataLength))
  615. {
  616. TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
  617. SetLastError(NTE_BAD_ALGID);
  618. if(pbyDecryptedData)
  619. delete [] pbyDecryptedData;
  620. return FALSE;
  621. }
  622. LPTSTR MicroProvider;
  623. // Try to create new container
  624. if(pskh->blobHeader.aiKeyAlg==CALG_RC2 && wDecryptedDataLength==5)
  625. MicroProvider="Microsoft Base Cryptographic Provider v1.0";
  626. else
  627. MicroProvider="Microsoft Enhanced Cryptographic Provider v1.0";
  628.     
  629. fResult =CreatePrivateExponentOneKey(MicroProvider, PROV_RSA_FULL,
  630.                                             "importKey", AT_KEYEXCHANGE, 
  631.                                             &hProv_m, &hPubPrivKey);
  632. if(!fResult)
  633.     {
  634.        TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
  635.    SetLastError(NTE_FAIL);
  636.    if(pbyDecryptedData)
  637. delete [] pbyDecryptedData;
  638.    return FALSE;
  639.        
  640.     }
  641.  // Import this key and get an HCRYPTKEY handle
  642.      if (!ImportPlainSessionBlob(hProv_m, hPubPrivKey,pskh->blobHeader.aiKeyAlg , pbyDecryptedData, wDecryptedDataLength, phKey))
  643.      {
  644. TRACE(__LINE__,"HandleContainer::ImportKey FALSE ",NULL);
  645. SetLastError(NTE_FAIL);
  646. if(pbyDecryptedData)
  647. delete [] pbyDecryptedData;
  648.     return FALSE;
  649.      }
  650.  
  651. bRet = TRUE;
  652.     if(pbyDecryptedData)
  653. delete [] pbyDecryptedData;
  654. TRACE(__LINE__,"HandleContainer::ImportKey TRUE ",NULL);
  655. return bRet;
  656. }
  657. /*
  658. %--------------------------------------------------------------------------
  659. % GetKeyParam
  660. %
  661. % GetKeyParam seeks the data which govern the operations of a key:  manage by Provider Microsoft
  662. %
  663. % Parameters of entry  :
  664. % IN hKey     - Handle on the key
  665. % IN ulParametre  - value of parameter
  666. % IN pulDataLen   - length of the parameter pucData 
  667. % IN ulFlags - values of the flag 
  668. %
  669. % Parameters of exit  :
  670. % OUT pucData - Address to which the function copies the data corresponding to the ulFlags
  671. %  
  672. % return : TRUE if the operation occurred well, FALSE if not
  673. %---------------------------------------------------------------------------
  674. */
  675. BOOL HandleContainer::GetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE* pbData, DWORD* pdwDataLen, DWORD dwFlags)
  676. {
  677. TRACE(__LINE__,"HandleContainer::GetKeyParam",NULL);
  678. return CryptGetKeyParam(hKey, dwParam, pbData, pdwDataLen, dwFlags);
  679. }
  680. /*
  681. %--------------------------------------------------------------------------
  682. % SetKeyParam
  683. %
  684. % SetKeyParam adapt the operations to the customer requirements of a key:  
  685. % manage by Provider Microsoft
  686. %
  687. % Parameters of entry  :
  688. % IN hKey     - Handle on a key
  689. % IN ulParametre  - value of the parameter
  690. % IN pucData - Pointer containing the data which correspond to the value 
  691. %                                         of parameter dwParam
  692. % IN ulFlags - Values of the flag (not used)
  693. %
  694. % return : TRUE if the operation occurred well, FALSE if not
  695. %---------------------------------------------------------------------------
  696. */
  697. BOOL HandleContainer::SetKeyParam(HCRYPTKEY hKey, DWORD dwParam,CONST BYTE*pbData, DWORD dwFlags)
  698. {
  699. TRACE(__LINE__,"HandleContainer::SetKeyParam",NULL);
  700. return CryptSetKeyParam(hKey, dwParam, pbData, dwFlags);
  701. }
  702. /*
  703. %--------------------------------------------------------------------------
  704. % GetUserKey
  705. %
  706. % GetUserKey is used to return a handle on the pair of key of the user
  707. %
  708. % Parameters of entry  :
  709. % IN dwKeySpec - desired type of key (AT_KEYEXCHANGEAT_SIGNATURE)
  710. % OUT phUserKey - address to which is copied the handle desired key
  711. %  
  712. % return : TRUE if the operation occurred well, FALSE if not
  713. %---------------------------------------------------------------------------
  714. */
  715. BOOL HandleContainer::GetUserKey(DWORD dwKeySpec, HCRYPTKEY* phUserKey)
  716. {
  717. TRACE(__LINE__,"HandleContainer::GetUserKey BEGIN",NULL);
  718.    if(!(currentPContainer->GetUserKey(dwKeySpec,phUserKey)))
  719.    {
  720.    TRACE(__LINE__,"HandleContainer::GetUserKey FALSE",NULL);
  721.    SetLastError(NTE_NO_KEY);
  722.        return FALSE;
  723.    }
  724.    TRACE(__LINE__,"HandleContainer::GetUserKey TRUE",NULL);
  725.    return TRUE;
  726. }
  727. /*
  728. %--------------------------------------------------------------------------
  729. % CreatePrivateExponentOneKey
  730. %
  731. % CreatePrivateExponentOneKey is used to create a key private which carries
  732. % out during coding the identity
  733. %
  734. % Parameters of entry  :
  735. % IN szProvider Name of provider
  736. % IN dwProvType
  737. % IN szContainer Name of container
  738. % IN dwKeySpec type of key
  739. % IN hProv handle to the provider
  740. % IN hPrivateKey handle to the private key
  741. %
  742. %  
  743. % return : TRUE if the operation occurred well, FALSE if not
  744. %---------------------------------------------------------------------------
  745. */
  746. BOOL HandleContainer::CreatePrivateExponentOneKey(LPTSTR szProvider,DWORD dwProvType,LPTSTR szContainer,DWORD dwKeySpec,HCRYPTPROV *hProv,HCRYPTKEY *hPrivateKey)
  747. {
  748.    BOOL fReturn = FALSE;
  749.    BOOL fResult;
  750.    int n;
  751.    LPBYTE keyblob = NULL;
  752.    DWORD dwkeyblob;
  753.    DWORD dwBitLen;
  754.    BYTE *ptr;
  755.    TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey BEGIN",NULL);
  756.    __try
  757.    {
  758.       *hProv = 0;
  759.       *hPrivateKey = 0;
  760.       if ((dwKeySpec != AT_KEYEXCHANGE) && (dwKeySpec != AT_SIGNATURE))  __leave;
  761.       // Try to create new container
  762.       fResult = CryptAcquireContext(hProv, szContainer, szProvider, 
  763.                                     dwProvType, CRYPT_NEWKEYSET);
  764.       if (!fResult)
  765.       {
  766.          // If the container exists, open it
  767.          if (GetLastError() == NTE_EXISTS)
  768.          {
  769.             fResult = CryptAcquireContext(hProv, szContainer, szProvider, dwProvType, 0);
  770.             if (!fResult)
  771.             {
  772.   TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
  773.                // No good, leave
  774.                __leave;
  775.             }
  776.          }
  777.          else
  778.          {
  779. TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
  780.             // No good, leave
  781.             __leave;
  782.          }
  783.       }
  784.       // Generate the private key
  785.       fResult = CryptGenKey(*hProv, dwKeySpec, CRYPT_EXPORTABLE, hPrivateKey);
  786.       if (!fResult){
  787.   TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
  788. __leave;
  789.   }
  790.       // Export the private key, we'll convert it to a private
  791.       // exponent of one key
  792.       fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwkeyblob);
  793.       if (!fResult){
  794. TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
  795.   __leave;  
  796.   }
  797.       keyblob = (LPBYTE)LocalAlloc(LPTR, dwkeyblob);
  798.       if (!keyblob){
  799. TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
  800.   __leave;
  801.   }
  802.       fResult = CryptExportKey(*hPrivateKey, 0, PRIVATEKEYBLOB, 0, keyblob, &dwkeyblob);
  803.       if (!fResult){
  804. TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
  805.   __leave;
  806.   }
  807.       CryptDestroyKey(*hPrivateKey);
  808.       *hPrivateKey = 0;
  809.       // Get the bit length of the key
  810.       memcpy(&dwBitLen, &keyblob[12], 4);      
  811.       // Modify the Exponent in Key BLOB format
  812.       // Key BLOB format is documented in SDK
  813.       // Convert pubexp in rsapubkey to 1
  814.       ptr = &keyblob[16];
  815.       for (n = 0; n < 4; n++)
  816.       {
  817.          if (n == 0) ptr[n] = 1;
  818.          else ptr[n] = 0;
  819.       }
  820.       // Skip pubexp
  821.       ptr += 4;
  822.       // Skip modulus, prime1, prime2
  823.       ptr += (dwBitLen/8);
  824.       ptr += (dwBitLen/16);
  825.       ptr += (dwBitLen/16);
  826.       // Convert exponent1 to 1
  827.       for (n = 0; n < (dwBitLen/16); n++)
  828.       {
  829.          if (n == 0) ptr[n] = 1;
  830.          else ptr[n] = 0;
  831.       }
  832.       // Skip exponent1
  833.       ptr += (dwBitLen/16);
  834.       // Convert exponent2 to 1
  835.       for (n = 0; n < (dwBitLen/16); n++)
  836.       {
  837.          if (n == 0) ptr[n] = 1;
  838.          else ptr[n] = 0;
  839.       }
  840.       // Skip exponent2, coefficient
  841.       ptr += (dwBitLen/16);
  842.       ptr += (dwBitLen/16);
  843.       // Convert privateExponent to 1
  844.       for (n = 0; n < (dwBitLen/8); n++)
  845.       {
  846.          if (n == 0) ptr[n] = 1;
  847.          else ptr[n] = 0;
  848.       }
  849.       
  850.       // Import the exponent-of-one private key.      
  851.       if (!CryptImportKey(*hProv, keyblob, dwkeyblob, 0, 0, hPrivateKey))
  852.       {   
  853. TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey FALSE",NULL);
  854.          __leave;
  855.       }
  856.       TRACE(__LINE__,"HandleContainer::CreatePrivateExponentOneKey TRUE",NULL);
  857.       fReturn = TRUE;
  858.    }
  859.    __finally
  860.    {
  861.       if (keyblob) LocalFree(keyblob);
  862.       if (!fReturn)
  863.       {
  864.          if (*hPrivateKey) CryptDestroyKey(*hPrivateKey);
  865.          if (*hProv) CryptReleaseContext(*hProv, 0);
  866.       }
  867.    }
  868.    return fReturn;
  869. }
  870. /*
  871. %--------------------------------------------------------------------------
  872. % ImportPlainSessionBlob
  873. %
  874. % ImportPlainSessionBlob is used to import a key of session in light in a provider
  875. % microsoft
  876. %
  877. % Parameters of entry  :
  878. % IN hProv handle to the provider
  879. % IN hPrivateKey handle to the private key
  880. % IN dwAlgId Algo ID
  881. % IN pbKeyMaterial key
  882. % IN dwKeyMaterial length of the key
  883. % IN handle to the sessionKey
  884. %  
  885. % return : TRUE if the operation occurred well, FALSE if not
  886. %---------------------------------------------------------------------------
  887. */
  888. BOOL HandleContainer::ImportPlainSessionBlob(HCRYPTPROV hProv,
  889.                             HCRYPTKEY hPrivateKey,
  890.                             ALG_ID dwAlgId,
  891.                             LPBYTE pbKeyMaterial ,
  892.                             DWORD dwKeyMaterial ,
  893.                             HCRYPTKEY *hSessionKey)
  894. {
  895.    BOOL fResult;   
  896.    BOOL fReturn = FALSE;
  897.    BOOL fFound = FALSE;
  898.    LPBYTE pbSessionBlob = NULL;
  899.    DWORD dwSessionBlob, dwSize, n;
  900.    DWORD dwPublicKeySize;
  901.    DWORD dwProvSessionKeySize;
  902.    ALG_ID dwPrivKeyAlg;
  903.    LPBYTE pbPtr; 
  904.    DWORD dwFlags = CRYPT_FIRST;
  905.    PROV_ENUMALGS_EX ProvEnum;
  906.    HCRYPTKEY hTempKey = 0;
  907.   TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob BEGIN",NULL);
  908.    __try
  909.    {
  910.       // Double check to see if this provider supports this algorithm
  911.       // and key size
  912.       do
  913.       {        
  914.          dwSize = sizeof(ProvEnum);
  915.          fResult = CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum,
  916.                                      &dwSize, dwFlags);
  917.          if (!fResult) break;
  918.          dwFlags = 0;
  919.          if (ProvEnum.aiAlgid == dwAlgId) fFound = TRUE;
  920.                                      
  921.       } while (!fFound);
  922.       if (!fFound){
  923. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  924.   __leave;
  925.   }
  926.       // We have to get the key size(including padding)
  927.       // from an HCRYPTKEY handle.  PP_ENUMALGS_EX contains
  928.       // the key size without the padding so we can't use it.
  929.   if(dwAlgId==CALG_RC2 && dwKeyMaterial==5)
  930.   {
  931.   fResult = CryptGenKey(hProv, dwAlgId, CRYPT_NO_SALT, &hTempKey);
  932.   if (!fResult){
  933.    TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  934.   __leave;
  935.   }
  936.   }
  937.   else
  938.   {
  939.   fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);
  940.   if (!fResult){
  941. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  942.   __leave;
  943.   }
  944.   }
  945.       /*fResult = CryptGenKey(hProv, dwAlgId, 0, &hTempKey);
  946.       if (!fResult){
  947. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  948.   __leave;
  949.   }*/
  950.       dwSize = sizeof(DWORD);
  951.       fResult = CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize,
  952.                                  &dwSize, 0);
  953.       if (!fResult){
  954. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  955.   __leave;
  956.   }      
  957.       CryptDestroyKey(hTempKey);
  958.       hTempKey = 0;
  959.       // Our key is too big, leave
  960.       if ((dwKeyMaterial * 8) > dwProvSessionKeySize){
  961. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  962.   __leave;
  963.   }
  964.       // Get private key's algorithm
  965.       dwSize = sizeof(ALG_ID);
  966.       fResult = CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0);
  967.       if (!fResult){
  968. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  969.   __leave;
  970.   }
  971.       // Get private key's length in bits
  972.       dwSize = sizeof(DWORD);
  973.       fResult = CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0);
  974.       if (!fResult){
  975. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  976.   __leave;
  977.   }
  978.       // calculate Simple blob's length
  979.       dwSessionBlob = (dwPublicKeySize/8) + sizeof(ALG_ID) + sizeof(BLOBHEADER);
  980.       // allocate simple blob buffer
  981.       pbSessionBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob);
  982.       if (!pbSessionBlob) {
  983. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  984.   __leave;
  985.   }
  986.       pbPtr = pbSessionBlob;
  987.       // SIMPLEBLOB Format is documented in SDK
  988.       // Copy header to buffer
  989.       ((BLOBHEADER *)pbPtr)->bType = SIMPLEBLOB;
  990.       ((BLOBHEADER *)pbPtr)->bVersion = 2;
  991.       ((BLOBHEADER *)pbPtr)->reserved = 0;
  992.       ((BLOBHEADER *)pbPtr)->aiKeyAlg = dwAlgId;
  993.       pbPtr += sizeof(BLOBHEADER);
  994.       // Copy private key algorithm to buffer
  995.       *((DWORD *)pbPtr) = dwPrivKeyAlg;
  996.       pbPtr += sizeof(ALG_ID);
  997.   
  998.       // Place the key material in reverse order
  999.       for (n = 0; n < dwKeyMaterial; n++)
  1000.       {
  1001.          pbPtr[n] = pbKeyMaterial[dwKeyMaterial-n-1];
  1002.       }
  1003.   
  1004.  
  1005.       // 3 is for the first reserved byte after the key material + the 2 reserved bytes at the end.
  1006.       dwSize = dwSessionBlob - (sizeof(ALG_ID) + sizeof(BLOBHEADER) + dwKeyMaterial+ 3);
  1007.       pbPtr +=dwKeyMaterial+1;
  1008.       // Generate random data for the rest of the buffer
  1009.       // (except that last two bytes)
  1010.       fResult = CryptGenRandom(hProv, dwSize, pbPtr);
  1011.       if (!fResult){
  1012. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  1013.   __leave;
  1014.   }
  1015.       for (n = 0; n < dwSize; n++)
  1016.       {
  1017.          if (pbPtr[n] == 0) pbPtr[n] = 1;
  1018.       }
  1019.       pbSessionBlob[dwSessionBlob - 2] = 2;
  1020.   if(dwAlgId==CALG_RC2 && dwKeyMaterial==5)
  1021.   {
  1022.   TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob CALG RC2 40 Bits",NULL);
  1023.       fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob, 
  1024.                                hPrivateKey, CRYPT_EXPORTABLE|CRYPT_NO_SALT, hSessionKey);
  1025.   if (!fResult) {
  1026.    TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  1027.   __leave;
  1028. }
  1029.   }
  1030.   else{
  1031.       fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob, 
  1032.                                hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);
  1033.   if (!fResult) {
  1034.    TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  1035.   __leave;
  1036. }
  1037.   }
  1038.      /*fResult = CryptImportKey(hProv, pbSessionBlob , dwSessionBlob, 
  1039.                                hPrivateKey, CRYPT_EXPORTABLE, hSessionKey);
  1040.       if (!fResult) {
  1041. TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob FALSE",NULL);
  1042.   __leave;
  1043.   }*/
  1044.   TRACE(__LINE__,"HandleContainer::ImportPlainSessionBlob TRUE",NULL);
  1045.       fReturn = TRUE;           
  1046.    }
  1047.    __finally
  1048.    {
  1049.       if (hTempKey) CryptDestroyKey(hTempKey);
  1050.       if (pbSessionBlob) LocalFree(pbSessionBlob);
  1051.    }
  1052.    
  1053.    return fReturn;
  1054. }
  1055. /*
  1056. %--------------------------------------------------------------------------
  1057. % ExportPlainSessionBlob
  1058. %
  1059. % ExportPlainSessionBlob is used to export a key of session in light
  1060. %
  1061. % Parameters of entry  :
  1062. % IN hPublicKey handle to the public key
  1063. % IN hSessionKey handle to the session key
  1064. % IN pbKeyMaterial key
  1065. % IN dwKeyMaterial length of the key
  1066. %  
  1067. % return : TRUE if the operation occurred well, FALSE if not
  1068. %---------------------------------------------------------------------------
  1069. */
  1070. BOOL HandleContainer::ExportPlainSessionBlob(HCRYPTKEY hPublicKey,
  1071.                             HCRYPTKEY hSessionKey,
  1072.                             LPBYTE *pbKeyMaterial ,
  1073.                             DWORD *dwKeyMaterial )
  1074. {
  1075.    BOOL fReturn = FALSE;
  1076.    BOOL fResult;
  1077.    DWORD dwSize, n;
  1078.    LPBYTE pbSessionBlob = NULL;
  1079.    DWORD dwSessionBlob;
  1080.    LPBYTE pbPtr;
  1081.    __try
  1082.    {
  1083.       *pbKeyMaterial  = NULL;
  1084.       *dwKeyMaterial  = 0;
  1085.       fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,
  1086.                                0, NULL, &dwSessionBlob );
  1087.       if (!fResult) __leave;
  1088.       pbSessionBlob  = (LPBYTE)LocalAlloc(LPTR, dwSessionBlob );
  1089.       if (!pbSessionBlob) __leave;
  1090.       fResult = CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB,
  1091.                                0, pbSessionBlob , &dwSessionBlob );
  1092.       if (!fResult) __leave;
  1093.       // Get session key size in bits
  1094.       dwSize = sizeof(DWORD);
  1095.       fResult = CryptGetKeyParam(hSessionKey, KP_KEYLEN, (LPBYTE)dwKeyMaterial, &dwSize, 0);
  1096.       if (!fResult) __leave;
  1097.       // Get the number of bytes and allocate buffer
  1098.       *dwKeyMaterial /= 8;
  1099.       *pbKeyMaterial = (LPBYTE)LocalAlloc(LPTR, *dwKeyMaterial);
  1100.       if (!*pbKeyMaterial) __leave;
  1101.       // Skip the header
  1102.       pbPtr = pbSessionBlob;
  1103.       pbPtr += sizeof(BLOBHEADER);
  1104.       pbPtr += sizeof(ALG_ID);
  1105.       // We are at the beginning of the key
  1106.       // but we need to start at the end since 
  1107.       // it's reversed
  1108.       pbPtr += (*dwKeyMaterial - 1);
  1109.       
  1110.       // Copy the raw key into our return buffer      
  1111.       for (n = 0; n < *dwKeyMaterial; n++)
  1112.       {
  1113.          (*pbKeyMaterial)[n] = *pbPtr;
  1114.          pbPtr--;
  1115.       }      
  1116.       
  1117.       fReturn = TRUE;
  1118.    }
  1119.    __finally
  1120.    {
  1121.       if (pbSessionBlob) LocalFree(pbSessionBlob);
  1122.       if ((!fReturn) && (*pbKeyMaterial ))
  1123.       {
  1124.          LocalFree(*pbKeyMaterial );
  1125.          *pbKeyMaterial  = NULL;
  1126.          *dwKeyMaterial  = 0;
  1127.       }
  1128.    }
  1129.    return fReturn;
  1130. }