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

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 : pkcs
  38. %
  39. % VERSION : 1.00
  40. %
  41. % FILE : pkcs.cpp
  42. %
  43. % cryptool: class giving access functions PKCS#11
  44. %----------------------------------------------------------------------------
  45. % Version 1.00
  46. % CPX-31/03/2003-Creation
  47. %----------------------------------------------------------------------------
  48. */ 
  49. /*
  50. % Libraries ANSI or system
  51. %------------------------------
  52. */
  53. #include <windows.h>
  54. #include <stdlib.h>
  55. #include <errno.h>
  56. #include <stdio.h>
  57. /*
  58. % HEADER Files include
  59. %-----------------------
  60. */
  61. #include "handlecontainer.h"
  62. #include "pkcs.h"
  63. #include "resource.h"
  64. /*
  65. % Macros
  66. %-------
  67. */
  68. #define      idCtrl(w,l)    (LOWORD(w))
  69. TableOfHandle Pkcs::table_Containers;
  70. CK_FUNCTION_LIST_PTR Pkcs::pFunctionList;
  71. extern bool already_initialized;
  72. extern int  pkcsInitialized;
  73. BOOL CALLBACK DialogProc(HWND hWnd, UINT wMsgID, WPARAM wParam, LPARAM lParam);
  74. CK_RV getCodePorteur(unsigned char * pCodePorteur, CK_ULONG codePorteurLen);
  75. char getchar(char val);
  76. CK_CHAR  g_strPwd[MAX_PIN_LEN] = "CANCEL";
  77. extern "C" HINSTANCE g_hModule;
  78. Pkcs::Pkcs() 
  79. {
  80. }
  81. /*
  82. %--------------------------------------------------------------------------
  83. % Initialize
  84. %
  85. % Initialize is used to tinitialize the dll PKCS#11
  86. %  
  87. %
  88. % return : TRUE if the operation occurred well, FALSE if not
  89. %---------------------------------------------------------------------------
  90. */
  91. BOOL Pkcs::Initialize()
  92. {
  93.     CK_RV rv=0;      
  94. pFunctionList=NULL;
  95. TRACE(__LINE__,"Pkcs::Initialize BEGIN",NULL);    
  96.     /* Load the PKCS11 library */
  97.     rv= init(&pFunctionList);
  98. if (rv!=CKR_OK){
  99. TRACE(__LINE__,"Pkcs::Initialize FALSE",NULL);    
  100. return FALSE;
  101. }
  102. TRACE(__LINE__,"Pkcs::Initialize TRUE",NULL);    
  103. return TRUE;
  104. }
  105. /*
  106. %--------------------------------------------------------------------------
  107. % FreePkcs
  108. %
  109. % FreePkcs is used to release the dll PKCS#11
  110. %  
  111. %
  112. % return : TRUE if the operation occurred well, FALSE if not
  113. %---------------------------------------------------------------------------
  114. */
  115. BOOL Pkcs::FreePkcs()
  116. {
  117. TRACE(__LINE__,"Pkcs::FreePkcs BEGIN",NULL);    
  118. CK_RV rv=0; 
  119. // The sessions of all the containers are closed
  120. int i = START;
  121. table_Containers.Lock();
  122. PKCSContainer * pCnt;
  123. do
  124. {
  125. pCnt = (PKCSContainer*)table_Containers.GetNext(i);
  126. if(pCnt==NULL)
  127. break;
  128. pCnt->Delete();
  129. table_Containers.RemoveEntry(pCnt);
  130. } while(pCnt);
  131. table_Containers.Unlock();
  132. i = START;
  133. HandleContainer *phandleContainer;
  134. HandleContainer::handles_Container.Lock();
  135. do
  136. {
  137. phandleContainer= (HandleContainer*)((HandleContainer::handles_Container).GetNext(i));
  138. if(phandleContainer==NULL)
  139. break;
  140. delete phandleContainer;
  141. } while(phandleContainer);
  142. (HandleContainer::handles_Container).Unlock();
  143. if(!already_initialized){
  144. TRACE(__LINE__,"CleanUP PKCS#11 ",NULL );
  145. rv=cleanup(pFunctionList);
  146. if (rv!=CKR_OK)
  147. return FALSE;
  148. TRACE(__LINE__,"CleanUP OK PKCS#11 ",NULL );
  149. return TRUE;
  150. }
  151. TRACE(__LINE__,"NOT CleanUP ",NULL );
  152. return TRUE;
  153. }
  154. /*
  155. %--------------------------------------------------------------------------
  156. % FreeContainer
  157. %
  158. % FreeContainer is used to free the container
  159. %  
  160. %
  161. % return : TRUE if the operation occurred well, FALSE if not
  162. %---------------------------------------------------------------------------
  163. */
  164. BOOL Pkcs::FreeContainer()
  165. {
  166. TRACE(__LINE__,"FreeContainer ",NULL );
  167. CK_RV rv=0; 
  168. // The sessions of all the containers are closed
  169. int i = START;
  170. table_Containers.Lock();
  171. PKCSContainer * pCnt;
  172. do
  173. {
  174. pCnt = (PKCSContainer*)table_Containers.GetNext(i);
  175. if(pCnt==NULL)
  176. break;
  177. pCnt->Delete();
  178. table_Containers.RemoveEntry(pCnt);
  179. delete pCnt;
  180. } while(pCnt);
  181. table_Containers.Unlock();
  182. i = START;
  183. HandleContainer *phandleContainer;
  184. HandleContainer::handles_Container.Lock();
  185. do
  186. {
  187. phandleContainer= (HandleContainer*)((HandleContainer::handles_Container).GetNext(i));
  188. if(phandleContainer==NULL)
  189. break;
  190. delete phandleContainer;
  191. } while(phandleContainer);
  192. (HandleContainer::handles_Container).Unlock();
  193. TRACE(__LINE__,"Pkcs::FreeContainer TRUE",NULL);    
  194. return TRUE;
  195. }
  196. /*
  197. %--------------------------------------------------------------------------
  198. % CreateContainerTable
  199. %
  200. % CreateContainerTable is used to create a tablecontainer with initialization
  201. %  
  202. %
  203. % return : TRUE if the operation occurred well, FALSE if not
  204. %---------------------------------------------------------------------------
  205. */
  206. BOOL Pkcs::CreateContainerTable(){
  207. TRACE(__LINE__,"PKCS CreateContainerTable BEGIN",NULL );
  208. CK_RV rv=0;                   // Return Code
  209. CK_ULONG tokenIndex=0;
  210. CK_ULONG tokenInSlotListSize = 256;
  211. CK_SLOT_ID_PTR tokenInSlotList = (CK_SLOT_ID_PTR)malloc(tokenInSlotListSize*sizeof(CK_SLOT_ID));
  212. CK_SESSION_HANDLE hSession;
  213.  
  214. CK_ULONG certListSize = 256;
  215. CK_OBJECT_HANDLE_PTR phCertList = (CK_OBJECT_HANDLE_PTR) malloc(certListSize*sizeof(CK_OBJECT_HANDLE));
  216. CK_BYTE_PTR  curSubject=NULL;
  217. CK_ULONG    curSubjectLen=512;
  218. CK_ULONG keyIdLen=256; 
  219. CK_BYTE_PTR keyId = NULL;
  220. /* One recovers all the slots having tokens */
  221. rv = getSlotListWithToken(Pkcs::pFunctionList, tokenInSlotList, &tokenInSlotListSize);
  222. if (rv!=CKR_OK){
  223. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  224. free(tokenInSlotList);
  225. free(phCertList);
  226. return FALSE;
  227. }
  228. /* one traverses all the tokens */
  229. for ( tokenIndex = 0; tokenIndex < tokenInSlotListSize ; tokenIndex++)
  230.     {
  231.         rv=CKR_OK;
  232. /* One opens a session for each token */
  233. if (openSession(Pkcs::pFunctionList, tokenInSlotList[tokenIndex],&hSession)==CKR_OK)
  234.     {
  235. certListSize=256;
  236. rv = getAllX509CertificateList(pFunctionList, hSession, phCertList, &certListSize);
  237. /* one courses the list of the certificates available on this token */
  238. for (CK_ULONG j=0; j<certListSize; j++)
  239. {
  240. /* If the certificate has no public Key, we consider that it is certificate chain */
  241. CK_OBJECT_HANDLE hKey;
  242. rv=getPublicKeyFromX509Cert(pFunctionList,hSession,&hKey,phCertList[j]);
  243. if(rv!=CKR_OK)
  244. continue;
  245. /* one creates the name of the container */
  246. char containerName[256]="";
  247. char curSubjectContainer[101]="";
  248. char keyIdContainer[101]="";
  249. rv =  getX509Subject( pFunctionList, hSession, phCertList[j],NULL_PTR, &curSubjectLen);
  250. if (rv!=CKR_OK)
  251. {
  252. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  253. free(tokenInSlotList);
  254. free(phCertList);
  255. return FALSE;
  256. }
  257. curSubject=(CK_BYTE_PTR) malloc(curSubjectLen*sizeof(CK_BYTE));
  258. if (curSubject == NULL)
  259. {
  260. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  261. free(tokenInSlotList);
  262. free(phCertList);
  263. return FALSE;
  264. }
  265. rv =  getX509Subject( pFunctionList, hSession, phCertList[j],curSubject, &curSubjectLen);
  266. if (rv == CKR_OK)
  267. {
  268. int i=0;
  269. for ( CK_ULONG j=0; j < min(curSubjectLen,(strlen(curSubjectContainer)-1)); j++)
  270. {
  271. /*if ( (unsigned)curSubject[j] > 0x20 && (unsigned)curSubject[j] < 0x7F)
  272. {
  273. curSubjectContainer[i]=curSubject[j];
  274. i++;
  275. }*/
  276. curSubjectContainer[i]=getchar(curSubject[j]);
  277. i++;
  278. }
  279. curSubjectContainer[i]=0;
  280. }
  281. else
  282. {
  283. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  284. free(tokenInSlotList);
  285. free(curSubject);
  286. free(phCertList);
  287. return FALSE;
  288. }
  289. rv = getX509KeyId(pFunctionList, hSession,  phCertList[j], NULL_PTR, &keyIdLen);
  290. if (rv!=CKR_OK) 
  291. {
  292. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  293. free(tokenInSlotList);
  294. free(curSubject);
  295. free(phCertList);
  296. return FALSE;
  297. }
  298. keyId = (CK_BYTE_PTR) malloc(keyIdLen*sizeof(CK_BYTE));
  299. if ( keyId == NULL)
  300. {
  301. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  302. free(tokenInSlotList);
  303. free(curSubject);
  304. free(phCertList);
  305. return FALSE;
  306. }
  307. rv = getX509KeyId(pFunctionList, hSession, phCertList[j], keyId, &keyIdLen);
  308. if (rv == CKR_OK)
  309. {
  310. for ( CK_ULONG j=0; j < min(keyIdLen,(strlen(keyIdContainer)-1)); j++)
  311. {
  312. //keyIdContainer[j]=keyId[j];
  313. keyIdContainer[j]=getchar(keyId[j]);
  314. }
  315. keyIdContainer[j]=0;
  316. }
  317. else
  318. {
  319. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  320. free(tokenInSlotList);
  321. free(curSubject);
  322. free(keyId);
  323. free(phCertList);
  324. return FALSE;
  325. }
  326. strcpy(containerName,curSubjectContainer);
  327. strcat( containerName,keyIdContainer);
  328. TRACE(__LINE__," Pkcs containerName to be added: %s", containerName );
  329. PKCSContainer* pContainer = NULL;
  330. /* one creates the container object */
  331. pContainer=new PKCSContainer();
  332. if(!pContainer->Initialize(pFunctionList,tokenInSlotList[tokenIndex],hSession,phCertList[j],curSubject,curSubjectLen,keyId,keyIdLen,containerName))
  333. {
  334. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  335. delete pContainer;
  336. free(tokenInSlotList);
  337. free(curSubject);
  338. free(keyId);
  339. free(phCertList);
  340. return FALSE;
  341. }
  342. /* one adds this container to the table of the containers*/
  343. if(!table_Containers.AddEntry(pContainer))
  344. {
  345. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  346. delete pContainer;
  347. free(tokenInSlotList);
  348. free(curSubject);
  349. free(keyId);
  350. free(phCertList);
  351. return FALSE;
  352. }
  353. }
  354. if(curSubject){
  355. free(curSubject);
  356. curSubject=NULL_PTR;
  357. }
  358. if(keyId){
  359. free(keyId);
  360. keyId=NULL_PTR;
  361. }
  362. }
  363. else
  364. {
  365. TRACE(__LINE__,"PKCS CreateContainerTable FALSE",NULL );
  366. if(tokenInSlotList)
  367. free(tokenInSlotList);
  368. if(phCertList)
  369. free(phCertList);
  370. return FALSE;
  371. }
  372.   
  373. }
  374. if(tokenInSlotList)
  375. free(tokenInSlotList);
  376. if(phCertList)
  377. free(phCertList);
  378. TRACE(__LINE__,"PKCS CreateContainerTable TRUE",NULL );
  379. return TRUE;
  380. }
  381. /*
  382. %--------------------------------------------------------------------------
  383. % ~Pkcs()
  384. %
  385. % ~Pkcs() est le destructor
  386. %---------------------------------------------------------------------------
  387. */
  388. Pkcs::~Pkcs()
  389. {
  390. }
  391. /*
  392. %--------------------------------------------------------------------------
  393. % VerifyContainerExistance
  394. %
  395. % VerifyContainerExistance checks the existance container
  396. %  
  397. %
  398. % Parameters of entry :
  399. % IN container The required container
  400. %  
  401. % return : TRUE if the operation occurred well, FALSE if not
  402. %---------------------------------------------------------------------------
  403. */
  404. BOOL Pkcs::VerifyContainerExistance(PKCSContainer* container)
  405. {
  406. TRACE(__LINE__,"VerifyContainerExistance",NULL );
  407. return table_Containers.VerifyEntry(container);
  408. }
  409. /*
  410. %--------------------------------------------------------------------------
  411. % GetContainer
  412. %
  413. % GetContainer is used to recover a container starting from its name 
  414. %        in the table container_table
  415. %  
  416. %
  417. % Parameters of entry :
  418. % IN szContainerName the name of the required container
  419. %  
  420. % return : the container
  421. %---------------------------------------------------------------------------
  422. */
  423. PKCSContainer* Pkcs::GetContainer(const CHAR IN * szContainerName)
  424. {
  425. TRACE(__LINE__,"Pkcs::GetContainer",NULL );
  426. if(!szContainerName)
  427. return NULL;
  428. int iCookie = START;
  429. table_Containers.Lock();
  430. PKCSContainer * pCnt;
  431. /*One seeks the Container with the good name*/
  432. do
  433. {
  434. pCnt = (PKCSContainer*)table_Containers.GetNext(iCookie);
  435. } while(pCnt && strcmp(pCnt->GetName(), szContainerName) != 0);
  436. table_Containers.Unlock();
  437. return pCnt;
  438. }
  439. /*
  440. %--------------------------------------------------------------------------
  441. % DoSign
  442. %
  443. % DoSign is used to sign data.  Two calls are carried out to DoSign 
  444. % the first call, in order to recover the size with alouer for the signature
  445. % the second call, in order to really carry out the signature
  446. %  
  447. %
  448. % Parameters of entry :
  449. % IN pContainer the container to be used
  450. % IN pbyHashLen length of the data to be signed
  451. % IN pbyHash data to be signed
  452. % IN dwKeySpec type of key to be used
  453. % OUT pbySignature signed data
  454. % OUT pdwSigLen length of the signed data
  455. % IN g_strPwd pine code to use to reach the key private
  456. %  
  457. % return : TRUE if the operation occurred well, FALSE if not
  458. %---------------------------------------------------------------------------
  459. */
  460. BOOL Pkcs::DoSign(PKCSContainer* pContainer, unsigned long pbyHashLen, LPBYTE pbyHash,DWORD dwKeySpec, LPBYTE pbySignature, LPDWORD pdwSigLen)
  461. {
  462. CK_RV rv = CKR_OK;
  463. CK_OBJECT_HANDLE hPrivKey=NULL;
  464. CK_TOKEN_INFO tokenInfo;
  465. CK_BYTE_PTR signature=NULL;
  466. bool bret;
  467. bool correctPin=false;
  468. TRACE(__LINE__,"Pkcs::DoSign BEGIN",NULL );
  469. CK_SESSION_INFO info;
  470. /* one loggs */
  471. /* Are we already logged */
  472. rv=((pContainer->GetpFunctionList())->C_GetSessionInfo)(pContainer->GethSession(),&info);
  473. if(rv!=CKR_OK)
  474. return FALSE;
  475. if(info.state!= CKS_RW_USER_FUNCTIONS && info.state!= CKS_RO_USER_FUNCTIONS)
  476. {
  477. do
  478. {
  479. unsigned char * codepin=(unsigned char *)malloc(MAX_PIN_LEN);
  480. CK_ULONG codepinLen=MAX_PIN_LEN;
  481. rv=getCodePorteur(codepin,codepinLen);
  482. if(rv!=CKR_OK){
  483. free(codepin);
  484. TRACE(__LINE__,"Pkcs::DoSign Cancel of code pin",NULL );
  485. return FALSE;
  486. }
  487. rv = login(pContainer->GetpFunctionList(),  pContainer->GethSession(),codepin,strlen((const char *)codepin));
  488. if(rv==CKR_OK)
  489. {
  490. correctPin=true;
  491. }
  492. memset(codepin,0,codepinLen);
  493. if(rv==CKR_PIN_INCORRECT)
  494. {
  495. rv =((pContainer->GetpFunctionList())->C_GetTokenInfo)(pContainer->GetslotID(), &tokenInfo);
  496. if ((rv == CKR_OK)&&((tokenInfo.flags & CKF_USER_PIN_FINAL_TRY)))
  497. {
  498. rv=getCodePorteur(codepin,codepinLen);
  499. if(rv!=CKR_OK){
  500. free(codepin);
  501. TRACE(__LINE__,"DoSign::Decrypt Cancel of code pin",NULL );
  502. return FALSE;
  503. }
  504. rv = login(pContainer->GetpFunctionList(),  pContainer->GethSession(),codepin,strlen((const char *)codepin));
  505. if(rv!=CKR_OK) 
  506. {
  507. free(codepin);
  508. TRACE(__LINE__,"Pkcs::DoSign FALSE",NULL );
  509. return FALSE;
  510. }
  511. free(codepin);
  512. break;
  513. }
  514. else if(rv != CKR_OK)
  515. {
  516. free(codepin);
  517. TRACE(__LINE__,"Pkcs::DoSign FALSE",NULL );
  518. return FALSE;
  519. }
  520. }
  521. if((rv!=CKR_OK)&&(rv!=CKR_PIN_INCORRECT))
  522. {
  523. free(codepin);
  524. TRACE(__LINE__,"Pkcs::DoSign FALSE",NULL );
  525. return FALSE;
  526. }
  527. }while(!correctPin);
  528. }
  529. /* Recovery of the private key */
  530. rv = getPrivateKeyFromX509Cert(pContainer->GetpFunctionList(),pContainer->GethSession(), &hPrivKey, pContainer->Gethcert());
  531. if (rv!=CKR_OK) {
  532. TRACE(__LINE__,"Pkcs::DoSign FALSE",NULL );
  533. return FALSE;
  534. }
  535. /* If one invites CPSign the first time in order to recover the size to allow for the signature */
  536. if(!pbySignature)
  537. {
  538. /*CK_BYTE_PTR defaultSignature=(CK_BYTE_PTR)malloc(256*sizeof(CK_BYTE));
  539. CK_ULONG defaultSignatureLength=256;*/
  540. rv = sign(pContainer->GetpFunctionList(),pContainer->GethSession(),hPrivKey, (CK_BYTE_PTR)pbyHash,pbyHashLen,NULL_PTR/*defaultSignature*/,(CK_ULONG_PTR)pdwSigLen/*&defaultSignatureLength*/,1);
  541. if(rv!=CKR_OK){
  542. TRACE(__LINE__,"Pkcs::DoSign FALSE",NULL );
  543. free(signature);
  544. return FALSE;
  545. }
  546. //*pdwSigLen=defaultSignatureLength;
  547. }
  548. /* Recovery of the signature */
  549. else
  550. {
  551. /* real signature */
  552. signature=(CK_BYTE_PTR)malloc((*pdwSigLen)*sizeof(CK_BYTE));
  553. rv = sign(pContainer->GetpFunctionList(),pContainer->GethSession(),hPrivKey, (CK_BYTE_PTR)pbyHash,pbyHashLen,(CK_BYTE_PTR)signature,(CK_ULONG_PTR)pdwSigLen,1);
  554. if(rv!=CKR_OK){
  555. TRACE(__LINE__,"Pkcs::DoSign FALSE",NULL );
  556. free(signature);
  557. return FALSE;
  558. }
  559. /* Inversion of the block signature because CAPI awaits a turned over block*/
  560. int i,j;
  561. for (i=(*pdwSigLen)-1, j=0; i > j; --i, ++j)
  562. {
  563. CK_BYTE bTmp = signature[i];
  564. signature[i] = signature[j];
  565. signature[j] = bTmp;
  566. }
  567. memcpy(pbySignature,signature,*pdwSigLen);
  568. }
  569. if(signature)
  570. free(signature);
  571. bret=TRUE;
  572. TRACE(__LINE__,"Pkcs::DoSign TRUE",NULL );
  573. return bret;
  574. }
  575. /*
  576. %--------------------------------------------------------------------------
  577. % Decrypt
  578. %
  579. % Decrypt is used to decipher data
  580. %  
  581. %
  582. % Parameters of entry :
  583. % IN hPubKey handle on the container to use to decipher
  584. % IN pbySource data to be deciphered
  585. % IN wSourceLength length of data to be deciphered
  586. % OUT pbyDestination deciphered data
  587. % OUT pwDestinationLen length of deciphered data
  588. % IN pass pine code to use to reach the key private
  589. %  
  590. % return : TRUE if the operation occurred well, FALSE if not
  591. %---------------------------------------------------------------------------
  592. */
  593. BOOL Pkcs::Decrypt(HCRYPTKEY hPubKey, BYTE* pbySource, DWORD wSourceLength, BYTE* pbyDestination, DWORD* pwDestinationLen)
  594. {
  595. CK_RV rv = CKR_OK;
  596. CK_TOKEN_INFO tokenInfo;
  597. bool correctPin=false;
  598. TRACE(__LINE__,"Pkcs::Decrypt BEGIN",NULL );
  599. if(!Pkcs::VerifyContainerExistance((PKCSContainer*) hPubKey)){
  600. TRACE(__LINE__,"Pkcs::Decrypt FALSE",NULL );
  601. return FALSE;
  602. }
  603. CK_SESSION_INFO info;
  604. /* one loggs */
  605. /* Are we already logged */
  606. rv=((((PKCSContainer*) hPubKey)->GetpFunctionList())->C_GetSessionInfo)(((PKCSContainer*) hPubKey)->GethSession(),&info);
  607. if(rv!=CKR_OK)
  608. return FALSE;
  609. if(info.state!= CKS_RW_USER_FUNCTIONS && info.state!= CKS_RO_USER_FUNCTIONS)
  610. {
  611. /* we logg  */
  612. do
  613. {
  614. unsigned char * codepin=(unsigned char *)malloc(MAX_PIN_LEN);
  615. CK_ULONG codepinLen=MAX_PIN_LEN;
  616. rv=getCodePorteur(codepin,codepinLen);
  617. if(rv!=CKR_OK){
  618. free(codepin);
  619. TRACE(__LINE__,"Pkcs::Decrypt Cancel of code pin",NULL );
  620. return FALSE;
  621. }
  622. rv = login(((PKCSContainer*) hPubKey)->GetpFunctionList(), ((PKCSContainer*) hPubKey)->GethSession(),codepin,strlen((const char *)codepin));
  623. if(rv==CKR_OK)
  624. {
  625. correctPin=true;
  626. }
  627. memset(codepin,0,codepinLen);
  628. if(rv==CKR_PIN_INCORRECT)
  629. {
  630. rv =((((PKCSContainer*) hPubKey)->GetpFunctionList())->C_GetTokenInfo)(((PKCSContainer*) hPubKey)->GetslotID(), &tokenInfo);
  631. if ((rv == CKR_OK)&&((tokenInfo.flags & CKF_USER_PIN_FINAL_TRY)))
  632. {
  633. rv=getCodePorteur(codepin,codepinLen);
  634. if(rv!=CKR_OK){
  635. free(codepin);
  636. TRACE(__LINE__,"Pkcs::Decrypt Cancel of code pin",NULL );
  637. return FALSE;
  638. }
  639. rv = login(((PKCSContainer*) hPubKey)->GetpFunctionList(), ((PKCSContainer*) hPubKey)->GethSession(),codepin,strlen((const char *)codepin));
  640. if(rv!=CKR_OK) 
  641. {
  642. free(codepin);
  643. TRACE(__LINE__,"Pkcs::Decrypt FALSE",NULL );
  644. return FALSE;
  645. }
  646. free(codepin);
  647. break;
  648. }
  649. else if(rv != CKR_OK)
  650. {
  651. free(codepin);
  652. TRACE(__LINE__,"Pkcs::Decrypt FALSE",NULL );
  653. return FALSE;
  654. }
  655. }
  656. if((rv!=CKR_OK)&&(rv!=CKR_PIN_INCORRECT))
  657. {
  658. free(codepin);
  659. TRACE(__LINE__,"Pkcs::Decrypt FALSE",NULL );
  660. return FALSE;
  661. }
  662. }while(!correctPin);
  663. }
  664. /* one recovers a handle on the private key */
  665. CK_OBJECT_HANDLE hPrivKey=NULL;
  666. rv = getPrivateKeyFromX509Cert(((PKCSContainer*)hPubKey)->GetpFunctionList(), ((PKCSContainer*)hPubKey)->GethSession(), &hPrivKey, ((PKCSContainer*)hPubKey)->Gethcert());
  667. if (rv!=CKR_OK) {
  668. TRACE(__LINE__,"Pkcs::Decrypt FALSE",NULL );
  669. return FALSE;
  670. }
  671. /* the data are deciphered */
  672. rv=decrypt(((PKCSContainer*)hPubKey)->GetpFunctionList(), ((PKCSContainer*)hPubKey)->GethSession(), hPrivKey, (CK_BYTE_PTR) pbySource, (CK_ULONG_PTR)&wSourceLength,(CK_BYTE_PTR)pbyDestination,(CK_ULONG_PTR)pwDestinationLen);
  673. if (rv!=CKR_OK) {
  674. TRACE(__LINE__,"Pkcs::Decrypt FALSE",NULL );
  675. return FALSE;
  676. }
  677. TRACE(__LINE__,"Pkcs::Decrypt TRUE",NULL );
  678. return TRUE;
  679. }
  680. CK_RV getCodePorteur(unsigned char * pCodePorteur, CK_ULONG codePorteurLen) {
  681. CK_RV rv=CKR_OK;
  682. if (pCodePorteur==NULL) {
  683. rv=CKR_ARGUMENTS_BAD;
  684. return rv;
  685. }
  686. // get the pin code
  687. DialogBox(g_hModule, MAKEINTRESOURCE(IDD_PWD), NULL, DialogProc);
  688. if (!strcmp((const char*)g_strPwd,"CANCEL")){
  689. memset(g_strPwd,0,sizeof(g_strPwd));
  690. rv=CKR_CANCEL;
  691. return rv;
  692. }
  693. memcpy(pCodePorteur, g_strPwd, codePorteurLen);
  694. memset(g_strPwd,0,sizeof(g_strPwd));
  695. return rv;
  696. }
  697. /*
  698. %--------------------------------------------------------------------------
  699. % DialogProc
  700. %
  701. % return : TRUE if the operation occurred well, FALSE if not
  702. %---------------------------------------------------------------------------
  703. */
  704. BOOL CALLBACK DialogProc(
  705.     HWND hwndDlg,         /* handle to dialog box*/
  706.     UINT uMsg,      /* message*/
  707.     WPARAM wParam,      /* first message parameter*/
  708.     LPARAM lParam       /* second message parameter*/
  709.    )
  710. {
  711.   switch( uMsg )
  712.   {
  713. case WM_INITDIALOG:
  714. break;
  715. case WM_COMMAND:
  716. switch ( idCtrl(wParam, lParam) )
  717. {
  718. case IDOK:
  719. // memorisation du mot de passe
  720. GetDlgItemText(hwndDlg,IDC_PWD,(char *)g_strPwd,30);
  721. EndDialog(hwndDlg, idCtrl(wParam, lParam));
  722. return TRUE;
  723. case IDCANCEL:
  724. strncpy((char *)g_strPwd,"CANCEL",6);
  725. EndDialog(hwndDlg, idCtrl(wParam, lParam));
  726. return TRUE;
  727. }
  728. return TRUE;
  729. break;
  730.   }
  731.   return FALSE;
  732. }
  733. char getchar(char val){
  734. int valMod=val&0x0F;
  735. char temp;
  736. if(valMod<=9)
  737. temp='0'+valMod;
  738. else
  739. temp='A'+(valMod-0xA);
  740. return temp;
  741. }