Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

11762 lines
340 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2000 Gemplus Canada Inc.
  4. //
  5. // Project:
  6. // Kenny (GPK CSP)
  7. //
  8. // Authors: Laurent CASSIER
  9. // Jean-Marc ROBERT
  10. //
  11. // Modifications: Thierry Tremblay
  12. // Francois Paradis
  13. // GPK8000 support, key importation, enhancement for Whistler & debug
  14. //
  15. // Compiler:
  16. // Microsoft Visual C++ 6.0 - SP3
  17. // Platform SDK - January 2000
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////////////////
  20. #ifdef _UNICODE
  21. #define UNICODE
  22. #endif
  23. #include "gpkcsp.h"
  24. #include <tchar.h>
  25. #include <process.h>
  26. #include <cassert>
  27. #include <cstdio>
  28. #include "resource.h"
  29. #include "gmem.h"
  30. #include "compcert.h"
  31. #include "pincache.h"
  32. //////////////////////////////////////////////////////////////////////////
  33. //
  34. // Configuration
  35. //
  36. //////////////////////////////////////////////////////////////////////////
  37. const int MAX_SLOT = 16;
  38. //////////////////////////////////////////////////////////////////////////
  39. //
  40. // Prototypes
  41. //
  42. //////////////////////////////////////////////////////////////////////////
  43. static void zap_gpk_objects( DWORD SlotNb, BOOL IsPrivate );
  44. BOOL SCARDPROBLEM( LONG result, WORD sc_status, BYTE offset );
  45. #ifdef _DEBUG
  46. static DWORD dw1, dw2;
  47. #endif
  48. //////////////////////////////////////////////////////////////////////////
  49. //
  50. // Macros & Templates
  51. //
  52. //////////////////////////////////////////////////////////////////////////
  53. template<class T>
  54. bool IsNull( const T* p )
  55. {
  56. return p == 0;
  57. }
  58. template<class T>
  59. bool IsNotNull( const T* p )
  60. {
  61. return p != 0;
  62. }
  63. template<class T>
  64. bool IsNullStr( const T* p )
  65. {
  66. return p == 0 || *p == 0;
  67. }
  68. template<class T>
  69. bool IsNotNullStr( const T* p )
  70. {
  71. return p != 0 && *p != 0;
  72. }
  73. //////////////////////////////////////////////////////////////////////////
  74. //
  75. // Definitions
  76. //
  77. //////////////////////////////////////////////////////////////////////////
  78. const char* SYSTEM_DF = "SYSTEM";
  79. const char* GPK_DF = "GTOK1";
  80. const WORD MAX_SES_KEY_EF = 0x01FF;
  81. const WORD GPK_MF = 0x3F00;
  82. const WORD GPK_OBJ_PRIV_EF = 0x0002;
  83. const WORD GPK_OBJ_PUB_EF = 0x0004;
  84. const WORD GPK_IADF_EF = 0x0005;
  85. const WORD GPK_PIN_EF = 0x0006;
  86. const BYTE GPK_FIRST_KEY = 0x07;
  87. const BYTE FILE_CHUNK_SIZE = 200;
  88. const int REALLOC_SIZE = 50;
  89. const int MAX_FIELD = 16;
  90. extern const DWORD MAX_GPK_OBJ = 100;
  91. // Values for a GPK8000 INTL
  92. const int MAX_GPK_PUBLIC = 4000;
  93. const int MAX_GPK_PRIVATE = 1600;
  94. const int RC2_40_SIZE = 0x05;
  95. const int RC2_128_SIZE = 0x10;
  96. const int DES_SIZE = 0x08;
  97. const int DES3_112_SIZE = 0x10;
  98. const int DES3_SIZE = 0x18;
  99. const int DES_BLOCK_SIZE = 0x08;
  100. const int RC2_BLOCK_SIZE = 0x08;
  101. const BYTE TAG_RSA_PUBLIC = 0x01;
  102. const BYTE TAG_DSA_PUBLIC = 0x02;
  103. const BYTE TAG_RSA_PRIVATE = 0x03;
  104. const BYTE TAG_DSA_PRIVATE = 0x04;
  105. const BYTE TAG_CERTIFICATE = 0x05;
  106. const BYTE TAG_DATA = 0x06;
  107. const BYTE TAG_KEYSET = 0x20;
  108. const WORD FLAG_APPLICATION = 0x0001;
  109. const WORD FLAG_END_DATE = 0x0002;
  110. const WORD FLAG_ID = 0x0004;
  111. const WORD FLAG_ISSUER = 0x0008;
  112. const WORD FLAG_LABEL = 0x0010;
  113. const WORD FLAG_SERIAL_NUMBER = 0x0020;
  114. const WORD FLAG_START_DATE = 0x0040;
  115. const WORD FLAG_SUBJECT = 0x0080;
  116. const WORD FLAG_VALUE = 0x0100;
  117. const WORD FLAG_RESERVED = 0x0200; // Not used by CSP
  118. const WORD FLAG_KEY_TYPE = 0x0400;
  119. const WORD FLAG_KEYSET = 0x0800;
  120. const WORD FLAG_SIGN = 0x1000;
  121. const WORD FLAG_EXCHANGE = 0x2000;
  122. const WORD FLAG_EXPORT = 0x4000;
  123. const WORD FLAG_MODIFIABLE = 0x8000;
  124. enum
  125. {
  126. POS_APPLICATION = 0,
  127. POS_END_DATE,
  128. POS_ID,
  129. POS_ISSUER,
  130. POS_LABEL,
  131. POS_SERIAL_NUMBER,
  132. POS_START_DATE,
  133. POS_SUBJECT,
  134. POS_VALUE,
  135. POS_RESERVED, // Not used by CSP
  136. POS_KEY_TYPE,
  137. POS_KEYSET
  138. };
  139. const int PIN_LEN = PIN_MAX;
  140. const int TIME_GEN_512 = 30;
  141. const int TIME_GEN_1024 = 35;
  142. // Used for GPK4000 perso (filter)
  143. const WORD EF_PUBLIC_SIZE = 1483;
  144. const WORD EF_PRIVATE_SIZE = 620;
  145. const WORD DIFF_US_EXPORT = 240;
  146. // depend on the GemSAFE mapping
  147. const BYTE USER_PIN = 0;
  148. const BYTE TAG_MODULUS = 0x01;
  149. const BYTE TAG_PUB_EXP = 0x07;
  150. const BYTE TAG_LEN = 1;
  151. const BYTE PUB_EXP_LEN = 3;
  152. //////////////////////////////////////////////////////////////////////////
  153. //
  154. // Structures
  155. //
  156. //////////////////////////////////////////////////////////////////////////
  157. typedef struct OBJ_FIELD
  158. {
  159. BYTE *pValue;
  160. WORD Len;
  161. WORD Reserved1;
  162. BOOL bReal;
  163. WORD Reserved2;
  164. } OBJ_FIELD;
  165. typedef struct GPK_EXP_KEY
  166. {
  167. BYTE KeySize;
  168. BYTE ExpSize;
  169. WORD Reserved;
  170. BYTE Exposant[256];
  171. BYTE Modulus[256];
  172. } GPK_EXP_KEY;
  173. typedef struct GPK_OBJ
  174. {
  175. BYTE Tag;
  176. BYTE LastField;
  177. BYTE ObjId;
  178. BYTE FileId;
  179. WORD Flags;
  180. WORD Reserved1;
  181. GPK_EXP_KEY PubKey;
  182. OBJ_FIELD Field[MAX_FIELD];
  183. HCRYPTKEY hKeyBase;
  184. BOOL IsPrivate;
  185. WORD Reserved2;
  186. BOOL IsCreated;
  187. WORD Reserved3;
  188. } GPK_OBJ;
  189. typedef struct TMP_OBJ
  190. {
  191. HCRYPTPROV hProv;
  192. HCRYPTKEY hKeyBase;
  193. } TMP_OBJ;
  194. typedef struct TMP_HASH
  195. {
  196. HCRYPTPROV hProv;
  197. HCRYPTHASH hHashBase;
  198. } TMP_HASH;
  199. typedef struct Slot_Description
  200. {
  201. // NK 06.02.2001 - PinCache
  202. PINCACHE_HANDLE hPinCacheHandle;
  203. // End NK
  204. BOOL Read_Priv;
  205. BOOL Read_Public;
  206. BOOL InitFlag;
  207. BOOL UseFile [MAX_REAL_KEY];
  208. BYTE NbGpkObject;
  209. BYTE bGpkSerNb[8];
  210. GPK_EXP_KEY GpkPubKeys[MAX_REAL_KEY];
  211. GPK_OBJ GpkObject[MAX_GPK_OBJ + 1]; // 0 is not used, valid 1-MAX_GPK_OBJ
  212. DWORD NbKeyFile; // number of key file version 2.00.002
  213. DWORD GpkMaxSessionKey; // Card unwrap capability
  214. DWORD ContextCount;
  215. HANDLE CheckThread;
  216. SCARD_READERSTATE ReaderState;
  217. BOOL CheckThreadStateEmpty; // TRUE if card has been removed and detected by checkThread
  218. TCHAR szReaderName[128];
  219. // TT - 17/10/2000 - Timestamps on card
  220. BYTE m_TSPublic;
  221. BYTE m_TSPrivate;
  222. BYTE m_TSPIN;
  223. BOOL ValidateTimestamps( HCRYPTPROV prov );
  224. } Slot_Description;
  225. //////////////////////////////////////////////////////////////////////////
  226. //
  227. // Statics (locals)
  228. //
  229. //////////////////////////////////////////////////////////////////////////
  230. static HINSTANCE hFirstInstMod = 0;
  231. static BOOL bFirstGUILoad = TRUE;
  232. static HCRYPTPROV hProvBase = 0;
  233. static SCARDCONTEXT hCardContext = 0; // mv
  234. static unsigned l_globalLockCount;
  235. static BYTE bSendBuffer[512];
  236. static BYTE bRecvBuffer[512];
  237. static BYTE* g_pbGpkObj = 0;
  238. static DWORD cbSendLength;
  239. static DWORD cbRecvLength;
  240. static DWORD dwSW1SW2;
  241. static DWORD countCardContextRef= 0;
  242. static DWORD NbInst;
  243. static TCHAR mszCardList[MAX_PATH];
  244. // For dynamic reallocation of TmpObject, hHashGpk and ProvCont
  245. static DWORD MAX_CONTEXT = 50;
  246. static DWORD MAX_TMP_KEY = 200;
  247. static DWORD MAX_TMP_HASH = 200;
  248. // Temporary objects in each context
  249. static TMP_OBJ* TmpObject; // dynamic allocated/reallocated
  250. static TMP_HASH* hHashGpk; // dynamic allocated/reallocated
  251. // Many contexts management
  252. Prov_Context* ProvCont; // dynamic allocated/reallocated
  253. // Per slot information
  254. static SCARDCONTEXT hCardContextCheck[MAX_SLOT];
  255. static volatile BOOL g_fStopMonitor[MAX_SLOT];
  256. static Slot_Description Slot[MAX_SLOT];
  257. static BOOL InitSlot[MAX_SLOT];
  258. static DWORD g_FuncSlotNb = 0;
  259. static long g_threadAttach = 0;
  260. // Gen key time for GPK8000
  261. static int g_GPK8000KeyGenTime512 = 0;
  262. static int g_GPK8000KeyGenTime1024 = 0;
  263. // End of the Dialogue Management
  264. static HCRYPTKEY hRsaIdentityKey = 0;
  265. static DWORD AuxMaxSessionKeyLength = 0;
  266. static DWORD dwRsaIdentityLen = 64;
  267. static BYTE RC2_Key_Size = 0;
  268. static BYTE RSA_KEK_Size = 0;
  269. static BYTE PrivateBlob[] =
  270. {
  271. // Blob header
  272. 0x07, // PRIVATEKEYBLOB
  273. 0x02, // CUR_BLOB_VERSION
  274. 0x00,0x00, // RESERVED
  275. 0x00,0xa4,0x00,0x00, // CALG_RSA_KEYX
  276. // RSA Public Key
  277. 0x52,0x53,0x41,0x32, // "RSA2"
  278. 0x00,0x02,0x00,0x00, // 512 bits
  279. 0x01,0x00,0x00,0x00, // Public Exponent
  280. // Modulus
  281. 0x6b,0xdf,0x51,0xef,0xdb,0x6f,0x10,0x5c,
  282. 0x32,0xbf,0x87,0x1c,0xd1,0x4c,0x24,0x7e,
  283. 0xe7,0x2a,0x14,0x10,0x6d,0xeb,0x2c,0xd5,
  284. 0x8c,0x0b,0x95,0x7b,0xc7,0x5d,0xc6,0x87,
  285. 0x12,0xea,0xa9,0xcd,0x57,0x7d,0x3e,0xcb,
  286. 0xe9,0x6a,0x46,0xd0,0xe1,0xae,0x2f,0x86,
  287. 0xd9,0x50,0xf9,0x98,0x71,0xdd,0x39,0xfc,
  288. 0x0e,0x60,0xa9,0xd3,0xf2,0x38,0xbb,0x8d,
  289. // Prime 1
  290. 0x5d,0x2c,0xbc,0x1e,0xc3,0x38,0xfe,0x00,
  291. 0x5e,0xca,0xcf,0xcd,0xb4,0x13,0x89,0x16,
  292. 0xd2,0x07,0xbc,0x9b,0xe1,0x20,0x31,0x0b,
  293. 0x81,0x28,0x17,0x0c,0xc7,0x73,0x94,0xee,
  294. // Prime 2
  295. 0x67,0xbe,0x7b,0x78,0x4e,0xc7,0x91,0x73,
  296. 0xa8,0x34,0x5a,0x24,0x9d,0x92,0x0d,0xe8,
  297. 0x91,0x61,0x24,0xdc,0xb5,0xeb,0xdf,0x71,
  298. 0x66,0xdc,0xe1,0x77,0xd4,0x78,0x14,0x98,
  299. // Exponent 1
  300. 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  301. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  302. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  303. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  304. // Exponent 2
  305. 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  306. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  307. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  308. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  309. // Coefficient
  310. 0xa0,0x51,0xe9,0x83,0xca,0xee,0x4b,0xf0,
  311. 0x59,0xeb,0xa4,0x81,0xd6,0x1f,0x49,0x42,
  312. 0x2b,0x75,0x89,0xa7,0x9f,0x84,0x7f,0x1f,
  313. 0xc3,0x8f,0x70,0xb6,0x7e,0x06,0x5e,0x8b,
  314. // Private Exponent
  315. 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  316. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  317. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  318. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  319. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  320. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  321. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  322. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  323. };
  324. static BYTE InitValue[2][2*16+2] =
  325. {
  326. {
  327. // 1 key case
  328. 0x01, 0xF0, 0x00, GPK_FIRST_KEY,
  329. 0x01, 0xD0, 0x00, GPK_FIRST_KEY,
  330. 0x03, 0xB0, 0x00, GPK_FIRST_KEY,
  331. 0x03, 0x90, 0x00, GPK_FIRST_KEY,
  332. 0x00,
  333. 0xFF
  334. },
  335. {
  336. // 2 keys case
  337. 0x01, 0xF0,0x00, GPK_FIRST_KEY,
  338. 0x01, 0xD0,0x00, GPK_FIRST_KEY,
  339. 0x03, 0xB0,0x00, GPK_FIRST_KEY,
  340. 0x03, 0x90,0x00, GPK_FIRST_KEY,
  341. 0x01, 0xF0,0x00, GPK_FIRST_KEY+1,
  342. 0x01, 0xD0,0x00, GPK_FIRST_KEY+1,
  343. 0x03, 0xB0,0x00, GPK_FIRST_KEY+1,
  344. 0x03, 0x90,0x00, GPK_FIRST_KEY+1,
  345. 0x00,
  346. 0xFF
  347. }
  348. };
  349. // NK 09.02.2001 PinCache functions
  350. //////////////////////////////////////////////////////////////////////////
  351. //
  352. // PopulatePins()
  353. // Initializes the Pins structure and storea data
  354. //
  355. //////////////////////////////////////////////////////////////////////////
  356. void PopulatePins( PPINCACHE_PINS pPins,
  357. BYTE *szCurPin,
  358. DWORD bCurPin,
  359. BYTE *szNewPin,
  360. DWORD bNewPin )
  361. {
  362. if ( NULL == szCurPin )
  363. pPins->pbCurrentPin = NULL;
  364. else
  365. pPins->pbCurrentPin = szCurPin;
  366. pPins->cbCurrentPin = bCurPin;
  367. if ( NULL == szNewPin )
  368. pPins->pbNewPin = NULL;
  369. else
  370. pPins->pbNewPin = szNewPin;
  371. pPins->cbNewPin = bNewPin;
  372. }
  373. /*------------------------------------------------------------------------------
  374. ------------------------------------------------------------------------------*/
  375. DWORD Select_MF(HCRYPTPROV hProv);
  376. BOOL Coherent(HCRYPTPROV hProv);
  377. static DWORD OpenCard(CHAR* szContainerAsked, DWORD dwFlags, SCARDHANDLE* hCard, PTCHAR szReaderName, DWORD dwReaderNameLen);
  378. void ReleaseProvider(HCRYPTPROV hProv);
  379. static int get_pin_free(HCRYPTPROV hProv);
  380. static BOOL verify_pin(HCRYPTPROV hProv, const char* pPin, DWORD dwPinLen);
  381. static BOOL change_pin(HCRYPTPROV hProv, BYTE secretCode, const char* a_pOldPin, DWORD dwOldPinLen, const char* a_pNewPin, DWORD dwNewPinLen);
  382. static BOOL Context_exist(HCRYPTPROV hProv);
  383. /*------------------------------------------------------------------------------
  384. ------------------------------------------------------------------------------*/
  385. struct CallbackData
  386. {
  387. HCRYPTPROV hProv;
  388. BOOL IsCoherent;
  389. };
  390. //////////////////////////////////////////////////////////////////////////
  391. //
  392. // Callbacks for PinCache
  393. //
  394. //////////////////////////////////////////////////////////////////////////
  395. DWORD Callback_VerifyPinLength( PPINCACHE_PINS pPins, PVOID pvCallBackCtx )
  396. {
  397. if ((pPins->cbCurrentPin < PIN_MIN) || (pPins->cbCurrentPin > PIN_MAX))
  398. return SCARD_E_INVALID_CHV;
  399. if (( pPins->cbNewPin != 0 ) &&
  400. ((pPins->cbNewPin < PIN_MIN) || (pPins->cbNewPin > PIN_MAX)))
  401. return SCARD_E_INVALID_CHV;
  402. return ERROR_SUCCESS;
  403. }
  404. DWORD Callback_VerifyChangePin( PPINCACHE_PINS pPins, PVOID pvCallBackCtx )
  405. {
  406. DWORD dwStatus;
  407. if ((dwStatus = Callback_VerifyPinLength(pPins, 0)) != ERROR_SUCCESS)
  408. return dwStatus;
  409. if (pvCallBackCtx == 0)
  410. return NTE_FAIL;
  411. CallbackData* pCallbackData = (CallbackData*)pvCallBackCtx;
  412. HCRYPTPROV hProv = pCallbackData->hProv;
  413. BOOL IsCoherent = pCallbackData->IsCoherent;
  414. if (!IsCoherent)
  415. {
  416. if (!Coherent(hProv))
  417. return NTE_FAIL;
  418. }
  419. DWORD dwPinFree = get_pin_free(hProv);
  420. if (dwPinFree == -1)
  421. dwStatus = NTE_FAIL;
  422. if ((dwStatus == ERROR_SUCCESS) && (dwPinFree == 0))
  423. dwStatus = SCARD_W_CHV_BLOCKED;
  424. if ((dwStatus == ERROR_SUCCESS) && (!verify_pin(hProv, (CHAR*)pPins->pbCurrentPin, pPins->cbCurrentPin)))
  425. dwStatus = SCARD_W_WRONG_CHV;
  426. if (pPins->cbNewPin != 0)
  427. {
  428. if ((dwStatus == ERROR_SUCCESS) && (!change_pin(hProv, USER_PIN, (CHAR*)pPins->pbCurrentPin, pPins->cbCurrentPin, (CHAR*)pPins->pbNewPin, pPins->cbNewPin)))
  429. dwStatus = SCARD_W_WRONG_CHV;
  430. }
  431. if (!IsCoherent)
  432. {
  433. Select_MF(hProv);
  434. SCardEndTransaction(ProvCont[hProv].hCard, SCARD_LEAVE_CARD);
  435. }
  436. return dwStatus;
  437. }
  438. DWORD Callback_VerifyChangePin2( PPINCACHE_PINS pPins, PVOID pvCallBackCtx )
  439. {
  440. DWORD dwStatus;
  441. if ((dwStatus = Callback_VerifyPinLength(pPins, 0)) != ERROR_SUCCESS)
  442. return dwStatus;
  443. if (pvCallBackCtx == 0)
  444. return NTE_FAIL;
  445. HCRYPTPROV hProv = (HCRYPTPROV)pvCallBackCtx;
  446. if (!verify_pin(hProv, (CHAR*)pPins->pbCurrentPin, pPins->cbCurrentPin))
  447. return SCARD_W_WRONG_CHV;
  448. if (pPins->cbNewPin != 0)
  449. {
  450. if (!change_pin(hProv, USER_PIN, (CHAR*)pPins->pbCurrentPin, pPins->cbCurrentPin, (CHAR*)pPins->pbNewPin, pPins->cbNewPin))
  451. return SCARD_W_WRONG_CHV;
  452. }
  453. return ERROR_SUCCESS;
  454. }
  455. //////////////////////////////////////////////////////////////////////////
  456. //
  457. // Query_MSPinCache()
  458. // Wrapper for Microsoft PinCacheQuery
  459. //
  460. //////////////////////////////////////////////////////////////////////////
  461. DWORD Query_MSPinCache( PINCACHE_HANDLE hCache, PBYTE pbPin, PDWORD pcbPin )
  462. {
  463. DWORD dwStatus = PinCacheQuery( hCache, pbPin, pcbPin );
  464. if ( (dwStatus == ERROR_EMPTY) && (*pcbPin == 0) )
  465. return ERROR_EMPTY;
  466. if ( (dwStatus == ERROR_SUCCESS) && (*pcbPin == 0) )
  467. return SCARD_E_INVALID_CHV;
  468. return ERROR_SUCCESS;
  469. }
  470. //////////////////////////////////////////////////////////////////////////
  471. //
  472. // Flush_MSPinCache()
  473. // Wrapper for Microsoft PinCacheFlush
  474. //
  475. //////////////////////////////////////////////////////////////////////////
  476. void Flush_MSPinCache ( PINCACHE_HANDLE *phCache )
  477. {
  478. PinCacheFlush( phCache );
  479. }
  480. //////////////////////////////////////////////////////////////////////////
  481. //
  482. // Wrapper for SCardConnect
  483. //
  484. // fix SCR 43 : Reconnect after the ressource manager had been stopped and
  485. // restarted.
  486. //
  487. //////////////////////////////////////////////////////////////////////////
  488. DWORD ConnectToCard( IN LPCTSTR szReaderFriendlyName,
  489. IN DWORD dwShareMode,
  490. IN DWORD dwPreferredProtocols,
  491. OUT LPSCARDHANDLE phCard,
  492. OUT LPDWORD pdwActiveProtocol
  493. )
  494. {
  495. DWORD dwSts = SCardConnect( hCardContext, szReaderFriendlyName,
  496. dwShareMode, dwPreferredProtocols,
  497. phCard, pdwActiveProtocol );
  498. if (dwSts == SCARD_E_SERVICE_STOPPED)
  499. {
  500. DBG_PRINT(TEXT("ScardConnect fails because RM has been stopped and restarted"));
  501. SCardReleaseContext(hCardContext);
  502. dwSts = SCardEstablishContext( SCARD_SCOPE_SYSTEM, 0, 0, &hCardContext );
  503. if (dwSts == SCARD_S_SUCCESS)
  504. {
  505. dwSts = SCardConnect( hCardContext, szReaderFriendlyName,
  506. dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol );
  507. }
  508. }
  509. DBG_PRINT(TEXT("SCardConnect"));
  510. return dwSts;
  511. }
  512. //////////////////////////////////////////////////////////////////////////
  513. //
  514. // Add_MSPinCache()
  515. // Wrapper for Microsoft PinCacheAdd
  516. //
  517. //////////////////////////////////////////////////////////////////////////
  518. DWORD Add_MSPinCache( PINCACHE_HANDLE *phCache,
  519. PPINCACHE_PINS pPins,
  520. PFN_VERIFYPIN_CALLBACK pfnVerifyPinCallback,
  521. PVOID pvCallbackCtx)
  522. {
  523. DWORD dwStatus = PinCacheAdd( phCache,
  524. pPins,
  525. pfnVerifyPinCallback,
  526. pvCallbackCtx );
  527. return dwStatus;
  528. }
  529. // End NK
  530. //////////////////////////////////////////////////////////////////////////
  531. //
  532. // DoSCardTransmit:
  533. // This function performs an SCardTransmit operation, plus retries the
  534. // operation should an SCARD_E_COMM_DATA_LOST or similar error be reported.
  535. //
  536. // Arguments:
  537. // Per SCardTransmit
  538. //
  539. // Return Value:
  540. // Per SCardTransmit
  541. //
  542. // Author:
  543. // Doug Barlow (dbarlow) 1/27/1999
  544. //
  545. //////////////////////////////////////////////////////////////////////////
  546. LONG WINAPI
  547. DoSCardTransmit(
  548. IN SCARDHANDLE hCard,
  549. IN LPCSCARD_IO_REQUEST pioSendPci,
  550. IN LPCBYTE pbSendBuffer,
  551. IN DWORD cbSendLength,
  552. IN OUT LPSCARD_IO_REQUEST pioRecvPci,
  553. OUT LPBYTE pbRecvBuffer,
  554. IN OUT LPDWORD pcbRecvLength)
  555. {
  556. LONG lRet;
  557. BOOL fAgain = TRUE;
  558. DWORD dwRetryLimit = 3;
  559. DWORD dwLength;
  560. DBG_TIME1;
  561. while (fAgain)
  562. {
  563. if (0 == dwRetryLimit--)
  564. break;
  565. dwLength = *pcbRecvLength;
  566. lRet = SCardTransmit(
  567. hCard,
  568. pioSendPci,
  569. pbSendBuffer,
  570. cbSendLength,
  571. pioRecvPci,
  572. pbRecvBuffer,
  573. &dwLength);
  574. switch (lRet)
  575. {
  576. #ifdef SCARD_E_COMM_DATA_LOST
  577. case SCARD_E_COMM_DATA_LOST:
  578. #endif
  579. case ERROR_SEM_TIMEOUT:
  580. break;
  581. default:
  582. fAgain = FALSE;
  583. *pcbRecvLength = dwLength;
  584. }
  585. }
  586. DBG_TIME2;
  587. DBG_PRINT(TEXT("SCardTransmit(CLA:0x%02X, INS:0x%02X, P1:0x%02X, P2:0x%02X, Li:0x%02X) in %d msec"),
  588. pbSendBuffer[0],
  589. pbSendBuffer[1],
  590. pbSendBuffer[2],
  591. pbSendBuffer[3],
  592. pbSendBuffer[4],
  593. DBG_DELTA);
  594. return lRet;
  595. }
  596. #define SCardTransmit DoSCardTransmit
  597. //////////////////////////////////////////////////////////////////////////
  598. // TT END: La passe a Doug
  599. //////////////////////////////////////////////////////////////////////////
  600. //////////////////////////////////////////////////////////////////////////
  601. //
  602. // TT - 17/10/2000 - Inter-process synchronisation using timestamps
  603. // stored on the card. There is three timestamps:
  604. //
  605. // Public objects timestamp: GemSAFE IADF offset 68
  606. // Private objects timestamp: GemSAFE IADF offset 69
  607. // PIN modification timestamp: GemSAFE IADF offset 70
  608. //
  609. //////////////////////////////////////////////////////////////////////////
  610. BOOL ReadTimestamps( HCRYPTPROV hProv, BYTE* pTSPublic, BYTE* pTSPrivate, BYTE* pTSPIN )
  611. {
  612. // Issue a read binary command at offset 68 of the IADF
  613. bSendBuffer[0] = 0x00;
  614. bSendBuffer[1] = 0xB0;
  615. bSendBuffer[2] = 0x80 | LOBYTE( GPK_IADF_EF );
  616. bSendBuffer[3] = 68 / ProvCont[hProv].dataUnitSize;
  617. bSendBuffer[4] = 3;
  618. cbSendLength = 5;
  619. cbRecvLength = sizeof(bRecvBuffer);
  620. DWORD lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  621. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  622. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  623. {
  624. RETURN( CRYPT_FAILED, SCARD_W_EOF );
  625. }
  626. *pTSPublic = bRecvBuffer[0];
  627. *pTSPrivate = bRecvBuffer[1];
  628. *pTSPIN = bRecvBuffer[2];
  629. RETURN( CRYPT_SUCCEED, 0 );
  630. }
  631. BOOL WriteTimestamps( HCRYPTPROV hProv, BYTE TSPublic, BYTE TSPrivate, BYTE TSPIN )
  632. {
  633. // Issue a update binary command at offset 68 of the IADF
  634. bSendBuffer[0] = 0x00;
  635. bSendBuffer[1] = 0xD6;
  636. bSendBuffer[2] = 0x80 | LOBYTE( GPK_IADF_EF );
  637. bSendBuffer[3] = 68 / ProvCont[hProv].dataUnitSize;
  638. bSendBuffer[4] = 3;
  639. bSendBuffer[5] = TSPublic;
  640. bSendBuffer[6] = TSPrivate;
  641. bSendBuffer[7] = TSPIN;
  642. cbSendLength = 8;
  643. cbRecvLength = sizeof(bRecvBuffer);
  644. DWORD lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  645. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  646. if (SCARDPROBLEM(lRet,0x9000,0))
  647. {
  648. RETURN( CRYPT_FAILED, SCARD_W_EOF );
  649. }
  650. RETURN( CRYPT_SUCCEED, 0 );
  651. }
  652. BOOL Slot_Description::ValidateTimestamps( HCRYPTPROV hProv )
  653. {
  654. BYTE TSPublic, TSPrivate, TSPIN;
  655. if (!ReadTimestamps( hProv, &TSPublic, &TSPrivate, &TSPIN ))
  656. return CRYPT_FAILED;
  657. if (m_TSPublic != TSPublic)
  658. {
  659. Read_Public = FALSE;
  660. zap_gpk_objects( ProvCont[hProv].Slot, FALSE );
  661. }
  662. if (m_TSPrivate != TSPrivate)
  663. {
  664. Read_Priv = FALSE;
  665. zap_gpk_objects( ProvCont[hProv].Slot, TRUE );
  666. }
  667. if (m_TSPIN != TSPIN)
  668. {
  669. // ClearPin(); // NK 06.02.2001
  670. Flush_MSPinCache(&hPinCacheHandle);
  671. }
  672. m_TSPublic = TSPublic;
  673. m_TSPrivate = TSPrivate;
  674. m_TSPIN = TSPIN;
  675. return CRYPT_SUCCEED;
  676. }
  677. //////////////////////////////////////////////////////////////////////////
  678. //
  679. // IsWin2000() - Detect if we are running under Win2000 (and above)
  680. //
  681. //////////////////////////////////////////////////////////////////////////
  682. bool IsWin2000()
  683. {
  684. #if (_WIN32_WINNT >= 0x0500)
  685. return true;
  686. #else
  687. OSVERSIONINFO info;
  688. info.dwOSVersionInfoSize = sizeof(info);
  689. GetVersionEx( &info );
  690. if (info.dwPlatformId == VER_PLATFORM_WIN32_NT && info.dwMajorVersion >= 5)
  691. return true;
  692. return false;
  693. #endif
  694. }
  695. ////////////////////////////////////////////////////////////////////////////////
  696. //
  697. // TT 28/07/2000
  698. //
  699. // Detect GPK4000 ATR instead of GPK8000 ATR. This is to ensure
  700. // that the GPK16000 will work as-is with the CSP.
  701. //
  702. // The return value is the error code from SCardStatus()
  703. //
  704. ////////////////////////////////////////////////////////////////////////////////
  705. static DWORD DetectGPK8000( SCARDHANDLE hCard, BOOL* pbGPK8000 )
  706. {
  707. const BYTE ATR_GPK4000[] = { 0x3B, 0x27, 0x00, 0x80, 0x65, 0xA2, 0x04, 0x01, 0x01, 0x37 };
  708. const BYTE ATR_MASK[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0xFF, 0xFF, 0xFF };
  709. DWORD lRet;
  710. TCHAR szReaderName[1024];
  711. DWORD lenReaderName;
  712. DWORD state;
  713. DWORD protocol;
  714. BYTE ATR[32];
  715. DWORD lenATR;
  716. DWORD i;
  717. lenReaderName = sizeof( szReaderName ) / sizeof( TCHAR );
  718. lenATR = sizeof(ATR);
  719. // Assume we have a GPK4000
  720. *pbGPK8000 = FALSE;
  721. // Read the ATR
  722. lRet = SCardStatus( hCard, szReaderName, &lenReaderName, &state, &protocol, ATR, &lenATR );
  723. if (lRet != SCARD_S_SUCCESS)
  724. return lRet;
  725. // Check for GPK4000
  726. for (i = 0; i < lenATR; ++i)
  727. {
  728. if ( (ATR[i] & ATR_MASK[i]) != (ATR_GPK4000[i] & ATR_MASK[i]) )
  729. {
  730. // Not a GPK4000
  731. *pbGPK8000 = TRUE;
  732. break;
  733. }
  734. }
  735. return SCARD_S_SUCCESS;
  736. }
  737. /*------------------------------------------------------------------------------
  738. // Critical section
  739. ------------------------------------------------------------------------------*/
  740. static CRITICAL_SECTION l_csLocalLock;
  741. void GpkLocalLock()
  742. {
  743. EnterCriticalSection(&l_csLocalLock);
  744. }
  745. void GpkLocalUnlock()
  746. {
  747. LeaveCriticalSection(&l_csLocalLock);
  748. }
  749. /*------------------------------------------------------------------------------
  750. ------------------------------------------------------------------------------*/
  751. static void r_memcpy(BYTE *pbOut, BYTE *pbIn, DWORD dwLen)
  752. {
  753. DWORD i;
  754. for (i = 0; i < dwLen; i++)
  755. {
  756. pbOut[i] = pbIn[dwLen - i -1];
  757. }
  758. }
  759. /*------------------------------------------------------------------------------
  760. ------------------------------------------------------------------------------*/
  761. static BOOL sw_mask(WORD sw, BYTE x)
  762. {
  763. if ((sw == 0x0000) || (x == 0xFF))
  764. {
  765. return (CRYPT_SUCCEED);
  766. }
  767. dwSW1SW2 = (bRecvBuffer[x]*256) + bRecvBuffer[x+1];
  768. if (LOBYTE(sw) == 0xFF)
  769. {
  770. if (bRecvBuffer[x] != HIBYTE(sw))
  771. {
  772. return (CRYPT_FAILED);
  773. }
  774. }
  775. else
  776. {
  777. if ((bRecvBuffer[x] != HIBYTE(sw))
  778. ||(bRecvBuffer[x+1] != LOBYTE(sw))
  779. )
  780. {
  781. return (CRYPT_FAILED);
  782. }
  783. }
  784. return (CRYPT_SUCCEED);
  785. }
  786. BOOL SCARDPROBLEM( LONG result, WORD sc_status, BYTE offset )
  787. {
  788. if (!sw_mask( sc_status, offset ))
  789. return TRUE;
  790. if (result != SCARD_S_SUCCESS)
  791. return TRUE;
  792. return FALSE;
  793. }
  794. /*------------------------------------------------------------------------------
  795. ------------------------------------------------------------------------------*/
  796. static void conv_hex( const char* pInput, WORD wLen, BYTE* pOut )
  797. {
  798. BYTE pin[32];
  799. WORD i;
  800. memcpy( pin, pInput, wLen );
  801. if (wLen & 1)
  802. pin[wLen] = '0';
  803. for (i=0; i < wLen; i+=2)
  804. {
  805. pOut[i/2] = ((pin[i] & 0x0F) << 4) + (pin[i+1] & 0x0F);
  806. }
  807. }
  808. /*------------------------------------------------------------------------------
  809. ------------------------------------------------------------------------------*/
  810. HWND GetAppWindow()
  811. {
  812. HWND hActWnd = g_hMainWnd;
  813. if (!IsWindow(hActWnd))
  814. hActWnd = GetActiveWindow();
  815. return hActWnd;
  816. }
  817. /*------------------------------------------------------------------------------
  818. ------------------------------------------------------------------------------*/
  819. static void clean_slot( DWORD SlotNb, Prov_Context* pContext )
  820. {
  821. Slot_Description* pSlot;
  822. pSlot = &Slot[ SlotNb ];
  823. pSlot->Read_Priv = FALSE;
  824. pSlot->Read_Public = FALSE;
  825. pSlot->ContextCount = 0;
  826. pSlot->GpkMaxSessionKey = 0;
  827. pSlot->NbKeyFile = 0;
  828. // pSlot->ClearPin(); NK 06.02.2001
  829. Flush_MSPinCache(&(pSlot->hPinCacheHandle));
  830. if (pContext->hRSASign != 0)
  831. {
  832. CryptDestroyKey( pContext->hRSASign );
  833. pContext->hRSASign = 0;
  834. }
  835. if (pContext->hRSAKEK != 0)
  836. {
  837. CryptDestroyKey( pContext->hRSAKEK );
  838. pContext->hRSAKEK = 0;
  839. }
  840. }
  841. /*------------------------------------------------------------------------------
  842. ------------------------------------------------------------------------------*/
  843. static int multistrlen( const PTCHAR mszString )
  844. {
  845. int res, tmp;
  846. PTCHAR ptr = mszString;
  847. res = 0;
  848. if (IsNullStr(ptr))
  849. {
  850. ptr++;
  851. res++;
  852. }
  853. while (IsNotNullStr(ptr))
  854. {
  855. tmp = _tcslen(ptr) + 1;
  856. res = res + tmp;
  857. ptr = ptr + tmp;
  858. }
  859. return (res);
  860. }
  861. /*------------------------------------------------------------------------------
  862. ------------------------------------------------------------------------------*/
  863. static LONG BeginTransaction(SCARDHANDLE hCard)
  864. {
  865. DWORD lRet, dwProtocol;
  866. lRet = SCardBeginTransaction(hCard);
  867. if (lRet == SCARD_W_UNPOWERED_CARD || lRet == SCARD_W_RESET_CARD)
  868. {
  869. DBG_PRINT(TEXT("ScardBeginTransaction fails, try to reconnect"));
  870. lRet = SCardReconnect(hCard,
  871. SCARD_SHARE_SHARED,
  872. SCARD_PROTOCOL_T0,
  873. SCARD_LEAVE_CARD,
  874. &dwProtocol);
  875. if (lRet == SCARD_S_SUCCESS)
  876. {
  877. lRet = SCardBeginTransaction(hCard);
  878. }
  879. }
  880. DBG_PRINT(TEXT("SCardBeginTransaction"));
  881. return(lRet);
  882. }
  883. /*------------------------------------------------------------------------------
  884. ------------------------------------------------------------------------------*/
  885. DWORD Select_MF(HCRYPTPROV hProv)
  886. {
  887. DWORD lRet;
  888. // This function is used to make sure to reset the access condition
  889. // on the sensitive files
  890. /* Select GPK Card MF */
  891. bSendBuffer[0] = 0x00; //CLA
  892. bSendBuffer[1] = 0xA4; //INS
  893. bSendBuffer[2] = 0x00; //P1
  894. bSendBuffer[3] = 0x0C; //P2
  895. bSendBuffer[4] = 0x02; //Li
  896. bSendBuffer[5] = HIBYTE(GPK_MF);
  897. bSendBuffer[6] = LOBYTE(GPK_MF);
  898. cbSendLength = 7;
  899. cbRecvLength = sizeof(bRecvBuffer);
  900. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  901. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  902. if (SCARDPROBLEM(lRet,0x9000,0x00))
  903. {
  904. DBG_PRINT(TEXT("Select MF failed, lRet = 0x%08X, SW1 = %X%X, SW2 = %X%X"), lRet, (bRecvBuffer[0] & 0xF0) >> 4, (bRecvBuffer[0] & 0x0F), (bRecvBuffer[1] & 0xF0) >> 4, (bRecvBuffer[1] & 0x0F));
  905. RETURN (CRYPT_FAILED, SCARD_E_DIR_NOT_FOUND);
  906. }
  907. if (ProvCont[hProv].dataUnitSize == 0)
  908. {
  909. // TT 03/11/99: Check data unit size
  910. bSendBuffer[0] = 0x80;
  911. bSendBuffer[1] = 0xC0;
  912. bSendBuffer[2] = 0x02;
  913. bSendBuffer[3] = 0xA4;
  914. bSendBuffer[4] = 0x0D;
  915. cbSendLength = 5;
  916. cbRecvLength = sizeof(bRecvBuffer);
  917. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  918. cbSendLength, 0, bRecvBuffer, &cbRecvLength);
  919. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  920. {
  921. DBG_PRINT(TEXT("Check data unit size failed"));
  922. RETURN (CRYPT_FAILED, SCARD_E_DIR_NOT_FOUND);
  923. }
  924. if (bRecvBuffer[11] & 0x40) // LOCK1 & 0x40
  925. ProvCont[hProv].dataUnitSize = 1;
  926. else
  927. ProvCont[hProv].dataUnitSize = 4;
  928. }
  929. RETURN (CRYPT_SUCCEED, 0);
  930. }
  931. /*------------------------------------------------------------------------------
  932. ------------------------------------------------------------------------------*/
  933. static int get_pin_free(HCRYPTPROV hProv)
  934. {
  935. DWORD lRet;
  936. int nPinFree,
  937. nb, val; // [JMR 02-04]
  938. /* Select GPK PIN EF */
  939. bSendBuffer[0] = 0x00; //CLA
  940. bSendBuffer[1] = 0xA4; //INS
  941. bSendBuffer[2] = 0x02; //P1
  942. bSendBuffer[3] = 0x0C; //P2
  943. bSendBuffer[4] = 0x02; //Li
  944. bSendBuffer[5] = HIBYTE(GPK_PIN_EF);
  945. bSendBuffer[6] = LOBYTE(GPK_PIN_EF);
  946. cbSendLength = 7;
  947. cbRecvLength = sizeof(bRecvBuffer);
  948. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  949. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  950. if (SCARDPROBLEM(lRet,0x9000,0x00))
  951. {
  952. SetLastError(lRet);
  953. return (-1);
  954. }
  955. /* Get EF information for User PIN Code (code 0) */
  956. bSendBuffer[0] = 0x80; //CLA
  957. bSendBuffer[1] = 0xC0; //INS
  958. bSendBuffer[2] = 0x02; //P1
  959. bSendBuffer[3] = 0x05; //P2
  960. bSendBuffer[4] = 0x0C; //Lo 4*number of secret codes
  961. cbSendLength = 5;
  962. cbRecvLength = sizeof(bRecvBuffer);
  963. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  964. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  965. if (SCARDPROBLEM(lRet,0x9000, bSendBuffer[4]))
  966. {
  967. SetLastError(SCARD_E_UNEXPECTED);
  968. return (-1);
  969. }
  970. // [JMR 02-04] begin
  971. nb = 0;
  972. val = bRecvBuffer[1];
  973. while (val > 0)
  974. {
  975. nb++;
  976. val = val >> 1;
  977. }
  978. nPinFree = bRecvBuffer[0] - nb;
  979. // [JMR 02-04] end
  980. SetLastError(0);
  981. return (max(0, nPinFree));
  982. }
  983. /*------------------------------------------------------------------------------
  984. ------------------------------------------------------------------------------*/
  985. static BOOL verify_pin( HCRYPTPROV hProv,
  986. const char* pPin,
  987. DWORD dwPinLen
  988. )
  989. {
  990. DWORD lRet;
  991. /* Verify User PIN Code (code 0) */
  992. bSendBuffer[0] = 0x00; //CLA
  993. bSendBuffer[1] = 0x20; //INS
  994. bSendBuffer[2] = 0x00; //P1
  995. bSendBuffer[3] = 0x00; //P2
  996. bSendBuffer[4] = 0x08; //Li
  997. // TT 22/09/99: New PIN padding for GPK8000
  998. if (ProvCont[hProv].bGPK_ISO_DF)
  999. {
  1000. memset(&bSendBuffer[5], 0xFF, 8 );
  1001. memcpy(&bSendBuffer[5], pPin, min(strlen(pPin)+1,8) );
  1002. }
  1003. else
  1004. {
  1005. memset(&bSendBuffer[5], 0x00, 8);
  1006. memcpy(&bSendBuffer[5], pPin, dwPinLen);
  1007. }
  1008. // TT - END -
  1009. cbSendLength = 5 + bSendBuffer[4];
  1010. cbRecvLength = sizeof(bRecvBuffer);
  1011. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  1012. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  1013. if (SCARDPROBLEM(lRet,0x9000,0x00))
  1014. {
  1015. RETURN(CRYPT_FAILED, SCARD_W_WRONG_CHV);
  1016. }
  1017. RETURN(CRYPT_SUCCEED, 0);
  1018. }
  1019. /*------------------------------------------------------------------------------
  1020. ------------------------------------------------------------------------------*/
  1021. static BOOL change_pin(HCRYPTPROV hProv,
  1022. BYTE secretCode,
  1023. const char* a_pOldPin,
  1024. DWORD dwOldPinLen,
  1025. const char* a_pNewPin,
  1026. DWORD dwNewPinLen
  1027. )
  1028. {
  1029. DWORD lRet;
  1030. // TT - 17/10/2000 - Update the timestamps
  1031. Slot_Description* pSlot = &Slot[ProvCont[hProv].Slot];
  1032. ++pSlot->m_TSPIN;
  1033. if (0 == pSlot->m_TSPIN)
  1034. pSlot->m_TSPIN = 1;
  1035. if (!WriteTimestamps( hProv, pSlot->m_TSPublic, pSlot->m_TSPrivate, pSlot->m_TSPIN ))
  1036. return CRYPT_FAILED;
  1037. // TT - END -
  1038. // TT 22/09/99: New PIN padding for GPK8000
  1039. char pOldPin[PIN_MAX];
  1040. char pNewPin[PIN_MAX];
  1041. strncpy( pOldPin, a_pOldPin, PIN_MAX );
  1042. strncpy( pNewPin, a_pNewPin, PIN_MAX );
  1043. if (ProvCont[hProv].bGPK_ISO_DF)
  1044. {
  1045. if (dwOldPinLen < PIN_MAX)
  1046. {
  1047. pOldPin[dwOldPinLen] = 0;
  1048. ++dwOldPinLen;
  1049. while (dwOldPinLen != PIN_MAX)
  1050. {
  1051. pOldPin[dwOldPinLen] = '\xFF';
  1052. ++dwOldPinLen;
  1053. }
  1054. }
  1055. if (dwNewPinLen < PIN_MAX)
  1056. {
  1057. pNewPin[dwNewPinLen] = 0;
  1058. ++dwNewPinLen;
  1059. while (dwNewPinLen != PIN_MAX)
  1060. {
  1061. pNewPin[dwNewPinLen] = '\xFF';
  1062. ++dwNewPinLen;
  1063. }
  1064. }
  1065. }
  1066. // TT - END -
  1067. /* Change User PIN Code (code 0) */
  1068. bSendBuffer[0] = 0x80; //CLA
  1069. bSendBuffer[1] = 0x24; //INS
  1070. bSendBuffer[2] = 0x00; //P1
  1071. bSendBuffer[3] = secretCode; //P2
  1072. bSendBuffer[4] = 0x08; //Li
  1073. memset(&bSendBuffer[5], 0x00, 8);
  1074. conv_hex(pOldPin, (WORD)dwOldPinLen, &bSendBuffer[5]);
  1075. conv_hex(pNewPin, (WORD)dwNewPinLen, &bSendBuffer[9]);
  1076. cbSendLength = 5 + bSendBuffer[4];
  1077. cbRecvLength = sizeof(bRecvBuffer);
  1078. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  1079. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  1080. if (SCARDPROBLEM(lRet,0x9000,0x00))
  1081. {
  1082. RETURN(CRYPT_FAILED, SCARD_W_WRONG_CHV);
  1083. }
  1084. RETURN(CRYPT_SUCCEED, 0);
  1085. }
  1086. /* -----------------------------------------------------------------------------
  1087. --------------------------------------------------------------------------------*/
  1088. BOOL StopMonitor( DWORD SlotNb, DWORD* pThreadExitCode )
  1089. {
  1090. HANDLE hThread;
  1091. DWORD threadExitCode;
  1092. DWORD dwStatus;
  1093. if (SlotNb >= MAX_SLOT)
  1094. {
  1095. SetLastError( NTE_FAIL );
  1096. return FALSE;
  1097. }
  1098. hThread = Slot[SlotNb].CheckThread;
  1099. Slot[SlotNb].CheckThread = NULL;
  1100. Slot[SlotNb].CheckThreadStateEmpty = FALSE;
  1101. if (hThread==NULL)
  1102. {
  1103. return TRUE;
  1104. }
  1105. g_fStopMonitor[SlotNb] = TRUE;
  1106. SCardCancel( hCardContextCheck[SlotNb] );
  1107. dwStatus = WaitForSingleObject( hThread, 30000 );
  1108. if (dwStatus == WAIT_TIMEOUT)
  1109. {
  1110. DBG_PRINT( TEXT("THREAD: ...WaitForSingleObject() timeout, thread handle: %08x"), hThread );
  1111. // + [FP]
  1112. // TerminateThread( hThread, 0 );
  1113. // - [FP]
  1114. }
  1115. else
  1116. if (dwStatus == WAIT_FAILED)
  1117. {
  1118. DBG_PRINT( TEXT("THREAD: ...WaitForSingleObject() failed!, thread handle: %08x"), hThread );
  1119. return FALSE;
  1120. }
  1121. GetExitCodeThread( hThread, &threadExitCode );
  1122. if (pThreadExitCode) *pThreadExitCode = threadExitCode;
  1123. CloseHandle( hThread );
  1124. return TRUE;
  1125. }
  1126. /* -----------------------------------------------------------------------------
  1127. Function: CheckReaderThead
  1128. Out:
  1129. ExitCode:
  1130. 0 = any scard error
  1131. 1 = scard context has been cancelled
  1132. 2 = card has been removed
  1133. Global variables
  1134. g_fStopMonitor[SlotNb] can stops the thread
  1135. --------------------------------------------------------------------------------*/
  1136. unsigned WINAPI CheckReaderThread( void* lpParameter )
  1137. {
  1138. DWORD lRet, ExitCode;
  1139. DWORD SlotNb = (DWORD)((DWORD_PTR)lpParameter);
  1140. ExitCode = 0;
  1141. if (SlotNb >= MAX_SLOT)
  1142. {
  1143. return ExitCode;
  1144. }
  1145. DBG_PRINT(TEXT("CheckReaderThread on Slot %d\n"),SlotNb);
  1146. if (hCardContextCheck[SlotNb] == 0)
  1147. {
  1148. lRet = SCardEstablishContext (SCARD_SCOPE_SYSTEM, 0, 0, &hCardContextCheck[SlotNb]);
  1149. if (lRet != SCARD_S_SUCCESS)
  1150. {
  1151. DBG_PRINT(TEXT("CheckReaderThread. SCardEstablishContext returns 0x%x\n"),lRet);
  1152. return ExitCode;
  1153. }
  1154. }
  1155. while (( !ExitCode) && (!g_fStopMonitor[SlotNb]))
  1156. {
  1157. lRet = SCardGetStatusChange(hCardContextCheck[SlotNb], INFINITE, &Slot[SlotNb].ReaderState, 1);
  1158. if (lRet == SCARD_E_CANCELLED)
  1159. {
  1160. ExitCode = 1;
  1161. }
  1162. else
  1163. {
  1164. if (lRet == SCARD_S_SUCCESS)
  1165. {
  1166. if (Slot[SlotNb].ReaderState.dwEventState & SCARD_STATE_EMPTY)
  1167. {
  1168. DBG_PRINT(TEXT("Card has been removed"));
  1169. Slot[SlotNb].CheckThreadStateEmpty = TRUE;
  1170. GpkLocalLock();
  1171. // TT 19/11/99: When the card is removed, reset the PIN
  1172. // Slot[SlotNb].ClearPin();NK 06.02.2001
  1173. Flush_MSPinCache(&(Slot[SlotNb].hPinCacheHandle));
  1174. Slot[SlotNb].Read_Public = FALSE;
  1175. Slot[SlotNb].Read_Priv = FALSE;
  1176. zap_gpk_objects( SlotNb, FALSE );
  1177. zap_gpk_objects( SlotNb, TRUE );
  1178. Slot[SlotNb].NbKeyFile = 0;
  1179. Slot[SlotNb].GpkMaxSessionKey = 0;
  1180. GpkLocalUnlock();
  1181. // the thread has done is job, exit.
  1182. ExitCode = 2 ;
  1183. }
  1184. else
  1185. {
  1186. Slot[SlotNb].ReaderState.dwCurrentState = Slot[SlotNb].ReaderState.dwEventState;
  1187. }
  1188. }
  1189. // [FP] stop the thread on any other error returned by
  1190. //SCardGetStatusChange to avoid endless loop
  1191. else
  1192. {
  1193. DBG_PRINT(TEXT("Problem with RM"));
  1194. Slot[SlotNb].CheckThreadStateEmpty = TRUE;
  1195. GpkLocalLock();
  1196. // Slot[SlotNb].ClearPin();NK 06.02.2001
  1197. Flush_MSPinCache(&(Slot[SlotNb].hPinCacheHandle));
  1198. Slot[SlotNb].Read_Public = FALSE;
  1199. Slot[SlotNb].Read_Priv = FALSE;
  1200. zap_gpk_objects( SlotNb, FALSE );
  1201. zap_gpk_objects( SlotNb, TRUE );
  1202. Slot[SlotNb].NbKeyFile = 0;
  1203. Slot[SlotNb].GpkMaxSessionKey = 0;
  1204. //Slot[SlotNb].CheckThread = 0;
  1205. GpkLocalUnlock();
  1206. ExitCode = 2;
  1207. }
  1208. }
  1209. }
  1210. if (hCardContextCheck[SlotNb] != 0)
  1211. {
  1212. SCardReleaseContext( hCardContextCheck[SlotNb] );
  1213. hCardContextCheck[SlotNb] = 0;
  1214. }
  1215. return ExitCode;
  1216. }
  1217. /*------------------------------------------------------------------------------
  1218. ------------------------------------------------------------------------------*/
  1219. BOOL BeginCheckReaderThread(DWORD SlotNb)
  1220. {
  1221. unsigned checkThreadId;
  1222. DWORD lRet;
  1223. SCARDCONTEXT hCardContextThread;
  1224. if (SlotNb >= MAX_SLOT)
  1225. {
  1226. SetLastError( NTE_FAIL );
  1227. return FALSE;
  1228. }
  1229. // Monitoring thread
  1230. if (Slot[SlotNb].CheckThread == NULL)
  1231. {
  1232. // In this case, use an auxiliairy thread to check if the card has
  1233. // been removed from this reader.
  1234. // checks the initial state
  1235. lRet = SCardEstablishContext (SCARD_SCOPE_SYSTEM, 0, 0, &hCardContextThread);
  1236. if (lRet != SCARD_S_SUCCESS)
  1237. {
  1238. return FALSE;
  1239. }
  1240. Slot[SlotNb].ReaderState.szReader = Slot[SlotNb].szReaderName;
  1241. Slot[SlotNb].ReaderState.dwCurrentState = SCARD_STATE_UNAWARE;
  1242. lRet = SCardGetStatusChange(hCardContextThread, 1, &Slot[SlotNb].ReaderState, 1);
  1243. if (hCardContextThread != 0)
  1244. {
  1245. SCardReleaseContext( hCardContextThread );
  1246. hCardContextCheck[SlotNb] = 0;
  1247. }
  1248. if (lRet != SCARD_S_SUCCESS)
  1249. {
  1250. return FALSE;
  1251. }
  1252. Slot[SlotNb].ReaderState.dwCurrentState = Slot[SlotNb].ReaderState.dwEventState;
  1253. // Allocate and trigger the thread, if there is a card
  1254. g_fStopMonitor[SlotNb] = FALSE;
  1255. Slot[SlotNb].CheckThreadStateEmpty = FALSE;
  1256. if (Slot[SlotNb].ReaderState.dwEventState & SCARD_STATE_PRESENT)
  1257. {
  1258. Slot[SlotNb].CheckThread = (HANDLE)_beginthreadex( 0, 0, CheckReaderThread,
  1259. (LPVOID)((DWORD_PTR)SlotNb), 0, &checkThreadId );
  1260. }
  1261. }
  1262. return TRUE;
  1263. }
  1264. static BOOL PIN_Validation(HCRYPTPROV hProv)
  1265. {
  1266. BOOL CryptResp;
  1267. DWORD nPinFree;
  1268. DWORD SlotNb;
  1269. TCHAR szCspTitle[MAX_STRING];
  1270. PINCACHE_PINS Pins;
  1271. DWORD dwStatus;
  1272. SlotNb = ProvCont[hProv].Slot;
  1273. // Get PIN free presentation number
  1274. nPinFree = get_pin_free(hProv);
  1275. // The flags of the context should be passed to the GUI functions with the global variable
  1276. CspFlags = ProvCont[hProv].Flags;
  1277. // Failure to retreive PIN free presentation count (-1)
  1278. if ( nPinFree == DWORD(-1) )
  1279. {
  1280. // Slot[SlotNb].ClearPin();
  1281. Flush_MSPinCache( &(Slot[SlotNb].hPinCacheHandle) );
  1282. RETURN ( CRYPT_FAILED, NTE_FAIL );
  1283. }
  1284. // PIN is locked
  1285. if ( nPinFree == 0 )
  1286. {
  1287. // Slot[SlotNb].ClearPin();
  1288. Flush_MSPinCache( &(Slot[SlotNb].hPinCacheHandle) );
  1289. if ( ProvCont[hProv].Flags & CRYPT_SILENT )
  1290. {
  1291. RETURN ( CRYPT_FAILED, SCARD_W_CHV_BLOCKED );
  1292. }
  1293. else
  1294. {
  1295. LoadString( g_hInstMod, IDS_GPKCSP_TITLE, szCspTitle, sizeof(szCspTitle)/sizeof(TCHAR) );
  1296. DisplayMessage( TEXT("locked"), szCspTitle, 0 );
  1297. RETURN ( CRYPT_FAILED, SCARD_W_CHV_BLOCKED );
  1298. }
  1299. }
  1300. // Normal PIN verification
  1301. // dwGpkPinLen = strlen(Slot[SlotNb].GetPin());
  1302. dwGpkPinLen = PIN_LEN + 1;
  1303. dwStatus = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  1304. (BYTE*)szGpkPin,
  1305. &dwGpkPinLen );
  1306. if ( (dwStatus != ERROR_SUCCESS) && (dwStatus != ERROR_EMPTY) )
  1307. RETURN (CRYPT_FAILED, dwStatus);
  1308. bNewPin = FALSE;
  1309. bChangePin = FALSE;
  1310. if ( dwStatus == ERROR_EMPTY )
  1311. {
  1312. if (ProvCont[hProv].Flags & CRYPT_SILENT)
  1313. {
  1314. RETURN ( CRYPT_FAILED, NTE_SILENT_CONTEXT );
  1315. }
  1316. Select_MF( hProv );
  1317. SCardEndTransaction( ProvCont[hProv].hCard, SCARD_LEAVE_CARD );
  1318. DialogBox( g_hInstRes, TEXT("PINDIALOG"), GetAppWindow(), (DLGPROC)PinDlgProc );
  1319. if ( dwGpkPinLen == 0 )
  1320. {
  1321. RETURN( CRYPT_FAILED, SCARD_W_CANCELLED_BY_USER );
  1322. }
  1323. else
  1324. {
  1325. if ( !Coherent(hProv) )
  1326. RETURN ( CRYPT_FAILED, NTE_FAIL );
  1327. // Slot[SlotNb].SetPin( szGpkPin );
  1328. if (!bChangePin)
  1329. PopulatePins( &Pins, (BYTE *)szGpkPin, dwGpkPinLen, 0, 0 );
  1330. else
  1331. PopulatePins( &Pins, (BYTE *)szGpkPin, dwGpkPinLen, (BYTE *)szGpkNewPin, wGpkNewPinLen );
  1332. dwStatus = Add_MSPinCache( &(Slot[SlotNb].hPinCacheHandle),
  1333. &Pins,
  1334. Callback_VerifyChangePin2,
  1335. (void*)hProv );
  1336. if ( dwStatus != ERROR_SUCCESS && dwStatus != SCARD_W_WRONG_CHV )
  1337. {
  1338. RETURN ( CRYPT_FAILED, dwStatus );
  1339. }
  1340. }
  1341. }
  1342. else
  1343. {
  1344. CryptResp = verify_pin( hProv, szGpkPin, dwGpkPinLen );
  1345. if ( CryptResp )
  1346. {
  1347. dwStatus = ERROR_SUCCESS;
  1348. }
  1349. else
  1350. {
  1351. Flush_MSPinCache( &(Slot[SlotNb].hPinCacheHandle) );
  1352. dwStatus = SCARD_W_WRONG_CHV;
  1353. }
  1354. }
  1355. if ( dwStatus != ERROR_SUCCESS )
  1356. {
  1357. if ( ProvCont[hProv].Flags & CRYPT_SILENT )
  1358. {
  1359. // Slot[SlotNb].ClearPin();
  1360. //Flush_MSPinCache( &(Slot[SlotNb].hPinCacheHandle) );
  1361. RETURN ( CRYPT_FAILED, SCARD_W_WRONG_CHV );
  1362. }
  1363. do
  1364. {
  1365. bNewPin = FALSE;
  1366. bChangePin = FALSE;
  1367. nPinFree = get_pin_free(hProv);
  1368. // Failure to retrieve PIN free presentation count (-1)
  1369. if ( nPinFree == DWORD(-1) )
  1370. {
  1371. // Slot[SlotNb].ClearPin();
  1372. //Flush_MSPinCache(&(Slot[SlotNb].hPinCacheHandle));
  1373. RETURN ( CRYPT_FAILED, NTE_FAIL );
  1374. }
  1375. else if ( nPinFree > 0 )
  1376. {
  1377. LoadString( g_hInstMod, IDS_GPKCSP_TITLE, szCspTitle, sizeof(szCspTitle)/sizeof(TCHAR) );
  1378. DisplayMessage( TEXT("badpin"), szCspTitle, &nPinFree );
  1379. Select_MF( hProv );
  1380. SCardEndTransaction( ProvCont[hProv].hCard, SCARD_LEAVE_CARD );
  1381. DialogBox( g_hInstRes, TEXT("PINDIALOG"), GetAppWindow(), (DLGPROC)PinDlgProc );
  1382. if (dwGpkPinLen != 0)
  1383. {
  1384. if ( !Coherent(hProv) )
  1385. RETURN ( CRYPT_FAILED, NTE_FAIL );
  1386. if (!bChangePin)
  1387. PopulatePins( &Pins, (BYTE *)szGpkPin, dwGpkPinLen, 0, 0 );
  1388. else
  1389. PopulatePins( &Pins, (BYTE *)szGpkPin, dwGpkPinLen, (BYTE *)szGpkNewPin, wGpkNewPinLen );
  1390. dwStatus = Add_MSPinCache( &(Slot[SlotNb].hPinCacheHandle),
  1391. &Pins,
  1392. Callback_VerifyChangePin2,
  1393. (void*)hProv );
  1394. if ( dwStatus != ERROR_SUCCESS && dwStatus != SCARD_W_WRONG_CHV )
  1395. {
  1396. RETURN ( CRYPT_FAILED, dwStatus );
  1397. }
  1398. }
  1399. }
  1400. }
  1401. while ( dwStatus != ERROR_SUCCESS && dwGpkPinLen != 0 && nPinFree > 0 );
  1402. if ( dwStatus != ERROR_SUCCESS )
  1403. {
  1404. if ( nPinFree == 0 )
  1405. {
  1406. // Slot[SlotNb].ClearPin();
  1407. //Flush_MSPinCache(&(Slot[SlotNb].hPinCacheHandle));
  1408. if ( ProvCont[hProv].Flags & CRYPT_SILENT )
  1409. {
  1410. RETURN ( CRYPT_FAILED, SCARD_W_CHV_BLOCKED );
  1411. }
  1412. else
  1413. {
  1414. LoadString( g_hInstMod, IDS_GPKCSP_TITLE, szCspTitle, sizeof(szCspTitle)/sizeof(TCHAR) );
  1415. DisplayMessage( TEXT("locked"), szCspTitle, 0 );
  1416. RETURN( CRYPT_FAILED, SCARD_W_CHV_BLOCKED );
  1417. }
  1418. }
  1419. else
  1420. {
  1421. // Slot[SlotNb].ClearPin();
  1422. //Flush_MSPinCache(&(Slot[SlotNb].hPinCacheHandle));
  1423. RETURN( CRYPT_FAILED, SCARD_W_CANCELLED_BY_USER );
  1424. }
  1425. }
  1426. }
  1427. memset(szGpkPin, 0x00, PIN_MAX+2);
  1428. memset(szGpkNewPin, 0x00, PIN_MAX+2);
  1429. dwGpkPinLen = 0;
  1430. wGpkNewPinLen = 0;
  1431. RETURN(CRYPT_SUCCEED, 0);
  1432. }
  1433. /*------------------------------------------------------------------------------
  1434. ------------------------------------------------------------------------------*/
  1435. BOOL VerifyDivPIN(HCRYPTPROV hProv, BOOL Local)
  1436. {
  1437. DWORD lRet;
  1438. BYTE MKey[9] = "F1961ACF";
  1439. BYTE ChipSN[8];
  1440. BYTE Data[16];
  1441. BYTE hashData[20];
  1442. DWORD cbData = 20;
  1443. BYTE DivPIN[8];
  1444. HCRYPTHASH hHash = 0;
  1445. // Get Chip Serial Number
  1446. bSendBuffer[0] = 0x80; //CLA
  1447. bSendBuffer[1] = 0xC0; //INS
  1448. bSendBuffer[2] = 0x02; //P1
  1449. bSendBuffer[3] = 0xA0; //P2
  1450. bSendBuffer[4] = 0x08; //Lo
  1451. cbSendLength = 5;
  1452. cbRecvLength = sizeof(bRecvBuffer);
  1453. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  1454. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  1455. if (SCARDPROBLEM(lRet,0x9000, bSendBuffer[4]))
  1456. {
  1457. RETURN (CRYPT_FAILED, SCARD_E_UNEXPECTED);
  1458. }
  1459. ZeroMemory( ChipSN, sizeof(ChipSN) );
  1460. memcpy(ChipSN, bRecvBuffer, bSendBuffer[4]);
  1461. // Create Data buffer
  1462. memcpy(&Data[0], MKey, 8);
  1463. memcpy(&Data[8], ChipSN, 8);
  1464. // Create a hash object
  1465. if (!CryptCreateHash(hProvBase, CALG_SHA, 0, 0, &hHash))
  1466. return CRYPT_FAILED;
  1467. // hash data
  1468. if (!CryptHashData(hHash, Data, 16, 0))
  1469. {
  1470. lRet = GetLastError();
  1471. CryptDestroyHash(hHash);
  1472. RETURN (CRYPT_FAILED, lRet);
  1473. }
  1474. // get the hash value
  1475. ZeroMemory( hashData, sizeof(hashData) );
  1476. if (!CryptGetHashParam(hHash, HP_HASHVAL, hashData, &cbData, 0))
  1477. {
  1478. lRet = GetLastError();
  1479. CryptDestroyHash(hHash);
  1480. RETURN (CRYPT_FAILED, lRet);
  1481. }
  1482. // get the last 8 bytes of the hash value as diversified PIN
  1483. memcpy(DivPIN, &hashData[20-8], 8);
  1484. CryptDestroyHash(hHash);
  1485. // Send the VERIFY COMMAND to the card
  1486. bSendBuffer[0] = 0x00; //CLA
  1487. bSendBuffer[1] = 0x20; //INS
  1488. bSendBuffer[2] = 0x00; //P1
  1489. if (Local)
  1490. {
  1491. bSendBuffer[3] = 0x02; //P2 -> Locally it is the second PIN
  1492. }
  1493. else
  1494. {
  1495. bSendBuffer[3] = 0x00; //P2 -> At the MF level it is the first PIN
  1496. }
  1497. bSendBuffer[4] = 0x08; //Li
  1498. memset(&bSendBuffer[5], 0x00, 8);
  1499. memcpy(&bSendBuffer[5], DivPIN, 8);
  1500. cbSendLength = 5 + bSendBuffer[4];
  1501. cbRecvLength = sizeof(bRecvBuffer);
  1502. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  1503. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  1504. if (SCARDPROBLEM(lRet,0x9000,0x00))
  1505. {
  1506. RETURN( CRYPT_FAILED, SCARD_E_INVALID_CHV );
  1507. }
  1508. RETURN( CRYPT_SUCCEED, 0 );
  1509. }
  1510. /*------------------------------------------------------------------------------
  1511. ------------------------------------------------------------------------------*/
  1512. static DWORD Select_Crypto_DF(HCRYPTPROV hProv)
  1513. {
  1514. static BYTE GPK8000_ISO_DF[] = { 0xA0,0,0,0,0x18,0xF,0,1,0x63,0,1 };
  1515. DWORD lRet;
  1516. BOOL CryptResp;
  1517. // This function is used to avoid to presuppose the state in which the
  1518. // card might be in
  1519. BOOL fAgain = TRUE;
  1520. int iRetryLimit = 3;
  1521. while (fAgain)
  1522. {
  1523. if (0 == iRetryLimit--)
  1524. fAgain = FALSE;
  1525. else
  1526. {
  1527. CryptResp = Select_MF(hProv);
  1528. if (CryptResp)
  1529. fAgain = FALSE;
  1530. else
  1531. Sleep(250);
  1532. }
  1533. }
  1534. if (iRetryLimit < 0)
  1535. {
  1536. DBG_PRINT(TEXT("Select_MF failed"));
  1537. return CRYPT_FAILED;
  1538. }
  1539. // TT 22/09/99 : We now check for ISO 7816-5 compliant GPK8000
  1540. ProvCont[hProv].bGPK_ISO_DF = FALSE;
  1541. bSendBuffer[0] = 0x00;
  1542. bSendBuffer[1] = 0xA4; // Select File
  1543. bSendBuffer[2] = 0x04; // Select DF by name
  1544. bSendBuffer[3] = 0x00; // We want a response
  1545. bSendBuffer[4] = sizeof(GPK8000_ISO_DF);
  1546. memcpy( &bSendBuffer[5], GPK8000_ISO_DF, sizeof(GPK8000_ISO_DF) );
  1547. cbSendLength = sizeof(GPK8000_ISO_DF) + 5;
  1548. cbRecvLength = sizeof(bRecvBuffer);
  1549. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  1550. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  1551. // TT 17/11/99: Must check the status bytes
  1552. if (!(SCARDPROBLEM(lRet,0x61FF,0x00)))
  1553. {
  1554. ProvCont[hProv].bGPK_ISO_DF = TRUE;
  1555. }
  1556. else
  1557. {
  1558. // Select Dedicated Application DF on GPK Card
  1559. BYTE lenDF = strlen(GPK_DF);
  1560. bSendBuffer[0] = 0x00; //CLA
  1561. bSendBuffer[1] = 0xA4; //INS
  1562. bSendBuffer[2] = 0x04; //P1
  1563. bSendBuffer[3] = 0x00; //P2
  1564. bSendBuffer[4] = lenDF;
  1565. memcpy( &bSendBuffer[5], GPK_DF, lenDF );
  1566. cbSendLength = 5 + lenDF;
  1567. cbRecvLength = sizeof(bRecvBuffer);
  1568. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  1569. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  1570. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  1571. {
  1572. DBG_PRINT(TEXT("Select DF failed"));
  1573. RETURN (CRYPT_FAILED, SCARD_E_DIR_NOT_FOUND);
  1574. }
  1575. }
  1576. RETURN (CRYPT_SUCCEED, 0);
  1577. }
  1578. /*------------------------------------------------------------------------------
  1579. ------------------------------------------------------------------------------*/
  1580. static BOOL card_is_present (HCRYPTPROV hProv)
  1581. {
  1582. DWORD lRet;
  1583. DWORD SlotNb;
  1584. SlotNb = ProvCont[hProv].Slot;
  1585. /* Read Serial number to check if card is present */
  1586. bSendBuffer[0] = 0x80; //CLA
  1587. bSendBuffer[1] = 0xC0; //INS
  1588. bSendBuffer[2] = 0x02; //P1
  1589. bSendBuffer[3] = 0xA0; //P2
  1590. bSendBuffer[4] = 0x08; //Lo
  1591. cbSendLength = 5;
  1592. cbRecvLength = sizeof(bRecvBuffer);
  1593. lRet = SCardTransmit(ProvCont[hProv].hCard,
  1594. SCARD_PCI_T0,
  1595. bSendBuffer,
  1596. cbSendLength,
  1597. NULL,
  1598. bRecvBuffer,
  1599. &cbRecvLength
  1600. );
  1601. if (SCARDPROBLEM(lRet,0x9000, bSendBuffer[4]))
  1602. {
  1603. RETURN (CRYPT_FAILED, SCARD_E_UNEXPECTED);
  1604. }
  1605. if (memcmp(bRecvBuffer, Slot[SlotNb].bGpkSerNb, bSendBuffer[4]))
  1606. {
  1607. RETURN (CRYPT_FAILED, SCARD_W_REMOVED_CARD);
  1608. }
  1609. RETURN (CRYPT_SUCCEED, 0);
  1610. }
  1611. /*------------------------------------------------------------------------------
  1612. ------------------------------------------------------------------------------*/
  1613. static DWORD Auxiliary_CSP_key_size (DWORD AlgId)
  1614. {
  1615. DWORD i, dwFlags, cbData,dwBits, res;
  1616. BYTE pbData[1000], *ptr;
  1617. ALG_ID aiAlgid;
  1618. res = 0;
  1619. // Enumerate Algo.
  1620. for (i=0 ; ; i++)
  1621. {
  1622. if (i == 0)
  1623. dwFlags = CRYPT_FIRST;
  1624. else
  1625. dwFlags = 0;
  1626. // Retrieve information about an algorithm.
  1627. cbData = sizeof (pbData);
  1628. SetLastError(0);
  1629. if (!CryptGetProvParam(hProvBase, PP_ENUMALGS, pbData, &cbData, dwFlags))
  1630. {
  1631. break;
  1632. }
  1633. // Extract algorithm information from the �pbData� buffer.
  1634. ptr = pbData;
  1635. aiAlgid = *(ALG_ID UNALIGNED *)ptr;
  1636. if (aiAlgid == AlgId)
  1637. {
  1638. ptr += sizeof(ALG_ID);
  1639. dwBits = *(DWORD UNALIGNED *)ptr;
  1640. res = dwBits;
  1641. break;
  1642. }
  1643. }
  1644. return res;
  1645. }
  1646. /*------------------------------------------------------------------------------
  1647. ------------------------------------------------------------------------------*/
  1648. static BOOL copy_gpk_key( HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwAlgid )
  1649. {
  1650. BOOL CryptResp;
  1651. DWORD dwDataLen;
  1652. BYTE pbData[1024];
  1653. DWORD SlotNb;
  1654. SlotNb = ProvCont[hProv].Slot;
  1655. NoDisplay = TRUE;
  1656. if ((hKey >= 1) && (hKey <= MAX_GPK_OBJ))
  1657. {
  1658. dwDataLen = sizeof(pbData);
  1659. ZeroMemory( pbData, sizeof(pbData) );
  1660. if (MyCPExportKey(hProv, hKey, 0, PUBLICKEYBLOB, 0, pbData, &dwDataLen))
  1661. {
  1662. if (dwAlgid == AT_KEYEXCHANGE)
  1663. {
  1664. if (ProvCont[hProv].hRSAKEK != 0)
  1665. {
  1666. CryptResp = CryptDestroyKey (ProvCont[hProv].hRSAKEK);
  1667. if (!CryptResp)
  1668. {
  1669. NoDisplay = FALSE;
  1670. return CRYPT_FAILED;
  1671. }
  1672. ProvCont[hProv].hRSAKEK = 0;
  1673. }
  1674. CryptResp = CryptImportKey( hProvBase, pbData, dwDataLen, 0, 0,
  1675. &ProvCont[hProv].hRSAKEK );
  1676. //Slot[SlotNb].GpkObject[hKey].hKeyBase = ProvCont[hProv].hRSAKEK;
  1677. }
  1678. else
  1679. {
  1680. if (ProvCont[hProv].hRSASign!= 0)
  1681. {
  1682. CryptResp = CryptDestroyKey (ProvCont[hProv].hRSASign);
  1683. if (!CryptResp)
  1684. {
  1685. NoDisplay = FALSE;
  1686. return CRYPT_FAILED;
  1687. }
  1688. ProvCont[hProv].hRSASign = 0;
  1689. }
  1690. CryptResp = CryptImportKey( hProvBase, pbData, dwDataLen, 0, 0,
  1691. &ProvCont[hProv].hRSASign );
  1692. //Slot[SlotNb].GpkObject[hKey].hKeyBase = ProvCont[hProv].hRSASign;
  1693. }
  1694. if (!CryptResp)
  1695. {
  1696. NoDisplay = FALSE;
  1697. return CRYPT_FAILED;
  1698. }
  1699. }
  1700. else
  1701. {
  1702. NoDisplay = FALSE;
  1703. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  1704. }
  1705. }
  1706. else
  1707. {
  1708. NoDisplay = FALSE;
  1709. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  1710. }
  1711. NoDisplay = FALSE;
  1712. RETURN(CRYPT_SUCCEED, 0);
  1713. }
  1714. /*------------------------------------------------------------------------------
  1715. ------------------------------------------------------------------------------*/
  1716. static BOOL Select_Key_File(HCRYPTPROV hProv, int KeyFileId)
  1717. {
  1718. DWORD lRet;
  1719. BOOL CryptResp;
  1720. CryptResp = Select_Crypto_DF(hProv);
  1721. if (!CryptResp)
  1722. return CRYPT_FAILED;
  1723. /* Select Key File on GPK Card */
  1724. bSendBuffer[0] = 0x00; //CLA
  1725. bSendBuffer[1] = 0xA4; //INS
  1726. bSendBuffer[2] = 0x02; //P1
  1727. bSendBuffer[3] = 0x0C; //P2
  1728. bSendBuffer[4] = 0x02; //Li
  1729. bSendBuffer[5] = HIBYTE(KeyFileId);
  1730. bSendBuffer[6] = LOBYTE(KeyFileId);
  1731. cbSendLength = 7;
  1732. cbRecvLength = sizeof(bRecvBuffer);
  1733. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  1734. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  1735. if (SCARDPROBLEM(lRet,0x9000,0x00))
  1736. {
  1737. RETURN (CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND);
  1738. }
  1739. RETURN (CRYPT_SUCCEED, 0);
  1740. }
  1741. /*------------------------------------------------------------------------------
  1742. ------------------------------------------------------------------------------*/
  1743. static DWORD Read_NbKeyFile(HCRYPTPROV hProv)
  1744. {
  1745. DWORD i = 0;
  1746. while ((i<MAX_REAL_KEY) && Select_Key_File(hProv, GPK_FIRST_KEY + i))
  1747. i++;
  1748. return i;
  1749. }
  1750. /*------------------------------------------------------------------------------
  1751. ------------------------------------------------------------------------------*/
  1752. static void perso_public(HCRYPTPROV hProv, int Start)
  1753. {
  1754. DWORD i, j;
  1755. DWORD SlotNb;
  1756. SlotNb = ProvCont[hProv].Slot;
  1757. for (i = 0; i < Slot[SlotNb].NbKeyFile; i++)
  1758. {
  1759. Slot[SlotNb].GpkObject[Start+4*i+1].IsPrivate = FALSE;
  1760. Slot[SlotNb].GpkObject[Start+4*i+1].Tag = TAG_RSA_PUBLIC;
  1761. Slot[SlotNb].GpkObject[Start+4*i+1].Flags = 0xF000; // Verify + Encrypt + Export + Modifiable
  1762. Slot[SlotNb].GpkObject[Start+4*i+1].FileId = LOBYTE(GPK_FIRST_KEY + i);
  1763. Slot[SlotNb].GpkObject[Start+4*i+2].IsPrivate = FALSE;
  1764. Slot[SlotNb].GpkObject[Start+4*i+2].Tag = TAG_RSA_PUBLIC;
  1765. Slot[SlotNb].GpkObject[Start+4*i+2].Flags = 0xD000; // Verify + Export + Modifiable
  1766. Slot[SlotNb].GpkObject[Start+4*i+2].FileId = LOBYTE(GPK_FIRST_KEY + i);
  1767. Slot[SlotNb].GpkObject[Start+4*i+3].IsPrivate = FALSE;
  1768. Slot[SlotNb].GpkObject[Start+4*i+3].Tag = TAG_RSA_PRIVATE;
  1769. Slot[SlotNb].GpkObject[Start+4*i+3].Flags = 0xB000; // Sign + Decrypt + Modifiable
  1770. Slot[SlotNb].GpkObject[Start+4*i+3].FileId = LOBYTE(GPK_FIRST_KEY + i);
  1771. Slot[SlotNb].GpkObject[Start+4*i+4].IsPrivate = FALSE;
  1772. Slot[SlotNb].GpkObject[Start+4*i+4].Tag = TAG_RSA_PRIVATE;
  1773. Slot[SlotNb].GpkObject[Start+4*i+4].Flags = 0x9000; // Sign + Modifiable
  1774. Slot[SlotNb].GpkObject[Start+4*i+4].FileId = LOBYTE(GPK_FIRST_KEY + i);
  1775. }
  1776. Slot[SlotNb].NbGpkObject = Start+LOBYTE(4*Slot[SlotNb].NbKeyFile);
  1777. for (i = Start+1; i <= Slot[SlotNb].NbGpkObject; i++)
  1778. {
  1779. for (j = 0; j < MAX_FIELD; j++)
  1780. {
  1781. Slot[SlotNb].GpkObject[i].Field[j].bReal = TRUE;
  1782. }
  1783. }
  1784. }
  1785. /*------------------------------------------------------------------------------
  1786. ------------------------------------------------------------------------------*/
  1787. static void perso_priv(HCRYPTPROV hProv, int Start)
  1788. {
  1789. DWORD i, j;
  1790. DWORD SlotNb;
  1791. SlotNb = ProvCont[hProv].Slot;
  1792. for (i = 0; i < Slot[SlotNb].NbKeyFile; i++)
  1793. {
  1794. Slot[SlotNb].GpkObject[Start+4*i+1].IsPrivate = TRUE;
  1795. Slot[SlotNb].GpkObject[Start+4*i+1].Tag = TAG_RSA_PUBLIC;
  1796. Slot[SlotNb].GpkObject[Start+4*i+1].Flags = 0xF000; // Verify + Encrypt + Export + Modifiable
  1797. Slot[SlotNb].GpkObject[Start+4*i+1].FileId = LOBYTE(GPK_FIRST_KEY+i);
  1798. Slot[SlotNb].GpkObject[Start+4*i+2].IsPrivate = TRUE;
  1799. Slot[SlotNb].GpkObject[Start+4*i+2].Tag = TAG_RSA_PUBLIC;
  1800. Slot[SlotNb].GpkObject[Start+4*i+2].Flags = 0xD000; // Verify + Export + Modifiable
  1801. Slot[SlotNb].GpkObject[Start+4*i+2].FileId = LOBYTE(GPK_FIRST_KEY+i);
  1802. Slot[SlotNb].GpkObject[Start+4*i+3].IsPrivate = TRUE;
  1803. Slot[SlotNb].GpkObject[Start+4*i+3].Tag = TAG_RSA_PRIVATE;
  1804. Slot[SlotNb].GpkObject[Start+4*i+3].Flags = 0xB000; // Sign + Decrypt + Modifiable
  1805. Slot[SlotNb].GpkObject[Start+4*i+3].FileId = LOBYTE(GPK_FIRST_KEY+i);
  1806. Slot[SlotNb].GpkObject[Start+4*i+4].IsPrivate = TRUE;
  1807. Slot[SlotNb].GpkObject[Start+4*i+4].Tag = TAG_RSA_PRIVATE;
  1808. Slot[SlotNb].GpkObject[Start+4*i+4].Flags = 0x9000; // Sign + Modifiable
  1809. Slot[SlotNb].GpkObject[Start+4*i+4].FileId = LOBYTE(GPK_FIRST_KEY+i);
  1810. }
  1811. Slot[SlotNb].NbGpkObject = Start+LOBYTE(4*Slot[SlotNb].NbKeyFile);
  1812. for (i = Start+1; i <= Slot[SlotNb].NbGpkObject; i++)
  1813. {
  1814. for (j = 0; j < MAX_FIELD; j++)
  1815. {
  1816. Slot[SlotNb].GpkObject[i].Field[j].bReal = TRUE;
  1817. }
  1818. }
  1819. }
  1820. /*------------------------------------------------------------------------------
  1821. ------------------------------------------------------------------------------*/
  1822. static void perso_card(HCRYPTPROV hProv, int Start)
  1823. {
  1824. perso_public (hProv, Start);
  1825. perso_priv (hProv, Slot[ProvCont[hProv].Slot].NbGpkObject);
  1826. }
  1827. /*------------------------------------------------------------------------------
  1828. ------------------------------------------------------------------------------*/
  1829. static void zap_gpk_objects( DWORD SlotNb, BOOL IsPrivate)
  1830. {
  1831. WORD
  1832. i, j;
  1833. if (IsPrivate)
  1834. {
  1835. for (i = 0; i <= MAX_GPK_OBJ; i++)
  1836. {
  1837. if ((Slot[SlotNb].GpkObject[i].IsPrivate) &&
  1838. (Slot[SlotNb].GpkObject[i].Tag > 0))
  1839. {
  1840. for (j = 0; j < MAX_FIELD; j++)
  1841. {
  1842. if (IsNotNull(Slot[SlotNb].GpkObject[i].Field[j].pValue))
  1843. {
  1844. GMEM_Free(Slot[SlotNb].GpkObject[i].Field[j].pValue);
  1845. }
  1846. }
  1847. for (j = i; j < Slot[SlotNb].NbGpkObject; j++)
  1848. {
  1849. Slot[SlotNb].GpkObject[j] = Slot[SlotNb].GpkObject[j+1];
  1850. }
  1851. ZeroMemory( &Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject], sizeof(GPK_OBJ));
  1852. // Since the object i+1 is now at position i, the new object i has to
  1853. // process again.
  1854. i--;
  1855. Slot[SlotNb].NbGpkObject--;
  1856. }
  1857. }
  1858. }
  1859. else
  1860. {
  1861. for (i = 0; i <= MAX_GPK_OBJ; i++)
  1862. {
  1863. for (j = 0; j < MAX_FIELD; j++)
  1864. {
  1865. if (IsNotNull(Slot[SlotNb].GpkObject[i].Field[j].pValue))
  1866. {
  1867. GMEM_Free(Slot[SlotNb].GpkObject[i].Field[j].pValue);
  1868. }
  1869. }
  1870. }
  1871. ZeroMemory( Slot[SlotNb].GpkObject, sizeof(Slot[SlotNb].GpkObject) );
  1872. ZeroMemory( Slot[SlotNb].GpkPubKeys, sizeof(Slot[SlotNb].GpkPubKeys) );
  1873. Slot[SlotNb].NbGpkObject = 0;
  1874. for (i = 0; i < MAX_REAL_KEY; i++) // version 2.00.002
  1875. Slot[SlotNb].UseFile[i] = FALSE;
  1876. }
  1877. }
  1878. /*------------------------------------------------------------------------------
  1879. ------------------------------------------------------------------------------*/
  1880. static void clean_card(HCRYPTPROV hProv)
  1881. {
  1882. /* Erase the GemSAFE objects of the cards BUT keep the other PKCS#11 objects */
  1883. WORD i, j;
  1884. DWORD SlotNb;
  1885. SlotNb = ProvCont[hProv].Slot;
  1886. for (i = 0; i <= Slot[SlotNb].NbGpkObject; i++)
  1887. {
  1888. if ((Slot[SlotNb].GpkObject[i].Tag <= TAG_CERTIFICATE) &&
  1889. (Slot[SlotNb].GpkObject[i].Tag > 0))
  1890. {
  1891. for (j = 0; j < MAX_FIELD; j++)
  1892. {
  1893. if (IsNotNull(Slot[SlotNb].GpkObject[i].Field[j].pValue))
  1894. {
  1895. GMEM_Free(Slot[SlotNb].GpkObject[i].Field[j].pValue);
  1896. }
  1897. }
  1898. for (j = i; j < Slot[SlotNb].NbGpkObject; j++)
  1899. {
  1900. Slot[SlotNb].GpkObject[j] = Slot[SlotNb].GpkObject[j+1];
  1901. }
  1902. ZeroMemory( &Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject], sizeof(GPK_OBJ) );
  1903. // Since the object i+1 is now at position i, the new object i has to
  1904. // process again.
  1905. i--;
  1906. Slot[SlotNb].NbGpkObject--;
  1907. }
  1908. }
  1909. perso_card (hProv, Slot[SlotNb].NbGpkObject);// value of Slot[SlotNb].NbGpkObject?0?
  1910. ZeroMemory( Slot[SlotNb].GpkPubKeys, sizeof(Slot[SlotNb].GpkPubKeys) );
  1911. }
  1912. /*------------------------------------------------------------------------------
  1913. ------------------------------------------------------------------------------*/
  1914. static BYTE get_gpk_object_nb(HCRYPTPROV hProv, BYTE ObjId, BOOL IsPrivate)
  1915. {
  1916. BYTE i;
  1917. DWORD SlotNb;
  1918. SlotNb = ProvCont[hProv].Slot;
  1919. for (i = 1; i <= Slot[SlotNb].NbGpkObject; i++)
  1920. {
  1921. if ((Slot[SlotNb].GpkObject[i].IsPrivate == IsPrivate)
  1922. &&(Slot[SlotNb].GpkObject[i].ObjId == ObjId)
  1923. )
  1924. {
  1925. break;
  1926. }
  1927. }
  1928. return (i);
  1929. }
  1930. /*------------------------------------------------------------------------------
  1931. ------------------------------------------------------------------------------*/
  1932. static BYTE calc_gpk_field(HCRYPTPROV hProv, BYTE ObjId)
  1933. {
  1934. BYTE i;
  1935. DWORD SlotNb;
  1936. SlotNb = ProvCont[hProv].Slot;
  1937. for (i = Slot[SlotNb].GpkObject[ObjId].LastField; i <= 15; i++)
  1938. {
  1939. if (Slot[SlotNb].GpkObject[ObjId].Flags & 1<<i)
  1940. {
  1941. Slot[SlotNb].GpkObject[ObjId].LastField = i+1;
  1942. break;
  1943. }
  1944. }
  1945. return (i);
  1946. }
  1947. /*------------------------------------------------------------------------------
  1948. ------------------------------------------------------------------------------*/
  1949. static BYTE find_gpk_obj_tag_type( HCRYPTPROV hProv,
  1950. BYTE KeyTag,
  1951. BYTE KeyType,
  1952. BYTE KeyLen,
  1953. BOOL IsExchange,
  1954. BOOL IsPrivate
  1955. )
  1956. {
  1957. BYTE i, tmp;
  1958. DWORD SlotNb;
  1959. BYTE keysetID;
  1960. GPK_OBJ* pObject;
  1961. SlotNb = ProvCont[hProv].Slot;
  1962. tmp = 0;
  1963. for (i = 1; i <= Slot[SlotNb].NbGpkObject; i++)
  1964. {
  1965. pObject = &Slot[SlotNb].GpkObject[i];
  1966. if ( pObject->Tag != KeyTag )
  1967. continue;
  1968. if ( pObject->IsPrivate != IsPrivate )
  1969. continue;
  1970. if (IsExchange && !(pObject->Flags & FLAG_EXCHANGE))
  1971. continue;
  1972. if ( (KeyType == 0xFF)
  1973. || (KeyType == 0x00 && !pObject->IsCreated && pObject->PubKey.KeySize == KeyLen)
  1974. || (KeyType != 0x00 && pObject->IsCreated && pObject->Field[POS_KEY_TYPE].pValue[0] == KeyType)
  1975. )
  1976. {
  1977. // Key file...
  1978. if (!Slot[SlotNb].UseFile[pObject->FileId - GPK_FIRST_KEY])
  1979. {
  1980. // If the file never has been used, use it. Otherwise, keep on the search
  1981. return i;
  1982. }
  1983. else
  1984. {
  1985. // Not a key file...
  1986. // Keep this possible choice. The file has already been
  1987. // used but another one may exist.
  1988. if (ProvCont[hProv].bLegacyKeyset)
  1989. {
  1990. tmp = i;
  1991. }
  1992. else
  1993. {
  1994. if ( (pObject->Flags & FLAG_KEYSET)
  1995. && (pObject->Field[POS_KEYSET].pValue))
  1996. {
  1997. keysetID = pObject->Field[POS_KEYSET].pValue[0];
  1998. if (keysetID == ProvCont[hProv].keysetID)
  1999. {
  2000. tmp = i;
  2001. }
  2002. }
  2003. }
  2004. }
  2005. }
  2006. }
  2007. return tmp;
  2008. }
  2009. /*------------------------------------------------------------------------------
  2010. ------------------------------------------------------------------------------*/
  2011. static BYTE find_gpk_obj_tag_file(HCRYPTPROV hProv, BYTE KeyTag, BYTE FileId, BOOL IsExchange)
  2012. {
  2013. BYTE i;
  2014. DWORD SlotNb;
  2015. GPK_OBJ* pObject;
  2016. SlotNb = ProvCont[hProv].Slot;
  2017. for (i = 1; i <= Slot[SlotNb].NbGpkObject; i++)
  2018. {
  2019. pObject = &Slot[SlotNb].GpkObject[i];
  2020. if (pObject->Tag != KeyTag)
  2021. continue;
  2022. if (pObject->FileId != FileId)
  2023. continue;
  2024. if (pObject->IsPrivate == FALSE)
  2025. continue;
  2026. if (IsExchange && !(pObject->Flags & FLAG_EXCHANGE))
  2027. continue;
  2028. if (!pObject->IsCreated)
  2029. {
  2030. return i;
  2031. }
  2032. }
  2033. return 0;
  2034. }
  2035. /*------------------------------------------------------------------------------
  2036. ------------------------------------------------------------------------------*/
  2037. static BOOL read_gpk_pub_key(HCRYPTPROV hProv,
  2038. HCRYPTKEY hKey,
  2039. GPK_EXP_KEY *PubKey
  2040. )
  2041. {
  2042. DWORD lRet;
  2043. BYTE Sfi, RecLen, RecNum;
  2044. BOOL IsLast = FALSE;
  2045. DWORD SlotNb;
  2046. SlotNb = ProvCont[hProv].Slot;
  2047. ZeroMemory( PubKey, sizeof(GPK_EXP_KEY) );
  2048. /* Check if Public Key file already read to avoid new access if possible */
  2049. if (Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY].KeySize > 0)
  2050. {
  2051. memcpy(PubKey,
  2052. &(Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY]),
  2053. sizeof(GPK_EXP_KEY)
  2054. );
  2055. RETURN(CRYPT_SUCCEED, 0);
  2056. }
  2057. /* Initialize Default Public key value */
  2058. memcpy(PubKey->Exposant, "\x01\x00\x01", 3);
  2059. PubKey->ExpSize = 3;
  2060. /* Calculate Short File id of PK file for P2 parameter */
  2061. Sfi = 0x04 | (Slot[SlotNb].GpkObject[hKey].FileId<<3);
  2062. /* First record to read is number 2, number 1 is reserved for TAG_INFO */
  2063. RecNum = 2;
  2064. do
  2065. {
  2066. /* Read Record (RecNum) to get size */
  2067. bSendBuffer[0] = 0x00; //CLA
  2068. bSendBuffer[1] = 0xB2; //INS
  2069. bSendBuffer[2] = RecNum; //P1
  2070. bSendBuffer[3] = Sfi; //P2
  2071. bSendBuffer[4] = 0xFB; //Lo
  2072. cbSendLength = 5;
  2073. cbRecvLength = sizeof(bRecvBuffer);
  2074. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2075. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2076. if (SCARDPROBLEM(lRet,0x0000,0xFF))
  2077. {
  2078. RETURN (CRYPT_FAILED, SCARD_W_EOF);
  2079. }
  2080. if (bRecvBuffer[0] == 0x6C) // Communication bufer exceeded
  2081. {
  2082. RecLen = bRecvBuffer[1];
  2083. }
  2084. else
  2085. {
  2086. IsLast = TRUE;
  2087. break;
  2088. }
  2089. /* Read Record (RecNum) to get value */
  2090. bSendBuffer[0] = 0x00; //CLA
  2091. bSendBuffer[1] = 0xB2; //INS
  2092. bSendBuffer[2] = RecNum; //P1
  2093. bSendBuffer[3] = Sfi; //P2
  2094. bSendBuffer[4] = RecLen; //Lo
  2095. cbSendLength = 5;
  2096. cbRecvLength = sizeof(bRecvBuffer);
  2097. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2098. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2099. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  2100. {
  2101. RETURN (CRYPT_FAILED, SCARD_W_EOF);
  2102. }
  2103. /* Which Record is it? */
  2104. switch (bRecvBuffer[0])
  2105. {
  2106. /* This is the Modulus */
  2107. case 0x01:
  2108. {
  2109. ZeroMemory( PubKey->Modulus, PubKey->KeySize );
  2110. PubKey->KeySize = RecLen-1;
  2111. r_memcpy(PubKey->Modulus, &bRecvBuffer[1],RecLen-1);
  2112. }
  2113. break;
  2114. /* This is the Public Exposant */
  2115. case 0x06:
  2116. case 0x07:
  2117. {
  2118. ZeroMemory( PubKey->Exposant, PubKey->ExpSize );
  2119. PubKey->ExpSize = RecLen-1;
  2120. r_memcpy(PubKey->Exposant, &bRecvBuffer[1],RecLen-1);
  2121. }
  2122. break;
  2123. /* This is an unknown or not signifiant record, ignore it */
  2124. default:
  2125. break;
  2126. }
  2127. RecNum++;
  2128. }
  2129. while (!IsLast);
  2130. if ((PubKey->KeySize == 0) || (PubKey->ExpSize == 0))
  2131. {
  2132. RETURN (CRYPT_FAILED, NTE_BAD_PUBLIC_KEY);
  2133. }
  2134. /* Store Public key to avoid new read if requested */
  2135. memcpy(&(Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY]),
  2136. PubKey,
  2137. sizeof(GPK_EXP_KEY)
  2138. );
  2139. RETURN (CRYPT_SUCCEED, 0);
  2140. }
  2141. /*------------------------------------------------------------------------------
  2142. ------------------------------------------------------------------------------*/
  2143. static BOOL read_gpk_objects(HCRYPTPROV hProv, BOOL IsPrivate)
  2144. {
  2145. DWORD lRet;
  2146. DWORD
  2147. dwGpkObjLen,
  2148. dwNumberofCommands,
  2149. dwLastCommandLen,
  2150. dwCommandLen,
  2151. i, j,
  2152. dwLen,
  2153. dwNb,
  2154. FirstObj;
  2155. BYTE
  2156. curId,
  2157. EmptyBuff[512];
  2158. DWORD SlotNb;
  2159. WORD offset;
  2160. ZeroMemory( EmptyBuff, sizeof(EmptyBuff) );
  2161. SlotNb = ProvCont[hProv].Slot;
  2162. BeginWait();
  2163. zap_gpk_objects( SlotNb, IsPrivate);
  2164. FirstObj = Slot[SlotNb].NbGpkObject;
  2165. /* Select Dedicated Object storage EF on GPK Card */
  2166. bSendBuffer[0] = 0x00; //CLA
  2167. bSendBuffer[1] = 0xA4; //INS
  2168. bSendBuffer[2] = 0x02; //P1
  2169. bSendBuffer[3] = 0x00; //P2
  2170. bSendBuffer[4] = 0x02; //Li
  2171. if (IsPrivate)
  2172. {
  2173. bSendBuffer[5] = HIBYTE(GPK_OBJ_PRIV_EF);
  2174. bSendBuffer[6] = LOBYTE(GPK_OBJ_PRIV_EF);
  2175. }
  2176. else
  2177. {
  2178. bSendBuffer[5] = HIBYTE(GPK_OBJ_PUB_EF);
  2179. bSendBuffer[6] = LOBYTE(GPK_OBJ_PUB_EF);
  2180. }
  2181. cbSendLength = 7;
  2182. cbRecvLength = sizeof(bRecvBuffer);
  2183. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2184. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2185. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  2186. {
  2187. if (IsPrivate)
  2188. {
  2189. perso_priv (hProv, Slot[SlotNb].NbGpkObject);
  2190. }
  2191. else
  2192. {
  2193. perso_public (hProv, Slot[SlotNb].NbGpkObject);
  2194. }
  2195. RETURN (CRYPT_SUCCEED, 0);
  2196. }
  2197. /* Get Response */
  2198. bSendBuffer[0] = 0x00; //CLA
  2199. bSendBuffer[1] = 0xC0; //INS
  2200. bSendBuffer[2] = 0x00; //P1
  2201. bSendBuffer[3] = 0x00; //P2
  2202. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  2203. cbSendLength = 5;
  2204. cbRecvLength = sizeof(bRecvBuffer);
  2205. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2206. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2207. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  2208. {
  2209. RETURN (CRYPT_FAILED, SCARD_E_UNEXPECTED);
  2210. }
  2211. dwGpkObjLen = bRecvBuffer[8]*256 + bRecvBuffer[9];
  2212. if (IsNotNull(g_pbGpkObj))
  2213. {
  2214. GMEM_Free(g_pbGpkObj);
  2215. }
  2216. g_pbGpkObj = (BYTE*)GMEM_Alloc(dwGpkObjLen);
  2217. if (IsNull(g_pbGpkObj))
  2218. {
  2219. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  2220. }
  2221. /* Read the Objects EF */
  2222. dwNumberofCommands = (dwGpkObjLen-1)/FILE_CHUNK_SIZE + 1;
  2223. dwLastCommandLen = dwGpkObjLen%FILE_CHUNK_SIZE;
  2224. if (dwLastCommandLen == 0)
  2225. {
  2226. dwLastCommandLen = FILE_CHUNK_SIZE;
  2227. }
  2228. dwCommandLen = FILE_CHUNK_SIZE;
  2229. for (i=0; i < dwNumberofCommands ; i++)
  2230. {
  2231. if (i == dwNumberofCommands - 1)
  2232. {
  2233. dwCommandLen = dwLastCommandLen;
  2234. }
  2235. /* Read FILE_CHUCK_SIZE bytes or last bytes */
  2236. bSendBuffer[0] = 0x00; //CLA
  2237. bSendBuffer[1] = 0xB0; //INS
  2238. offset = (WORD)(i * FILE_CHUNK_SIZE) / ProvCont[hProv].dataUnitSize;
  2239. bSendBuffer[2] = HIBYTE( offset );
  2240. bSendBuffer[3] = LOBYTE( offset );
  2241. bSendBuffer[4] = (BYTE) dwCommandLen; //Lo
  2242. cbSendLength = 5;
  2243. cbRecvLength = sizeof(bRecvBuffer);
  2244. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2245. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2246. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  2247. RETURN( CRYPT_FAILED, SCARD_W_EOF );
  2248. memcpy( &g_pbGpkObj[i*FILE_CHUNK_SIZE], bRecvBuffer, cbRecvLength - 2 );
  2249. if (memcmp(bRecvBuffer, EmptyBuff, cbRecvLength -2) == 0)
  2250. break;
  2251. }
  2252. // Fill Gpk Fixed Objects structure with read Buffer
  2253. i = 0;
  2254. while (i < dwGpkObjLen)
  2255. {
  2256. // No more fixed object
  2257. if (g_pbGpkObj[i] == 0x00)
  2258. {
  2259. i++;
  2260. break;
  2261. }
  2262. if (Slot[SlotNb].NbGpkObject >= MAX_GPK_OBJ)
  2263. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  2264. Slot[SlotNb].NbGpkObject++;
  2265. // Initalize fields
  2266. for (j = 0; j < MAX_FIELD; j++)
  2267. {
  2268. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Field[j].bReal = TRUE;
  2269. }
  2270. // Tag
  2271. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Tag = g_pbGpkObj[i];
  2272. i++;
  2273. if (i > dwGpkObjLen-1)
  2274. RETURN( CRYPT_FAILED, SCARD_W_EOF );
  2275. // Flags
  2276. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Flags = (g_pbGpkObj[i]*256) + g_pbGpkObj[i+1];
  2277. i = i + 2;
  2278. // IsPrivate
  2279. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].IsPrivate = IsPrivate;
  2280. // IsCreated
  2281. if (Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Tag >= TAG_CERTIFICATE)
  2282. {
  2283. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].IsCreated = TRUE;
  2284. }
  2285. else if ((Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Tag <= TAG_DSA_PRIVATE)
  2286. &&(Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Flags & FLAG_KEY_TYPE)
  2287. )
  2288. {
  2289. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].IsCreated = TRUE;
  2290. }
  2291. else
  2292. {
  2293. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].IsCreated = FALSE;
  2294. }
  2295. // Object Id ?
  2296. if ((Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Flags & 0x0FFF) != 0x0000)
  2297. {
  2298. if (i > dwGpkObjLen)
  2299. {
  2300. RETURN (CRYPT_FAILED, SCARD_W_EOF);
  2301. }
  2302. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].ObjId = g_pbGpkObj[i];
  2303. i++;
  2304. }
  2305. else
  2306. {
  2307. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].ObjId = 0xFF;
  2308. }
  2309. // File Id ?
  2310. if (Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].Tag <= TAG_CERTIFICATE)
  2311. {
  2312. if (i > dwGpkObjLen)
  2313. {
  2314. RETURN (CRYPT_FAILED, SCARD_W_EOF);
  2315. }
  2316. Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].FileId = g_pbGpkObj[i];
  2317. i++;
  2318. if (Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].IsCreated)
  2319. {
  2320. // If the object has been created, the corresponding key file is used
  2321. Slot[SlotNb].UseFile[ Slot[SlotNb].GpkObject[Slot[SlotNb].NbGpkObject].FileId - GPK_FIRST_KEY] = TRUE;
  2322. }
  2323. }
  2324. }
  2325. // Fill Gpk Variable Objects structure with read Buffer
  2326. curId = 0;
  2327. dwNb = 0;
  2328. while (i < dwGpkObjLen)
  2329. {
  2330. if (g_pbGpkObj[i] == 0xFF)
  2331. {
  2332. break;
  2333. }
  2334. // Field length
  2335. dwLen = 0;
  2336. if (g_pbGpkObj[i] & 0x80)
  2337. {
  2338. dwLen = (g_pbGpkObj[i] & 0x7F) * 256;
  2339. i++;
  2340. }
  2341. if (i > dwGpkObjLen)
  2342. {
  2343. RETURN (CRYPT_FAILED, SCARD_W_EOF);
  2344. }
  2345. dwLen = dwLen + g_pbGpkObj[i];
  2346. i++;
  2347. /* Object Id for retrieve object number */
  2348. if (i > dwGpkObjLen)
  2349. {
  2350. RETURN (CRYPT_FAILED, SCARD_W_EOF);
  2351. }
  2352. curId = g_pbGpkObj[i];
  2353. i++;
  2354. dwNb = get_gpk_object_nb(hProv, curId, IsPrivate);
  2355. j = calc_gpk_field(hProv, (BYTE)dwNb);
  2356. /* Object Field length */
  2357. Slot[SlotNb].GpkObject[dwNb].Field[j].Len = (WORD)dwLen;
  2358. /* Object Field value */
  2359. if (dwLen > 0)
  2360. {
  2361. if ((i + dwLen - 1)> dwGpkObjLen)
  2362. {
  2363. RETURN (CRYPT_FAILED, SCARD_W_EOF);
  2364. }
  2365. Slot[SlotNb]. GpkObject[dwNb].Field[j].pValue = (BYTE*)GMEM_Alloc(dwLen);
  2366. if (IsNull(Slot[SlotNb].GpkObject[dwNb].Field[j].pValue))
  2367. {
  2368. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  2369. }
  2370. memcpy(Slot[SlotNb].GpkObject[dwNb].Field[j].pValue, &g_pbGpkObj[i], dwLen);
  2371. i = i + dwLen;
  2372. Slot[SlotNb].GpkObject[dwNb].Field[j].bReal = TRUE;
  2373. }
  2374. else
  2375. {
  2376. Slot[SlotNb].GpkObject[dwNb].Field[j].bReal = FALSE;
  2377. }
  2378. }
  2379. /* Read Extra objects attributes */
  2380. for (i = FirstObj+1; i <= Slot[SlotNb].NbGpkObject; i++)
  2381. {
  2382. /* RSA Public or Private keys */
  2383. if ((Slot[SlotNb].GpkObject[i].Tag == TAG_RSA_PUBLIC)
  2384. ||(Slot[SlotNb].GpkObject[i].Tag == TAG_RSA_PRIVATE)
  2385. )
  2386. {
  2387. /* Modulus and Public Exponant */
  2388. if (!read_gpk_pub_key(hProv, i, &(Slot[SlotNb].GpkObject[i].PubKey)))
  2389. return CRYPT_FAILED;
  2390. //if ((Slot[SlotNb].GpkObject[i].Flags & FLAG_EXCHANGE) == FLAG_EXCHANGE)
  2391. //{
  2392. // Slot[SlotNb].GpkObject[i].hKeyBase = ProvCont[hProv].hRSAKEK;
  2393. //}
  2394. //else
  2395. //{
  2396. // Slot[SlotNb].GpkObject[i].hKeyBase = ProvCont[hProv].hRSASign;
  2397. //}
  2398. }
  2399. /* X509 Certificate */
  2400. if (Slot[SlotNb].GpkObject[i].Tag == TAG_CERTIFICATE)
  2401. {
  2402. /* Uncompress Certificate Value if necessary */
  2403. if ((Slot[SlotNb].GpkObject[i].Field[POS_VALUE].Len > 0)
  2404. &&(Slot[SlotNb].GpkObject[i].Field[POS_VALUE].pValue[0] != 0x30)
  2405. )
  2406. {
  2407. BLOC InpBlock, OutBlock;
  2408. InpBlock.usLen = (USHORT)Slot[SlotNb].GpkObject[i].Field[POS_VALUE].Len;
  2409. InpBlock.pData = Slot[SlotNb].GpkObject[i].Field[POS_VALUE].pValue;
  2410. OutBlock.usLen = 0;
  2411. OutBlock.pData = 0;
  2412. if (CC_Uncompress(&InpBlock, &OutBlock) != RV_SUCCESS)
  2413. {
  2414. RETURN(CRYPT_FAILED, SCARD_E_CERTIFICATE_UNAVAILABLE);
  2415. }
  2416. OutBlock.pData = (BYTE*)GMEM_Alloc (OutBlock.usLen);
  2417. if (IsNull(OutBlock.pData))
  2418. {
  2419. RETURN(CRYPT_FAILED, NTE_NO_MEMORY);
  2420. }
  2421. if (CC_Uncompress(&InpBlock, &OutBlock) != RV_SUCCESS)
  2422. {
  2423. GMEM_Free (OutBlock.pData);
  2424. RETURN(CRYPT_FAILED, SCARD_E_CERTIFICATE_UNAVAILABLE);
  2425. }
  2426. GMEM_Free(Slot[SlotNb].GpkObject[i].Field[POS_VALUE].pValue);
  2427. Slot[SlotNb].GpkObject[i].Field[POS_VALUE].pValue = (BYTE*)GMEM_Alloc(OutBlock.usLen);
  2428. if (IsNull(Slot[SlotNb].GpkObject[i].Field[POS_VALUE].pValue))
  2429. {
  2430. GMEM_Free (OutBlock.pData);
  2431. RETURN(CRYPT_FAILED, NTE_NO_MEMORY);
  2432. }
  2433. memcpy(Slot[SlotNb].GpkObject[i].Field[POS_VALUE].pValue,
  2434. OutBlock.pData,
  2435. OutBlock.usLen
  2436. );
  2437. Slot[SlotNb].GpkObject[i].Field[POS_VALUE].Len = OutBlock.usLen;
  2438. GMEM_Free(OutBlock.pData);
  2439. }
  2440. /* Associated RSA key */
  2441. if (Slot[SlotNb].GpkObject[i].FileId != 0)
  2442. {
  2443. if (!read_gpk_pub_key(hProv, i, &(Slot[SlotNb].GpkObject[i].PubKey)))
  2444. return CRYPT_FAILED;
  2445. }
  2446. }
  2447. }
  2448. RETURN (CRYPT_SUCCEED, 0);
  2449. }
  2450. /*------------------------------------------------------------------------------
  2451. ------------------------------------------------------------------------------*/
  2452. static BOOL prepare_write_gpk_objects(HCRYPTPROV hProv, BYTE *pbGpkObj, DWORD *dwGpkObjLen, BOOL IsPrivate)
  2453. {
  2454. DWORD lRet;
  2455. DWORD
  2456. i, j, dwNb;
  2457. WORD
  2458. FieldLen;
  2459. BYTE
  2460. ObjId;
  2461. BLOC
  2462. InpBlock,
  2463. OutBlock;
  2464. DWORD SlotNb;
  2465. DWORD FileLen;
  2466. SlotNb = ProvCont[hProv].Slot;
  2467. i = 0;
  2468. /* Remap Internal GPK ObjId */
  2469. ObjId = 0;
  2470. for (dwNb = 1; dwNb <= Slot[SlotNb].NbGpkObject; dwNb++)
  2471. {
  2472. if (((Slot[SlotNb].GpkObject[dwNb].Flags & 0x0FFF) != 0x0000) &&
  2473. (Slot[SlotNb].GpkObject[dwNb].IsPrivate == IsPrivate)
  2474. )
  2475. {
  2476. Slot[SlotNb].GpkObject[dwNb].ObjId = ObjId;
  2477. ObjId++;
  2478. }
  2479. }
  2480. /* Fixed Object part */
  2481. for (dwNb = 1; dwNb <= Slot[SlotNb].NbGpkObject; dwNb++)
  2482. {
  2483. if (Slot[SlotNb].GpkObject[dwNb].IsPrivate != IsPrivate)
  2484. {
  2485. continue;
  2486. }
  2487. /* Tag */
  2488. if (i > *dwGpkObjLen)
  2489. {
  2490. *dwGpkObjLen = 0;
  2491. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2492. }
  2493. pbGpkObj[i] = Slot[SlotNb].GpkObject[dwNb].Tag;
  2494. i++;
  2495. /* Flag */
  2496. if (i > *dwGpkObjLen)
  2497. {
  2498. *dwGpkObjLen = 0;
  2499. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2500. }
  2501. pbGpkObj[i] = HIBYTE(Slot[SlotNb].GpkObject[dwNb].Flags);
  2502. i++;
  2503. if (i > *dwGpkObjLen)
  2504. {
  2505. *dwGpkObjLen = 0;
  2506. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2507. }
  2508. pbGpkObj[i] = LOBYTE(Slot[SlotNb].GpkObject[dwNb].Flags);
  2509. if (i > *dwGpkObjLen)
  2510. {
  2511. *dwGpkObjLen = 0;
  2512. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2513. }
  2514. i++;
  2515. /* Object Id ? */
  2516. if (((Slot[SlotNb].GpkObject[dwNb].Flags & 0x0FFF) != 0x0000) &&
  2517. (Slot[SlotNb].GpkObject[dwNb].IsPrivate == IsPrivate)
  2518. )
  2519. {
  2520. if (i > *dwGpkObjLen)
  2521. {
  2522. *dwGpkObjLen = 0;
  2523. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2524. }
  2525. pbGpkObj[i] = Slot[SlotNb].GpkObject[dwNb].ObjId;
  2526. i++;
  2527. }
  2528. /* File Id ? */
  2529. if (Slot[SlotNb].GpkObject[dwNb].Tag <= TAG_CERTIFICATE)
  2530. {
  2531. if (i > *dwGpkObjLen)
  2532. {
  2533. *dwGpkObjLen = 0;
  2534. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2535. }
  2536. pbGpkObj[i] = Slot[SlotNb].GpkObject[dwNb].FileId;
  2537. i++;
  2538. }
  2539. }
  2540. if (i > *dwGpkObjLen)
  2541. {
  2542. *dwGpkObjLen = 0;
  2543. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2544. }
  2545. pbGpkObj[i] = 0x00;
  2546. i++;
  2547. /* Variable Object part */
  2548. for (dwNb = 1; dwNb <= Slot[SlotNb].NbGpkObject; dwNb++)
  2549. {
  2550. if (Slot[SlotNb].GpkObject[dwNb].IsPrivate != IsPrivate)
  2551. {
  2552. continue;
  2553. }
  2554. for (j = 0; j < MAX_FIELD; j++)
  2555. {
  2556. if (( (Slot[SlotNb].GpkObject[dwNb].Field[j].Len != 0) &&
  2557. (Slot[SlotNb].GpkObject[dwNb].Field[j].bReal)
  2558. ) ||
  2559. ( (Slot[SlotNb].GpkObject[dwNb].Field[j].Len == 0) &&
  2560. (!Slot[SlotNb].GpkObject[dwNb].Field[j].bReal)
  2561. )
  2562. )
  2563. {
  2564. OutBlock.usLen = 0;
  2565. /* Field Length */
  2566. if (Slot[SlotNb].GpkObject[dwNb].Field[j].bReal)
  2567. {
  2568. FieldLen = Slot[SlotNb].GpkObject[dwNb].Field[j].Len;
  2569. /* Try to Compress Certificate Value */
  2570. if ((j == POS_VALUE)
  2571. &&(Slot[SlotNb].GpkObject[dwNb].Tag == TAG_CERTIFICATE)
  2572. &&(Slot[SlotNb].GpkObject[dwNb].Field[POS_VALUE].Len > 0)
  2573. &&(Slot[SlotNb].GpkObject[dwNb].Field[POS_VALUE].pValue[0] == 0x30)
  2574. )
  2575. {
  2576. InpBlock.usLen = (USHORT)Slot[SlotNb].GpkObject[dwNb].Field[POS_VALUE].Len;
  2577. InpBlock.pData = Slot[SlotNb].GpkObject[dwNb].Field[POS_VALUE].pValue;
  2578. OutBlock.usLen = InpBlock.usLen+1;
  2579. OutBlock.pData = (BYTE*)GMEM_Alloc(OutBlock.usLen);
  2580. if (IsNull(OutBlock.pData))
  2581. {
  2582. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  2583. }
  2584. if (CC_Compress(&InpBlock, &OutBlock) != RV_SUCCESS)
  2585. {
  2586. OutBlock.usLen = 0;
  2587. }
  2588. else
  2589. {
  2590. FieldLen = OutBlock.usLen;
  2591. }
  2592. }
  2593. if (FieldLen > 0x7F)
  2594. {
  2595. if (i > *dwGpkObjLen)
  2596. {
  2597. GMEM_Free(OutBlock.pData);
  2598. *dwGpkObjLen = 0;
  2599. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2600. }
  2601. pbGpkObj[i] = HIBYTE(FieldLen) | 0x80;
  2602. i++;
  2603. }
  2604. if (i > *dwGpkObjLen)
  2605. {
  2606. GMEM_Free(OutBlock.pData);
  2607. *dwGpkObjLen = 0;
  2608. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2609. }
  2610. pbGpkObj[i] = LOBYTE(FieldLen);
  2611. i++;
  2612. }
  2613. else
  2614. {
  2615. if (i > *dwGpkObjLen)
  2616. {
  2617. GMEM_Free(OutBlock.pData);
  2618. *dwGpkObjLen = 0;
  2619. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2620. }
  2621. pbGpkObj[i] = 0x00;
  2622. i++;
  2623. }
  2624. /* Object Id */
  2625. if (i > *dwGpkObjLen)
  2626. {
  2627. GMEM_Free(OutBlock.pData);
  2628. *dwGpkObjLen = 0;
  2629. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2630. }
  2631. pbGpkObj[i] = Slot[SlotNb].GpkObject[dwNb].ObjId;
  2632. i++;
  2633. /* Field Value */
  2634. if (Slot[SlotNb].GpkObject[dwNb].Field[j].bReal)
  2635. {
  2636. if ((j == POS_VALUE)
  2637. &&(Slot[SlotNb].GpkObject[dwNb].Tag == TAG_CERTIFICATE)
  2638. &&(OutBlock.usLen > 0)
  2639. )
  2640. {
  2641. if ((i+OutBlock.usLen-1) > *dwGpkObjLen)
  2642. {
  2643. GMEM_Free(OutBlock.pData);
  2644. *dwGpkObjLen = 0;
  2645. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2646. }
  2647. memcpy(&pbGpkObj[i],
  2648. OutBlock.pData,
  2649. OutBlock.usLen
  2650. );
  2651. i = i + OutBlock.usLen;
  2652. GMEM_Free(OutBlock.pData);
  2653. OutBlock.usLen = 0;
  2654. }
  2655. else
  2656. {
  2657. if ((i+Slot[SlotNb].GpkObject[dwNb].Field[j].Len-1) > *dwGpkObjLen)
  2658. {
  2659. *dwGpkObjLen = 0;
  2660. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2661. }
  2662. memcpy(&pbGpkObj[i],
  2663. Slot[SlotNb].GpkObject[dwNb].Field[j].pValue,
  2664. Slot[SlotNb].GpkObject[dwNb].Field[j].Len
  2665. );
  2666. i = i + Slot[SlotNb].GpkObject[dwNb].Field[j].Len;
  2667. }
  2668. }
  2669. }
  2670. }
  2671. }
  2672. if (i > *dwGpkObjLen)
  2673. {
  2674. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2675. }
  2676. pbGpkObj[i] = 0xFF;
  2677. *dwGpkObjLen = i+1;
  2678. /* Select Dedicated Object storage EF on GPK Card */
  2679. bSendBuffer[0] = 0x00; //CLA
  2680. bSendBuffer[1] = 0xA4; //INS
  2681. bSendBuffer[2] = 0x02; //P1
  2682. bSendBuffer[3] = 0x00; //P2
  2683. bSendBuffer[4] = 0x02; //Li
  2684. if (IsPrivate)
  2685. {
  2686. bSendBuffer[5] = HIBYTE(GPK_OBJ_PRIV_EF);
  2687. bSendBuffer[6] = LOBYTE(GPK_OBJ_PRIV_EF);
  2688. }
  2689. else
  2690. {
  2691. bSendBuffer[5] = HIBYTE(GPK_OBJ_PUB_EF);
  2692. bSendBuffer[6] = LOBYTE(GPK_OBJ_PUB_EF);
  2693. }
  2694. cbSendLength = 7;
  2695. cbRecvLength = sizeof(bRecvBuffer);
  2696. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2697. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2698. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  2699. RETURN( CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND );
  2700. /* Get Response */
  2701. bSendBuffer[0] = 0x00; //CLA
  2702. bSendBuffer[1] = 0xC0; //INS
  2703. bSendBuffer[2] = 0x00; //P1
  2704. bSendBuffer[3] = 0x00; //P2
  2705. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  2706. cbSendLength = 5;
  2707. cbRecvLength = sizeof(bRecvBuffer);
  2708. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2709. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2710. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  2711. RETURN( CRYPT_FAILED, SCARD_E_UNEXPECTED );
  2712. FileLen = bRecvBuffer[8]*256 + bRecvBuffer[9];
  2713. if (*dwGpkObjLen < FileLen)
  2714. {
  2715. RETURN( CRYPT_SUCCEED, 0 );
  2716. }
  2717. else
  2718. {
  2719. *dwGpkObjLen = 0;
  2720. RETURN( CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY );
  2721. }
  2722. }
  2723. /*------------------------------------------------------------------------------
  2724. ------------------------------------------------------------------------------*/
  2725. static BOOL write_gpk_objects(HCRYPTPROV hProv, BYTE *pbGpkObj, DWORD dwGpkObjLen, BOOL IsErase, BOOL IsPrivate)
  2726. {
  2727. DWORD lRet,
  2728. i,
  2729. dwCommandLen,
  2730. dwNumberofCommands,
  2731. dwLastCommandLen,
  2732. FileLen;
  2733. DWORD SlotNb;
  2734. BYTE EmptyBuff[512];
  2735. WORD offset;
  2736. SlotNb = ProvCont[hProv].Slot;
  2737. ZeroMemory( EmptyBuff, sizeof(EmptyBuff) );
  2738. BeginWait();
  2739. // TT - 17/10/2000 - Update the timestamps
  2740. Slot_Description* pSlot = &Slot[SlotNb];
  2741. BYTE& refTimestamp = (IsPrivate) ? pSlot->m_TSPrivate : pSlot->m_TSPublic;
  2742. ++refTimestamp;
  2743. if (0 == refTimestamp)
  2744. refTimestamp = 1;
  2745. if (!WriteTimestamps( hProv, pSlot->m_TSPublic, pSlot->m_TSPrivate, pSlot->m_TSPIN ))
  2746. return CRYPT_FAILED;
  2747. /* Select Dedicated Object storage EF on GPK Card */
  2748. bSendBuffer[0] = 0x00; //CLA
  2749. bSendBuffer[1] = 0xA4; //INS
  2750. bSendBuffer[2] = 0x02; //P1
  2751. bSendBuffer[3] = 0x00; //P2
  2752. bSendBuffer[4] = 0x02; //Li
  2753. if (IsPrivate)
  2754. {
  2755. bSendBuffer[5] = HIBYTE(GPK_OBJ_PRIV_EF);
  2756. bSendBuffer[6] = LOBYTE(GPK_OBJ_PRIV_EF);
  2757. }
  2758. else
  2759. {
  2760. bSendBuffer[5] = HIBYTE(GPK_OBJ_PUB_EF);
  2761. bSendBuffer[6] = LOBYTE(GPK_OBJ_PUB_EF);
  2762. }
  2763. cbSendLength = 7;
  2764. cbRecvLength = sizeof(bRecvBuffer);
  2765. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2766. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2767. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  2768. RETURN( CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND );
  2769. /* Get Response */
  2770. bSendBuffer[0] = 0x00; //CLA
  2771. bSendBuffer[1] = 0xC0; //INS
  2772. bSendBuffer[2] = 0x00; //P1
  2773. bSendBuffer[3] = 0x00; //P2
  2774. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  2775. cbSendLength = 5;
  2776. cbRecvLength = sizeof(bRecvBuffer);
  2777. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2778. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2779. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  2780. {
  2781. RETURN (CRYPT_FAILED, SCARD_E_UNEXPECTED);
  2782. }
  2783. FileLen = bRecvBuffer[8]*256 + bRecvBuffer[9];
  2784. /* Write the Objects EF */
  2785. dwNumberofCommands = (dwGpkObjLen-1)/FILE_CHUNK_SIZE + 1;
  2786. dwLastCommandLen = dwGpkObjLen%FILE_CHUNK_SIZE;
  2787. if (dwLastCommandLen == 0)
  2788. {
  2789. dwLastCommandLen = FILE_CHUNK_SIZE;
  2790. }
  2791. dwCommandLen = FILE_CHUNK_SIZE;
  2792. for (i=0; i < dwNumberofCommands ; i++)
  2793. {
  2794. if (i == dwNumberofCommands - 1)
  2795. {
  2796. dwCommandLen = dwLastCommandLen;
  2797. }
  2798. // Write FILE_CHUCK_SIZE bytes or last bytes
  2799. bSendBuffer[0] = 0x00; //CLA
  2800. bSendBuffer[1] = 0xD6; //INS
  2801. offset = (WORD)(i * FILE_CHUNK_SIZE) / ProvCont[hProv].dataUnitSize;
  2802. bSendBuffer[2] = HIBYTE( offset );
  2803. bSendBuffer[3] = LOBYTE( offset );
  2804. bSendBuffer[4] = (BYTE)dwCommandLen; //Li
  2805. memcpy( &bSendBuffer[5], &pbGpkObj[i*FILE_CHUNK_SIZE], dwCommandLen );
  2806. cbSendLength = 5 + dwCommandLen;
  2807. cbRecvLength = sizeof(bRecvBuffer);
  2808. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2809. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2810. if (SCARDPROBLEM(lRet,0x9000,0x00))
  2811. {
  2812. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2813. }
  2814. }
  2815. if (IsErase)
  2816. {
  2817. // Align the info on a word (4 bytes) boundary
  2818. if ((dwGpkObjLen % 4) != 0)
  2819. dwGpkObjLen = dwGpkObjLen + 4 - (dwGpkObjLen % 4);
  2820. dwNumberofCommands = ((FileLen - dwGpkObjLen)-1)/FILE_CHUNK_SIZE + 1;
  2821. dwLastCommandLen = (FileLen - dwGpkObjLen)%FILE_CHUNK_SIZE;
  2822. if (dwLastCommandLen == 0)
  2823. {
  2824. dwLastCommandLen = FILE_CHUNK_SIZE;
  2825. }
  2826. dwCommandLen = FILE_CHUNK_SIZE;
  2827. for (i=0; i < dwNumberofCommands ; i++)
  2828. {
  2829. if (i == dwNumberofCommands - 1)
  2830. {
  2831. dwCommandLen = dwLastCommandLen;
  2832. }
  2833. // Write FILE_CHUCK_SIZE bytes or last bytes
  2834. bSendBuffer[0] = 0x00; //CLA
  2835. bSendBuffer[1] = 0xD6; //INS
  2836. offset = (WORD)(i * FILE_CHUNK_SIZE + dwGpkObjLen) / ProvCont[hProv].dataUnitSize;
  2837. bSendBuffer[2] = HIBYTE( offset );
  2838. bSendBuffer[3] = LOBYTE( offset );
  2839. bSendBuffer[4] = (BYTE)dwCommandLen; //Li
  2840. memcpy(&bSendBuffer[5], EmptyBuff, dwCommandLen );
  2841. cbSendLength = 5 + dwCommandLen;
  2842. cbRecvLength = sizeof(bRecvBuffer);
  2843. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  2844. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  2845. if (SCARDPROBLEM(lRet,0x9000,0x00))
  2846. {
  2847. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  2848. }
  2849. }
  2850. }
  2851. RETURN (CRYPT_SUCCEED, 0);
  2852. }
  2853. /*------------------------------------------------------------------------------
  2854. ------------------------------------------------------------------------------*/
  2855. static DWORD find_tmp_free(void)
  2856. {
  2857. DWORD i;
  2858. TMP_OBJ* aTemp;
  2859. for (i = 1; i <= MAX_TMP_KEY; i++)
  2860. {
  2861. if (TmpObject[i].hKeyBase == 0x00)
  2862. {
  2863. return (i);
  2864. }
  2865. }
  2866. // realloc TmpObject
  2867. // use aTemp pointer in case of failure
  2868. aTemp = (TMP_OBJ*)GMEM_ReAlloc( TmpObject,
  2869. (MAX_TMP_KEY + REALLOC_SIZE + 1)*sizeof(TMP_OBJ));
  2870. if (IsNotNull(aTemp))
  2871. {
  2872. TmpObject = aTemp;
  2873. MAX_TMP_KEY += REALLOC_SIZE;
  2874. return (MAX_TMP_KEY - REALLOC_SIZE + 1);
  2875. }
  2876. return (0);
  2877. }
  2878. /*------------------------------------------------------------------------------
  2879. ------------------------------------------------------------------------------*/
  2880. static BOOL Context_exist(HCRYPTPROV hProv)
  2881. {
  2882. if ((hProv > 0) && (hProv <= MAX_CONTEXT) && (ProvCont[hProv].hProv != 0))
  2883. return (TRUE);
  2884. else
  2885. return (FALSE);
  2886. }
  2887. /*------------------------------------------------------------------------------
  2888. ------------------------------------------------------------------------------*/
  2889. static BOOL hash_exist(HCRYPTHASH hHash, HCRYPTPROV hProv)
  2890. {
  2891. if ((hHash > 0) && (hHash <= MAX_TMP_HASH) &&
  2892. (hHashGpk[hHash].hHashBase != 0) && (hHashGpk[hHash].hProv == hProv))
  2893. return (TRUE);
  2894. else
  2895. if (hHash == 0) // Special case. The NULL Handle exits
  2896. return (TRUE); // It corresponds to the NULL Handle in the RSA Base
  2897. else
  2898. return (FALSE);
  2899. }
  2900. /*------------------------------------------------------------------------------
  2901. ------------------------------------------------------------------------------*/
  2902. static BOOL key_exist(HCRYPTKEY hKey, HCRYPTPROV hProv)
  2903. {
  2904. if ((hKey > 0) && (hKey <= MAX_TMP_KEY) &&
  2905. (TmpObject[hKey].hKeyBase != 0) && (TmpObject[hKey].hProv == hProv))
  2906. return (TRUE);
  2907. else
  2908. return (FALSE);
  2909. }
  2910. /*------------------------------------------------------------------------------
  2911. ------------------------------------------------------------------------------*/
  2912. static DWORD find_context_free(void)
  2913. {
  2914. DWORD i;
  2915. Prov_Context* aTemp;
  2916. for (i = 1; i <= MAX_CONTEXT; i++)
  2917. {
  2918. if (ProvCont[i].hProv == 0x00)
  2919. {
  2920. return (i);
  2921. }
  2922. }
  2923. // realloc TmpObject
  2924. // use aTemp pointer in case of failure
  2925. aTemp = (Prov_Context*)GMEM_ReAlloc(ProvCont,
  2926. (MAX_CONTEXT + REALLOC_SIZE + 1)*sizeof(Prov_Context));
  2927. if (IsNotNull(aTemp))
  2928. {
  2929. ProvCont = aTemp;
  2930. MAX_CONTEXT += REALLOC_SIZE;
  2931. return (MAX_CONTEXT - REALLOC_SIZE + 1);
  2932. }
  2933. return (0);
  2934. }
  2935. /*------------------------------------------------------------------------------
  2936. ------------------------------------------------------------------------------*/
  2937. static DWORD find_hash_free(void)
  2938. {
  2939. DWORD i;
  2940. TMP_HASH* aTemp;
  2941. for (i = 1; i <= MAX_TMP_HASH; i++)
  2942. {
  2943. if (hHashGpk[i].hHashBase == 0x00)
  2944. {
  2945. return (i);
  2946. }
  2947. }
  2948. // realloc TmpObject
  2949. // use aTemp pointer in case of failure
  2950. aTemp = (TMP_HASH*)GMEM_ReAlloc(hHashGpk,
  2951. (MAX_TMP_HASH + REALLOC_SIZE + 1)*sizeof(TMP_HASH));
  2952. if (IsNotNull(aTemp))
  2953. {
  2954. hHashGpk = aTemp;
  2955. MAX_TMP_HASH += REALLOC_SIZE;
  2956. return (MAX_TMP_HASH - REALLOC_SIZE + 1);
  2957. }
  2958. return (0);
  2959. }
  2960. static BOOL find_reader( DWORD *SlotNb, const PTCHAR szReaderName )
  2961. {
  2962. int i, j;
  2963. DWORD dwReturnSlot = (DWORD)(-1);
  2964. DWORD cchReaders, dwSts;
  2965. LPCTSTR mszReaders = 0, szRdr;
  2966. BOOL fFreedSlot;
  2967. for (;;)
  2968. {
  2969. //
  2970. // Look for an existing slot with this reader name.
  2971. //
  2972. for (i = 0; i < MAX_SLOT; i++)
  2973. {
  2974. if (0 == _tcsnicmp( Slot[i].szReaderName, szReaderName, sizeof(Slot[i].szReaderName) / sizeof(TCHAR)))
  2975. {
  2976. dwReturnSlot = i;
  2977. break;
  2978. }
  2979. }
  2980. if ((DWORD)(-1) != dwReturnSlot)
  2981. break; // All Done!
  2982. //
  2983. // Look for an empty reader slot.
  2984. //
  2985. for (i = 0; i < MAX_SLOT; i++)
  2986. {
  2987. if (IsNullStr(Slot[i].szReaderName))
  2988. {
  2989. _tcsncpy(Slot[i].szReaderName, szReaderName, (sizeof(Slot[i].szReaderName) / sizeof(TCHAR)) - 1);
  2990. dwReturnSlot = i;
  2991. break;
  2992. }
  2993. }
  2994. if ((DWORD)(-1) != dwReturnSlot)
  2995. break; // All Done!
  2996. //
  2997. // Look for an existing unused reader, and replace it.
  2998. //
  2999. for (i = 0; i < MAX_SLOT; i++)
  3000. {
  3001. if (0 == Slot[i].ContextCount)
  3002. {
  3003. _tcsncpy( Slot[i].szReaderName, szReaderName, (sizeof(Slot[i].szReaderName) / sizeof(TCHAR)) - 1);
  3004. dwReturnSlot = i;
  3005. break;
  3006. }
  3007. }
  3008. if ((DWORD)(-1) != dwReturnSlot)
  3009. break; // All Done!
  3010. //
  3011. // Eliminate any duplicate entries.
  3012. //
  3013. fFreedSlot = FALSE;
  3014. for (i = 0; i < MAX_SLOT; i++)
  3015. {
  3016. if (0 != *Slot[i].szReaderName)
  3017. {
  3018. for (j = i + 1; j < MAX_SLOT; j++)
  3019. {
  3020. if (0 == _tcsnicmp(Slot[i].szReaderName, Slot[j].szReaderName, sizeof(Slot[i].szReaderName) / sizeof(TCHAR)))
  3021. {
  3022. ZeroMemory(&Slot[j], sizeof(Slot_Description));
  3023. fFreedSlot = TRUE;
  3024. }
  3025. }
  3026. }
  3027. }
  3028. if (fFreedSlot)
  3029. continue;
  3030. //
  3031. // Make sure all the entries are valid.
  3032. //
  3033. cchReaders = SCARD_AUTOALLOCATE;
  3034. fFreedSlot = FALSE;
  3035. assert(0 != hCardContext);
  3036. assert(0 == mszReaders);
  3037. dwSts = SCardListReaders( hCardContext, 0, (LPTSTR)&mszReaders, &cchReaders );
  3038. if (SCARD_S_SUCCESS != dwSts)
  3039. goto ErrorExit;
  3040. for (i = 0; i < MAX_SLOT; i++)
  3041. {
  3042. for (szRdr = mszReaders; 0 != *szRdr; szRdr += lstrlen(szRdr) + 1)
  3043. {
  3044. if (0 == _tcsnicmp(szRdr, Slot[i].szReaderName, sizeof(Slot[i].szReaderName) / sizeof(TCHAR)))
  3045. break;
  3046. }
  3047. if (0 == *szRdr)
  3048. {
  3049. ZeroMemory(&Slot[i], sizeof(Slot_Description));
  3050. fFreedSlot = TRUE;
  3051. }
  3052. }
  3053. if (!fFreedSlot)
  3054. goto ErrorExit;
  3055. dwSts = SCardFreeMemory(hCardContext, mszReaders);
  3056. assert(SCARD_S_SUCCESS == dwSts);
  3057. mszReaders = 0;
  3058. }
  3059. *SlotNb = dwReturnSlot;
  3060. return TRUE;
  3061. ErrorExit:
  3062. if (0 != mszReaders)
  3063. SCardFreeMemory(hCardContext, mszReaders);
  3064. return FALSE;
  3065. }
  3066. /*------------------------------------------------------------------------------
  3067. ------------------------------------------------------------------------------*/
  3068. static BOOL copy_tmp_key(HCRYPTPROV hProv,HCRYPTKEY hKey,
  3069. DWORD dwFlags, int Algid,
  3070. BYTE KeyBuff[], DWORD KeyLen,
  3071. BYTE SaltBuff[], DWORD SaltLen)
  3072. {
  3073. BOOL CryptResp;
  3074. DWORD i, dwDataLen, dwAlgid;
  3075. BLOBHEADER BlobHeader;
  3076. BYTE *pbTmp;
  3077. BYTE pbData[1024];
  3078. NoDisplay = TRUE;
  3079. dwDataLen = sizeof(pbData);
  3080. ZeroMemory( pbData, sizeof(pbData) );
  3081. /* Make the Blob for Session key */
  3082. BlobHeader.bType = SIMPLEBLOB;
  3083. BlobHeader.bVersion = CUR_BLOB_VERSION;
  3084. BlobHeader.reserved = 0x0000;
  3085. BlobHeader.aiKeyAlg = Algid;
  3086. memcpy(pbData,
  3087. &BlobHeader,
  3088. sizeof(BlobHeader)
  3089. );
  3090. dwAlgid = CALG_RSA_KEYX;
  3091. memcpy( &pbData[sizeof(BlobHeader)], &dwAlgid, sizeof(DWORD) );
  3092. pbTmp = (BYTE*)GMEM_Alloc(dwRsaIdentityLen);
  3093. if (IsNull(pbTmp))
  3094. {
  3095. RETURN(CRYPT_FAILED, NTE_NO_MEMORY);
  3096. }
  3097. pbTmp[0] = 0x00;
  3098. pbTmp[1] = 0x02;
  3099. CryptGenRandom(hProvBase, dwRsaIdentityLen-KeyLen-3, &pbTmp[2]);
  3100. for (i = 2; i < dwRsaIdentityLen-KeyLen-1; i++)
  3101. {
  3102. if (pbTmp[i] == 0x00)
  3103. {
  3104. pbTmp[i] = 0x01;
  3105. }
  3106. }
  3107. pbTmp[dwRsaIdentityLen-KeyLen-1] = 0x00;
  3108. memcpy( &pbTmp[dwRsaIdentityLen-KeyLen], KeyBuff, KeyLen );
  3109. r_memcpy( &pbData[sizeof(BlobHeader)+sizeof(DWORD)], pbTmp, dwRsaIdentityLen );
  3110. GMEM_Free(pbTmp);
  3111. dwDataLen = sizeof(BLOBHEADER) + sizeof(DWORD) + dwRsaIdentityLen;
  3112. /* Import Session key blob in RSA Base without the SALT, if presents */
  3113. CryptResp = CryptImportKey(hProvBase,
  3114. pbData,
  3115. dwDataLen,
  3116. hRsaIdentityKey,
  3117. dwFlags,
  3118. &(TmpObject[hKey].hKeyBase));
  3119. if (!CryptResp)
  3120. return CRYPT_FAILED;
  3121. TmpObject[hKey].hProv = hProv;
  3122. if (SaltLen > 0)
  3123. {
  3124. // In this case, the key has been created with a SALT
  3125. CRYPT_DATA_BLOB sCrypt_Data_Blob;
  3126. sCrypt_Data_Blob.cbData = SaltLen;
  3127. sCrypt_Data_Blob.pbData = (BYTE*)GMEM_Alloc (sCrypt_Data_Blob.cbData);
  3128. if (IsNull(sCrypt_Data_Blob.pbData))
  3129. {
  3130. RETURN(CRYPT_FAILED, NTE_NO_MEMORY);
  3131. }
  3132. memcpy( sCrypt_Data_Blob.pbData, SaltBuff, SaltLen );
  3133. CryptResp = CryptSetKeyParam( TmpObject[hKey].hKeyBase, KP_SALT_EX, (BYTE*)&sCrypt_Data_Blob, 0 );
  3134. GMEM_Free (sCrypt_Data_Blob.pbData);
  3135. if (!CryptResp)
  3136. return CRYPT_FAILED;
  3137. }
  3138. NoDisplay = FALSE;
  3139. RETURN( CRYPT_SUCCEED, 0 );
  3140. }
  3141. /*------------------------------------------------------------------------------
  3142. ------------------------------------------------------------------------------*/
  3143. static BOOL key_unwrap( HCRYPTPROV hProv,
  3144. HCRYPTKEY hKey,
  3145. BYTE* pIn,
  3146. DWORD dwInLen,
  3147. BYTE* pOut,
  3148. DWORD* pdwOutLen )
  3149. {
  3150. DWORD lRet;
  3151. BYTE GpkKeySize;
  3152. DWORD SlotNb;
  3153. SlotNb = ProvCont[hProv].Slot;
  3154. if (hKey < 1 || hKey > MAX_GPK_OBJ)
  3155. {
  3156. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  3157. }
  3158. if (!(Slot[SlotNb].GpkObject[hKey].Flags & FLAG_EXCHANGE))
  3159. {
  3160. RETURN( CRYPT_FAILED, NTE_PERM );
  3161. }
  3162. GpkKeySize = Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY].KeySize;
  3163. if (GpkKeySize == 0)
  3164. {
  3165. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  3166. }
  3167. if (dwInLen != GpkKeySize)
  3168. {
  3169. RETURN( CRYPT_FAILED, NTE_BAD_DATA );
  3170. }
  3171. // Card Select Context for enveloppe opening
  3172. bSendBuffer[0] = 0x80; //CLA
  3173. bSendBuffer[1] = 0xA6; //INS
  3174. bSendBuffer[2] = Slot[SlotNb].GpkObject[hKey].FileId; //P1
  3175. bSendBuffer[3] = 0x77; //P2
  3176. cbSendLength = 4;
  3177. cbRecvLength = sizeof(bRecvBuffer);
  3178. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3179. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3180. if (SCARDPROBLEM(lRet,0x9000,0x00))
  3181. {
  3182. RETURN( CRYPT_FAILED, NTE_BAD_KEY_STATE );
  3183. }
  3184. // Open the enveloppe containing the session key
  3185. bSendBuffer[0] = 0x80; //CLA
  3186. bSendBuffer[1] = 0x1C; //INS
  3187. bSendBuffer[2] = 0x00; //P1
  3188. bSendBuffer[3] = 0x00; //P2
  3189. bSendBuffer[4] = (BYTE) dwInLen; //Lo
  3190. memcpy(&bSendBuffer[5], pIn, dwInLen);
  3191. cbSendLength = dwInLen + 5;
  3192. cbRecvLength = sizeof(bRecvBuffer);
  3193. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3194. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3195. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  3196. RETURN( CRYPT_FAILED, SCARD_E_UNSUPPORTED_FEATURE );
  3197. // Get Response
  3198. bSendBuffer[0] = 0x00; //CLA
  3199. bSendBuffer[1] = 0xC0; //INS
  3200. bSendBuffer[2] = 0x00; //P1
  3201. bSendBuffer[3] = 0x00; //P2
  3202. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  3203. cbSendLength = 5;
  3204. cbRecvLength = sizeof(bRecvBuffer);
  3205. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3206. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3207. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  3208. RETURN( CRYPT_FAILED, SCARD_E_UNEXPECTED );
  3209. *pdwOutLen = cbRecvLength - 2;
  3210. r_memcpy(pOut, bRecvBuffer, *pdwOutLen);
  3211. RETURN( CRYPT_SUCCEED, 0 );
  3212. }
  3213. /*------------------------------------------------------------------------------
  3214. ------------------------------------------------------------------------------*/
  3215. static BYTE GPKHashMode (HCRYPTHASH hHash)
  3216. {
  3217. BOOL CryptResp;
  3218. DWORD dwLen, dwTypeAlg;
  3219. // This function is called only if the hHash exists
  3220. dwLen = sizeof (DWORD);
  3221. CryptResp = CryptGetHashParam( hHashGpk[hHash].hHashBase, HP_ALGID, (BYTE *)&dwTypeAlg, &dwLen, 0 );
  3222. if (CryptResp)
  3223. {
  3224. switch (dwTypeAlg)
  3225. {
  3226. case CALG_MD5 : return 0x11; break;
  3227. case CALG_SHA : return 0x12; break;
  3228. case CALG_SSL3_SHAMD5 : return 0x18; break;
  3229. }
  3230. }
  3231. return 0;
  3232. }
  3233. /*------------------------------------------------------------------------------
  3234. ------------------------------------------------------------------------------*/
  3235. static BOOL PublicEFExists(HCRYPTPROV hProv)
  3236. {
  3237. // The DF Crypto has been already selected
  3238. DWORD lRet;
  3239. if (ProvCont[hProv].bGPK8000)
  3240. return TRUE; // Public object EF always exists on GPK8000
  3241. // Select Dedicated Object storage EF on GPK Card
  3242. bSendBuffer[0] = 0x00; //CLA
  3243. bSendBuffer[1] = 0xA4; //INS
  3244. bSendBuffer[2] = 0x02; //P1
  3245. bSendBuffer[3] = 0x00; //P2
  3246. bSendBuffer[4] = 0x02; //Li
  3247. bSendBuffer[5] = HIBYTE(GPK_OBJ_PUB_EF);
  3248. bSendBuffer[6] = LOBYTE(GPK_OBJ_PUB_EF);
  3249. cbSendLength = 7;
  3250. cbRecvLength = sizeof(bRecvBuffer);
  3251. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3252. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3253. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  3254. return FALSE;
  3255. return TRUE;
  3256. }
  3257. /*------------------------------------------------------------------------------
  3258. ------------------------------------------------------------------------------*/
  3259. static BOOL Read_MaxSessionKey_EF( HCRYPTPROV hProv, DWORD* ptrMaxSessionKey )
  3260. {
  3261. DWORD lRet;
  3262. *ptrMaxSessionKey = 0; // default, nothing supported
  3263. // Select System DF on GPK Card
  3264. BYTE lenDF = strlen(SYSTEM_DF);
  3265. bSendBuffer[0] = 0x00; //CLA
  3266. bSendBuffer[1] = 0xA4; //INS
  3267. bSendBuffer[2] = 0x04; //P1
  3268. bSendBuffer[3] = 0x00; //P2
  3269. bSendBuffer[4] = lenDF;
  3270. memcpy( &bSendBuffer[5], SYSTEM_DF, lenDF );
  3271. cbSendLength = 5 + lenDF;
  3272. cbRecvLength = sizeof(bRecvBuffer);
  3273. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3274. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3275. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  3276. RETURN( CRYPT_FAILED, SCARD_E_DIR_NOT_FOUND );
  3277. // Select Max Session key EF on GPK Card
  3278. bSendBuffer[0] = 0x00; //CLA
  3279. bSendBuffer[1] = 0xA4; //INS
  3280. bSendBuffer[2] = 0x02; //P1
  3281. bSendBuffer[3] = 0x00; //P2
  3282. bSendBuffer[4] = 0x02; //Li
  3283. bSendBuffer[5] = HIBYTE(MAX_SES_KEY_EF);
  3284. bSendBuffer[6] = LOBYTE(MAX_SES_KEY_EF);
  3285. cbSendLength = 7;
  3286. cbRecvLength = sizeof(bRecvBuffer);
  3287. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3288. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3289. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  3290. {
  3291. RETURN (CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND);
  3292. }
  3293. // Read Max Session key data on GPK Card
  3294. bSendBuffer[0] = 0x00; //CLA
  3295. bSendBuffer[1] = 0xB0; //INS
  3296. bSendBuffer[2] = 0x00; //P1
  3297. bSendBuffer[3] = 0x00; //P2
  3298. bSendBuffer[4] = 0x01; //Li
  3299. cbSendLength = 5;
  3300. cbRecvLength = sizeof(bRecvBuffer);
  3301. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3302. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3303. if (SCARDPROBLEM(lRet,0x9000, bSendBuffer[4]))
  3304. {
  3305. RETURN(CRYPT_FAILED, NTE_BAD_DATA);
  3306. }
  3307. *ptrMaxSessionKey = (bRecvBuffer[0] * 8);
  3308. RETURN (CRYPT_SUCCEED, 0);
  3309. }
  3310. /*------------------------------------------------------------------------------
  3311. ------------------------------------------------------------------------------*/
  3312. static BOOL init_key_set( HCRYPTPROV hProv,
  3313. const char* szContainerName,
  3314. const char* pPin,
  3315. DWORD dwPinLen )
  3316. {
  3317. BYTE* pbBuff1 = 0;
  3318. WORD wIadfLen;
  3319. DWORD lRet, dwBuff1Len, SlotNb;
  3320. SlotNb = ProvCont[hProv].Slot;
  3321. if (Slot[SlotNb].NbKeyFile == 0)
  3322. Slot[SlotNb].NbKeyFile = Read_NbKeyFile(hProv);
  3323. if (Slot[SlotNb].NbKeyFile == 0 || Slot[SlotNb].NbKeyFile > MAX_REAL_KEY)
  3324. {
  3325. RETURN( CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND );
  3326. }
  3327. // Select GPK EF_IADF
  3328. bSendBuffer[0] = 0x00; //CLA
  3329. bSendBuffer[1] = 0xA4; //INS
  3330. bSendBuffer[2] = 0x02; //P1
  3331. bSendBuffer[3] = 0x00; //P2
  3332. bSendBuffer[4] = 0x02; //Li
  3333. bSendBuffer[5] = HIBYTE(GPK_IADF_EF);
  3334. bSendBuffer[6] = LOBYTE(GPK_IADF_EF);
  3335. cbSendLength = 7;
  3336. cbRecvLength = sizeof(bRecvBuffer);
  3337. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3338. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3339. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  3340. RETURN( CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND );
  3341. // Get Response
  3342. bSendBuffer[0] = 0x00; //CLA
  3343. bSendBuffer[1] = 0xC0; //INS
  3344. bSendBuffer[2] = 0x00; //P1
  3345. bSendBuffer[3] = 0x00; //P2
  3346. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  3347. cbSendLength = 5;
  3348. cbRecvLength = sizeof(bRecvBuffer);
  3349. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3350. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3351. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  3352. {
  3353. RETURN( CRYPT_FAILED, SCARD_E_UNEXPECTED );
  3354. }
  3355. wIadfLen = bRecvBuffer[8]*256 + bRecvBuffer[9];
  3356. // Update GPK EF_IADF with Container Name
  3357. memset(bSendBuffer, 0x00, sizeof(bSendBuffer));
  3358. bSendBuffer[0] = 0x00; //CLA
  3359. bSendBuffer[1] = 0xD6; //INS
  3360. bSendBuffer[2] = 0x00; //P1
  3361. bSendBuffer[3] = 8 / ProvCont[hProv].dataUnitSize;
  3362. bSendBuffer[4] = (BYTE)wIadfLen - 8;//Li
  3363. ZeroMemory( &bSendBuffer[5], wIadfLen-8 );
  3364. if (IsNullStr(szContainerName))
  3365. {
  3366. bSendBuffer[5] = 0x30;
  3367. Slot[SlotNb].InitFlag = FALSE;
  3368. }
  3369. else
  3370. {
  3371. bSendBuffer[5] = 0x31;
  3372. Slot[SlotNb].InitFlag = TRUE;
  3373. }
  3374. strcpy( (char*)&bSendBuffer[6], szContainerName );
  3375. cbSendLength = wIadfLen - 8 + 5;
  3376. cbRecvLength = sizeof(bRecvBuffer);
  3377. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3378. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3379. if (SCARDPROBLEM(lRet,0x9000,0x00))
  3380. {
  3381. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  3382. }
  3383. if (!Select_Crypto_DF(hProv))
  3384. return CRYPT_FAILED;
  3385. // Get Response
  3386. bSendBuffer[0] = 0x00; //CLA
  3387. bSendBuffer[1] = 0xC0; //INS
  3388. bSendBuffer[2] = 0x00; //P1
  3389. bSendBuffer[3] = 0x00; //P2
  3390. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  3391. cbSendLength = 5;
  3392. cbRecvLength = sizeof(bRecvBuffer);
  3393. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  3394. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3395. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  3396. {
  3397. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  3398. }
  3399. // Initialize New Container Name
  3400. ZeroMemory( ProvCont[hProv].szContainer, sizeof(ProvCont[hProv].szContainer) );
  3401. memcpy(ProvCont[hProv].szContainer, &bRecvBuffer[5], cbRecvLength - 7);
  3402. if (!PublicEFExists(hProv))
  3403. {
  3404. // The GPK4000suo still has its generation on-board filter. No key has been
  3405. // generated yet.
  3406. RETURN( CRYPT_SUCCEED, 0 );
  3407. }
  3408. // New verify Pin code because DF reselected
  3409. if (!PIN_Validation(hProv))
  3410. {
  3411. lRet = GetLastError();
  3412. Select_MF(hProv);
  3413. RETURN( CRYPT_FAILED, lRet );
  3414. }
  3415. if (read_gpk_objects( hProv, FALSE ))
  3416. {
  3417. if (read_gpk_objects( hProv, TRUE ))
  3418. {
  3419. /* Re-personalize the card BUT keep the PKCS#11 objects not related
  3420. to the GemSAFE application */
  3421. Slot[SlotNb].Read_Public = FALSE;
  3422. Slot[SlotNb].Read_Priv = FALSE;
  3423. clean_card(hProv);
  3424. }
  3425. else
  3426. {
  3427. /* An error occured in the card; ERASE all the objects */
  3428. Slot[SlotNb].Read_Public = FALSE;
  3429. zap_gpk_objects(SlotNb, FALSE);
  3430. /* Re-personalize the card */
  3431. perso_card(hProv, 0);
  3432. }
  3433. }
  3434. else
  3435. {
  3436. /* An error occured in the card; ERASE all the objects */
  3437. Slot[SlotNb].Read_Public = FALSE;
  3438. zap_gpk_objects(SlotNb, FALSE);
  3439. /* Re-personalize the card */
  3440. perso_card(hProv, 0);
  3441. }
  3442. pbBuff1 = (BYTE*)GMEM_Alloc(MAX_GPK_PUBLIC);
  3443. if (IsNull(pbBuff1))
  3444. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  3445. __try
  3446. {
  3447. dwBuff1Len = MAX_GPK_PUBLIC;
  3448. if (!prepare_write_gpk_objects( hProv, pbBuff1, &dwBuff1Len, FALSE ))
  3449. return CRYPT_FAILED;
  3450. if (!write_gpk_objects( hProv, pbBuff1, dwBuff1Len, TRUE, FALSE ))
  3451. return CRYPT_FAILED;
  3452. }
  3453. __finally
  3454. {
  3455. GMEM_Free( pbBuff1 );
  3456. }
  3457. pbBuff1 = (BYTE*)GMEM_Alloc( MAX_GPK_PRIVATE );
  3458. if (IsNull(pbBuff1))
  3459. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  3460. __try
  3461. {
  3462. dwBuff1Len = MAX_GPK_PRIVATE;
  3463. if (!prepare_write_gpk_objects( hProv, pbBuff1, &dwBuff1Len, TRUE ))
  3464. return CRYPT_FAILED;
  3465. if (!write_gpk_objects( hProv, pbBuff1, dwBuff1Len, TRUE, TRUE ))
  3466. return CRYPT_FAILED;
  3467. }
  3468. __finally
  3469. {
  3470. GMEM_Free( pbBuff1 );
  3471. }
  3472. RETURN( CRYPT_SUCCEED, 0 );
  3473. }
  3474. /*------------------------------------------------------------------------------
  3475. * static int ExtractContent(ASN1 *pAsn1)
  3476. *
  3477. * Description : Extract contents of a Asn1 block 'pAsn1->Asn1' and place it
  3478. * in 'pAsn1->Content'.
  3479. *
  3480. * Remarks : Field Asn1.pData is allocated by calling function.
  3481. *
  3482. * In : pAsn1->Asn1.pData
  3483. *
  3484. * Out : This fileds are filled (if RV_SUCCESS) :
  3485. * - Tag
  3486. * - Asn1.usLen
  3487. * - Content.usLen
  3488. * - Content.pData
  3489. *
  3490. * Responses : RV_SUCCESS : All is OK.
  3491. * RV_INVALID_DATA : Asn1 block format not supported.
  3492. *
  3493. ------------------------------------------------------------------------------*/
  3494. static int ExtractContent(ASN1 *pAsn1)
  3495. {
  3496. BYTE* pData;
  3497. int NbBytes, i;
  3498. pData = pAsn1->Asn1.pData;
  3499. if ((pData[0] & 0x1F) == 0x1F)
  3500. {
  3501. // High-tag-number: not supported
  3502. return RV_INVALID_DATA;
  3503. }
  3504. else
  3505. {
  3506. pAsn1->Tag = pData[0];
  3507. }
  3508. if (pData[1] == 0x80)
  3509. {
  3510. // Constructed, indefinite-length method : not supported
  3511. return (RV_INVALID_DATA);
  3512. }
  3513. else if (pData[1] > 0x82)
  3514. {
  3515. // Constructed, definite-length method : too long
  3516. return (RV_INVALID_DATA);
  3517. }
  3518. else if (pData[1] < 0x80)
  3519. {
  3520. // Primitive, definite-length method
  3521. pAsn1->Content.usLen = pData[1];
  3522. pAsn1->Content.pData = &pData[2];
  3523. pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2;
  3524. }
  3525. else
  3526. {
  3527. // Constructed, definite-length method
  3528. NbBytes = pData[1] & 0x7F;
  3529. pAsn1->Content.usLen = 0;
  3530. for (i = 0; i < NbBytes; i++)
  3531. {
  3532. pAsn1->Content.usLen = (pAsn1->Content.usLen << 8) + pData[2+i];
  3533. }
  3534. pAsn1->Content.pData = &pData[2+NbBytes];
  3535. pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2 + NbBytes;
  3536. }
  3537. return RV_SUCCESS;
  3538. }
  3539. /**********************************************************************************/
  3540. static BOOL Read_Priv_Obj (HCRYPTPROV hProv)
  3541. {
  3542. DWORD lRet;
  3543. if (!PIN_Validation(hProv))
  3544. {
  3545. lRet = GetLastError();
  3546. Select_MF(hProv);
  3547. SCardEndTransaction(ProvCont[hProv].hCard, SCARD_LEAVE_CARD);
  3548. RETURN( CRYPT_FAILED, lRet );
  3549. }
  3550. if (!Slot[ProvCont[hProv].Slot].Read_Priv)
  3551. {
  3552. if (!read_gpk_objects(hProv, TRUE))
  3553. {
  3554. lRet = GetLastError();
  3555. Select_MF(hProv);
  3556. SCardEndTransaction(ProvCont[hProv].hCard, SCARD_LEAVE_CARD);
  3557. RETURN( CRYPT_FAILED, lRet );
  3558. }
  3559. Slot[ProvCont[hProv].Slot].Read_Priv = TRUE;
  3560. }
  3561. RETURN( CRYPT_SUCCEED, 0 );
  3562. }
  3563. /**********************************************************************************/
  3564. BOOL Coherent(HCRYPTPROV hProv)
  3565. {
  3566. DWORD lRet, SlotNb;
  3567. if (!Context_exist(hProv))
  3568. RETURN( CRYPT_FAILED, NTE_BAD_UID );
  3569. // [mv - 15/05/98]
  3570. // No access to the card in this case
  3571. if ( ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT &&
  3572. ProvCont[hProv].isContNameNullBlank )
  3573. {
  3574. RETURN( CRYPT_SUCCEED, 0 );
  3575. }
  3576. SlotNb = ProvCont[hProv].Slot;
  3577. // The thread is stopping, wait for it
  3578. if ( Slot[SlotNb].CheckThreadStateEmpty)
  3579. {
  3580. DWORD threadExitCode;
  3581. StopMonitor(SlotNb,&threadExitCode);
  3582. // TT 19/11/99: When the card is removed, reset the PIN
  3583. //Slot[SlotNb].ClearPin(); [FP] already cleared
  3584. Slot[SlotNb].Read_Public = FALSE;
  3585. Slot[SlotNb].Read_Priv = FALSE;
  3586. zap_gpk_objects( SlotNb, FALSE );
  3587. zap_gpk_objects( SlotNb, TRUE );
  3588. Slot[SlotNb].NbKeyFile = 0;
  3589. Slot[SlotNb].GpkMaxSessionKey = 0;
  3590. // [FP] req for Whistler, if card has been removed, ask card to continue
  3591. SCARDHANDLE hCard = 0;
  3592. TCHAR szReaderName[512];
  3593. DWORD dwFlags = ProvCont[hProv].Flags;
  3594. if (dwFlags & CRYPT_NEWKEYSET) dwFlags = dwFlags^CRYPT_NEWKEYSET; // always find the keyset on the card
  3595. DWORD dwStatus = OpenCard(ProvCont[hProv].szContainer, dwFlags, &hCard, szReaderName, sizeof(szReaderName)/sizeof(TCHAR));
  3596. if ((hCard == 0) || (dwStatus != SCARD_S_SUCCESS))
  3597. {
  3598. if ((dwStatus == SCARD_E_CANCELLED) && (dwFlags & CRYPT_SILENT))
  3599. {
  3600. // Silent reconnection to the card failed
  3601. dwStatus = SCARD_W_REMOVED_CARD;
  3602. }
  3603. //ReleaseProvider(hProv);
  3604. Slot[SlotNb].CheckThreadStateEmpty = TRUE;
  3605. RETURN (CRYPT_FAILED, dwStatus);
  3606. }
  3607. else
  3608. {
  3609. if (ProvCont[hProv].Slot != g_FuncSlotNb)
  3610. {
  3611. DWORD OldSlotNb = SlotNb;
  3612. SlotNb = ProvCont[hProv].Slot = g_FuncSlotNb;
  3613. //copy slot info
  3614. //Slot[SlotNb].SetPin(Slot[OldSlotNb].GetPin());
  3615. Slot[SlotNb].InitFlag = Slot[OldSlotNb].InitFlag;
  3616. memcpy(Slot[SlotNb].bGpkSerNb, Slot[OldSlotNb].bGpkSerNb, 8);
  3617. Slot[SlotNb].ContextCount = Slot[OldSlotNb].ContextCount;
  3618. //Slot[SlotNb].CheckThread = Slot[OldSlotNb].CheckThread;
  3619. // clean old slot
  3620. Slot[OldSlotNb].ContextCount = 0;
  3621. // Slot[OldSlotNb].ClearPin();
  3622. // synchronize other contexts
  3623. for (DWORD i = 1; i < MAX_CONTEXT; i++)
  3624. {
  3625. if (Context_exist(i))
  3626. {
  3627. if (ProvCont[i].Slot == OldSlotNb)
  3628. {
  3629. ProvCont[i].Slot = SlotNb;
  3630. ProvCont[i].hCard = 0;
  3631. ProvCont[i].bDisconnected = TRUE;
  3632. }
  3633. }
  3634. }
  3635. }
  3636. else
  3637. {
  3638. // synchronize other contexts
  3639. for (DWORD i = 1; i < MAX_CONTEXT; i++)
  3640. {
  3641. if (Context_exist(i))
  3642. {
  3643. if ((ProvCont[i].Slot == SlotNb) && (i != hProv))
  3644. {
  3645. ProvCont[i].hCard = 0;
  3646. ProvCont[i].bDisconnected = TRUE;
  3647. }
  3648. }
  3649. }
  3650. }
  3651. // compare SN
  3652. bSendBuffer[0] = 0x80; //CLA
  3653. bSendBuffer[1] = 0xC0; //INS
  3654. bSendBuffer[2] = 0x02; //P1
  3655. bSendBuffer[3] = 0xA0; //P2
  3656. bSendBuffer[4] = 0x08; //Lo
  3657. cbSendLength = 5;
  3658. cbRecvLength = sizeof(bRecvBuffer);
  3659. lRet = SCardTransmit(hCard,
  3660. SCARD_PCI_T0,
  3661. bSendBuffer,
  3662. cbSendLength,
  3663. NULL,
  3664. bRecvBuffer,
  3665. &cbRecvLength);
  3666. if (SCARDPROBLEM(lRet,0x9000, bSendBuffer[4]))
  3667. {
  3668. //ReleaseProvider(hProv);
  3669. RETURN (CRYPT_FAILED, (SCARD_S_SUCCESS == lRet) ? NTE_FAIL : lRet);
  3670. }
  3671. if (memcmp(Slot[SlotNb].bGpkSerNb, bRecvBuffer, bSendBuffer[4]) != 0)
  3672. {
  3673. //ReleaseProvider(hProv);
  3674. RETURN (CRYPT_FAILED, NTE_FAIL);
  3675. }
  3676. }
  3677. ProvCont[hProv].hCard = hCard;
  3678. // reassign hKeyBase
  3679. //BOOL CryptResp;
  3680. //HCRYPTKEY hPubKey = 0;
  3681. //CryptResp = MyCPGetUserKey(hProv, AT_KEYEXCHANGE, &hPubKey);
  3682. //if (CryptResp && hPubKey !=0 && ProvCont[hProv].hRSAKEK!=0)
  3683. // Slot[SlotNb].GpkObject[hPubKey].hKeyBase = ProvCont[hProv].hRSAKEK;
  3684. //CryptResp = MyCPGetUserKey(hProv, AT_SIGNATURE, &hPubKey);
  3685. //if (CryptResp && hPubKey !=0 && ProvCont[hProv].hRSASign!=0)
  3686. // Slot[SlotNb].GpkObject[hPubKey].hKeyBase = ProvCont[hProv].hRSASign;
  3687. }
  3688. if (ProvCont[hProv].bDisconnected)
  3689. {
  3690. DWORD dwProto;
  3691. DWORD dwSts = ConnectToCard( Slot[SlotNb].szReaderName,
  3692. SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0,
  3693. &ProvCont[hProv].hCard, &dwProto );
  3694. if (dwSts != SCARD_S_SUCCESS)
  3695. {
  3696. //ReleaseProvider(hProv);
  3697. RETURN( CRYPT_FAILED, dwSts );
  3698. }
  3699. ProvCont[hProv].bDisconnected = FALSE;
  3700. }
  3701. //////////////////////////////////////////////////////////
  3702. /*if (!Prepare_CardBeginTransaction(hProv))
  3703. return CRYPT_FAILED;
  3704. lRet = SCardBeginTransaction(ProvCont[hProv].hCard);
  3705. if (SCARDPROBLEM(lRet,0x0000,0xFF))
  3706. {
  3707. RETURN (CRYPT_FAILED, lRet);
  3708. }*/
  3709. lRet = BeginTransaction(ProvCont[hProv].hCard);
  3710. if (lRet != SCARD_S_SUCCESS)
  3711. {
  3712. RETURN (CRYPT_FAILED, lRet);
  3713. }
  3714. // Monitoring thread
  3715. BeginCheckReaderThread(SlotNb);
  3716. // Make sure that the card has not been replaced by another one [JMR 27-07]
  3717. if (!Select_Crypto_DF(hProv))
  3718. {
  3719. lRet = GetLastError();
  3720. clean_slot(SlotNb, &ProvCont[hProv]);
  3721. SCardEndTransaction(ProvCont[hProv].hCard, SCARD_LEAVE_CARD);
  3722. RETURN (CRYPT_FAILED, lRet);
  3723. }
  3724. // TT - START 17/10/2000 - Check the card's timestamps
  3725. if (!Slot[SlotNb].ValidateTimestamps(hProv))
  3726. return CRYPT_FAILED;
  3727. // TT - END 17/10/2000
  3728. // Check modif flags
  3729. if (!Slot[SlotNb].Read_Public)
  3730. {
  3731. if (!read_gpk_objects(hProv, FALSE))
  3732. {
  3733. lRet = GetLastError();
  3734. Select_MF(hProv);
  3735. SCardEndTransaction(ProvCont[hProv].hCard, SCARD_LEAVE_CARD);
  3736. RETURN (CRYPT_FAILED, lRet);
  3737. }
  3738. Slot[SlotNb].Read_Public = TRUE;
  3739. Slot[SlotNb].Read_Priv = FALSE;
  3740. }
  3741. RETURN (CRYPT_SUCCEED, 0);
  3742. }
  3743. /*------------------------------------------------------------------------------
  3744. * int MakeLabel(BYTE *pValue, USHORT usValueLen,
  3745. * BYTE *pLabel, USHORT *pusLabelLen
  3746. * )
  3747. *
  3748. * In : pValue : Certificat value
  3749. * usValueLen : Value length
  3750. *
  3751. * Out : pLabel : Certificate Label
  3752. * pLabelLen : Field length
  3753. *
  3754. * Responses : RV_SUCCESS : All is OK.
  3755. * RV_INVALID_DATA : Bad certificate value format.
  3756. * RV_BUFFER_TOO_SMALL : At least one buffer is to small.
  3757. *
  3758. ------------------------------------------------------------------------------*/
  3759. int MakeLabel(BYTE *pValue, USHORT usValueLen,
  3760. BYTE *pLabel, USHORT *pusLabelLen
  3761. )
  3762. {
  3763. ASN1
  3764. AttributeTypePart,
  3765. AttributeValuePart,
  3766. AVA,
  3767. RDN,
  3768. Value,
  3769. tbsCert,
  3770. serialNumberPart,
  3771. signaturePart,
  3772. issuerPart,
  3773. validityPart,
  3774. subjectPart;
  3775. BLOC
  3776. OrganizationName,
  3777. CommonName;
  3778. BOOL
  3779. bValuesToBeReturned;
  3780. BYTE
  3781. *pCurrentRDN,
  3782. *pCurrent;
  3783. int
  3784. rv;
  3785. OrganizationName.pData = 0;
  3786. OrganizationName.usLen = 0;
  3787. CommonName.pData = 0;
  3788. CommonName.usLen = 0;
  3789. bValuesToBeReturned = (pLabel != 0);
  3790. Value.Asn1.pData = pValue;
  3791. rv = ExtractContent(&Value);
  3792. if (rv != RV_SUCCESS) return rv;
  3793. tbsCert.Asn1.pData = Value.Content.pData;
  3794. rv = ExtractContent(&tbsCert);
  3795. if (rv != RV_SUCCESS) return rv;
  3796. pCurrent = tbsCert.Content.pData;
  3797. if (pCurrent[0] == 0xA0)
  3798. {
  3799. // We have A0 03 02 01 vv where vv is the version
  3800. pCurrent += 5;
  3801. }
  3802. serialNumberPart.Asn1.pData = pCurrent;
  3803. rv = ExtractContent(&serialNumberPart);
  3804. if (rv != RV_SUCCESS) return rv;
  3805. pCurrent = serialNumberPart.Content.pData + serialNumberPart.Content.usLen;
  3806. signaturePart.Asn1.pData = pCurrent;
  3807. rv = ExtractContent(&signaturePart);
  3808. if (rv != RV_SUCCESS) return rv;
  3809. pCurrent = signaturePart.Content.pData + signaturePart.Content.usLen;
  3810. issuerPart.Asn1.pData = pCurrent;
  3811. rv = ExtractContent(&issuerPart);
  3812. if (rv != RV_SUCCESS) return rv;
  3813. pCurrent = issuerPart.Content.pData + issuerPart.Content.usLen;
  3814. validityPart.Asn1.pData = pCurrent;
  3815. rv = ExtractContent(&validityPart);
  3816. if (rv != RV_SUCCESS) return rv;
  3817. pCurrent = validityPart.Content.pData + validityPart.Content.usLen;
  3818. subjectPart.Asn1.pData = pCurrent;
  3819. rv = ExtractContent(&subjectPart);
  3820. if (rv != RV_SUCCESS) return rv;
  3821. pCurrent = subjectPart.Content.pData + subjectPart.Content.usLen;
  3822. // Search field 'OrganizationName' in 'Issuer'
  3823. pCurrent = issuerPart.Content.pData;
  3824. while (pCurrent < issuerPart.Content.pData + issuerPart.Content.usLen)
  3825. {
  3826. RDN.Asn1.pData = pCurrent;
  3827. rv = ExtractContent(&RDN);
  3828. if (rv != RV_SUCCESS) return rv;
  3829. pCurrentRDN = RDN.Content.pData;
  3830. while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
  3831. {
  3832. AVA.Asn1.pData = pCurrentRDN;
  3833. rv = ExtractContent(&AVA);
  3834. if (rv != RV_SUCCESS) return rv;
  3835. AttributeTypePart.Asn1.pData = AVA.Content.pData;
  3836. rv = ExtractContent(&AttributeTypePart);
  3837. if (rv != RV_SUCCESS) return rv;
  3838. AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
  3839. + AttributeTypePart.Content.usLen;
  3840. rv = ExtractContent(&AttributeValuePart);
  3841. if (rv != RV_SUCCESS) return rv;
  3842. // Search 'OrganisationName'
  3843. if (!memcmp("\x55\x04\x0A",
  3844. AttributeTypePart.Content.pData,
  3845. AttributeTypePart.Content.usLen)
  3846. )
  3847. {
  3848. OrganizationName = AttributeValuePart.Content;
  3849. }
  3850. pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
  3851. }
  3852. pCurrent = RDN.Content.pData + RDN.Content.usLen;
  3853. }
  3854. // Search 'CommonName' in 'Subject'
  3855. pCurrent = subjectPart.Content.pData;
  3856. while (pCurrent < subjectPart.Content.pData + subjectPart.Content.usLen)
  3857. {
  3858. RDN.Asn1.pData = pCurrent;
  3859. rv = ExtractContent(&RDN);
  3860. if (rv != RV_SUCCESS) return rv;
  3861. pCurrentRDN = RDN.Content.pData;
  3862. while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
  3863. {
  3864. AVA.Asn1.pData = pCurrentRDN;
  3865. rv = ExtractContent(&AVA);
  3866. if (rv != RV_SUCCESS) return rv;
  3867. AttributeTypePart.Asn1.pData = AVA.Content.pData;
  3868. rv = ExtractContent(&AttributeTypePart);
  3869. if (rv != RV_SUCCESS) return rv;
  3870. AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
  3871. + AttributeTypePart.Content.usLen;
  3872. rv = ExtractContent(&AttributeValuePart);
  3873. if (rv != RV_SUCCESS) return rv;
  3874. // Search 'CommonName'
  3875. if (!memcmp("\x55\x04\x03",
  3876. AttributeTypePart.Content.pData,
  3877. AttributeTypePart.Content.usLen)
  3878. )
  3879. {
  3880. CommonName = AttributeValuePart.Content;
  3881. }
  3882. pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
  3883. }
  3884. pCurrent = RDN.Content.pData + RDN.Content.usLen;
  3885. }
  3886. if (bValuesToBeReturned)
  3887. {
  3888. if ((*pusLabelLen < OrganizationName.usLen + CommonName.usLen + 6)
  3889. )
  3890. {
  3891. return (RV_BUFFER_TOO_SMALL);
  3892. }
  3893. memcpy(pLabel,
  3894. CommonName.pData,
  3895. CommonName.usLen
  3896. );
  3897. memcpy(&pLabel[CommonName.usLen],
  3898. "'s ",
  3899. 3
  3900. );
  3901. memcpy(&pLabel[CommonName.usLen+3],
  3902. OrganizationName.pData,
  3903. OrganizationName.usLen
  3904. );
  3905. memcpy(&pLabel[CommonName.usLen+3+OrganizationName.usLen],
  3906. " ID",
  3907. 3
  3908. );
  3909. *pusLabelLen = OrganizationName.usLen + CommonName.usLen + 6;
  3910. }
  3911. else
  3912. {
  3913. *pusLabelLen = OrganizationName.usLen + CommonName.usLen + 6;
  3914. }
  3915. return RV_SUCCESS;
  3916. }
  3917. /* -----------------------------------------------------------------------------
  3918. [DCB3] vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv [DCB3]
  3919. --------------------------------------------------------------------------------*/
  3920. static LPCSTR read_gpk_keyset(SCARDHANDLE hLocalCard)
  3921. {
  3922. DWORD lRet;
  3923. BYTE lenDF;
  3924. /*lRet = SCardBeginTransaction(hLocalCard);
  3925. if (SCARD_S_SUCCESS != lRet)
  3926. goto ErrorExit;*/
  3927. lRet = BeginTransaction(hLocalCard);
  3928. if (lRet != SCARD_S_SUCCESS)
  3929. goto ErrorExit;
  3930. /* Select GPK Card MF */
  3931. bSendBuffer[0] = 0x00; //CLA
  3932. bSendBuffer[1] = 0xA4; //INS
  3933. bSendBuffer[2] = 0x00; //P1
  3934. bSendBuffer[3] = 0x0C; //P2
  3935. bSendBuffer[4] = 0x02; //Li
  3936. bSendBuffer[5] = HIBYTE(GPK_MF);
  3937. bSendBuffer[6] = LOBYTE(GPK_MF);
  3938. cbSendLength = 7;
  3939. cbRecvLength = sizeof(bRecvBuffer);
  3940. lRet = SCardTransmit( hLocalCard, SCARD_PCI_T0, bSendBuffer,
  3941. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3942. if (SCARDPROBLEM(lRet,0x9000,0x00))
  3943. goto ErrorExit;
  3944. /* Select Dedicated Application DF on GPK Card */
  3945. lenDF = strlen(GPK_DF);
  3946. bSendBuffer[0] = 0x00; //CLA
  3947. bSendBuffer[1] = 0xA4; //INS
  3948. bSendBuffer[2] = 0x04; //P1
  3949. bSendBuffer[3] = 0x00; //P2
  3950. bSendBuffer[4] = lenDF;
  3951. memcpy( &bSendBuffer[5], GPK_DF, lenDF );
  3952. cbSendLength = 5 + lenDF;
  3953. cbRecvLength = sizeof(bRecvBuffer);
  3954. lRet = SCardTransmit( hLocalCard, SCARD_PCI_T0, bSendBuffer,
  3955. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3956. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  3957. goto ErrorExit;
  3958. /* Get Response of the Select DF to obtain the IADF */
  3959. bSendBuffer[0] = 0x00; //CLA
  3960. bSendBuffer[1] = 0xC0; //INS
  3961. bSendBuffer[2] = 0x00; //P1
  3962. bSendBuffer[3] = 0x00; //P2
  3963. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  3964. cbSendLength = 5;
  3965. cbRecvLength = sizeof(bRecvBuffer);
  3966. lRet = SCardTransmit( hLocalCard, SCARD_PCI_T0, bSendBuffer,
  3967. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  3968. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  3969. goto ErrorExit;
  3970. bRecvBuffer[cbRecvLength - 2] = 0;
  3971. SCardEndTransaction(hLocalCard, SCARD_LEAVE_CARD);
  3972. return (LPCSTR)&bRecvBuffer[5];
  3973. ErrorExit:
  3974. SCardEndTransaction(hLocalCard, SCARD_LEAVE_CARD);
  3975. return 0;
  3976. }
  3977. /* -----------------------------------------------------------------------------
  3978. [DCB3] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [DCB3]
  3979. --------------------------------------------------------------------------------*/
  3980. /* -----------------------------------------------------------------------------
  3981. --------------------------------------------------------------------------------*/
  3982. GPK_OBJ* FindKeySet( Slot_Description* pSlot, LPCSTR szDesiredContainer )
  3983. {
  3984. GPK_OBJ* pFirstObject = &pSlot->GpkObject[1];
  3985. GPK_OBJ* pLastObject = pFirstObject + pSlot->NbGpkObject;
  3986. GPK_OBJ* pObject;
  3987. int len;
  3988. if (IsNullStr( szDesiredContainer))
  3989. return 0;
  3990. len = strlen( szDesiredContainer );
  3991. for (pObject = pFirstObject; pObject != pLastObject; ++pObject)
  3992. {
  3993. if ( (pObject->Tag & 0x7F) == TAG_KEYSET )
  3994. {
  3995. if ( pObject->Field[POS_LABEL].Len == len )
  3996. {
  3997. if (0==memcmp( szDesiredContainer, pObject->Field[POS_LABEL].pValue, len))
  3998. {
  3999. // Found the keyset
  4000. return pObject;
  4001. }
  4002. }
  4003. }
  4004. }
  4005. return 0;
  4006. }
  4007. GPK_OBJ* FindKeySetByID( Slot_Description* pSlot, BYTE keysetID )
  4008. {
  4009. GPK_OBJ* pFirstObject = &pSlot->GpkObject[1];
  4010. GPK_OBJ* pLastObject = pFirstObject + pSlot->NbGpkObject;
  4011. GPK_OBJ* pObject;
  4012. for (pObject = pFirstObject; pObject != pLastObject; ++pObject)
  4013. {
  4014. if ( (pObject->Tag & 0x7F) == TAG_KEYSET )
  4015. {
  4016. if (pObject->Field[POS_ID].Len > 0)
  4017. {
  4018. if (keysetID == pObject->Field[POS_ID].pValue[0])
  4019. {
  4020. // Found the keyset
  4021. return pObject;
  4022. }
  4023. }
  4024. }
  4025. }
  4026. return 0;
  4027. }
  4028. GPK_OBJ* FindFirstKeyset( Slot_Description* pSlot )
  4029. {
  4030. GPK_OBJ* pFirstObject = &pSlot->GpkObject[1];
  4031. GPK_OBJ* pLastObject = pFirstObject + pSlot->NbGpkObject;
  4032. GPK_OBJ* pObject;
  4033. for (pObject = pFirstObject; pObject != pLastObject; ++pObject)
  4034. {
  4035. if ( (pObject->Tag & 0x7F) == TAG_KEYSET )
  4036. {
  4037. return pObject;
  4038. }
  4039. }
  4040. return 0;
  4041. }
  4042. BOOL DetectLegacy( Slot_Description* pSlot )
  4043. {
  4044. BOOL bHasPublicKey = FALSE;
  4045. BOOL bHasKeyset = FALSE;
  4046. GPK_OBJ* pFirstObject = &pSlot->GpkObject[1];
  4047. GPK_OBJ* pLastObject = pFirstObject + pSlot->NbGpkObject;
  4048. GPK_OBJ* pObject;
  4049. for (pObject = pFirstObject; pObject != pLastObject; ++pObject)
  4050. {
  4051. if (((pObject->Tag & 0x7F) == TAG_RSA_PUBLIC) &&
  4052. ( pObject->IsCreated == TRUE))
  4053. bHasPublicKey = TRUE;
  4054. if ( (pObject->Tag & 0x7F) == TAG_KEYSET )
  4055. bHasKeyset = TRUE;
  4056. }
  4057. if (bHasPublicKey && !bHasKeyset)
  4058. return TRUE;
  4059. else
  4060. return FALSE;
  4061. }
  4062. //////////////////////////////////////////////////////////////////////////////////////
  4063. //
  4064. // Initialize the specified slot
  4065. //
  4066. //////////////////////////////////////////////////////////////////////////////////////
  4067. void InitializeSlot( DWORD SlotNb )
  4068. {
  4069. if (SlotNb >= MAX_SLOT)
  4070. {
  4071. SetLastError( NTE_FAIL );
  4072. return;
  4073. }
  4074. if (!InitSlot[SlotNb])
  4075. {
  4076. TCHAR szBuff[128];
  4077. _tcsncpy(szBuff, Slot[SlotNb].szReaderName, 128);
  4078. ZeroMemory( &Slot[SlotNb], sizeof(Slot_Description) );
  4079. _tcsncpy(Slot[SlotNb].szReaderName, szBuff, 128);
  4080. InitSlot[SlotNb] = TRUE;
  4081. }
  4082. if (Slot[SlotNb].CheckThreadStateEmpty)
  4083. {
  4084. DBG_PRINT(TEXT("Thread had stopped, wait for it"));
  4085. DWORD threadExitCode;
  4086. StopMonitor(SlotNb,&threadExitCode);
  4087. // TT 19/11/99: When the card is removed, reset the PIN
  4088. // Slot[SlotNb].ClearPin();
  4089. Flush_MSPinCache(&(Slot[SlotNb].hPinCacheHandle)); // NK 06.02.2001 #5 5106
  4090. Slot[SlotNb].Read_Public = FALSE;
  4091. Slot[SlotNb].Read_Priv = FALSE;
  4092. zap_gpk_objects( SlotNb, FALSE );
  4093. zap_gpk_objects( SlotNb, TRUE );
  4094. Slot[SlotNb].NbKeyFile = 0;
  4095. Slot[SlotNb].GpkMaxSessionKey = 0;
  4096. // [FP] +
  4097. for (DWORD i = 1; i < MAX_CONTEXT; i++)
  4098. {
  4099. if (Context_exist(i))
  4100. {
  4101. if (ProvCont[i].Slot == SlotNb)
  4102. {
  4103. ProvCont[i].hCard = 0;
  4104. ProvCont[i].bDisconnected = TRUE;
  4105. }
  4106. }
  4107. }
  4108. // [FP] -
  4109. }
  4110. // Monitoring thread
  4111. BeginCheckReaderThread(SlotNb);
  4112. }
  4113. /* -----------------------------------------------------------------------------
  4114. --------------------------------------------------------------------------------*/
  4115. SCARDHANDLE WINAPI funcConnect (SCARDCONTEXT hSCardContext, LPTSTR szReader, LPTSTR mszCards, PVOID pvUserData)
  4116. {
  4117. SCARDHANDLE hCard;
  4118. DWORD dwProto, dwSts;
  4119. GpkLocalLock();
  4120. hCard = 0;
  4121. dwSts = ConnectToCard( szReader, SCARD_SHARE_SHARED,
  4122. SCARD_PROTOCOL_T0, &hCard, &dwProto );
  4123. if (dwSts != SCARD_S_SUCCESS)
  4124. {
  4125. hCard =0;
  4126. GpkLocalUnlock();
  4127. return 0;
  4128. }
  4129. if (!find_reader( &g_FuncSlotNb, szReader ))
  4130. {
  4131. GpkLocalUnlock();
  4132. return 0;
  4133. }
  4134. GpkLocalUnlock();
  4135. return hCard;
  4136. }
  4137. /* -----------------------------------------------------------------------------
  4138. --------------------------------------------------------------------------------*/
  4139. // TT 05/10/99
  4140. BOOL WINAPI funcCheck( SCARDCONTEXT hSCardContext, SCARDHANDLE hCard, void* pvUserData )
  4141. {
  4142. GPK_OBJ* pKeySet = 0;
  4143. int hProv = 0;
  4144. int SlotNb = g_FuncSlotNb;
  4145. BOOL bGPK8000;
  4146. BOOL bResult;
  4147. ProvCont[hProv].hCard = hCard;
  4148. ProvCont[hProv].Slot = SlotNb;
  4149. ProvCont[hProv].dataUnitSize = 0;
  4150. GpkLocalLock();
  4151. /*if (!Prepare_CardBeginTransaction(0))
  4152. {
  4153. GpkLocalUnlock();
  4154. return FALSE;
  4155. }*/
  4156. if (BeginTransaction(hCard) != SCARD_S_SUCCESS)
  4157. {
  4158. GpkLocalUnlock();
  4159. return FALSE;
  4160. }
  4161. LPCSTR szDesiredContainer = (char*)pvUserData;
  4162. /*
  4163. GPK_OBJ* pKeySet = 0;
  4164. int hProv = 0;
  4165. int SlotNb = g_FuncSlotNb;
  4166. BOOL bGPK8000;
  4167. BOOL bResult;
  4168. */
  4169. InitializeSlot( SlotNb );
  4170. // If we are acquiring a new keyset, we return TRUE
  4171. if ( szDesiredContainer == 0 || *szDesiredContainer == 0)
  4172. {
  4173. SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
  4174. GpkLocalUnlock();
  4175. return TRUE;
  4176. }
  4177. // Read the public objects
  4178. /*
  4179. ProvCont[hProv].hCard = hCard;
  4180. ProvCont[hProv].Slot = SlotNb;
  4181. ProvCont[hProv].dataUnitSize = 0;
  4182. */
  4183. bResult = Select_Crypto_DF( hProv );
  4184. if (bResult)
  4185. {
  4186. bResult = Slot[SlotNb].ValidateTimestamps(hProv);
  4187. if (bResult && !Slot[SlotNb].Read_Public)
  4188. {
  4189. bResult = read_gpk_objects( hProv, FALSE );
  4190. if (bResult)
  4191. {
  4192. Slot[SlotNb].Read_Public = TRUE;
  4193. Slot[SlotNb].Read_Priv = FALSE;
  4194. }
  4195. }
  4196. if (bResult)
  4197. {
  4198. pKeySet = FindKeySet( &Slot[SlotNb], szDesiredContainer );
  4199. if (pKeySet==0)
  4200. {
  4201. if (DetectGPK8000( hCard, &bGPK8000 ) == SCARD_S_SUCCESS)
  4202. {
  4203. bResult = FALSE;
  4204. if (!bGPK8000)
  4205. {
  4206. BOOL bLegacy = DetectLegacy( &Slot[SlotNb] );
  4207. if (bLegacy)
  4208. {
  4209. LPCSTR szCardContainer = read_gpk_keyset( hCard );
  4210. if (szCardContainer!=0)
  4211. {
  4212. bResult = (0 == strcmp(szCardContainer, szDesiredContainer));
  4213. }
  4214. }
  4215. }
  4216. }
  4217. }
  4218. else
  4219. {
  4220. bResult = TRUE;
  4221. }
  4222. }
  4223. }
  4224. ZeroMemory( &ProvCont[hProv], sizeof(ProvCont[hProv]) );
  4225. SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
  4226. GpkLocalUnlock();
  4227. return bResult;
  4228. }
  4229. // TT: END
  4230. /* -----------------------------------------------------------------------------
  4231. --------------------------------------------------------------------------------*/
  4232. void WINAPI funcDisconnect( SCARDCONTEXT hSCardContext, SCARDHANDLE hCard, PVOID pvUserData )
  4233. {
  4234. SCardDisconnect( hCard, SCARD_LEAVE_CARD );
  4235. }
  4236. /*------------------------------------------------------------------------------
  4237. ------------------------------------------------------------------------------*/
  4238. static DWORD OpenCard(CHAR* szContainerAsked, DWORD dwFlags, SCARDHANDLE* hCard, PTCHAR szReaderName, DWORD dwReaderNameLen)
  4239. {
  4240. OPENCARDNAME open_card;
  4241. TCHAR szCardName[512],
  4242. szOpenDlgTitle[MAX_STRING];
  4243. ZeroMemory( szReaderName, dwReaderNameLen * sizeof(TCHAR) );
  4244. ZeroMemory( szCardName, sizeof(szCardName) );
  4245. open_card.dwStructSize = sizeof(open_card);
  4246. open_card.hwndOwner = GetAppWindow();
  4247. open_card.hSCardContext = hCardContext;
  4248. open_card.lpstrGroupNames = 0;
  4249. open_card.nMaxGroupNames = 0;
  4250. open_card.lpstrCardNames = mszCardList;
  4251. open_card.nMaxCardNames = multistrlen(mszCardList)+1;
  4252. open_card.rgguidInterfaces = 0;
  4253. open_card.cguidInterfaces = 0;
  4254. open_card.lpstrRdr = szReaderName;
  4255. open_card.nMaxRdr = dwReaderNameLen;
  4256. open_card.lpstrCard = szCardName;
  4257. open_card.nMaxCard = sizeof(szCardName) / sizeof(TCHAR);
  4258. LoadString(g_hInstRes, 1017, szOpenDlgTitle, sizeof(szOpenDlgTitle)/sizeof(TCHAR));
  4259. open_card.lpstrTitle = szOpenDlgTitle;
  4260. if (dwFlags & CRYPT_SILENT)
  4261. open_card.dwFlags = SC_DLG_NO_UI;
  4262. else
  4263. open_card.dwFlags = SC_DLG_MINIMAL_UI;
  4264. if (dwFlags & CRYPT_NEWKEYSET) // [DCB3]
  4265. open_card.pvUserData = 0; // [DCB3]
  4266. else // [DCB3]
  4267. open_card.pvUserData = szContainerAsked; // [DCB3]
  4268. open_card.dwShareMode = SCARD_SHARE_SHARED;
  4269. open_card.dwPreferredProtocols = SCARD_PROTOCOL_T0;
  4270. open_card.dwActiveProtocol = 0;
  4271. open_card.lpfnConnect = funcConnect;
  4272. open_card.lpfnCheck = funcCheck;
  4273. open_card.lpfnDisconnect = funcDisconnect;
  4274. open_card.hCardHandle = 0;
  4275. GpkLocalUnlock();
  4276. DWORD dwStatus = GetOpenCardName (&open_card);
  4277. DBG_PRINT(TEXT("dwStatus = 0x%08X, open_card.hCardHandle = 0x%08X"), dwStatus, open_card.hCardHandle);
  4278. GpkLocalLock();
  4279. *hCard = open_card.hCardHandle;
  4280. return(dwStatus);
  4281. }
  4282. /* -----------------------------------------------------------------------------
  4283. --------------------------------------------------------------------------------*/
  4284. void ReleaseProvider(HCRYPTPROV hProv)
  4285. {
  4286. BOOL CryptResp;
  4287. DWORD i;
  4288. DWORD dwProto; //[FP]
  4289. /* Release Hash parameters */
  4290. for (i = 1; i <= MAX_TMP_HASH; i++)
  4291. {
  4292. if ((hHashGpk[i].hHashBase != 0) && (hHashGpk[i].hProv == hProv))
  4293. {
  4294. CryptResp = CryptDestroyHash(hHashGpk[i].hHashBase);
  4295. hHashGpk[i].hHashBase = 0;
  4296. hHashGpk[i].hProv = 0;
  4297. }
  4298. }
  4299. /* Release Key parameters */
  4300. for (i = 1; i <= MAX_TMP_KEY; i++)
  4301. {
  4302. if ((TmpObject[i].hKeyBase != 0) && (TmpObject[i].hProv == hProv))
  4303. {
  4304. CryptResp = CryptDestroyKey(TmpObject[i].hKeyBase);
  4305. TmpObject[i].hKeyBase = 0;
  4306. TmpObject[i].hProv = 0;
  4307. }
  4308. }
  4309. ProvCont[hProv].hProv = 0;
  4310. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  4311. (ProvCont[hProv].isContNameNullBlank))
  4312. {
  4313. }
  4314. else
  4315. {
  4316. // + [FP] if a transaction is opened, close it and reconnect in shared mode
  4317. if (ProvCont[hProv].bCardTransactionOpened)
  4318. {
  4319. // Select_MF(hProv); [FP] PIN not presented
  4320. SCardEndTransaction(ProvCont[hProv].hCard, SCARD_LEAVE_CARD);
  4321. SCardReconnect(ProvCont[hProv].hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwProto);
  4322. ProvCont[hProv].bCardTransactionOpened = FALSE;
  4323. }
  4324. // - [FP]
  4325. if (ProvCont[hProv].hRSAKEK != 0)
  4326. {
  4327. CryptDestroyKey( ProvCont[hProv].hRSAKEK );
  4328. ProvCont[hProv].hRSAKEK = 0;
  4329. }
  4330. if (ProvCont[hProv].hRSASign != 0)
  4331. {
  4332. CryptDestroyKey( ProvCont[hProv].hRSASign );
  4333. ProvCont[hProv].hRSASign = 0;
  4334. }
  4335. if (ProvCont[hProv].hCard != 0)
  4336. {
  4337. SCardDisconnect(ProvCont[hProv].hCard, SCARD_LEAVE_CARD);
  4338. ProvCont[hProv].hCard = 0;
  4339. }
  4340. if (countCardContextRef == 0)
  4341. {
  4342. if (hCardContext != 0)
  4343. SCardReleaseContext(hCardContext);
  4344. hCardContext = 0;
  4345. }
  4346. }
  4347. ProvCont[hProv].Flags = 0;
  4348. ProvCont[hProv].isContNameNullBlank = TRUE;
  4349. ProvCont[hProv].hCard = 0;
  4350. ProvCont[hProv].Slot = 0;
  4351. }
  4352. DWORD getAuxMaxKeyLength(HCRYPTPROV hProv)
  4353. {
  4354. BYTE *ptr = 0;
  4355. DWORD i;
  4356. ALG_ID aiAlgid;
  4357. DWORD dwBits;
  4358. BYTE pbData[1000];
  4359. DWORD cbData;
  4360. DWORD dwFlags = 0;
  4361. DWORD maxLength = 0;
  4362. // Enumerate the supported algorithms.
  4363. for (i=0 ; ; i++)
  4364. {
  4365. if (i == 0)
  4366. dwFlags = CRYPT_FIRST;
  4367. else
  4368. dwFlags = 0;
  4369. cbData = 1000;
  4370. if (!CryptGetProvParam(hProv, PP_ENUMALGS, pbData, &cbData, dwFlags))
  4371. break;
  4372. // Extract algorithm information from the �pbData� buffer.
  4373. ptr = pbData;
  4374. aiAlgid = *(ALG_ID UNALIGNED *)ptr;
  4375. ptr += sizeof(ALG_ID);
  4376. dwBits = *(DWORD UNALIGNED *)ptr;
  4377. switch (aiAlgid)
  4378. {
  4379. case CALG_DES: dwBits += 8;
  4380. break;
  4381. case CALG_3DES_112: dwBits += 16;
  4382. break;
  4383. case CALG_3DES: dwBits += 24;
  4384. break;
  4385. }
  4386. if (GET_ALG_CLASS(aiAlgid) == ALG_CLASS_DATA_ENCRYPT)
  4387. {
  4388. maxLength = max(maxLength, dwBits);
  4389. }
  4390. }
  4391. return maxLength;
  4392. }
  4393. /* -----------------------------------------------------------------------------
  4394. [FP] used in the case of PRIVATEKEYBLOB in MyCPImportKey
  4395. --------------------------------------------------------------------------------*/
  4396. BOOL LoadPrivateKey(SCARDHANDLE hCard,
  4397. BYTE Sfi,
  4398. WORD ElementLen,
  4399. CONST BYTE* pbData,
  4400. DWORD dwDataLen
  4401. )
  4402. {
  4403. DWORD lRet;
  4404. /* Load SK APDU command */
  4405. bSendBuffer[0] = 0x80; //CLA
  4406. bSendBuffer[1] = 0x18; //INS
  4407. bSendBuffer[2] = Sfi; //P1
  4408. bSendBuffer[3] = (BYTE)ElementLen; //P2
  4409. bSendBuffer[4] = (BYTE)dwDataLen; //Li
  4410. memcpy(&bSendBuffer[5], pbData, dwDataLen);
  4411. cbSendLength = 5 + dwDataLen;
  4412. cbRecvLength = sizeof(bRecvBuffer);
  4413. lRet = SCardTransmit( hCard, SCARD_PCI_T0, bSendBuffer,
  4414. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  4415. if(SCARDPROBLEM(lRet, 0x9000, 0x00))
  4416. {
  4417. SetLastError(lRet);
  4418. return (FALSE);
  4419. }
  4420. return (TRUE);
  4421. }
  4422. /*******************************************************************************
  4423. * BOOL WINAPI DllMain (HINSTANCE hInstDLL,
  4424. * DWORD fdwRaison,
  4425. * LPVOID lpReserved
  4426. * )
  4427. *
  4428. * Description :
  4429. *
  4430. * Remarks :
  4431. *
  4432. * In :
  4433. *
  4434. * Out :
  4435. *
  4436. * Responses :
  4437. *
  4438. *******************************************************************************/
  4439. BOOL WINAPI DllMain (HINSTANCE hInstDLL,
  4440. DWORD fdwRaison,
  4441. LPVOID lpReserved
  4442. )
  4443. {
  4444. int i;
  4445. BOOL ReturnValue = TRUE;
  4446. switch (fdwRaison)
  4447. {
  4448. case DLL_PROCESS_ATTACH:
  4449. {
  4450. DBG_PRINT(TEXT("DLL_PROCESS_ATTACH [start]..."));
  4451. g_hInstMod = hInstDLL;
  4452. // Allocation of TmpObject, hHashGpk and ProvCont
  4453. TmpObject= (TMP_OBJ*)GMEM_Alloc((MAX_TMP_KEY + 1)*sizeof(TMP_OBJ));
  4454. hHashGpk = (TMP_HASH*)GMEM_Alloc((MAX_TMP_HASH + 1)*sizeof(TMP_HASH));
  4455. ProvCont = (Prov_Context*)GMEM_Alloc((MAX_CONTEXT + 1)*sizeof(Prov_Context));
  4456. if (IsNull(TmpObject) || IsNull(hHashGpk) || IsNull (ProvCont))
  4457. {
  4458. ReturnValue = FALSE;
  4459. break;
  4460. }
  4461. ZeroMemory( ProvCont, (MAX_CONTEXT+1) * sizeof(Prov_Context) );
  4462. ZeroMemory( TmpObject, (MAX_TMP_KEY+1) * sizeof(TMP_OBJ) );
  4463. ZeroMemory( hHashGpk, (MAX_TMP_HASH+1) * sizeof(TMP_HASH) );
  4464. InitializeCriticalSection(&l_csLocalLock);
  4465. DBG_PRINT(TEXT("...[end] DLL_PROCESS_ATTACH"));
  4466. break;
  4467. }
  4468. case DLL_PROCESS_DETACH:
  4469. {
  4470. DBG_PRINT(TEXT("DLL_PROCESS_DETACH [start]..."));
  4471. ReturnValue = TRUE;
  4472. // Deallocation of TmpObject, hHashGpk and ProvCont
  4473. if (TmpObject != 0)
  4474. GMEM_Free(TmpObject);
  4475. if (hHashGpk != 0)
  4476. GMEM_Free(hHashGpk);
  4477. if (ProvCont != 0)
  4478. GMEM_Free(ProvCont);
  4479. for (i=0; i< MAX_SLOT; i++)
  4480. {
  4481. if (Slot[i].CheckThread != NULL)
  4482. {
  4483. // + [FP]
  4484. g_fStopMonitor[i] = TRUE;
  4485. SCardCancel( hCardContextCheck[i] );
  4486. // TerminateThread( Slot[i].CheckThread, 0 );
  4487. // - [FP]
  4488. CloseHandle( Slot[i].CheckThread );
  4489. Slot[i].CheckThread = NULL;
  4490. }
  4491. }
  4492. if (hProvBase != 0)
  4493. {
  4494. CryptDestroyKey(hRsaIdentityKey);
  4495. CryptReleaseContext(hProvBase, 0);
  4496. }
  4497. CC_Exit();
  4498. DeleteCriticalSection(&l_csLocalLock);
  4499. DBG_PRINT(TEXT("...[end] DLL_PROCESS_DETACH"));
  4500. }
  4501. break;
  4502. case DLL_THREAD_ATTACH:
  4503. InterlockedIncrement( &g_threadAttach );
  4504. break;
  4505. case DLL_THREAD_DETACH:
  4506. InterlockedDecrement( &g_threadAttach );
  4507. break;
  4508. }
  4509. return (ReturnValue);
  4510. }
  4511. /* -----------------------------------------------------------------------------
  4512. --------------------------------------------------------------------------------*/
  4513. BOOL InitAcquire()
  4514. {
  4515. BOOL CryptResp;
  4516. DWORD dwIgn, lRet;
  4517. TCHAR szCspName[MAX_STRING];
  4518. TCHAR szCspBaseName[256];
  4519. TCHAR szDictionaryName[256];
  4520. TCHAR szEntry[MAX_STRING];
  4521. HKEY hRegKey;
  4522. int i;
  4523. // Initialize arrays here instead of using static initializers.
  4524. for (i = 0; i < MAX_SLOT; ++i)
  4525. hCardContextCheck[i] = 0;
  4526. for (i = 0; i < MAX_SLOT; ++i)
  4527. InitSlot[i] = FALSE;
  4528. ZeroMemory( Slot, sizeof(Slot) );
  4529. for (i = 0; i < MAX_SLOT; ++i)
  4530. Slot[i].CheckThreadStateEmpty = FALSE;
  4531. OSVERSIONINFO osver;
  4532. HCRYPTPROV hProvTest;
  4533. LoadString(g_hInstMod, IDS_GPKCSP_ENTRY, szEntry, sizeof(szEntry)/sizeof(TCHAR));
  4534. DBG_PRINT(TEXT(" Registry entry: \"%s\"\n"), szEntry );
  4535. lRet = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szEntry, 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  4536. KEY_READ, 0, &hRegKey, &dwIgn );
  4537. // Detect provider available
  4538. CryptResp = CryptAcquireContext( &hProvTest, 0, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT );
  4539. if (CryptResp)
  4540. {
  4541. lstrcpy( szCspBaseName, MS_ENHANCED_PROV );
  4542. CryptReleaseContext( hProvTest, 0 );
  4543. }
  4544. else
  4545. {
  4546. lstrcpy( szCspBaseName, MS_DEF_PROV );
  4547. }
  4548. DBG_PRINT(TEXT(" Base CSP provider: \"%s\"\n"), szCspBaseName );
  4549. hProvBase = 0;
  4550. osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  4551. GetVersionEx (&osver);
  4552. if (osver.dwPlatformId==VER_PLATFORM_WIN32_NT && osver.dwMajorVersion > 4)
  4553. {
  4554. CryptResp = CryptAcquireContext( &hProvBase, 0, szCspBaseName, PROV_RSA_FULL,
  4555. CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET );
  4556. if (!CryptResp)
  4557. return CRYPT_FAILED;
  4558. }
  4559. else
  4560. {
  4561. LoadString(g_hInstMod, IDS_GPKCSP_NAME, szCspName, sizeof(szCspName)/sizeof(TCHAR));
  4562. CryptResp = CryptAcquireContext( &hProvBase, szCspName, szCspBaseName,
  4563. PROV_RSA_FULL, CRYPT_DELETEKEYSET );
  4564. if (0 != hProvBase)
  4565. {
  4566. CryptReleaseContext(hProvBase, 0);
  4567. }
  4568. LoadString(g_hInstMod, IDS_GPKCSP_NAME, szCspName, sizeof(szCspName)/sizeof(TCHAR));
  4569. CryptResp = CryptAcquireContext( &hProvBase, szCspName, szCspBaseName,
  4570. PROV_RSA_FULL, CRYPT_NEWKEYSET );
  4571. if (!CryptResp)
  4572. return CRYPT_FAILED;
  4573. }
  4574. /* Set a Dummy RSA exchange key in RSA Base */
  4575. CryptResp = CryptImportKey( hProvBase, PrivateBlob, sizeof(PrivateBlob),
  4576. 0, 0, &hRsaIdentityKey );
  4577. if (!CryptResp)
  4578. {
  4579. lRet = GetLastError();
  4580. CryptReleaseContext( hProvBase, 0 );
  4581. RETURN( CRYPT_FAILED, lRet );
  4582. }
  4583. RC2_Key_Size = (BYTE) (Auxiliary_CSP_key_size (CALG_RC2) / 8);
  4584. if (RC2_Key_Size == 0)
  4585. {
  4586. lRet = GetLastError();
  4587. CryptDestroyKey(hRsaIdentityKey); // MV - 13/03/98
  4588. CryptReleaseContext(hProvBase, 0); // MV - 13/03/98
  4589. RETURN( CRYPT_FAILED, lRet );
  4590. }
  4591. RSA_KEK_Size = (BYTE) (Auxiliary_CSP_key_size (CALG_RSA_KEYX) / 8);
  4592. if (RSA_KEK_Size == 0)
  4593. {
  4594. lRet = GetLastError();
  4595. CryptDestroyKey(hRsaIdentityKey); // MV - 13/03/98
  4596. CryptReleaseContext(hProvBase, 0); // MV - 13/03/98
  4597. RETURN( CRYPT_FAILED, lRet );
  4598. }
  4599. AuxMaxSessionKeyLength = getAuxMaxKeyLength(hProvBase) / 8;
  4600. if (AuxMaxSessionKeyLength == 0)
  4601. {
  4602. lRet = GetLastError();
  4603. CryptDestroyKey(hRsaIdentityKey); // MV - 13/03/98
  4604. CryptReleaseContext(hProvBase, 0); // MV - 13/03/98
  4605. RETURN( CRYPT_FAILED, lRet );
  4606. }
  4607. // CARD_LIST UPDATE
  4608. LoadString(g_hInstMod, IDS_GPKCSP_CARDLIST, mszCardList, sizeof(mszCardList)/sizeof(TCHAR));
  4609. DBG_PRINT(TEXT(" Card list entry string: \"%s\"\n"), mszCardList );
  4610. #ifndef UNICODE
  4611. dwIgn = sizeof(mszCardList);
  4612. lRet = RegQueryValueEx( hRegKey, "Card List", 0, 0, (BYTE*)mszCardList, &dwIgn );
  4613. #else
  4614. BYTE bCardList[MAX_PATH];
  4615. DWORD dwCardListLen = MAX_PATH;
  4616. lRet = RegQueryValueEx( hRegKey, TEXT("Card List"), 0, 0, bCardList, &dwCardListLen );
  4617. MultiByteToWideChar( CP_ACP, 0, (char*)bCardList, MAX_PATH, mszCardList, MAX_PATH );
  4618. #endif
  4619. // Find in the base registry the name (and the path) for the dictionary
  4620. DBG_PRINT(TEXT(" Reading dictionary name...\n") );
  4621. #ifndef UNICODE
  4622. dwIgn = sizeof(szDictionaryName);
  4623. lRet = RegQueryValueEx( hRegKey, "X509 Dictionary Name", 0, 0, (BYTE*)szDictionaryName, &dwIgn );
  4624. #else
  4625. BYTE bDictName[256];
  4626. DWORD dwDictNameLen = 256;
  4627. lRet = RegQueryValueEx( hRegKey, TEXT("X509 Dictionary Name"), 0, 0, bDictName, &dwDictNameLen );
  4628. if (lRet == ERROR_SUCCESS)
  4629. {
  4630. // always use the resource dictionary
  4631. lRet = 2;
  4632. //MultiByteToWideChar( CP_ACP, 0, (char*)bDictName, 256, szDictionaryName, 256);
  4633. }
  4634. #endif
  4635. // Try to use registry dict first
  4636. if (lRet == ERROR_SUCCESS && IsNotNull( szDictionaryName ))
  4637. {
  4638. lRet = CC_Init( DICT_FILE, (BYTE*)szDictionaryName );
  4639. if (lRet != RV_SUCCESS)
  4640. lRet = CC_Init( DICT_STANDARD, 0 );
  4641. }
  4642. else
  4643. lRet = CC_Init( DICT_STANDARD, 0 );
  4644. RegCloseKey(hRegKey);
  4645. if (lRet)
  4646. {
  4647. CryptDestroyKey(hRsaIdentityKey);
  4648. CryptReleaseContext(hProvBase, 0);
  4649. RETURN (CRYPT_FAILED, NTE_NOT_FOUND);
  4650. }
  4651. // Key gen time for GPK8000
  4652. g_GPK8000KeyGenTime512 = 0;
  4653. g_GPK8000KeyGenTime1024 = 0;
  4654. lRet = RegCreateKeyEx( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Gemplus\\Cryptography\\SmartCards"),
  4655. 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_READ, 0, &hRegKey, 0 );
  4656. if (lRet == ERROR_SUCCESS)
  4657. {
  4658. dwIgn = sizeof(g_GPK8000KeyGenTime512);
  4659. lRet = RegQueryValueEx( hRegKey, TEXT("GPK8000KeyGenTime512"), 0, 0, (BYTE*)&g_GPK8000KeyGenTime512, &dwIgn );
  4660. dwIgn = sizeof(g_GPK8000KeyGenTime1024);
  4661. lRet = RegQueryValueEx( hRegKey, TEXT("GPK8000KeyGenTime1024"), 0, 0, (BYTE*)&g_GPK8000KeyGenTime1024, &dwIgn );
  4662. RegCloseKey(hRegKey);
  4663. }
  4664. RETURN (CRYPT_SUCCEED, 0);
  4665. }
  4666. /* -----------------------------------------------------------------------------
  4667. --------------------------------------------------------------------------------*/
  4668. BOOL LegacyAcquireDeleteKeySet( HCRYPTPROV* phProv,
  4669. const char* szContainer,
  4670. const char* szContainerAsked,
  4671. DWORD BuffFlags )
  4672. {
  4673. BOOL CryptResp;
  4674. //DWORD i;
  4675. DWORD SlotNb;
  4676. SlotNb = ProvCont[*phProv].Slot;
  4677. /*if (Slot[SlotNb].ContextCount > 0)
  4678. {
  4679. fLocked = TRUE;
  4680. }
  4681. else
  4682. {
  4683. // Must have exclusive access to destroy a keyset
  4684. DWORD protocol;
  4685. lRet = SCardReconnect( ProvCont[*phProv].hCard, SCARD_SHARE_EXCLUSIVE,
  4686. SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &protocol );
  4687. if (lRet==SCARD_S_SUCCESS)
  4688. fLocked = FALSE;
  4689. else if (lRet==SCARD_E_SHARING_VIOLATION)
  4690. fLocked = TRUE;
  4691. else
  4692. RETURN( CRYPT_FAILED, lRet );
  4693. }
  4694. if (fLocked)
  4695. RETURN( CRYPT_FAILED, SCARD_E_SHARING_VIOLATION );*/
  4696. if (BuffFlags & CRYPT_VERIFYCONTEXT)
  4697. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  4698. if (IsNotNullStr(szContainer))
  4699. {
  4700. if (strcmp(szContainer, szContainerAsked))
  4701. RETURN( CRYPT_FAILED, SCARD_W_REMOVED_CARD );
  4702. /* Release Microsoft RSA Base Module */
  4703. //for (i = 1; i <= MAX_GPK_OBJ; i++)
  4704. //{
  4705. // if (Slot[SlotNb].GpkObject[i].hKeyBase != 0)
  4706. // {
  4707. // CryptResp = CryptDestroyKey(Slot[SlotNb].GpkObject[i].hKeyBase);
  4708. // }
  4709. //}
  4710. //ProvCont[*phProv].hRSASign = 0;
  4711. //ProvCont[*phProv].hRSAKEK = 0;
  4712. if (ProvCont[*phProv].hRSAKEK != 0)
  4713. {
  4714. CryptDestroyKey( ProvCont[*phProv].hRSAKEK );
  4715. ProvCont[*phProv].hRSAKEK = 0;
  4716. }
  4717. if (ProvCont[*phProv].hRSASign != 0)
  4718. {
  4719. CryptDestroyKey( ProvCont[*phProv].hRSASign );
  4720. ProvCont[*phProv].hRSASign = 0;
  4721. }
  4722. ProvCont[*phProv].hProv = *phProv;
  4723. ProvCont[*phProv].Flags = BuffFlags;
  4724. if (!PIN_Validation(*phProv))
  4725. return CRYPT_FAILED;
  4726. ProvCont[*phProv].hProv = 0;
  4727. ProvCont[*phProv].Flags = 0;
  4728. CryptResp = init_key_set(*phProv, "", szGpkPin, dwGpkPinLen);
  4729. if (!CryptResp)
  4730. return CRYPT_FAILED;
  4731. // Update the container name
  4732. strcpy( ProvCont[*phProv].szContainer, "" );
  4733. RETURN( CRYPT_SUCCEED, 0 );
  4734. }
  4735. else
  4736. {
  4737. RETURN( CRYPT_FAILED, NTE_BAD_KEYSET_PARAM );
  4738. }
  4739. }
  4740. // TT 12/10/99: Bug #1454
  4741. void DeleteGPKObject( Slot_Description* pSlot, int i )
  4742. {
  4743. GPK_OBJ* pObject = &pSlot->GpkObject[i];
  4744. int j;
  4745. // Delete object #i
  4746. // Release Microsoft RSA Base Module
  4747. if (pObject->hKeyBase != 0)
  4748. {
  4749. CryptDestroyKey( pObject->hKeyBase );
  4750. pObject->hKeyBase = 0;
  4751. }
  4752. // First free all memory for this object
  4753. for (j=0; j<MAX_FIELD; ++j)
  4754. {
  4755. if (pObject->Field[j].pValue)
  4756. {
  4757. GMEM_Free( pObject->Field[j].pValue );
  4758. pObject->Field[j].pValue = 0;
  4759. pObject->Field[j].Len = 0;
  4760. }
  4761. }
  4762. if (i < pSlot->NbGpkObject)
  4763. {
  4764. // Patch the hole
  4765. memmove( pObject, pObject + 1, (pSlot->NbGpkObject - i) * sizeof(GPK_OBJ) );
  4766. }
  4767. // Clear last object
  4768. ZeroMemory( &pSlot->GpkObject[pSlot->NbGpkObject], sizeof(GPK_OBJ) );
  4769. --pSlot->NbGpkObject;
  4770. }
  4771. // TT: End
  4772. BOOL AcquireDeleteKeySet( HCRYPTPROV* phProv,
  4773. const char* szContainer,
  4774. const char* szContainerAsked,
  4775. DWORD BuffFlags )
  4776. {
  4777. Prov_Context* pContext;
  4778. GPK_OBJ* pKeySet;
  4779. GPK_OBJ* pObject;
  4780. Slot_Description* pSlot;
  4781. BYTE keysetID;
  4782. int i, j, k;
  4783. BYTE* pbBuff1;
  4784. DWORD dwBuff1Len;
  4785. DWORD lRet;
  4786. DWORD SlotNb = ProvCont[*phProv].Slot;
  4787. /*if (Slot[SlotNb].ContextCount > 0)
  4788. {
  4789. fLocked = TRUE;
  4790. }
  4791. else
  4792. {
  4793. // Must have exclusive access to destroy a keyset
  4794. DWORD protocol;
  4795. lRet = SCardReconnect( ProvCont[*phProv].hCard, SCARD_SHARE_EXCLUSIVE,
  4796. SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &protocol );
  4797. if (lRet==SCARD_S_SUCCESS)
  4798. fLocked = FALSE;
  4799. else if (lRet==SCARD_E_SHARING_VIOLATION)
  4800. fLocked = TRUE;
  4801. else
  4802. RETURN( CRYPT_FAILED, lRet );
  4803. }
  4804. if (fLocked)
  4805. {
  4806. RETURN( CRYPT_FAILED, SCARD_E_SHARING_VIOLATION );
  4807. }*/
  4808. if (BuffFlags & CRYPT_VERIFYCONTEXT)
  4809. {
  4810. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  4811. }
  4812. pContext = &ProvCont[*phProv];
  4813. pSlot = &Slot[ pContext->Slot ];
  4814. pKeySet = FindKeySet( pSlot, szContainerAsked );
  4815. if (!pKeySet)
  4816. {
  4817. RETURN( CRYPT_FAILED, NTE_BAD_KEYSET_PARAM );
  4818. }
  4819. // Must validate PIN to destroy the key objects
  4820. //pContext->hRSASign = 0;
  4821. //pContext->hRSAKEK = 0;
  4822. if (pContext->hRSAKEK != 0)
  4823. {
  4824. CryptDestroyKey( pContext->hRSAKEK );
  4825. pContext->hRSAKEK = 0;
  4826. }
  4827. if (pContext->hRSASign != 0)
  4828. {
  4829. CryptDestroyKey( pContext->hRSASign );
  4830. pContext->hRSASign = 0;
  4831. }
  4832. pContext->hProv = *phProv;
  4833. pContext->Flags = BuffFlags;
  4834. if (!PIN_Validation(*phProv))
  4835. {
  4836. // SetLastError() already used by PIN_Validation()
  4837. return CRYPT_FAILED;
  4838. }
  4839. if (!Read_Priv_Obj(*phProv))
  4840. return CRYPT_FAILED;
  4841. // TT 12/10/99: Bug #1454
  4842. keysetID = pKeySet->Field[POS_ID].pValue[0];
  4843. // Find objects in the keyset and destroy them
  4844. for (i = 1; i <= pSlot->NbGpkObject; ++i)
  4845. {
  4846. pObject = &pSlot->GpkObject[i];
  4847. if (pObject->Flags & FLAG_KEYSET && pObject->Field[POS_KEYSET].pValue[0] == keysetID)
  4848. {
  4849. // If we found a key, "zap it"
  4850. if (pObject->Tag >= TAG_RSA_PUBLIC && pObject->Tag <= TAG_DSA_PRIVATE)
  4851. {
  4852. // Zap all keys with the same FileId
  4853. BYTE FileId = pObject->FileId;
  4854. for (j = 1; j<= pSlot->NbGpkObject; ++j)
  4855. {
  4856. GPK_OBJ* pObj = &pSlot->GpkObject[j];
  4857. if (pObj->Tag >= TAG_RSA_PUBLIC && pObj->Tag <= TAG_DSA_PRIVATE)
  4858. {
  4859. if (pObj->FileId == FileId)
  4860. {
  4861. pObj->Flags &= 0xF000;
  4862. pObj->ObjId = 0xFF;
  4863. // Release the fields
  4864. for (k=0; k<MAX_FIELD; ++k)
  4865. {
  4866. if (pObj->Field[k].pValue)
  4867. {
  4868. GMEM_Free( pObj->Field[k].pValue );
  4869. pObj->Field[k].pValue = 0;
  4870. pObj->Field[k].Len = 0;
  4871. }
  4872. pObj->Field[k].bReal = TRUE;
  4873. }
  4874. pObj->LastField = 0;
  4875. pObj->IsCreated = FALSE; //PYR 00/08/08 ensure that find_gpk_obj_tag_type will still work
  4876. // Release Microsoft RSA Base Module
  4877. //if (pObj->hKeyBase != 0)
  4878. //{
  4879. // CryptDestroyKey( pObj->hKeyBase );
  4880. // pObj->hKeyBase = 0;
  4881. //}
  4882. // PYR 00/08/08. This key becomes available
  4883. pSlot->UseFile[FileId - GPK_FIRST_KEY] = FALSE;
  4884. }
  4885. }
  4886. }
  4887. }
  4888. else
  4889. {
  4890. // Not a key, destroy the object
  4891. DeleteGPKObject( pSlot, i );
  4892. --i;
  4893. }
  4894. }
  4895. }
  4896. // Destroy the keyset object
  4897. pKeySet = FindKeySet( pSlot, szContainerAsked );
  4898. assert( pKeySet != 0 );
  4899. DeleteGPKObject( pSlot, (int)(pKeySet - &pSlot->GpkObject[0]) );
  4900. // TT: End
  4901. // TT 12/10/99: Bug #1454 - Update the card
  4902. pbBuff1 = (BYTE*)GMEM_Alloc( MAX_GPK_PUBLIC );
  4903. if (IsNull(pbBuff1))
  4904. {
  4905. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  4906. }
  4907. dwBuff1Len = MAX_GPK_PUBLIC;
  4908. if (!prepare_write_gpk_objects (pContext->hProv, pbBuff1, &dwBuff1Len, FALSE))
  4909. {
  4910. lRet = GetLastError();
  4911. GMEM_Free (pbBuff1);
  4912. RETURN( CRYPT_FAILED, lRet );
  4913. }
  4914. if (!write_gpk_objects(pContext->hProv, pbBuff1, dwBuff1Len, TRUE, FALSE))
  4915. {
  4916. lRet = GetLastError();
  4917. GMEM_Free (pbBuff1);
  4918. RETURN( CRYPT_FAILED, lRet );
  4919. }
  4920. GMEM_Free( pbBuff1 );
  4921. pbBuff1 = (BYTE*)GMEM_Alloc( MAX_GPK_PRIVATE );
  4922. if (IsNull(pbBuff1))
  4923. {
  4924. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  4925. }
  4926. dwBuff1Len = MAX_GPK_PRIVATE;
  4927. if (!prepare_write_gpk_objects (pContext->hProv, pbBuff1, &dwBuff1Len, TRUE))
  4928. {
  4929. lRet = GetLastError();
  4930. GMEM_Free (pbBuff1);
  4931. RETURN( CRYPT_FAILED, lRet );
  4932. }
  4933. if (!write_gpk_objects(pContext->hProv, pbBuff1, dwBuff1Len, TRUE, TRUE))
  4934. {
  4935. lRet = GetLastError();
  4936. GMEM_Free (pbBuff1);
  4937. RETURN( CRYPT_FAILED, lRet );
  4938. }
  4939. GMEM_Free( pbBuff1 );
  4940. // TT: End
  4941. // Byebye context
  4942. pContext->hProv = 0;
  4943. pContext->Flags = 0;
  4944. pContext->szContainer[0] = 0;
  4945. RETURN( CRYPT_SUCCEED, 0 );
  4946. }
  4947. /* -----------------------------------------------------------------------------
  4948. --------------------------------------------------------------------------------*/
  4949. BOOL LegacyAcquireNewKeySet( IN HCRYPTPROV* phProv,
  4950. OUT char* szContainer,
  4951. IN const char* szContainerAsked,
  4952. IN DWORD BuffFlags )
  4953. {
  4954. BOOL CryptResp, fLocked;
  4955. DWORD i, SlotNb;
  4956. HCRYPTKEY hPubKey;
  4957. // +NK 06.02.2001
  4958. // BYTE bPinValue[PIN_MAX+2];
  4959. DWORD dwPinLength;
  4960. DWORD dwStatus;
  4961. // -
  4962. ProvCont[*phProv].keysetID = 0;
  4963. SlotNb = ProvCont[*phProv].Slot;
  4964. // If another AcquireContext - without its related ReleaseContest -
  4965. // has been done before, this new AcquireContext can not be done
  4966. if (BuffFlags & CRYPT_VERIFYCONTEXT)
  4967. {
  4968. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  4969. }
  4970. // If no szContainerAsked is specified, the process is aborted
  4971. if (IsNullStr(szContainerAsked))
  4972. {
  4973. RETURN(CRYPT_FAILED, NTE_BAD_KEYSET_PARAM);
  4974. }
  4975. /* IN CASE THAT A DELETEKEY IS NOT DONE FOR A RE-ENROLLMENT */
  4976. // Reserve the Provider Context handle since the Acquire Context succeeded
  4977. ProvCont[*phProv].hProv = *phProv;
  4978. ProvCont[*phProv].Flags = BuffFlags;
  4979. if (Slot[SlotNb].InitFlag)
  4980. {
  4981. CryptResp = MyCPGetUserKey(*phProv, AT_KEYEXCHANGE, &hPubKey);
  4982. if (CryptResp)
  4983. {
  4984. RETURN (CRYPT_FAILED, NTE_TOKEN_KEYSET_STORAGE_FULL);
  4985. }
  4986. else
  4987. {
  4988. CryptResp = MyCPGetUserKey(*phProv, AT_SIGNATURE, &hPubKey);
  4989. if (CryptResp)
  4990. {
  4991. RETURN (CRYPT_FAILED, NTE_TOKEN_KEYSET_STORAGE_FULL);
  4992. }
  4993. }
  4994. }
  4995. // If another AcquireContext - without its related ReleaseContest -
  4996. // has been done before, this new AcquireContext can not be done
  4997. // {DCB} -- It's possible that the application that marked this busy
  4998. // exited without calling CryptReleaseContext. Hence, it's
  4999. // possible that this check will fail even if no one else
  5000. // is using the card. By making this check last, we reduce
  5001. // the likelyhood that this bug is encountered.
  5002. fLocked = FALSE;
  5003. if (fLocked)
  5004. {
  5005. RETURN (CRYPT_FAILED, SCARD_E_SHARING_VIOLATION);
  5006. }
  5007. // +NK 06.02.2001
  5008. // if ((BuffFlags & CRYPT_SILENT) && (IsNullStr(Slot[SlotNb].GetPin())))
  5009. dwStatus = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  5010. NULL,
  5011. &dwPinLength );
  5012. if ( (dwStatus != ERROR_SUCCESS) && (dwStatus != ERROR_EMPTY) )
  5013. RETURN (CRYPT_FAILED, dwStatus);
  5014. if ((BuffFlags & CRYPT_SILENT) && (dwStatus == ERROR_EMPTY))
  5015. // -
  5016. {
  5017. RETURN (CRYPT_FAILED, NTE_SILENT_CONTEXT);
  5018. }
  5019. if (!PIN_Validation(*phProv))
  5020. return CRYPT_FAILED;
  5021. /* If the PIN code can be or has been entered, read the description of the
  5022. private key parameters*/
  5023. CspFlags = BuffFlags;
  5024. CryptResp = init_key_set(*phProv,
  5025. szContainerAsked,
  5026. szGpkPin,
  5027. dwGpkPinLen
  5028. );
  5029. if (!CryptResp)
  5030. return CRYPT_FAILED;
  5031. if (PublicEFExists(*phProv))
  5032. {
  5033. for (i = 1; i <= Slot[SlotNb].NbGpkObject; i++)
  5034. {
  5035. if ((Slot[SlotNb].GpkObject[i].Tag == TAG_RSA_PUBLIC)||
  5036. (Slot[SlotNb].GpkObject[i].Tag == TAG_RSA_PRIVATE))
  5037. {
  5038. read_gpk_pub_key(*phProv, i, &(Slot[SlotNb].GpkObject[i].PubKey));
  5039. }
  5040. }
  5041. }
  5042. else
  5043. {
  5044. for (i = 1; i <= Slot[SlotNb].NbGpkObject; i++)
  5045. {
  5046. if ((Slot[SlotNb].GpkObject[i].Tag == TAG_RSA_PUBLIC)||
  5047. (Slot[SlotNb].GpkObject[i].Tag == TAG_RSA_PRIVATE))
  5048. {
  5049. Slot[SlotNb].GpkObject[i].PubKey.KeySize = 0;
  5050. }
  5051. }
  5052. }
  5053. // Update the container name
  5054. strcpy( szContainer, szContainerAsked );
  5055. Slot[SlotNb].ContextCount++;
  5056. countCardContextRef++;
  5057. ProvCont[*phProv].keysetID = 0xFF;
  5058. RETURN (CRYPT_SUCCEED, 0);
  5059. }
  5060. BOOL CreateKeyset( HCRYPTPROV hProv, Slot_Description* pSlot, LPCSTR szName, BYTE* pKeySetID )
  5061. {
  5062. GPK_OBJ* pObject;
  5063. BYTE* pbBuff1;
  5064. DWORD dwBuff1Len;
  5065. int lRet;
  5066. BYTE keysetID;
  5067. int i, len;
  5068. *pKeySetID = 0;
  5069. if (pSlot->NbGpkObject >= MAX_GPK_OBJ)
  5070. {
  5071. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  5072. }
  5073. pObject = &pSlot->GpkObject[ pSlot->NbGpkObject + 1 ];
  5074. ZeroMemory( pObject, sizeof(*pObject) );
  5075. // Find an unused keyset ID
  5076. for (keysetID = 1; keysetID < 0xFF; ++keysetID)
  5077. {
  5078. if (FindKeySetByID( pSlot, keysetID ) == 0)
  5079. break; // Found one =)
  5080. }
  5081. if (keysetID == 0xFF)
  5082. {
  5083. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  5084. }
  5085. // Now initialize the fields
  5086. for (i=0; i<MAX_FIELD; ++i)
  5087. pObject->Field[i].bReal = TRUE;
  5088. pObject->Tag = TAG_KEYSET;
  5089. pObject->Flags = FLAG_ID | FLAG_LABEL;
  5090. pObject->ObjId = pSlot->NbGpkObject + 1;
  5091. pObject->IsPrivate = FALSE;
  5092. // Keyset ID
  5093. pObject->Field[POS_ID].Len = 1;
  5094. pObject->Field[POS_ID].pValue = (BYTE*)GMEM_Alloc( 1 );
  5095. pObject->Field[POS_ID].pValue[0] = keysetID;
  5096. // Keyset name
  5097. len = strlen( szName );
  5098. pObject->Field[POS_LABEL].Len = (WORD)len;
  5099. pObject->Field[POS_LABEL].pValue = (BYTE*)GMEM_Alloc( len );
  5100. memcpy( pObject->Field[POS_LABEL].pValue, szName, len );
  5101. // One more object!
  5102. ++(pSlot->NbGpkObject);
  5103. *pKeySetID = keysetID;
  5104. // TT 29/09/99: Save the keyset object =)
  5105. pbBuff1 = (BYTE*)GMEM_Alloc(MAX_GPK_PUBLIC);
  5106. if (IsNull(pbBuff1))
  5107. {
  5108. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  5109. }
  5110. dwBuff1Len = MAX_GPK_PUBLIC;
  5111. if (!prepare_write_gpk_objects (hProv, pbBuff1, &dwBuff1Len, FALSE))
  5112. {
  5113. lRet = GetLastError();
  5114. GMEM_Free (pbBuff1);
  5115. RETURN (CRYPT_FAILED, lRet);
  5116. }
  5117. if (!write_gpk_objects(hProv, pbBuff1, dwBuff1Len, FALSE, FALSE))
  5118. {
  5119. lRet = GetLastError();
  5120. GMEM_Free (pbBuff1);
  5121. RETURN (CRYPT_FAILED, lRet);
  5122. }
  5123. GMEM_Free (pbBuff1);
  5124. // TT - END -
  5125. RETURN( CRYPT_SUCCEED, 0 );
  5126. }
  5127. BOOL AcquireNewKeySet( IN HCRYPTPROV* phProv,
  5128. OUT char* szContainer,
  5129. IN const char* szContainerAsked,
  5130. DWORD BuffFlags )
  5131. {
  5132. Slot_Description* pSlot;
  5133. int SlotNb;
  5134. SlotNb = ProvCont[*phProv].Slot;
  5135. pSlot = &Slot[SlotNb];
  5136. ProvCont[*phProv].keysetID = 0;
  5137. // If another AcquireContext - without its related ReleaseContest -
  5138. // has been done before, this new AcquireContext can not be done
  5139. if (BuffFlags & CRYPT_VERIFYCONTEXT)
  5140. {
  5141. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  5142. }
  5143. // Check if keyset already exist on the card
  5144. if (FindKeySet( pSlot, szContainerAsked ))
  5145. {
  5146. RETURN( CRYPT_FAILED, NTE_EXISTS );
  5147. }
  5148. // If no szContainerAsked is specified, the process is aborted
  5149. if (IsNullStr(szContainerAsked))
  5150. {
  5151. RETURN( CRYPT_FAILED, NTE_BAD_KEYSET_PARAM );
  5152. }
  5153. // Reserve the Provider Context handle since the Acquire Context succeeded
  5154. ProvCont[*phProv].hProv = *phProv;
  5155. ProvCont[*phProv].Flags = BuffFlags;
  5156. CspFlags = BuffFlags;
  5157. // Create the keyset object
  5158. if (!CreateKeyset( *phProv, pSlot, szContainerAsked, &ProvCont[*phProv].keysetID ))
  5159. {
  5160. return FALSE;
  5161. }
  5162. // Update the container name
  5163. strcpy( szContainer, szContainerAsked );
  5164. ++(pSlot->ContextCount);
  5165. ++countCardContextRef;
  5166. RETURN( CRYPT_SUCCEED, 0 );
  5167. }
  5168. /* -----------------------------------------------------------------------------
  5169. --------------------------------------------------------------------------------*/
  5170. BOOL LegacyAcquireUseKeySet( HCRYPTPROV* phProv,
  5171. const char* szContainer,
  5172. const char* szContainerAsked,
  5173. DWORD BuffFlags )
  5174. {
  5175. BOOL CryptResp;
  5176. HCRYPTKEY hPubKey;
  5177. DWORD SlotNb;
  5178. SlotNb = ProvCont[*phProv].Slot;
  5179. ProvCont[*phProv].keysetID = 0;
  5180. if (IsNullStr(szContainer))
  5181. {
  5182. RETURN( CRYPT_FAILED, NTE_KEYSET_NOT_DEF );
  5183. }
  5184. // Accept only if the container asked is the same as the one on the card
  5185. // OR if the container asked is NULL and a reader is specified (SECURE LOGON)
  5186. if (IsNotNullStr(szContainerAsked) && strcmp(szContainer, szContainerAsked))
  5187. {
  5188. RETURN( CRYPT_FAILED, NTE_BAD_KEYSET );
  5189. }
  5190. // Reserve the Provider Context handle since the Acquire Context succeeded
  5191. ProvCont[*phProv].hProv = *phProv;
  5192. ProvCont[*phProv].Flags = BuffFlags;
  5193. hPubKey = 0;
  5194. CryptResp = MyCPGetUserKey(*phProv, AT_KEYEXCHANGE, &hPubKey);
  5195. // Copy the key into the RSA Base, if the key exists AND it has not been imported
  5196. // previously
  5197. if ((CryptResp) && (hPubKey != 0) && (ProvCont[*phProv].hRSAKEK == 0))
  5198. {
  5199. if (!copy_gpk_key(*phProv, hPubKey, AT_KEYEXCHANGE))
  5200. return CRYPT_FAILED;
  5201. }
  5202. hPubKey = 0;
  5203. CryptResp = MyCPGetUserKey(*phProv, AT_SIGNATURE, &hPubKey);
  5204. // Copy the key into the RSA Base, if the key exists AND it has not been imported
  5205. // previously
  5206. if (CryptResp && hPubKey!=0 && ProvCont[*phProv].hRSASign==0)
  5207. {
  5208. if (!copy_gpk_key(*phProv, hPubKey, AT_SIGNATURE))
  5209. return CRYPT_FAILED;
  5210. }
  5211. Slot[SlotNb].ContextCount++;
  5212. countCardContextRef++;
  5213. ProvCont[*phProv].keysetID = 0xFF;
  5214. RETURN( CRYPT_SUCCEED, 0 );
  5215. }
  5216. BOOL AcquireUseKeySet( HCRYPTPROV* phProv,
  5217. const char* szContainer,
  5218. const char* szContainerAsked,
  5219. DWORD BuffFlags )
  5220. {
  5221. BOOL CryptResp;
  5222. HCRYPTKEY hPubKey;
  5223. DWORD SlotNb;
  5224. GPK_OBJ* pKeySet;
  5225. SlotNb = ProvCont[*phProv].Slot;
  5226. ProvCont[*phProv].keysetID = 0;
  5227. // Secure logon doesn't specify a keyset name, let's use the first
  5228. // one available =)
  5229. if ( IsNullStr(szContainerAsked) )
  5230. {
  5231. pKeySet = FindFirstKeyset( &Slot[SlotNb] );
  5232. }
  5233. else
  5234. {
  5235. // Check if keyset is on the card
  5236. pKeySet = FindKeySet( &Slot[SlotNb], szContainerAsked );
  5237. }
  5238. if (pKeySet==0)
  5239. {
  5240. RETURN( CRYPT_FAILED, NTE_KEYSET_NOT_DEF );
  5241. }
  5242. // Found the container...
  5243. memcpy( ProvCont[*phProv].szContainer, (char*)pKeySet->Field[POS_LABEL].pValue,
  5244. pKeySet->Field[POS_LABEL].Len );
  5245. // Reserve the Provider Context handle since the Acquire Context succeeded
  5246. ProvCont[*phProv].hProv = *phProv;
  5247. ProvCont[*phProv].Flags = BuffFlags;
  5248. ProvCont[*phProv].keysetID = pKeySet->Field[POS_ID].pValue[0];
  5249. hPubKey = 0;
  5250. CryptResp = MyCPGetUserKey(*phProv, AT_KEYEXCHANGE, &hPubKey);
  5251. // Copy the key into the RSA Base, if the key exists AND it has not been imported
  5252. // previously
  5253. if ((CryptResp) && (hPubKey != 0) && (ProvCont[*phProv].hRSAKEK == 0))
  5254. {
  5255. if (!copy_gpk_key(*phProv, hPubKey, AT_KEYEXCHANGE))
  5256. {
  5257. return CRYPT_FAILED;
  5258. }
  5259. }
  5260. hPubKey = 0;
  5261. CryptResp = MyCPGetUserKey(*phProv, AT_SIGNATURE, &hPubKey);
  5262. // Copy the key into the RSA Base, if the key exists AND it has not been imported
  5263. // previously
  5264. if ((CryptResp) && (hPubKey != 0) && (ProvCont[*phProv].hRSASign == 0))
  5265. {
  5266. if (!copy_gpk_key(*phProv, hPubKey, AT_SIGNATURE))
  5267. {
  5268. return CRYPT_FAILED;
  5269. }
  5270. }
  5271. Slot[SlotNb].ContextCount++;
  5272. countCardContextRef++;
  5273. RETURN( CRYPT_SUCCEED, 0 );
  5274. }
  5275. /*
  5276. - MyCPAcquireContext
  5277. -
  5278. * Purpose:
  5279. * The CPAcquireContext function is used to acquire a context
  5280. * handle to a cryptograghic service provider (CSP).
  5281. *
  5282. *
  5283. * Parameters:
  5284. * OUT phProv - Handle to a CSP
  5285. * OUT pszIdentity - Pointer to a string which is the
  5286. * identity of the logged on user
  5287. * IN dwFlags - Flags values
  5288. * IN pVTable - Pointer to table of function pointers
  5289. *
  5290. * Returns:
  5291. */
  5292. BOOL WINAPI MyCPAcquireContext(OUT HCRYPTPROV *phProv,
  5293. IN LPCSTR pszContainer,
  5294. IN DWORD dwFlags,
  5295. IN PVTableProvStruc pVTable
  5296. )
  5297. {
  5298. SCARD_READERSTATE ReaderState;
  5299. DWORD dwStatus;
  5300. DWORD dwProto, ind, ind2;
  5301. DWORD BuffFlags;
  5302. DWORD lRet;
  5303. DWORD SlotNb;
  5304. BOOL CryptResp;
  5305. char szContainerAsked[128];
  5306. TCHAR szReaderName[512],
  5307. szReaderFriendlyName[512],
  5308. szModulePath[MAX_PATH],
  5309. szCspTitle[MAX_STRING],
  5310. szCspText[MAX_STRING];
  5311. *phProv = 0;
  5312. if (IsNull(hFirstInstMod))
  5313. {
  5314. hFirstInstMod = g_hInstMod;
  5315. dwStatus = GetModuleFileName( g_hInstMod, szModulePath, sizeof(szModulePath)/sizeof(TCHAR) );
  5316. if (dwStatus)
  5317. LoadLibrary(szModulePath);
  5318. }
  5319. if (bFirstGUILoad)
  5320. {
  5321. bFirstGUILoad = FALSE;
  5322. dwStatus = GetModuleFileName( g_hInstMod, szModulePath, sizeof(szModulePath)/sizeof(TCHAR) );
  5323. if (dwStatus)
  5324. {
  5325. #ifdef MS_BUILD
  5326. // Microsoft uses "gpkrsrc.dll"
  5327. _tcscpy(&szModulePath[_tcslen(szModulePath) - 7], TEXT("rsrc.dll"));
  5328. #else
  5329. // Gemplus uses "gpkgui.dll"
  5330. _tcscpy(&szModulePath[_tcslen(szModulePath) - 7], TEXT("gui.dll"));
  5331. #endif
  5332. DBG_PRINT(TEXT("Trying to load resource DLL: \"%s\""), szModulePath );
  5333. g_hInstRes = LoadLibrary(szModulePath);
  5334. DBG_PRINT(TEXT("Result is g_hInstRes = %08x, error is %08x"), g_hInstRes, (g_hInstRes) ? GetLastError(): 0 );
  5335. if (IsNull(g_hInstRes))
  5336. {
  5337. if (!(dwFlags & CRYPT_SILENT))
  5338. {
  5339. LoadString(g_hInstMod, IDS_GPKCSP_TITLE, szCspTitle, sizeof(szCspTitle)/sizeof(TCHAR));
  5340. LoadString(g_hInstMod, IDS_GPKCSP_NOGUI, szCspText, sizeof(szCspText)/sizeof(TCHAR));
  5341. MessageBox(0, szCspText, szCspTitle, MB_OK | MB_ICONEXCLAMATION);
  5342. }
  5343. RETURN( CRYPT_FAILED, NTE_PROVIDER_DLL_FAIL );
  5344. }
  5345. }
  5346. else
  5347. {
  5348. if (!(dwFlags & CRYPT_SILENT))
  5349. {
  5350. LoadString(g_hInstMod, IDS_GPKCSP_TITLE, szCspTitle, sizeof(szCspTitle)/sizeof(TCHAR));
  5351. LoadString(g_hInstMod, IDS_GPKCSP_NOGUI, szCspText, sizeof(szCspText)/sizeof(TCHAR));
  5352. MessageBox(0, szCspText, szCspTitle, MB_OK | MB_ICONEXCLAMATION);
  5353. }
  5354. RETURN( CRYPT_FAILED, NTE_PROVIDER_DLL_FAIL );
  5355. }
  5356. }
  5357. g_hMainWnd = 0;
  5358. if (pVTable)
  5359. {
  5360. if (pVTable->FuncReturnhWnd != 0)
  5361. {
  5362. // cspdk.h doesn't define the calling convention properly
  5363. typedef void (__stdcall *STDCALL_CRYPT_RETURN_HWND)(HWND *phWnd);
  5364. STDCALL_CRYPT_RETURN_HWND pfnFuncRreturnhWnd = (STDCALL_CRYPT_RETURN_HWND)pVTable->FuncReturnhWnd;
  5365. pfnFuncRreturnhWnd( &g_hMainWnd );
  5366. }
  5367. }
  5368. // If it is the first AcquireContext done by the application, then
  5369. // prepare the RSA BASE and initialize some variables;
  5370. if (hProvBase == 0)
  5371. {
  5372. CryptResp = InitAcquire();
  5373. if (!CryptResp)
  5374. return CRYPT_FAILED;
  5375. }
  5376. BuffFlags = dwFlags;
  5377. if (dwFlags & CRYPT_VERIFYCONTEXT)
  5378. dwFlags = dwFlags^CRYPT_VERIFYCONTEXT;
  5379. if (dwFlags & CRYPT_SILENT)
  5380. dwFlags = dwFlags^CRYPT_SILENT;
  5381. if (dwFlags & CRYPT_MACHINE_KEYSET) // This flag is ignored by this CSP
  5382. dwFlags = dwFlags^CRYPT_MACHINE_KEYSET;
  5383. // Parse the container name
  5384. ZeroMemory( szReaderFriendlyName, sizeof(szReaderFriendlyName) );
  5385. ZeroMemory( szContainerAsked, sizeof(szContainerAsked) );
  5386. if (IsNotNull (pszContainer))
  5387. {
  5388. ind = 0;
  5389. if (pszContainer[ind] == '\\')
  5390. {
  5391. ind = 4;
  5392. while ((pszContainer[ind] != 0x00) && (pszContainer[ind] != '\\'))
  5393. {
  5394. szReaderFriendlyName[ind-4] = pszContainer[ind];
  5395. ind++;
  5396. }
  5397. if (pszContainer[ind] == '\\')
  5398. {
  5399. ind++;
  5400. }
  5401. }
  5402. ind2 = 0;
  5403. while (pszContainer[ind] != 0x00)
  5404. {
  5405. szContainerAsked[ind2] = pszContainer[ind];
  5406. ind++;
  5407. ind2++;
  5408. }
  5409. }
  5410. else if (0 != (CRYPT_DELETEKEYSET & dwFlags))
  5411. {
  5412. RETURN( CRYPT_FAILED, NTE_PERM );
  5413. }
  5414. // Find a free handle for this new AcquireContext
  5415. *phProv = find_context_free();
  5416. if (*phProv == 0)
  5417. {
  5418. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  5419. }
  5420. ProvCont[*phProv].isContNameNullBlank = IsNullStr(pszContainer); // [mv - 15/05/98]
  5421. ProvCont[*phProv].bCardTransactionOpened = FALSE; // [FP]
  5422. if ((BuffFlags & CRYPT_VERIFYCONTEXT) && (ProvCont[*phProv].isContNameNullBlank)) // [mv - 15/05/98]
  5423. {
  5424. // return a velid handle, but without any access to the card
  5425. ProvCont[*phProv].hProv = *phProv;
  5426. ProvCont[*phProv].Flags = BuffFlags;
  5427. RETURN( CRYPT_SUCCEED, 0 );
  5428. }
  5429. else
  5430. {
  5431. /* Calais IRM Establish Context */
  5432. if (hCardContext == 0) // mv
  5433. {
  5434. lRet = SCardEstablishContext( SCARD_SCOPE_SYSTEM, 0, 0, &hCardContext );
  5435. if (SCARDPROBLEM(lRet,0x0000,0xFF))
  5436. {
  5437. hCardContext = 0;
  5438. countCardContextRef = 0;
  5439. ReleaseProvider(*phProv);
  5440. *phProv = 0;
  5441. RETURN( CRYPT_FAILED, lRet );
  5442. }
  5443. }
  5444. #if (_WIN32_WINNT < 0x0500)
  5445. // Read the reader list
  5446. char* pAllocatedBuff = 0;
  5447. __try
  5448. {
  5449. static s_bInit = false;
  5450. if (!s_bInit)
  5451. {
  5452. DWORD i, BuffLength;
  5453. char* Buff;
  5454. lRet = SCardListReaders(hCardContext, 0, 0, &BuffLength);
  5455. if (SCARDPROBLEM(lRet,0x0000,0xFF))
  5456. {
  5457. ReleaseProvider(*phProv);
  5458. *phProv = 0;
  5459. RETURN( CRYPT_FAILED, lRet );
  5460. }
  5461. pAllocatedBuff = (char*)GMEM_Alloc(BuffLength);
  5462. if (pAllocatedBuff == 0)
  5463. {
  5464. ReleaseProvider(*phProv);
  5465. *phProv = 0;
  5466. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  5467. }
  5468. Buff = pAllocatedBuff;
  5469. lRet = SCardListReaders(hCardContext, 0, Buff, &BuffLength);
  5470. if (SCARDPROBLEM(lRet,0x0000,0xFF))
  5471. {
  5472. ReleaseProvider(*phProv);
  5473. *phProv = 0;
  5474. RETURN( CRYPT_FAILED, lRet );
  5475. }
  5476. i = 0;
  5477. while (strlen(Buff) != 0 && i < MAX_SLOT)
  5478. {
  5479. ZeroMemory( Slot[i].szReaderName, sizeof(Slot[i].szReaderName) );
  5480. strcpy( Slot[i].szReaderName, Buff );
  5481. Buff = Buff + strlen(Buff) + 1;
  5482. i++;
  5483. }
  5484. if (strlen(Buff) != 0)
  5485. {
  5486. ReleaseProvider(*phProv);
  5487. *phProv = 0;
  5488. RETURN( CRYPT_FAILED, NTE_FAIL );
  5489. }
  5490. for (; i < MAX_SLOT; i++)
  5491. {
  5492. ZeroMemory( Slot[i].szReaderName, sizeof(Slot[i].szReaderName) );
  5493. }
  5494. s_bInit = true;
  5495. }
  5496. }
  5497. __finally
  5498. {
  5499. if (pAllocatedBuff)
  5500. {
  5501. GMEM_Free( pAllocatedBuff );
  5502. pAllocatedBuff = 0;
  5503. }
  5504. }
  5505. // If the ReaderFriendlyName is NULL, scan the list of readers to find the one
  5506. // containing the container key set that is looked for.
  5507. // This fix is to work around the bug on the
  5508. // OPEN_CARD - Ressource Manager v1.0 (NT4, Win 95) -
  5509. if (!IsWin2000() && IsNullStr(szReaderFriendlyName))
  5510. {
  5511. SCARDHANDLE hCard;
  5512. int NbMatch = 0;
  5513. GpkLocalUnlock();
  5514. __try
  5515. {
  5516. DWORD i;
  5517. char szSlotReaderName[512];
  5518. for (i = 0; i < MAX_SLOT; i++)
  5519. {
  5520. strcpy(szSlotReaderName, Slot[i].szReaderName);
  5521. if (IsNotNullStr (szSlotReaderName))
  5522. {
  5523. hCard = funcConnect (hCardContext, szSlotReaderName, mszCardList, 0);
  5524. if (hCard != 0)
  5525. {
  5526. //if (SCardBeginTransaction(hCard) == SCARD_S_SUCCESS)
  5527. //{
  5528. if (funcCheck (hCardContext, hCard, szContainerAsked))
  5529. {
  5530. strcpy (szReaderFriendlyName, szSlotReaderName);
  5531. NbMatch++;
  5532. }
  5533. // SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
  5534. //}
  5535. funcDisconnect (hCardContext, hCard, 0);
  5536. }
  5537. }
  5538. }
  5539. }
  5540. __finally
  5541. {
  5542. GpkLocalLock();
  5543. }
  5544. // If there are more than one match, the user has to chose
  5545. if (NbMatch != 1)
  5546. {
  5547. ZeroMemory( szReaderFriendlyName, sizeof(szReaderFriendlyName) );
  5548. }
  5549. }
  5550. #endif // (_WIN32_WINNT < 0x0500)
  5551. if (IsNullStr(szReaderFriendlyName))
  5552. {
  5553. SCARDHANDLE hCard = 0;
  5554. dwStatus = OpenCard(szContainerAsked, BuffFlags, &hCard, szReaderName, sizeof(szReaderName)/sizeof(TCHAR));
  5555. if ((hCard == 0) || (dwStatus != SCARD_S_SUCCESS))
  5556. {
  5557. ReleaseProvider(*phProv);
  5558. *phProv = 0;
  5559. RETURN (CRYPT_FAILED, dwStatus);
  5560. }
  5561. ProvCont[*phProv].hCard = hCard;
  5562. ReaderState.szReader = szReaderName;
  5563. ReaderState.dwCurrentState = SCARD_STATE_UNAWARE;
  5564. SCardGetStatusChange(hCardContext, 1, &ReaderState, 1);
  5565. _tcscpy(szReaderName, ReaderState.szReader);
  5566. if (!find_reader (&(ProvCont[*phProv].Slot), szReaderName))
  5567. {
  5568. ReleaseProvider(*phProv);
  5569. *phProv = 0;
  5570. RETURN( CRYPT_FAILED, SCARD_E_READER_UNAVAILABLE );
  5571. }
  5572. }
  5573. else
  5574. {
  5575. DWORD dwSts = ConnectToCard( szReaderFriendlyName,
  5576. SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0,
  5577. &ProvCont[*phProv].hCard, &dwProto );
  5578. if (dwSts != SCARD_S_SUCCESS)
  5579. {
  5580. ReleaseProvider(*phProv);
  5581. *phProv = 0;
  5582. RETURN( CRYPT_FAILED, dwSts );
  5583. }
  5584. ReaderState.szReader = szReaderFriendlyName;
  5585. ReaderState.dwCurrentState = SCARD_STATE_UNAWARE;
  5586. SCardGetStatusChange(hCardContext, 1, &ReaderState, 1);
  5587. _tcscpy(szReaderName, ReaderState.szReader);
  5588. if (!find_reader (&(ProvCont[*phProv].Slot), szReaderFriendlyName))
  5589. {
  5590. ReleaseProvider(*phProv);
  5591. *phProv = 0;
  5592. RETURN( CRYPT_FAILED, SCARD_E_READER_UNAVAILABLE );
  5593. }
  5594. }
  5595. // Now we know which reader is used. start a thread to check that reader if necessary
  5596. lRet = BeginTransaction(ProvCont[*phProv].hCard);
  5597. if (lRet != SCARD_S_SUCCESS)
  5598. {
  5599. ReleaseProvider(*phProv);
  5600. *phProv = 0;
  5601. RETURN (CRYPT_FAILED, lRet);
  5602. }
  5603. SlotNb = ProvCont[*phProv].Slot;
  5604. InitializeSlot( SlotNb );
  5605. // TT 30/07/99
  5606. lRet = DetectGPK8000( ProvCont[*phProv].hCard, &ProvCont[*phProv].bGPK8000 );
  5607. if (lRet != SCARD_S_SUCCESS)
  5608. {
  5609. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5610. ReleaseProvider(*phProv);
  5611. *phProv = 0;
  5612. RETURN (CRYPT_FAILED, lRet );
  5613. }
  5614. ProvCont[*phProv].bLegacyKeyset = FALSE;
  5615. // TT: END
  5616. ProvCont[*phProv].hRSASign = 0;
  5617. ProvCont[*phProv].hRSAKEK = 0;
  5618. ProvCont[*phProv].keysetID = 0xFF; // TT: GPK8000 support
  5619. ProvCont[*phProv].bGPK_ISO_DF = FALSE;
  5620. ProvCont[*phProv].dataUnitSize = 0;
  5621. ProvCont[*phProv].bDisconnected = FALSE;
  5622. if (!Select_MF(*phProv))
  5623. {
  5624. // [FP] +
  5625. DBG_PRINT(TEXT("Try to reconnect"));
  5626. DWORD dwProto;
  5627. lRet = SCardReconnect(ProvCont[*phProv].hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &dwProto);
  5628. if (lRet != SCARD_S_SUCCESS) RETURN (CRYPT_FAILED, lRet);
  5629. DBG_PRINT(TEXT("Try Select_MF again"));
  5630. if (!Select_MF(*phProv))
  5631. {
  5632. DBG_PRINT(TEXT("Second Select_MF fails"));
  5633. // [FP] -
  5634. lRet = GetLastError();
  5635. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5636. ReleaseProvider(*phProv);
  5637. *phProv = 0;
  5638. RETURN( CRYPT_FAILED, lRet );
  5639. }
  5640. }
  5641. // Read Serial number to store it
  5642. bSendBuffer[0] = 0x80; //CLA
  5643. bSendBuffer[1] = 0xC0; //INS
  5644. bSendBuffer[2] = 0x02; //P1
  5645. bSendBuffer[3] = 0xA0; //P2
  5646. bSendBuffer[4] = 0x08; //Lo
  5647. cbSendLength = 5;
  5648. cbRecvLength = sizeof(bRecvBuffer);
  5649. lRet = SCardTransmit(ProvCont[*phProv].hCard,
  5650. SCARD_PCI_T0,
  5651. bSendBuffer,
  5652. cbSendLength,
  5653. NULL,
  5654. bRecvBuffer,
  5655. &cbRecvLength);
  5656. if (SCARDPROBLEM(lRet,0x9000, bSendBuffer[4]))
  5657. {
  5658. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5659. ReleaseProvider(*phProv);
  5660. *phProv = 0;
  5661. RETURN (CRYPT_FAILED,
  5662. (SCARD_S_SUCCESS == lRet) ? NTE_BAD_KEYSET : lRet);
  5663. }
  5664. memcpy(Slot[SlotNb].bGpkSerNb, bRecvBuffer, bSendBuffer[4]);
  5665. if (!Select_Crypto_DF(*phProv))
  5666. {
  5667. lRet = GetLastError();
  5668. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5669. ReleaseProvider(*phProv);
  5670. *phProv = 0;
  5671. RETURN( CRYPT_FAILED, lRet );
  5672. }
  5673. // Get the response from the Select DF to obtain the IADF
  5674. bSendBuffer[0] = 0x00; //CLA
  5675. bSendBuffer[1] = 0xC0; //INS
  5676. bSendBuffer[2] = 0x00; //P1
  5677. bSendBuffer[3] = 0x00; //P2
  5678. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  5679. cbSendLength = 5;
  5680. cbRecvLength = sizeof(bRecvBuffer);
  5681. lRet = SCardTransmit( ProvCont[*phProv].hCard, SCARD_PCI_T0, bSendBuffer,
  5682. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  5683. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  5684. {
  5685. Select_MF(*phProv);
  5686. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5687. ReleaseProvider(*phProv);
  5688. *phProv = 0;
  5689. RETURN( CRYPT_FAILED, (SCARD_S_SUCCESS == lRet) ? NTE_BAD_KEYSET : lRet );
  5690. }
  5691. ZeroMemory( ProvCont[*phProv].szContainer, sizeof(ProvCont[*phProv].szContainer));
  5692. if (bRecvBuffer[4] == 0x30)
  5693. Slot[SlotNb].InitFlag = FALSE;
  5694. else
  5695. {
  5696. Slot[SlotNb].InitFlag = TRUE;
  5697. if (ProvCont[*phProv].bGPK8000)
  5698. {
  5699. // Find the keyset's name
  5700. // This is done in AcquireUseKeySet()
  5701. ZeroMemory( ProvCont[*phProv].szContainer, sizeof(ProvCont[*phProv].szContainer) );
  5702. }
  5703. else
  5704. {
  5705. memcpy(ProvCont[*phProv].szContainer, &bRecvBuffer[5], cbRecvLength - 7);
  5706. }
  5707. }
  5708. // read the description of the public key parameters
  5709. if (!Slot[SlotNb].ValidateTimestamps(*phProv))
  5710. return CRYPT_FAILED;
  5711. if (!Slot[SlotNb].Read_Public)
  5712. {
  5713. if (!read_gpk_objects(*phProv, FALSE))
  5714. {
  5715. lRet = GetLastError();
  5716. Select_MF(*phProv);
  5717. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5718. ReleaseProvider(*phProv);
  5719. *phProv = 0;
  5720. RETURN (CRYPT_FAILED, lRet);
  5721. }
  5722. Slot[SlotNb].Read_Public = TRUE;
  5723. Slot[SlotNb].Read_Priv = FALSE;
  5724. }
  5725. }
  5726. // TT 05/10/99
  5727. if (!ProvCont[*phProv].bGPK8000)
  5728. {
  5729. ProvCont[*phProv].bLegacyKeyset = DetectLegacy( &Slot[SlotNb] );
  5730. if (!ProvCont[*phProv].bLegacyKeyset)
  5731. {
  5732. ZeroMemory( ProvCont[*phProv].szContainer, sizeof(ProvCont[*phProv].szContainer) );
  5733. }
  5734. }
  5735. // TT - END -
  5736. if (dwFlags == CRYPT_DELETEKEYSET)
  5737. {
  5738. if (ProvCont[*phProv].bLegacyKeyset)
  5739. CryptResp = LegacyAcquireDeleteKeySet(phProv, ProvCont[*phProv].szContainer, szContainerAsked, BuffFlags);
  5740. else
  5741. CryptResp = AcquireDeleteKeySet(phProv, ProvCont[*phProv].szContainer, szContainerAsked, BuffFlags);
  5742. lRet = GetLastError();
  5743. Select_MF (*phProv);
  5744. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5745. ReleaseProvider(*phProv);
  5746. *phProv = 0;
  5747. RETURN( CryptResp, lRet );
  5748. }
  5749. else if (dwFlags == CRYPT_NEWKEYSET)
  5750. {
  5751. if (ProvCont[*phProv].bLegacyKeyset)
  5752. CryptResp = LegacyAcquireNewKeySet(phProv, ProvCont[*phProv].szContainer, szContainerAsked, BuffFlags);
  5753. else
  5754. CryptResp = AcquireNewKeySet( phProv, ProvCont[*phProv].szContainer, szContainerAsked, BuffFlags );
  5755. lRet = GetLastError();
  5756. Select_MF (*phProv);
  5757. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5758. if (!CryptResp)
  5759. {
  5760. ReleaseProvider (*phProv);
  5761. *phProv = 0;
  5762. }
  5763. RETURN( CryptResp, lRet );
  5764. }
  5765. else if (dwFlags == 0)
  5766. {
  5767. if (ProvCont[*phProv].bLegacyKeyset)
  5768. CryptResp = LegacyAcquireUseKeySet(phProv, ProvCont[*phProv].szContainer, szContainerAsked, BuffFlags);
  5769. else
  5770. CryptResp = AcquireUseKeySet(phProv, ProvCont[*phProv].szContainer, szContainerAsked, BuffFlags);
  5771. lRet = GetLastError();
  5772. //Select_MF (*phProv); // [FP] PIN not presented
  5773. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5774. if (!CryptResp)
  5775. {
  5776. ReleaseProvider (*phProv);
  5777. *phProv = 0;
  5778. }
  5779. RETURN( CryptResp, lRet );
  5780. }
  5781. else
  5782. {
  5783. SCardEndTransaction(ProvCont[*phProv].hCard, SCARD_LEAVE_CARD);
  5784. ReleaseProvider(*phProv);
  5785. *phProv = 0;
  5786. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  5787. }
  5788. }
  5789. /*
  5790. - MyCPGetProvParam
  5791. -
  5792. * Purpose:
  5793. * Allows applications to get various aspects of the
  5794. * operations of a provider
  5795. *
  5796. * Parameters:
  5797. * IN hProv - Handle to a CSP
  5798. * IN dwParam - Parameter number
  5799. * OUT pbData - Pointer to data
  5800. * IN pdwDataLen - Length of parameter data
  5801. * IN dwFlags - Flags values
  5802. *
  5803. * Returns:
  5804. */
  5805. BOOL WINAPI MyCPGetProvParam( IN HCRYPTPROV hProv,
  5806. IN DWORD dwParam,
  5807. IN BYTE* pbData,
  5808. IN DWORD* pdwDataLen,
  5809. IN DWORD dwFlags )
  5810. {
  5811. DWORD lRet;
  5812. BOOL CryptResp;
  5813. DWORD SlotNb;
  5814. ALG_ID aiAlgid;
  5815. BOOL algNotSupported;
  5816. TCHAR szCspName[MAX_STRING];
  5817. BYTE* ptr = 0;
  5818. if (!Context_exist(hProv))
  5819. {
  5820. RETURN( CRYPT_FAILED, NTE_BAD_UID );
  5821. }
  5822. SlotNb = ProvCont[hProv].Slot;
  5823. if (dwFlags & CRYPT_MACHINE_KEYSET)
  5824. {
  5825. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  5826. }
  5827. if ((dwFlags == CRYPT_FIRST)
  5828. &&(dwParam != PP_ENUMALGS)
  5829. &&(dwParam != PP_ENUMALGS_EX)
  5830. &&(dwParam != PP_ENUMCONTAINERS)
  5831. )
  5832. {
  5833. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  5834. }
  5835. switch (dwParam)
  5836. {
  5837. case PP_UNIQUE_CONTAINER:
  5838. case PP_CONTAINER:
  5839. // [mv - 15/05/98]
  5840. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  5841. (ProvCont[hProv].isContNameNullBlank))
  5842. {
  5843. RETURN (CRYPT_FAILED, NTE_PERM);
  5844. }
  5845. if (IsNotNull(pbData))
  5846. {
  5847. if (*pdwDataLen < strlen(ProvCont[hProv].szContainer)+1)
  5848. {
  5849. *pdwDataLen = strlen(ProvCont[hProv].szContainer)+1;
  5850. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  5851. }
  5852. strcpy( (char*)pbData, ProvCont[hProv].szContainer);
  5853. }
  5854. *pdwDataLen = strlen(ProvCont[hProv].szContainer)+1;
  5855. break;
  5856. case PP_ENUMALGS:
  5857. case PP_ENUMALGS_EX:
  5858. CryptResp = CryptGetProvParam(hProvBase,
  5859. dwParam,
  5860. pbData,
  5861. pdwDataLen,
  5862. dwFlags
  5863. );
  5864. if (!CryptResp)
  5865. {
  5866. lRet = GetLastError();
  5867. RETURN (CRYPT_FAILED, lRet);
  5868. }
  5869. if (NULL != pbData)
  5870. {
  5871. // Extract algorithm information from 'pbData' buffer.
  5872. ptr = pbData;
  5873. aiAlgid = *(ALG_ID UNALIGNED *)ptr;
  5874. BOOL b512exist = FALSE,
  5875. b1024exist = FALSE;
  5876. for ( unsigned i = 0 ; i < Slot[SlotNb].NbKeyFile; ++i )
  5877. {
  5878. if (Slot[SlotNb].GpkPubKeys[i].KeySize == 512/8) b512exist = TRUE;
  5879. else if (Slot[SlotNb].GpkPubKeys[i].KeySize == 1024/8) b1024exist = TRUE;
  5880. }
  5881. // Can happen if card is removed
  5882. if (!b512exist && !b1024exist)
  5883. Slot[SlotNb].NbKeyFile = 0;
  5884. if (aiAlgid == CALG_RSA_KEYX)
  5885. {
  5886. if (PP_ENUMALGS_EX == dwParam)
  5887. {
  5888. PROV_ENUMALGS_EX *penAlg = (PROV_ENUMALGS_EX *)pbData;
  5889. if (Slot[SlotNb].NbKeyFile==0)
  5890. {
  5891. penAlg->dwDefaultLen = RSA_KEK_Size * 8;
  5892. penAlg->dwMinLen = 512;
  5893. penAlg->dwMaxLen = RSA_KEK_Size * 8;
  5894. }
  5895. else
  5896. {
  5897. penAlg->dwDefaultLen = RSA_KEK_Size * 8;
  5898. penAlg->dwMinLen = (b512exist) ? 512 : 1024;
  5899. penAlg->dwMaxLen = (b1024exist) ? 1024 : 512;
  5900. if (penAlg->dwMaxLen > (DWORD)RSA_KEK_Size * 8)
  5901. penAlg->dwMaxLen = (DWORD)RSA_KEK_Size * 8;
  5902. }
  5903. }
  5904. else
  5905. {
  5906. PROV_ENUMALGS *penAlg = (PROV_ENUMALGS *)pbData;
  5907. if (Slot[SlotNb].NbKeyFile==0)
  5908. penAlg->dwBitLen = RSA_KEK_Size * 8;
  5909. else
  5910. {
  5911. penAlg->dwBitLen = (b1024exist) ? 1024 : 512;
  5912. if (penAlg->dwBitLen > (DWORD)RSA_KEK_Size * 8)
  5913. penAlg->dwBitLen = (DWORD)RSA_KEK_Size * 8;
  5914. }
  5915. }
  5916. }
  5917. else if (aiAlgid == CALG_RSA_SIGN)
  5918. {
  5919. if (PP_ENUMALGS_EX == dwParam)
  5920. {
  5921. PROV_ENUMALGS_EX *penAlg = (PROV_ENUMALGS_EX *)pbData;
  5922. if (Slot[SlotNb].NbKeyFile==0)
  5923. {
  5924. penAlg->dwDefaultLen = 1024;
  5925. penAlg->dwMinLen = 512;
  5926. penAlg->dwMaxLen = 1024;
  5927. }
  5928. else
  5929. {
  5930. penAlg->dwDefaultLen = (b1024exist) ? 1024 : 512;
  5931. penAlg->dwMinLen = (b512exist) ? 512 : 1024;
  5932. penAlg->dwMaxLen = (b1024exist) ? 1024 : 512;
  5933. }
  5934. }
  5935. else
  5936. {
  5937. PROV_ENUMALGS *penAlg = (PROV_ENUMALGS *)pbData;
  5938. if (Slot[SlotNb].NbKeyFile==0)
  5939. penAlg->dwBitLen = 1024;
  5940. else
  5941. penAlg->dwBitLen = (b1024exist) ? 1024 : 512;
  5942. }
  5943. }
  5944. else if ( ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT &&
  5945. ProvCont[hProv].isContNameNullBlank )
  5946. {
  5947. // No access to the card has been done in this case
  5948. }
  5949. else if ((dwFlags != CRYPT_FIRST ) && (Slot[SlotNb].GpkMaxSessionKey == 0))
  5950. {
  5951. // card was removed, nothing to do
  5952. }
  5953. else if (GET_ALG_CLASS(aiAlgid) == ALG_CLASS_DATA_ENCRYPT)
  5954. {
  5955. // The max session key in the card is only for encryption
  5956. // There is a card in the Reader,
  5957. // read the max session key, if not already done
  5958. if (Slot[SlotNb].GpkMaxSessionKey == 0)
  5959. {
  5960. CryptResp = Read_MaxSessionKey_EF(hProv,
  5961. &(Slot[SlotNb].GpkMaxSessionKey));
  5962. // if the DF of EF is not here, maxSessionKey==0
  5963. }
  5964. // skip the algo if not supported by the card
  5965. do
  5966. {
  5967. algNotSupported = FALSE;
  5968. if (dwParam == PP_ENUMALGS)
  5969. {
  5970. PROV_ENUMALGS *penAlg = (PROV_ENUMALGS *)pbData;
  5971. // TT Hack: "Unknown cryptographic algorithm" at winlogon problem.
  5972. if (penAlg->aiAlgid == CALG_RC2 && Slot[SlotNb].GpkMaxSessionKey < 128)
  5973. {
  5974. penAlg->dwBitLen = 40;
  5975. }
  5976. // DES needs 64 bits of unwrap capability
  5977. if (penAlg->aiAlgid == CALG_DES && Slot[SlotNb].GpkMaxSessionKey < 64)
  5978. algNotSupported = TRUE;
  5979. else
  5980. // Limit encryption algorithms to unwrap capabilities
  5981. if (GET_ALG_CLASS(penAlg->aiAlgid)==ALG_CLASS_DATA_ENCRYPT)
  5982. {
  5983. if (penAlg->dwBitLen > Slot[SlotNb].GpkMaxSessionKey)
  5984. algNotSupported = TRUE;
  5985. }
  5986. }
  5987. else
  5988. {
  5989. PROV_ENUMALGS_EX *penAlg = (PROV_ENUMALGS_EX *)pbData;
  5990. // TT Hack: "Unknown cryptographic algorithm" at winlogon problem.
  5991. if (penAlg->aiAlgid == CALG_RC2 && Slot[SlotNb].GpkMaxSessionKey < 128)
  5992. {
  5993. penAlg->dwDefaultLen = 40;
  5994. penAlg->dwMinLen = 40;
  5995. penAlg->dwMaxLen = 40;
  5996. }
  5997. // DES needs 64 bits of unwrap capability
  5998. if (penAlg->aiAlgid == CALG_DES && Slot[SlotNb].GpkMaxSessionKey < 64)
  5999. algNotSupported = TRUE;
  6000. else
  6001. // Limit encryption algorithms to unwrap capabilities
  6002. if (GET_ALG_CLASS(penAlg->aiAlgid)==ALG_CLASS_DATA_ENCRYPT)
  6003. {
  6004. if (penAlg->dwMinLen > Slot[SlotNb].GpkMaxSessionKey)
  6005. algNotSupported = TRUE;
  6006. else
  6007. {
  6008. if (penAlg->dwMaxLen > Slot[SlotNb].GpkMaxSessionKey)
  6009. penAlg->dwMaxLen = Slot[SlotNb].GpkMaxSessionKey;
  6010. if (penAlg->dwDefaultLen > penAlg->dwMaxLen)
  6011. penAlg->dwDefaultLen = penAlg->dwMaxLen;
  6012. }
  6013. }
  6014. }
  6015. if (algNotSupported)
  6016. {
  6017. // Algo not supported, read the next one
  6018. dwFlags = 0;
  6019. CryptResp = CryptGetProvParam( hProvBase, dwParam, pbData, pdwDataLen, dwFlags );
  6020. if (!CryptResp)
  6021. return CRYPT_FAILED;
  6022. }
  6023. } while (algNotSupported);
  6024. }
  6025. }
  6026. break;
  6027. case PP_ENUMCONTAINERS:
  6028. {
  6029. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  6030. (ProvCont[hProv].isContNameNullBlank))
  6031. {
  6032. static CHAR* ptr = 0;
  6033. static CHAR mszContainerList[(MAX_SLOT * 128) + 1];
  6034. DWORD dwContainerListLen = 0;
  6035. static DWORD dwContainerMaxLen = 0;
  6036. if (dwFlags == CRYPT_FIRST)
  6037. {
  6038. // List readers
  6039. SCARDCONTEXT hCardEnumContext;
  6040. lRet = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hCardEnumContext);
  6041. if (lRet != SCARD_S_SUCCESS)
  6042. {
  6043. if (lRet == SCARD_E_NO_SERVICE)
  6044. lRet = ERROR_NO_MORE_ITEMS;
  6045. RETURN (CRYPT_FAILED, lRet);
  6046. }
  6047. PTCHAR mszReaderList = 0;
  6048. DWORD dwReaderListLen = 0;
  6049. lRet = SCardListReaders(hCardEnumContext, 0, mszReaderList, &dwReaderListLen);
  6050. if (lRet != SCARD_S_SUCCESS)
  6051. {
  6052. if (lRet == SCARD_E_NO_READERS_AVAILABLE)
  6053. lRet = ERROR_NO_MORE_ITEMS;
  6054. SCardReleaseContext(hCardEnumContext);
  6055. RETURN (CRYPT_FAILED, lRet);
  6056. }
  6057. mszReaderList = (PTCHAR)GMEM_Alloc(dwReaderListLen * sizeof(TCHAR));
  6058. if (IsNull(mszReaderList))
  6059. {
  6060. SCardReleaseContext(hCardEnumContext);
  6061. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  6062. }
  6063. lRet = SCardListReaders(hCardEnumContext, 0, mszReaderList, &dwReaderListLen);
  6064. if (lRet != SCARD_S_SUCCESS)
  6065. {
  6066. GMEM_Free(mszReaderList);
  6067. SCardReleaseContext(hCardEnumContext);
  6068. RETURN (CRYPT_FAILED, lRet);
  6069. }
  6070. SCardReleaseContext(hCardEnumContext);
  6071. // For each reader, find the container if any
  6072. PTCHAR szReader = 0;
  6073. PTCHAR szReader2 = 0;
  6074. CHAR szContainer[128];
  6075. DWORD dwContainerLen = 128;
  6076. HCRYPTPROV hProv;
  6077. for (szReader = mszReaderList; *szReader != 0; szReader += (_tcsclen(szReader) + 1))
  6078. {
  6079. szReader2 = (PTCHAR)GMEM_Alloc((_tcslen(szReader) + 5)*sizeof(TCHAR));
  6080. if (IsNull(szReader2))
  6081. {
  6082. GMEM_Free(mszReaderList);
  6083. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  6084. }
  6085. _tcscpy(szReader2, TEXT("\\\\.\\"));
  6086. _tcscat(szReader2, szReader);
  6087. CHAR szReaderChar[128];
  6088. #ifndef UNICODE
  6089. strcpy(szReaderChar, szReader2);
  6090. #else
  6091. WideCharToMultiByte(CP_ACP, 0, szReader2, -1, szReaderChar, 128, 0, 0);
  6092. #endif
  6093. GMEM_Free(szReader2);
  6094. if (!MyCPAcquireContext(&hProv, szReaderChar, CRYPT_VERIFYCONTEXT | CRYPT_SILENT, 0))
  6095. {
  6096. DWORD dwGLE = GetLastError();
  6097. if (dwGLE == NTE_KEYSET_NOT_DEF ||
  6098. dwGLE == SCARD_W_REMOVED_CARD ||
  6099. dwGLE == SCARD_E_DIR_NOT_FOUND || // likely to happen with a non Gemplus card
  6100. dwGLE == SCARD_E_PROTO_MISMATCH) // likely to happen with T=1 card
  6101. {
  6102. continue;
  6103. }
  6104. else
  6105. {
  6106. GMEM_Free(mszReaderList);
  6107. RETURN (CRYPT_FAILED, NTE_FAIL);
  6108. }
  6109. }
  6110. dwContainerLen = 128;
  6111. if (!MyCPGetProvParam(hProv, PP_CONTAINER, (BYTE*)szContainer, &dwContainerLen, 0))
  6112. {
  6113. GMEM_Free(mszReaderList);
  6114. RETURN (CRYPT_FAILED, NTE_FAIL);
  6115. }
  6116. MyCPReleaseContext(hProv, 0);
  6117. strcpy(&mszContainerList[dwContainerListLen], szContainer);
  6118. dwContainerListLen += dwContainerLen;
  6119. dwContainerMaxLen = max(dwContainerMaxLen, dwContainerLen);
  6120. }
  6121. GMEM_Free(mszReaderList);
  6122. ptr = mszContainerList;
  6123. }
  6124. // Return containers one by one
  6125. if (ptr == 0 || *ptr == 0)
  6126. RETURN (CRYPT_FAILED, ERROR_NO_MORE_ITEMS);
  6127. if (IsNotNull(pbData))
  6128. {
  6129. if (*pdwDataLen < dwContainerMaxLen)
  6130. {
  6131. *pdwDataLen = dwContainerMaxLen;
  6132. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6133. }
  6134. strcpy((CHAR*)pbData, ptr);
  6135. *pdwDataLen = strlen(ptr) + 1;
  6136. ptr += strlen(ptr) + 1;
  6137. }
  6138. else
  6139. {
  6140. *pdwDataLen = dwContainerMaxLen;
  6141. }
  6142. }
  6143. else
  6144. {
  6145. if (dwFlags == CRYPT_FIRST)
  6146. {
  6147. if (!MyCPGetProvParam(hProv, PP_CONTAINER, pbData, pdwDataLen, 0))
  6148. {
  6149. RETURN (CRYPT_FAILED, GetLastError());
  6150. }
  6151. }
  6152. else
  6153. {
  6154. RETURN (CRYPT_FAILED, ERROR_NO_MORE_ITEMS);
  6155. }
  6156. }
  6157. }
  6158. break;
  6159. case PP_IMPTYPE:
  6160. if (IsNotNull(pbData))
  6161. {
  6162. DWORD dwType = CRYPT_IMPL_MIXED | CRYPT_IMPL_REMOVABLE;
  6163. if (*pdwDataLen < sizeof(DWORD))
  6164. {
  6165. *pdwDataLen = sizeof(DWORD);
  6166. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6167. }
  6168. memcpy(pbData, &dwType, sizeof(dwType));
  6169. }
  6170. *pdwDataLen = sizeof(DWORD);
  6171. break;
  6172. case PP_KEYX_KEYSIZE_INC:
  6173. case PP_SIG_KEYSIZE_INC:
  6174. if (IsNotNull(pbData))
  6175. {
  6176. BOOL b512exist = FALSE,
  6177. b1024exist = FALSE;
  6178. for ( unsigned i = 0 ; i < Slot[SlotNb].NbKeyFile; ++i )
  6179. {
  6180. if (Slot[SlotNb].GpkPubKeys[i].KeySize == 512) b512exist = TRUE;
  6181. else if (Slot[SlotNb].GpkPubKeys[i].KeySize == 1024) b1024exist = TRUE;
  6182. }
  6183. // Can happen if card is removed
  6184. if (!b512exist && !b1024exist)
  6185. Slot[SlotNb].NbKeyFile = 0;
  6186. if (dwParam == PP_KEYX_KEYSIZE_INC && b1024exist && RSA_KEK_Size * 8 < 1024)
  6187. b1024exist = FALSE;
  6188. DWORD dwSize = 0;
  6189. if (b512exist && b1024exist)
  6190. dwSize = 512;
  6191. if (*pdwDataLen < sizeof(DWORD))
  6192. {
  6193. *pdwDataLen = sizeof(DWORD);
  6194. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6195. }
  6196. memcpy(pbData, &dwSize, sizeof(dwSize));
  6197. }
  6198. *pdwDataLen = sizeof(DWORD);
  6199. break;
  6200. case PP_NAME:
  6201. LoadString(g_hInstMod, IDS_GPKCSP_NAME, szCspName, sizeof(szCspName)/sizeof(TCHAR));
  6202. if (IsNotNull(pbData))
  6203. {
  6204. if (*pdwDataLen < (_tcslen(szCspName)+1))
  6205. {
  6206. *pdwDataLen = (_tcslen(szCspName)+1);
  6207. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6208. }
  6209. #ifndef UNICODE
  6210. strcpy((CHAR*)pbData, szCspName);
  6211. #else
  6212. char szCspName1[MAX_STRING];
  6213. WideCharToMultiByte(CP_ACP, 0, szCspName, MAX_STRING, szCspName1, MAX_STRING, 0, 0);
  6214. strcpy((CHAR*)pbData, szCspName1);
  6215. #endif
  6216. }
  6217. *pdwDataLen = (_tcslen(szCspName)+1);
  6218. break;
  6219. case PP_VERSION:
  6220. if (IsNotNull(pbData))
  6221. {
  6222. if (*pdwDataLen < sizeof(DWORD))
  6223. {
  6224. *pdwDataLen = sizeof(DWORD);
  6225. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6226. }
  6227. pbData[0] = 20;
  6228. pbData[1] = 2;
  6229. pbData[2] = 0;
  6230. pbData[3] = 0;
  6231. }
  6232. *pdwDataLen = sizeof(DWORD);
  6233. break;
  6234. case PP_PROVTYPE:
  6235. if (IsNotNull(pbData))
  6236. {
  6237. if (*pdwDataLen < sizeof(DWORD))
  6238. {
  6239. *pdwDataLen = sizeof(DWORD);
  6240. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6241. }
  6242. *(LPDWORD)pbData = PROV_RSA_FULL;
  6243. }
  6244. *pdwDataLen = sizeof(DWORD);
  6245. break;
  6246. case PP_KEYSPEC:
  6247. if (IsNotNull(pbData))
  6248. {
  6249. DWORD dwSpec = AT_KEYEXCHANGE | AT_SIGNATURE;
  6250. if (*pdwDataLen < sizeof(DWORD))
  6251. {
  6252. *pdwDataLen = sizeof(DWORD);
  6253. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6254. }
  6255. memcpy(pbData, &dwSpec, sizeof(dwSpec));
  6256. }
  6257. *pdwDataLen = sizeof(DWORD);
  6258. break;
  6259. // + [FP] Proprietary functions used to load a RSA private key into the GPK card
  6260. case GPP_SERIAL_NUMBER:
  6261. if (dwFlags != 0)
  6262. {
  6263. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  6264. }
  6265. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  6266. (ProvCont[hProv].isContNameNullBlank))
  6267. {
  6268. RETURN (CRYPT_FAILED, NTE_PERM);
  6269. }
  6270. if (IsNotNull(pbData))
  6271. {
  6272. if (*pdwDataLen < 8)
  6273. {
  6274. *pdwDataLen = 8;
  6275. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6276. }
  6277. CryptResp = Select_MF(hProv);
  6278. if (!CryptResp)
  6279. return CRYPT_FAILED;
  6280. bSendBuffer[0] = 0x80; //CLA
  6281. bSendBuffer[1] = 0xC0; //INS
  6282. bSendBuffer[2] = 0x02; //P1
  6283. bSendBuffer[3] = 0xA0; //P2
  6284. bSendBuffer[4] = 0x08; //Lo
  6285. cbSendLength = 5;
  6286. cbRecvLength = sizeof(bRecvBuffer);
  6287. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  6288. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  6289. if (SCARDPROBLEM(lRet, 0x9000, bSendBuffer[4]))
  6290. {
  6291. RETURN (CRYPT_FAILED, SCARD_E_UNEXPECTED);
  6292. }
  6293. memcpy(pbData, bRecvBuffer, bSendBuffer[4]);
  6294. }
  6295. *pdwDataLen = 8;
  6296. break;
  6297. case GPP_SESSION_RANDOM:
  6298. if (dwFlags != 0)
  6299. {
  6300. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  6301. }
  6302. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  6303. (ProvCont[hProv].isContNameNullBlank))
  6304. {
  6305. RETURN (CRYPT_FAILED, NTE_PERM);
  6306. }
  6307. if (IsNotNull(pbData))
  6308. {
  6309. if (*pdwDataLen < 8)
  6310. {
  6311. *pdwDataLen = 8;
  6312. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6313. }
  6314. if (Slot[SlotNb].NbKeyFile == 0) // [FP] here instead of MyCPImportKey because
  6315. { // it does a Select_Crypto_DF and we have to do
  6316. Slot[SlotNb].NbKeyFile = Read_NbKeyFile(hProv); // it before the select file key
  6317. }
  6318. /* Select File Key */
  6319. bSendBuffer[0] = 0x80; //CLA
  6320. bSendBuffer[1] = 0x28; //INS
  6321. bSendBuffer[2] = 0x00; //P1
  6322. bSendBuffer[3] = (BYTE)(0x3F01 /*& 0x1F*/); //P2
  6323. bSendBuffer[4] = 0x08; //Lc
  6324. memcpy(&bSendBuffer[5], pbData, 0x08);
  6325. cbSendLength = 13;
  6326. cbRecvLength = sizeof(bRecvBuffer);
  6327. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  6328. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  6329. if(SCARDPROBLEM(lRet, 0x61FF, 0x00))
  6330. {
  6331. RETURN(CRYPT_FAILED, lRet);
  6332. }
  6333. /* Get Response */
  6334. bSendBuffer[0] = 0x00; //CLA
  6335. bSendBuffer[1] = 0xC0; //INS
  6336. bSendBuffer[2] = 0x00; //P1
  6337. bSendBuffer[3] = 0x00; //P2
  6338. bSendBuffer[4] = bRecvBuffer[1]; //Lo
  6339. cbSendLength = 5;
  6340. cbRecvLength = sizeof(bRecvBuffer);
  6341. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  6342. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  6343. if(SCARDPROBLEM(lRet, 0x9000, bSendBuffer[4]))
  6344. {
  6345. RETURN(CRYPT_FAILED, lRet);
  6346. }
  6347. memcpy(pbData, &bRecvBuffer[4], 8);
  6348. ProvCont[hProv].bCardTransactionOpened = TRUE;
  6349. }
  6350. *pdwDataLen = 8;
  6351. break;
  6352. case GPP_IMPORT_MECHANISM:
  6353. if (IsNotNull(pbData))
  6354. {
  6355. DWORD dwMechanism = GCRYPT_IMPORT_SECURE;
  6356. if (*pdwDataLen < sizeof(DWORD))
  6357. {
  6358. *pdwDataLen = sizeof(DWORD);
  6359. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  6360. }
  6361. memcpy(pbData, &dwMechanism, sizeof(dwMechanism));
  6362. }
  6363. *pdwDataLen = sizeof(DWORD);
  6364. break;
  6365. // - [FP]
  6366. default:
  6367. RETURN (CRYPT_FAILED, NTE_BAD_TYPE);
  6368. }
  6369. RETURN (CRYPT_SUCCEED, 0);
  6370. }
  6371. /*
  6372. - MyCPReleaseContext
  6373. -
  6374. * Purpose:
  6375. * The CPReleaseContext function is used to release a
  6376. * context created by CryptAcquireContext.
  6377. *
  6378. * Parameters:
  6379. * IN phProv - Handle to a CSP
  6380. * IN dwFlags - Flags values
  6381. *
  6382. * Returns:
  6383. */
  6384. BOOL WINAPI MyCPReleaseContext( HCRYPTPROV hProv, DWORD dwFlags )
  6385. {
  6386. DWORD SlotNb;
  6387. if (!Context_exist(hProv))
  6388. {
  6389. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  6390. }
  6391. if ( ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT &&
  6392. ProvCont[hProv].isContNameNullBlank)
  6393. {
  6394. }
  6395. else
  6396. {
  6397. SlotNb = ProvCont[hProv].Slot;
  6398. if (Slot[SlotNb].ContextCount > 0)
  6399. Slot[SlotNb].ContextCount--;
  6400. if (countCardContextRef > 0)
  6401. countCardContextRef--;
  6402. }
  6403. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT &&
  6404. ProvCont[hProv].isContNameNullBlank)
  6405. {
  6406. // No access to the card has been done in this case
  6407. }
  6408. else
  6409. {
  6410. // Select_MF(hProv); [FP] PIN not presented
  6411. // SCardEndTransaction(ProvCont[hProv].hCard, SCARD_LEAVE_CARD); [FP] coherence not checked
  6412. }
  6413. ReleaseProvider(hProv);
  6414. /* PYR 11/08/00: Do not unload
  6415. if (IsNotNull(g_hInstRes) && Slot[SlotNb].ContextCount == 0)
  6416. {
  6417. bFirstGUILoad = TRUE;
  6418. FreeLibrary(g_hInstRes);
  6419. g_hInstRes = 0;
  6420. }
  6421. */
  6422. //If dwFlags is not set to zero, this function returns FALSE but the CSP is released
  6423. //PYR 08/08/00. Note that CryptoAPI will not call again CPReleaseContext with the same handle.
  6424. if (dwFlags != 0)
  6425. {
  6426. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  6427. }
  6428. else
  6429. {
  6430. RETURN( CRYPT_SUCCEED, 0 );
  6431. }
  6432. }
  6433. /*
  6434. - MyCPSetProvParam
  6435. -
  6436. * Purpose:
  6437. * Allows applications to customize various aspects of the
  6438. * operations of a provider
  6439. *
  6440. * Parameters:
  6441. * IN hProv - Handle to a CSP
  6442. * IN dwParam - Parameter number
  6443. * IN pbData - Pointer to data
  6444. * IN dwFlags - Flags values
  6445. *
  6446. * Returns:
  6447. */
  6448. BOOL WINAPI MyCPSetProvParam(IN HCRYPTPROV hProv,
  6449. IN DWORD dwParam,
  6450. IN CONST BYTE *pbData,
  6451. IN DWORD dwFlags
  6452. )
  6453. {
  6454. DWORD SlotNb;
  6455. // + [FP] for GPP_CHANGE_PIN
  6456. const char* Buff;
  6457. char bOldPin[PIN_LEN + 1];
  6458. char bNewPin[PIN_LEN + 1];
  6459. // - [FP]
  6460. // + NK 06.02.2001
  6461. PINCACHE_PINS Pins;
  6462. CallbackData sCallbackData;
  6463. DWORD dwStatus;
  6464. // -
  6465. if (!Context_exist(hProv))
  6466. {
  6467. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  6468. }
  6469. SlotNb = ProvCont[hProv].Slot;
  6470. switch (dwParam)
  6471. {
  6472. case PP_KEYEXCHANGE_PIN:
  6473. case PP_SIGNATURE_PIN:
  6474. {
  6475. // Slot[SlotNb].ClearPin();
  6476. // Slot[SlotNb].SetPin( (char*)pbData );
  6477. PopulatePins( &Pins, (BYTE *)pbData, strlen( (char*)pbData ), NULL, 0 );
  6478. sCallbackData.hProv = hProv;
  6479. sCallbackData.IsCoherent = FALSE;
  6480. // SlotNb may not be the same before and after Add_MSPinCache because of the call
  6481. // to Coherent in the callback of the pin cache function. To be sure that we save
  6482. // the handle to the good slot, we store it after the call
  6483. PINCACHE_HANDLE hPinCacheHandle = Slot[SlotNb].hPinCacheHandle;
  6484. if ( (dwStatus = Add_MSPinCache( &hPinCacheHandle,
  6485. &Pins,
  6486. Callback_VerifyChangePin,
  6487. (void*)&sCallbackData )) != ERROR_SUCCESS )
  6488. {
  6489. RETURN (CRYPT_FAILED, dwStatus);
  6490. }
  6491. Slot[ProvCont[hProv].Slot].hPinCacheHandle = hPinCacheHandle;
  6492. break;
  6493. }
  6494. case PP_KEYSET_SEC_DESCR:
  6495. break; // Assume success.
  6496. case GPP_CHANGE_PIN:
  6497. if (dwFlags != 0)
  6498. {
  6499. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  6500. }
  6501. if ( ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT &&
  6502. ProvCont[hProv].isContNameNullBlank )
  6503. {
  6504. RETURN( CRYPT_FAILED, NTE_PERM );
  6505. }
  6506. // parse input buffer
  6507. Buff = (char*)pbData;
  6508. memset(bOldPin, 0x00, PIN_LEN + 1);
  6509. strncpy(bOldPin, Buff, PIN_LEN);
  6510. Buff = Buff + strlen(Buff) + 1;
  6511. memset(bNewPin, 0x00, PIN_LEN + 1);
  6512. strncpy(bNewPin, Buff, PIN_LEN);
  6513. PopulatePins( &Pins, (BYTE *)bOldPin, strlen(bOldPin), (BYTE *)bNewPin, strlen(bNewPin) );
  6514. sCallbackData.hProv = hProv;
  6515. sCallbackData.IsCoherent = TRUE;
  6516. if ( (dwStatus = Add_MSPinCache( &(Slot[SlotNb].hPinCacheHandle),
  6517. &Pins,
  6518. Callback_VerifyChangePin,
  6519. (void*)&sCallbackData )) != ERROR_SUCCESS )
  6520. {
  6521. RETURN (CRYPT_FAILED, dwStatus);
  6522. }
  6523. break;
  6524. default:
  6525. RETURN( CRYPT_FAILED, E_NOTIMPL );
  6526. }
  6527. RETURN( CRYPT_SUCCEED, 0 );
  6528. }
  6529. /*******************************************************************************
  6530. Key Generation and Exchange Functions
  6531. *******************************************************************************/
  6532. /*
  6533. - MyCPDeriveKey
  6534. -
  6535. * Purpose:
  6536. * Derive cryptographic keys from base data
  6537. *
  6538. *
  6539. * Parameters:
  6540. * IN hProv - Handle to a CSP
  6541. * IN Algid - Algorithm identifier
  6542. * IN hHash - Handle to hash
  6543. * IN dwFlags - Flags values
  6544. * OUT phKey - Handle to a generated key
  6545. *
  6546. * Returns:
  6547. */
  6548. BOOL WINAPI MyCPDeriveKey(IN HCRYPTPROV hProv,
  6549. IN ALG_ID Algid,
  6550. IN HCRYPTHASH hHash,
  6551. IN DWORD dwFlags,
  6552. OUT HCRYPTKEY *phKey
  6553. )
  6554. {
  6555. BOOL CryptResp;
  6556. HCRYPTKEY hKey;
  6557. *phKey = 0;
  6558. if (!Context_exist(hProv))
  6559. RETURN( CRYPT_FAILED, NTE_BAD_UID );
  6560. if (!hash_exist(hHash, hProv))
  6561. RETURN( CRYPT_FAILED, NTE_BAD_HASH );
  6562. hKey = find_tmp_free();
  6563. if (hKey == 0)
  6564. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  6565. // In fact, the flags are processed implicitly in the RSA Base
  6566. CryptResp = CryptDeriveKey( hProvBase, Algid, hHashGpk[hHash].hHashBase,
  6567. dwFlags, &TmpObject[hKey].hKeyBase );
  6568. if (!CryptResp)
  6569. return CRYPT_FAILED;
  6570. TmpObject[hKey].hProv = hProv;
  6571. *phKey = hKey + MAX_GPK_OBJ;
  6572. RETURN( CRYPT_SUCCEED, 0 );
  6573. }
  6574. /*
  6575. - MyCPDestroyKey
  6576. -
  6577. * Purpose:
  6578. * Destroys the cryptographic key that is being referenced
  6579. * with the hKey parameter
  6580. *
  6581. *
  6582. * Parameters:
  6583. * IN hProv - Handle to a CSP
  6584. * IN hKey - Handle to a key
  6585. *
  6586. * Returns:
  6587. */
  6588. BOOL WINAPI MyCPDestroyKey(IN HCRYPTPROV hProv,
  6589. IN HCRYPTKEY hKey
  6590. )
  6591. {
  6592. BOOL CryptResp;
  6593. if (!Context_exist(hProv))
  6594. RETURN( CRYPT_FAILED, NTE_BAD_UID );
  6595. if (hKey == 0)
  6596. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6597. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT)
  6598. RETURN( CRYPT_FAILED, NTE_PERM );
  6599. if (hKey <= MAX_GPK_OBJ)
  6600. RETURN( CRYPT_SUCCEED, 0 );
  6601. if (!key_exist(hKey-MAX_GPK_OBJ, hProv))
  6602. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6603. if (TmpObject[hKey-MAX_GPK_OBJ].hKeyBase != 0)
  6604. {
  6605. CryptResp = CryptDestroyKey(TmpObject[hKey-MAX_GPK_OBJ].hKeyBase);
  6606. if (!CryptResp)
  6607. return CRYPT_FAILED;
  6608. }
  6609. TmpObject[hKey-MAX_GPK_OBJ].hKeyBase = 0;
  6610. TmpObject[hKey-MAX_GPK_OBJ].hProv = 0;
  6611. RETURN( CRYPT_SUCCEED, 0 );
  6612. }
  6613. /*
  6614. - MyCPExportKey
  6615. -
  6616. * Purpose:
  6617. * Export cryptographic keys out of a CSP in a secure manner
  6618. *
  6619. *
  6620. * Parameters:
  6621. * IN hProv - Handle to the CSP user
  6622. * IN hKey - Handle to the key to export
  6623. * IN hPubKey - Handle to the exchange public key value of
  6624. * the destination user
  6625. * IN dwBlobType - Type of key blob to be exported
  6626. * IN dwFlags - Flags values
  6627. * OUT pbData - Key blob data
  6628. * OUT pdwDataLen - Length of key blob in bytes
  6629. *
  6630. * Returns:
  6631. */
  6632. BOOL WINAPI MyCPExportKey(IN HCRYPTPROV hProv,
  6633. IN HCRYPTKEY hKey,
  6634. IN HCRYPTKEY hPubKey,
  6635. IN DWORD dwBlobType,
  6636. IN DWORD dwFlags,
  6637. OUT BYTE *pbData,
  6638. OUT DWORD *pdwDataLen
  6639. )
  6640. {
  6641. BOOL CryptResp;
  6642. DWORD dwBlobLen;
  6643. HCRYPTKEY hTmpKey,hKeyExp;
  6644. BLOBHEADER BlobHeader;
  6645. RSAPUBKEY RsaPubKey;
  6646. GPK_EXP_KEY PubKey;
  6647. DWORD SlotNb;
  6648. if (!Context_exist(hProv))
  6649. {
  6650. *pdwDataLen = 0;
  6651. RETURN( CRYPT_FAILED, NTE_BAD_UID );
  6652. }
  6653. SlotNb = ProvCont[hProv].Slot;
  6654. if (hKey == 0)
  6655. {
  6656. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6657. }
  6658. else if (hKey <= MAX_GPK_OBJ)
  6659. {
  6660. if ( ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT &&
  6661. ProvCont[hProv].isContNameNullBlank )
  6662. {
  6663. RETURN( CRYPT_FAILED, NTE_PERM );
  6664. }
  6665. if (dwBlobType == PUBLICKEYBLOB)
  6666. {
  6667. if (dwFlags != 0)
  6668. RETURN( CRYPT_FAILED, NTE_BAD_FLAGS );
  6669. if (hPubKey != 0)
  6670. {
  6671. *pdwDataLen = 0;
  6672. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6673. }
  6674. if (Slot[SlotNb].GpkObject[hKey].FileId == 0x00)
  6675. {
  6676. *pdwDataLen = 0;
  6677. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6678. }
  6679. if ( Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].Len == 0 ||
  6680. ( Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0] != AT_KEYEXCHANGE &&
  6681. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0] != AT_SIGNATURE ) )
  6682. {
  6683. *pdwDataLen = 0;
  6684. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6685. }
  6686. PubKey = Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY];
  6687. if (PubKey.KeySize == 0)
  6688. {
  6689. *pdwDataLen = 0;
  6690. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6691. }
  6692. if (PubKey.ExpSize > sizeof(DWORD))
  6693. {
  6694. *pdwDataLen = 0;
  6695. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6696. }
  6697. dwBlobLen = sizeof(BLOBHEADER) +
  6698. sizeof(RSAPUBKEY) +
  6699. PubKey.KeySize;
  6700. if (IsNull(pbData))
  6701. {
  6702. *pdwDataLen = dwBlobLen;
  6703. RETURN( CRYPT_SUCCEED, 0 );
  6704. }
  6705. else if (*pdwDataLen < dwBlobLen)
  6706. {
  6707. *pdwDataLen = dwBlobLen;
  6708. RETURN( CRYPT_FAILED, ERROR_MORE_DATA );
  6709. }
  6710. BlobHeader.bType = PUBLICKEYBLOB;
  6711. BlobHeader.bVersion = CUR_BLOB_VERSION;
  6712. BlobHeader.reserved = 0x0000;
  6713. if (Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0] == AT_KEYEXCHANGE)
  6714. {
  6715. BlobHeader.aiKeyAlg = CALG_RSA_KEYX;
  6716. }
  6717. else
  6718. {
  6719. BlobHeader.aiKeyAlg = CALG_RSA_SIGN;
  6720. }
  6721. RsaPubKey.magic = 0x31415352;
  6722. RsaPubKey.bitlen = PubKey.KeySize * 8;
  6723. RsaPubKey.pubexp = 0;
  6724. memcpy( &RsaPubKey.pubexp, PubKey.Exposant, sizeof(DWORD) );
  6725. memcpy( pbData, &BlobHeader, sizeof(BlobHeader) );
  6726. memcpy( &pbData[sizeof(BlobHeader)], &RsaPubKey, sizeof(RsaPubKey) );
  6727. r_memcpy( &pbData[sizeof(BlobHeader)+ sizeof(RsaPubKey) ], PubKey.Modulus, PubKey.KeySize );
  6728. *pdwDataLen = dwBlobLen;
  6729. }
  6730. else
  6731. {
  6732. *pdwDataLen = 0;
  6733. RETURN( CRYPT_FAILED, NTE_BAD_TYPE );
  6734. }
  6735. }
  6736. /* Temporary key */
  6737. else if (key_exist( hKey - MAX_GPK_OBJ, hProv ))
  6738. {
  6739. hTmpKey = hKey - MAX_GPK_OBJ;
  6740. if (hPubKey == 0)
  6741. {
  6742. *pdwDataLen = 0;
  6743. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6744. }
  6745. if (hPubKey <= MAX_GPK_OBJ)
  6746. {
  6747. //hKeyExp = Slot[SlotNb].GpkObject[hPubKey].hKeyBase;
  6748. if ((Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].Len == 0) ||
  6749. ((Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].pValue[0] != AT_KEYEXCHANGE) &&
  6750. (Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].pValue[0] != AT_SIGNATURE)))
  6751. {
  6752. *pdwDataLen = 0;
  6753. RETURN(CRYPT_FAILED, NTE_BAD_KEY);
  6754. }
  6755. if (Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].pValue[0] == AT_KEYEXCHANGE)
  6756. {
  6757. hKeyExp = ProvCont[hProv].hRSAKEK;
  6758. }
  6759. else
  6760. {
  6761. hKeyExp = ProvCont[hProv].hRSASign;
  6762. }
  6763. }
  6764. else
  6765. {
  6766. if (!key_exist(hPubKey-MAX_GPK_OBJ, hProv))
  6767. {
  6768. *pdwDataLen = 0;
  6769. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6770. }
  6771. else
  6772. {
  6773. hKeyExp = TmpObject[hPubKey-MAX_GPK_OBJ].hKeyBase;
  6774. }
  6775. }
  6776. CryptResp = CryptExportKey( TmpObject[hTmpKey].hKeyBase, hKeyExp, dwBlobType,
  6777. dwFlags, pbData, pdwDataLen );
  6778. if (!CryptResp)
  6779. return CRYPT_FAILED;
  6780. }
  6781. /* Unknown key handle */
  6782. else
  6783. {
  6784. *pdwDataLen = 0;
  6785. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  6786. }
  6787. RETURN( CRYPT_SUCCEED, 0 );
  6788. }
  6789. /*------------------------------------------------------------------------------
  6790. ------------------------------------------------------------------------------*/
  6791. static BOOL gen_key_on_board8000( HCRYPTPROV hProv, BYTE fileId )
  6792. {
  6793. BOOL Is1024 = FALSE;
  6794. ULONG ulStart, ulEnd;
  6795. BYTE KeyType, Sfi;
  6796. //char szTmp[100];
  6797. WORD wKeySize = 0;
  6798. SCARDHANDLE hCard;
  6799. DWORD lRet;
  6800. hCard = ProvCont[hProv].hCard;
  6801. BeginWait();
  6802. /*-------------------------------------------------------------------------*/
  6803. /* Call on board generation for specified key file */
  6804. /*-------------------------------------------------------------------------*/
  6805. Sfi = 0x04 | (fileId<<3);
  6806. /* Read Record (TAG_INFO) to get key size */
  6807. bSendBuffer[0] = 0x00; //CLA
  6808. bSendBuffer[1] = 0xB2; //INS
  6809. bSendBuffer[2] = 0x01; //P1
  6810. bSendBuffer[3] = Sfi; //P2
  6811. bSendBuffer[4] = 0x07; //Lo
  6812. cbSendLength = 5;
  6813. cbRecvLength = sizeof(bRecvBuffer);
  6814. lRet = SCardTransmit( hCard, SCARD_PCI_T0, bSendBuffer,
  6815. cbSendLength, 0, bRecvBuffer, &cbRecvLength
  6816. );
  6817. if(SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  6818. {
  6819. EndWait();
  6820. return CRYPT_FAILED;
  6821. }
  6822. KeyType = bRecvBuffer[1];
  6823. if (KeyType == 0x11)
  6824. {
  6825. Is1024 = TRUE;
  6826. wKeySize = 1024;
  6827. }
  6828. else if (KeyType == 0x00)
  6829. {
  6830. Is1024 = FALSE;
  6831. wKeySize = 512;
  6832. }
  6833. else
  6834. {
  6835. EndWait();
  6836. return CRYPT_FAILED;
  6837. }
  6838. Sfi = 0x80 | (fileId);
  6839. // + [FP]
  6840. //sprintf(szTmp,
  6841. // "RSA %d bit key pair on-board generation",
  6842. // wKeySize
  6843. // );
  6844. //ShowProgress(GetActiveWindow(), szTmp, "Operation in progress...", 0);
  6845. ShowProgressWrapper(wKeySize);
  6846. // - [FP]
  6847. ulStart = GetTickCount();
  6848. if (Is1024)
  6849. {
  6850. ulEnd = ulStart + (TIME_GEN_1024 * 1000);
  6851. }
  6852. else
  6853. {
  6854. ulEnd = ulStart + (TIME_GEN_512 * 1000);
  6855. }
  6856. GEN_KEY:
  6857. /* Call on-board generation */
  6858. bSendBuffer[0] = 0x80; //CLA
  6859. bSendBuffer[1] = 0xD2; //INS
  6860. bSendBuffer[2] = Sfi; //P1
  6861. bSendBuffer[3] = KeyType; //P2
  6862. cbSendLength = 4;
  6863. cbRecvLength = sizeof(bRecvBuffer);
  6864. lRet = SCardTransmit( hCard, SCARD_PCI_T0, bSendBuffer,
  6865. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  6866. if(SCARDPROBLEM(lRet,0x9000,0x00))
  6867. {
  6868. DestroyProgress();
  6869. EndWait();
  6870. return CRYPT_FAILED;
  6871. }
  6872. /* Wait for generation is successfull */
  6873. if (Is1024 && g_GPK8000KeyGenTime1024 > 0)
  6874. {
  6875. Wait( 1, 1, g_GPK8000KeyGenTime1024 );
  6876. }
  6877. else
  6878. if (!Is1024 && g_GPK8000KeyGenTime512 > 0)
  6879. {
  6880. Wait( 1, 1, g_GPK8000KeyGenTime512 );
  6881. }
  6882. do
  6883. {
  6884. /* Get response to know if generation successfull */
  6885. bSendBuffer[0] = 0x00; //CLA
  6886. bSendBuffer[1] = 0xC0; //INS
  6887. bSendBuffer[2] = 0x00; //P1
  6888. bSendBuffer[3] = 0x00; //P2
  6889. bSendBuffer[4] = 0x42; //Le
  6890. if (Is1024)
  6891. {
  6892. bSendBuffer[4] = 0x82; //Le
  6893. }
  6894. cbSendLength = 5;
  6895. cbRecvLength = sizeof(bRecvBuffer);
  6896. lRet = SCardTransmit( hCard, SCARD_PCI_T0, bSendBuffer,
  6897. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  6898. if(SCARDPROBLEM(lRet,0x9000,0x00))
  6899. {
  6900. if ((dwSW1SW2 == 0x6a88) || (dwSW1SW2 == 0x9220))
  6901. {
  6902. goto GEN_KEY;
  6903. }
  6904. }
  6905. // + [FP]
  6906. //sprintf(szTmp,
  6907. // "Operation started since %d seconds",
  6908. // (GetTickCount() - ulStart) / 1000
  6909. // );
  6910. //ChangeProgressText(szTmp);
  6911. ChangeProgressWrapper((GetTickCount() - ulStart) / 1000);
  6912. // - [FP]
  6913. if (GetTickCount() > ulEnd)
  6914. {
  6915. break;
  6916. }
  6917. }
  6918. while ((lRet != SCARD_S_SUCCESS) || (dwSW1SW2 != 0x9000));
  6919. DestroyProgress();
  6920. if ((lRet != SCARD_S_SUCCESS) || (dwSW1SW2 != 0x9000))
  6921. {
  6922. EndWait();
  6923. return CRYPT_FAILED;
  6924. }
  6925. EndWait();
  6926. return CRYPT_SUCCEED;
  6927. }
  6928. /*------------------------------------------------------------------------------
  6929. ------------------------------------------------------------------------------*/
  6930. static BOOL gen_key_on_board (HCRYPTPROV hProv)
  6931. {
  6932. BOOL IsLast = FALSE,
  6933. IsExport = TRUE,
  6934. Is1024 = FALSE;
  6935. BYTE Sfi, TmpKeyLength;
  6936. WORD wPubSize;
  6937. DWORD i, lRet ,dwLen,
  6938. dwNumberofCommands,
  6939. dwLastCommandLen,
  6940. dwCommandLen;
  6941. DWORD SlotNb;
  6942. WORD offset;
  6943. SlotNb = ProvCont[hProv].Slot;
  6944. if (Slot[SlotNb].NbKeyFile == 0)
  6945. Slot[SlotNb].NbKeyFile = Read_NbKeyFile(hProv);
  6946. if (Slot[SlotNb].NbKeyFile == 0 || Slot[SlotNb].NbKeyFile > MAX_REAL_KEY)
  6947. {
  6948. RETURN( CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND );
  6949. }
  6950. if (!Select_MF(hProv))
  6951. return CRYPT_FAILED;
  6952. if (!VerifyDivPIN(hProv, FALSE))
  6953. return CRYPT_FAILED;
  6954. if (!Select_Crypto_DF(hProv))
  6955. return CRYPT_FAILED;
  6956. if (!PIN_Validation(hProv))
  6957. return CRYPT_FAILED;
  6958. if (!VerifyDivPIN(hProv, TRUE))
  6959. return CRYPT_FAILED;
  6960. /*-------------------------------------------------------------------------*/
  6961. /* Call on board generation for each key file */
  6962. /*-------------------------------------------------------------------------*/
  6963. i = 0;
  6964. do
  6965. {
  6966. Sfi = 0x04 | ((GPK_FIRST_KEY+(BYTE)i)<<3);
  6967. /* Read Record (TAG_INFO) to get key size */
  6968. bSendBuffer[0] = 0x00; //CLA
  6969. bSendBuffer[1] = 0xB2; //INS
  6970. bSendBuffer[2] = 0x01; //P1
  6971. bSendBuffer[3] = Sfi; //P2
  6972. bSendBuffer[4] = 0x07; //Lo
  6973. cbSendLength = 5;
  6974. cbRecvLength = sizeof(bRecvBuffer);
  6975. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  6976. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  6977. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  6978. {
  6979. EndWait();
  6980. RETURN( CRYPT_FAILED, SCARD_E_UNEXPECTED );
  6981. }
  6982. if (bRecvBuffer[1] == 0x11)
  6983. {
  6984. IsExport = FALSE;
  6985. Is1024 = TRUE;
  6986. }
  6987. else
  6988. {
  6989. Is1024 = FALSE;
  6990. }
  6991. TmpKeyLength = bRecvBuffer[1];
  6992. Sfi = 0x80 | (GPK_FIRST_KEY+(BYTE)i);
  6993. GEN_KEY:
  6994. /* Call on-board generation */
  6995. bSendBuffer[0] = 0x80; //CLA
  6996. bSendBuffer[1] = 0xD2; //INS
  6997. bSendBuffer[2] = Sfi; //P1
  6998. bSendBuffer[3] = TmpKeyLength; //P2
  6999. cbSendLength = 4;
  7000. cbRecvLength = sizeof(bRecvBuffer);
  7001. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7002. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7003. if (SCARDPROBLEM(lRet,0x9000,0x00))
  7004. {
  7005. // if the first key has been generate successfully -- meaning??
  7006. if (dwSW1SW2 == 0x6982) // 0x6982: access condition not fulfilled
  7007. {
  7008. i++; // skip and generate another key
  7009. continue;
  7010. }
  7011. EndWait();
  7012. RETURN( CRYPT_FAILED, SCARD_E_UNEXPECTED );
  7013. }
  7014. /* Wait for generation is successfull */
  7015. if (Is1024)
  7016. {
  7017. Wait( i+1, Slot[SlotNb].NbKeyFile, TIME_GEN_1024 );
  7018. }
  7019. else
  7020. {
  7021. Wait( i+1, Slot[SlotNb].NbKeyFile, TIME_GEN_512 );
  7022. }
  7023. /* Get response to know if generation successfull */
  7024. bSendBuffer[0] = 0x00; //CLA
  7025. bSendBuffer[1] = 0xC0; //INS
  7026. bSendBuffer[2] = 0x00; //P1
  7027. bSendBuffer[3] = 0x00; //P2
  7028. bSendBuffer[4] = 0x42; //Le
  7029. if (Is1024)
  7030. {
  7031. bSendBuffer[4] = 0x82; //Le
  7032. }
  7033. cbSendLength = 5;
  7034. cbRecvLength = sizeof(bRecvBuffer);
  7035. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7036. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7037. if (SCARDPROBLEM(lRet,0x9000,0x00))
  7038. {
  7039. if (dwSW1SW2 == 0x6a88) // 0x6a88: key selection error
  7040. {
  7041. goto GEN_KEY;
  7042. }
  7043. EndWait();
  7044. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7045. }
  7046. /* Freeze key file */
  7047. bSendBuffer[0] = 0x80; //CLA
  7048. bSendBuffer[1] = 0x16; //INS
  7049. bSendBuffer[2] = 0x02; //P1
  7050. bSendBuffer[3] = 0x00; //P2
  7051. bSendBuffer[4] = 0x05; //Li
  7052. bSendBuffer[5] = 0x00;
  7053. bSendBuffer[6] = 0x07+(BYTE)i;
  7054. bSendBuffer[7] = 0x40;
  7055. bSendBuffer[8] = 0x40;
  7056. bSendBuffer[9] = 0x00;
  7057. cbSendLength = 10;
  7058. cbRecvLength = sizeof(bRecvBuffer);
  7059. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7060. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7061. if (SCARDPROBLEM(lRet,0x9000,0x00))
  7062. {
  7063. EndWait();
  7064. RETURN( CRYPT_FAILED, SCARD_E_UNEXPECTED );
  7065. }
  7066. i++;
  7067. }
  7068. while (i < Slot[SlotNb].NbKeyFile); // version 2.00.002, it was "(i<MAX_REAL_KEY)"
  7069. /*-------------------------------------------------------------------------*/
  7070. /* Erase on board generation filter */
  7071. /*-------------------------------------------------------------------------*/
  7072. /* Call erase command */
  7073. bSendBuffer[0] = 0x80; //CLA
  7074. bSendBuffer[1] = 0xD4; //INS
  7075. bSendBuffer[2] = 0x00; //P1
  7076. bSendBuffer[3] = 0x00; //P2
  7077. cbSendLength = 4;
  7078. cbRecvLength = sizeof(bRecvBuffer);
  7079. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7080. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7081. if (SCARDPROBLEM(lRet,0x9000,0x00))
  7082. {
  7083. EndWait();
  7084. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7085. }
  7086. /*-------------------------------------------------------------------------*/
  7087. /* Public Part */
  7088. /*-------------------------------------------------------------------------*/
  7089. wPubSize = EF_PUBLIC_SIZE;
  7090. if (IsExport)
  7091. {
  7092. wPubSize = wPubSize + DIFF_US_EXPORT;
  7093. }
  7094. /* Create EF for Public Object storage */
  7095. bSendBuffer[0] = 0x80; //CLA
  7096. bSendBuffer[1] = 0xE0; //INS
  7097. bSendBuffer[2] = 0x02; //P1
  7098. bSendBuffer[3] = 0x00; //P2
  7099. bSendBuffer[4] = 0x0C; //Li
  7100. bSendBuffer[5] = HIBYTE(GPK_OBJ_PUB_EF); //File Id
  7101. bSendBuffer[6] = LOBYTE(GPK_OBJ_PUB_EF);
  7102. bSendBuffer[7] = 0x01; //FDB
  7103. bSendBuffer[8] = 0x00; //Rec Len
  7104. bSendBuffer[9] = HIBYTE(wPubSize); //Body Length
  7105. bSendBuffer[10] = LOBYTE(wPubSize);
  7106. bSendBuffer[11] = 0x00; //AC1
  7107. bSendBuffer[12] = 0x00;
  7108. bSendBuffer[13] = 0xC0; //AC2
  7109. bSendBuffer[14] = 0x00;
  7110. bSendBuffer[15] = 0x00; //AC3
  7111. bSendBuffer[16] = 0x00;
  7112. cbSendLength = 17;
  7113. cbRecvLength = sizeof(bRecvBuffer);
  7114. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7115. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7116. if (SCARDPROBLEM(lRet,0x9000,0x00))
  7117. {
  7118. EndWait();
  7119. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7120. }
  7121. /* Select Public Object storage EF */
  7122. bSendBuffer[0] = 0x00; //CLA
  7123. bSendBuffer[1] = 0xA4; //INS
  7124. bSendBuffer[2] = 0x02; //P1
  7125. bSendBuffer[3] = 0x00; //P2
  7126. bSendBuffer[4] = 0x02; //Li
  7127. bSendBuffer[5] = HIBYTE(GPK_OBJ_PUB_EF);
  7128. bSendBuffer[6] = LOBYTE(GPK_OBJ_PUB_EF);
  7129. cbSendLength = 7;
  7130. cbRecvLength = sizeof(bRecvBuffer);
  7131. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7132. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7133. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  7134. {
  7135. EndWait();
  7136. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7137. }
  7138. dwLen = sizeof(InitValue[Slot[SlotNb].NbKeyFile-1]);//wPubSize;
  7139. /* Write the Objects EF */
  7140. dwNumberofCommands = (dwLen-1)/FILE_CHUNK_SIZE + 1;
  7141. dwLastCommandLen = dwLen%FILE_CHUNK_SIZE;
  7142. if (dwLastCommandLen == 0)
  7143. {
  7144. dwLastCommandLen = FILE_CHUNK_SIZE;
  7145. }
  7146. dwCommandLen = FILE_CHUNK_SIZE;
  7147. for (i=0; i < dwNumberofCommands ; i++)
  7148. {
  7149. if (i == dwNumberofCommands - 1)
  7150. {
  7151. dwCommandLen = dwLastCommandLen;
  7152. }
  7153. /* Write FILE_CHUCK_SIZE bytes or last bytes */
  7154. bSendBuffer[0] = 0x00; //CLA
  7155. bSendBuffer[1] = 0xD6; //INS
  7156. // TT 03/11/99
  7157. //bSendBuffer[2] = HIBYTE(i*FILE_CHUNK_SIZE/4); //P1
  7158. //bSendBuffer[3] = LOBYTE(i*FILE_CHUNK_SIZE/4); //P2
  7159. offset = (WORD)(i * FILE_CHUNK_SIZE) / ProvCont[hProv].dataUnitSize;
  7160. bSendBuffer[2] = HIBYTE( offset );
  7161. bSendBuffer[3] = LOBYTE( offset );
  7162. bSendBuffer[4] = (BYTE)dwCommandLen; //Li
  7163. memcpy(&bSendBuffer[5],
  7164. &InitValue[Slot[SlotNb].NbKeyFile-1][i*FILE_CHUNK_SIZE],
  7165. dwCommandLen
  7166. );
  7167. cbSendLength = 5 + dwCommandLen;
  7168. cbRecvLength = sizeof(bRecvBuffer);
  7169. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7170. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7171. if (SCARDPROBLEM(lRet,0x9000, 0x00))
  7172. {
  7173. EndWait();
  7174. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7175. }
  7176. }
  7177. /*-------------------------------------------------------------------------*/
  7178. /* Private Part */
  7179. /*-------------------------------------------------------------------------*/
  7180. /* Create EF for Private Object storage */
  7181. bSendBuffer[0] = 0x80; //CLA
  7182. bSendBuffer[1] = 0xE0; //INS
  7183. bSendBuffer[2] = 0x02; //P1
  7184. bSendBuffer[3] = 0x00; //P2
  7185. bSendBuffer[4] = 0x0C; //Li
  7186. bSendBuffer[5] = HIBYTE(GPK_OBJ_PRIV_EF); //File Id
  7187. bSendBuffer[6] = LOBYTE(GPK_OBJ_PRIV_EF);
  7188. bSendBuffer[7] = 0x01; //FDB
  7189. bSendBuffer[8] = 0x00; //Rec Len
  7190. bSendBuffer[9] = HIBYTE(EF_PRIVATE_SIZE); //Body Length
  7191. bSendBuffer[10] = LOBYTE(EF_PRIVATE_SIZE);
  7192. bSendBuffer[11] = 0x40; //AC1
  7193. bSendBuffer[12] = 0x80;
  7194. bSendBuffer[13] = 0xC0; //AC2
  7195. bSendBuffer[14] = 0x80;
  7196. bSendBuffer[15] = 0x40; //AC3
  7197. bSendBuffer[16] = 0x80;
  7198. cbSendLength = 17;
  7199. cbRecvLength = sizeof(bRecvBuffer);
  7200. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7201. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7202. if (SCARDPROBLEM(lRet,0x9000,0x00))
  7203. {
  7204. EndWait();
  7205. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7206. }
  7207. /* Select Private Object storage EF */
  7208. bSendBuffer[0] = 0x00; //CLA
  7209. bSendBuffer[1] = 0xA4; //INS
  7210. bSendBuffer[2] = 0x02; //P1
  7211. bSendBuffer[3] = 0x00; //P2
  7212. bSendBuffer[4] = 0x02; //Li
  7213. bSendBuffer[5] = HIBYTE(GPK_OBJ_PRIV_EF);
  7214. bSendBuffer[6] = LOBYTE(GPK_OBJ_PRIV_EF);
  7215. cbSendLength = 7;
  7216. cbRecvLength = sizeof(bRecvBuffer);
  7217. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7218. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7219. if (SCARDPROBLEM(lRet,0x61FF,0x00))
  7220. {
  7221. EndWait();
  7222. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7223. }
  7224. dwLen = sizeof(InitValue[Slot[SlotNb].NbKeyFile-1]);//EF_PRIVATE_SIZE;
  7225. /* Write the Objects EF */
  7226. dwNumberofCommands = (dwLen-1)/FILE_CHUNK_SIZE + 1;
  7227. dwLastCommandLen = dwLen%FILE_CHUNK_SIZE;
  7228. if (dwLastCommandLen == 0)
  7229. {
  7230. dwLastCommandLen = FILE_CHUNK_SIZE;
  7231. }
  7232. dwCommandLen = FILE_CHUNK_SIZE;
  7233. for (i=0; i < dwNumberofCommands ; i++)
  7234. {
  7235. if (i == dwNumberofCommands - 1)
  7236. {
  7237. dwCommandLen = dwLastCommandLen;
  7238. }
  7239. // Write FILE_CHUCK_SIZE bytes or last bytes
  7240. bSendBuffer[0] = 0x00; //CLA
  7241. bSendBuffer[1] = 0xD6; //INS
  7242. offset = (WORD)(i * FILE_CHUNK_SIZE) / ProvCont[hProv].dataUnitSize;
  7243. bSendBuffer[2] = HIBYTE( offset );
  7244. bSendBuffer[3] = LOBYTE( offset );
  7245. bSendBuffer[4] = (BYTE)dwCommandLen; //Li
  7246. memcpy(&bSendBuffer[5],
  7247. &InitValue[Slot[SlotNb].NbKeyFile-1][i*FILE_CHUNK_SIZE],
  7248. dwCommandLen
  7249. );
  7250. cbSendLength = 5 + dwCommandLen;
  7251. cbRecvLength = sizeof(bRecvBuffer);
  7252. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7253. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7254. if (SCARDPROBLEM(lRet,0x9000, 0x00))
  7255. {
  7256. EndWait();
  7257. RETURN(CRYPT_FAILED, SCARD_E_UNEXPECTED);
  7258. }
  7259. }
  7260. EndWait();
  7261. RETURN (CRYPT_SUCCEED, 0);
  7262. }
  7263. /*
  7264. - MyCPGenKey
  7265. -
  7266. * Purpose:
  7267. * Generate cryptographic keys
  7268. *
  7269. *
  7270. * Parameters:
  7271. * IN hProv - Handle to a CSP
  7272. * IN Algid - Algorithm identifier
  7273. * IN dwFlags - Flags values
  7274. * OUT phKey - Handle to a generated key
  7275. *
  7276. * Returns:
  7277. */
  7278. BOOL WINAPI MyCPGenKey(IN HCRYPTPROV hProv,
  7279. IN ALG_ID Algid,
  7280. IN DWORD dwFlags,
  7281. OUT HCRYPTKEY *phKey
  7282. )
  7283. {
  7284. HCRYPTKEY hKey, hKeyPriv;
  7285. BOOL bSessKey;
  7286. BYTE *pbBuff1 = 0, i;
  7287. BYTE KeyBuff[50], SaltBuff[50];
  7288. BYTE SaltLen, KeyLen;
  7289. DWORD lRet,
  7290. dwBuff1Len,
  7291. SlotNb;
  7292. int nbKey;
  7293. BOOL bAllSameSize;
  7294. BOOL b512avail;
  7295. BOOL b1024avail;
  7296. // +NK 06.02.2001
  7297. DWORD dwPinLength;
  7298. // -
  7299. *phKey = 0;
  7300. bSessKey = FALSE;
  7301. if (!Context_exist(hProv))
  7302. {
  7303. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  7304. }
  7305. SlotNb = ProvCont[hProv].Slot;
  7306. if (Algid == AT_KEYEXCHANGE || Algid == AT_SIGNATURE)
  7307. {
  7308. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT)
  7309. {
  7310. RETURN( CRYPT_FAILED, NTE_PERM );
  7311. }
  7312. if (Slot[SlotNb].NbKeyFile == 0)
  7313. Slot[SlotNb].NbKeyFile = Read_NbKeyFile(hProv);
  7314. if (Slot[SlotNb].NbKeyFile == 0 || Slot[SlotNb].NbKeyFile > MAX_REAL_KEY)
  7315. {
  7316. RETURN (CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND); // should not bigger than MAX_REAL_KEY
  7317. }
  7318. }
  7319. switch (Algid)
  7320. {
  7321. case AT_SIGNATURE:
  7322. //
  7323. // Verisign Enrollment process does not respect this fact
  7324. //
  7325. // if (dwFlags & CRYPT_EXPORTABLE)
  7326. // {
  7327. // RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7328. // }
  7329. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT)
  7330. {
  7331. RETURN( CRYPT_FAILED, NTE_PERM );
  7332. }
  7333. // + NK 06.02.2001
  7334. // if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (IsNullStr(Slot[SlotNb].GetPin())))
  7335. lRet = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  7336. NULL,
  7337. &dwPinLength );
  7338. if ((lRet =! ERROR_SUCCESS) && (lRet =! ERROR_EMPTY))
  7339. RETURN (CRYPT_FAILED, lRet);
  7340. if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (lRet == ERROR_EMPTY))
  7341. // - NK
  7342. {
  7343. RETURN( CRYPT_FAILED, NTE_SILENT_CONTEXT );
  7344. }
  7345. if (!PublicEFExists(hProv))
  7346. {
  7347. if (!gen_key_on_board(hProv))
  7348. {
  7349. return CRYPT_FAILED;
  7350. }
  7351. else
  7352. {
  7353. if (!read_gpk_objects(hProv, FALSE))
  7354. return CRYPT_FAILED;
  7355. Slot[SlotNb].Read_Public = TRUE;
  7356. Slot[SlotNb].Read_Priv = FALSE;
  7357. }
  7358. }
  7359. if (!Read_Priv_Obj(hProv))
  7360. return CRYPT_FAILED;
  7361. if (HIWORD(dwFlags) != 0x0000)
  7362. {
  7363. KeyLen = HIWORD(dwFlags) / 8;
  7364. //check for the keylen, only 512 or 1024 key are supported for now
  7365. if (( KeyLen != 64 && KeyLen != 128 ) || (HIWORD(dwFlags) & 7))
  7366. {
  7367. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7368. }
  7369. // [FP] +
  7370. switch(Slot[SlotNb].NbKeyFile)
  7371. {
  7372. case 2:
  7373. if ((Slot[SlotNb].GpkPubKeys[0].KeySize == 64) &&
  7374. (Slot[SlotNb].GpkPubKeys[1].KeySize == 64) && // GPK4K Intl
  7375. (KeyLen == 128))
  7376. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7377. break;
  7378. case 4:
  7379. break;
  7380. default:
  7381. RETURN (CRYPT_FAILED, NTE_FAIL);
  7382. }
  7383. // [FP] +
  7384. }
  7385. else
  7386. {
  7387. KeyLen = 0;
  7388. // Read key file lengths
  7389. nbKey = Slot[SlotNb].NbKeyFile;
  7390. for (i = 0; i<nbKey; ++i)
  7391. KeyLenFile[i] = Slot[SlotNb].GpkPubKeys[i].KeySize;
  7392. // If all keys have the same size, use that size
  7393. bAllSameSize = TRUE;
  7394. for (i = 1; i<nbKey; ++i)
  7395. {
  7396. if (KeyLenFile[i] != KeyLenFile[0])
  7397. {
  7398. bAllSameSize = FALSE;
  7399. break;
  7400. }
  7401. }
  7402. if (bAllSameSize)
  7403. KeyLen = KeyLenFile[0];
  7404. else
  7405. {
  7406. // TT - BUG #1504: If only one key size is available, try to use it
  7407. b512avail = find_gpk_obj_tag_type( hProv, TAG_RSA_PUBLIC, 0, 512/8, FALSE, FALSE ) != 0;
  7408. b1024avail = find_gpk_obj_tag_type( hProv, TAG_RSA_PUBLIC, 0, 1024/8, FALSE, FALSE ) != 0;
  7409. if (!b512avail && !b1024avail)
  7410. {
  7411. RETURN (CRYPT_FAILED, NTE_FAIL );
  7412. }
  7413. if (b512avail && !b1024avail) KeyLen = 512/8;
  7414. else if (!b512avail && b1024avail) KeyLen = 1024/8;
  7415. else
  7416. {
  7417. // TT - END
  7418. if (ProvCont[hProv].Flags & CRYPT_SILENT)
  7419. {
  7420. // Check if default key length (1024) is available
  7421. for (i = 0; i<nbKey; ++i)
  7422. {
  7423. if (KeyLenFile[i] == 0x80)
  7424. {
  7425. KeyLen = 0x80;
  7426. break;
  7427. }
  7428. }
  7429. if (KeyLen==0)
  7430. {
  7431. // Take smallest key size available
  7432. KeyLen = KeyLenFile[0];
  7433. for (i = 1; i<nbKey; ++i)
  7434. {
  7435. if (KeyLenFile[i] < KeyLen)
  7436. KeyLen = KeyLenFile[i];
  7437. }
  7438. }
  7439. }
  7440. else
  7441. {
  7442. DialogBox(g_hInstRes, TEXT("KEYDIALOG"), GetAppWindow(), (DLGPROC)KeyDlgProc);
  7443. if (KeyLenChoice == 0)
  7444. {
  7445. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7446. }
  7447. else
  7448. {
  7449. KeyLen = KeyLenChoice;
  7450. }
  7451. }
  7452. }
  7453. }
  7454. }
  7455. // AT_SIGNATURE
  7456. hKey = find_gpk_obj_tag_type(hProv, TAG_RSA_PUBLIC, 0x00, KeyLen, FALSE, FALSE);
  7457. if ((hKey != 0)
  7458. &&(find_gpk_obj_tag_type(hProv, TAG_RSA_PUBLIC, AT_SIGNATURE, 0x00, FALSE, FALSE) == 0)
  7459. &&(find_gpk_obj_tag_type(hProv, TAG_CERTIFICATE, AT_SIGNATURE, 0x00, FALSE, FALSE) == 0)
  7460. )
  7461. {
  7462. *phKey = hKey;
  7463. }
  7464. else
  7465. {
  7466. RETURN (CRYPT_FAILED, NTE_FAIL );
  7467. }
  7468. // TT 24/09/99: On board key generation for GPK8000
  7469. if (ProvCont[hProv].bGPK8000)
  7470. {
  7471. if (!gen_key_on_board8000( hProv, Slot[SlotNb].GpkObject[hKey].FileId ))
  7472. {
  7473. RETURN( CRYPT_FAILED, NTE_FAIL );
  7474. }
  7475. }
  7476. // TT - END -
  7477. hKeyPriv = find_gpk_obj_tag_file(hProv,
  7478. TAG_RSA_PRIVATE,
  7479. Slot[SlotNb].GpkObject[hKey].FileId,
  7480. FALSE
  7481. );
  7482. if ( hKeyPriv == 0 )
  7483. {
  7484. RETURN (CRYPT_FAILED, NTE_SIGNATURE_FILE_BAD);
  7485. }
  7486. if ((HIWORD(dwFlags) != 0) &&
  7487. (Slot[SlotNb].GpkObject[hKeyPriv].PubKey.KeySize != (HIWORD(dwFlags) / 8))
  7488. )
  7489. {
  7490. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7491. }
  7492. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue = (BYTE*)GMEM_Alloc(1);
  7493. if (IsNull (Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue))
  7494. {
  7495. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  7496. }
  7497. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].pValue = (BYTE*)GMEM_Alloc(1);
  7498. if (IsNull (Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].pValue))
  7499. {
  7500. GMEM_Free (Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue);
  7501. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  7502. }
  7503. Slot[SlotNb].GpkObject[hKey].IsCreated = TRUE;
  7504. Slot[SlotNb].GpkObject[hKey].Flags = Slot[SlotNb].GpkObject[hKey].Flags | FLAG_KEY_TYPE;
  7505. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].Len = 1;
  7506. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0] = AT_SIGNATURE;
  7507. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].bReal = TRUE;
  7508. /* Set Flags of automatic fields for PKCS#11 compatibility */
  7509. Slot[SlotNb].GpkObject[hKey].Flags = Slot[SlotNb].GpkObject[hKey].Flags | FLAG_ID;
  7510. Slot[SlotNb].GpkObject[hKey].Field[POS_ID].Len = 0;
  7511. Slot[SlotNb].GpkObject[hKey].Field[POS_ID].bReal = FALSE;
  7512. Slot[SlotNb].GpkObject[hKeyPriv].IsCreated = TRUE;
  7513. Slot[SlotNb].GpkObject[hKeyPriv].Flags = Slot[SlotNb].GpkObject[hKeyPriv].Flags | FLAG_KEY_TYPE;
  7514. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].Len = 1;
  7515. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].pValue[0] = AT_SIGNATURE;
  7516. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].bReal = TRUE;
  7517. /* Set Flags of automatic fields for PKCS#11 compatibility */
  7518. Slot[SlotNb].GpkObject[hKeyPriv].Flags = Slot[SlotNb].GpkObject[hKeyPriv].Flags | FLAG_ID;
  7519. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_ID].Len = 0;
  7520. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_ID].bReal = FALSE;
  7521. if (!ProvCont[hProv].bLegacyKeyset)
  7522. {
  7523. Slot[SlotNb].GpkObject[hKey].Flags |= FLAG_KEYSET;
  7524. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].Len = 1;
  7525. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].pValue = (BYTE*)GMEM_Alloc(1);
  7526. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].pValue[0] = ProvCont[hProv].keysetID;
  7527. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].bReal = TRUE;
  7528. Slot[SlotNb].GpkObject[hKeyPriv].Flags |= FLAG_KEYSET;
  7529. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].Len = 1;
  7530. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].pValue = (BYTE*)GMEM_Alloc(1);
  7531. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].pValue[0] = ProvCont[hProv].keysetID;
  7532. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].bReal = TRUE;
  7533. }
  7534. // Set the file containing the key to USE, add "- GPK_FIRST_KEY" here. version 2.00.002
  7535. Slot[SlotNb].UseFile [Slot[SlotNb].GpkObject[hKey].FileId- GPK_FIRST_KEY] = TRUE;
  7536. break;
  7537. case AT_KEYEXCHANGE:
  7538. //
  7539. // Verisign Enrollment process does not respect this fact
  7540. //
  7541. // if (dwFlags & CRYPT_EXPORTABLE)
  7542. // {
  7543. // RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7544. // }
  7545. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT)
  7546. {
  7547. RETURN (CRYPT_FAILED, NTE_PERM);
  7548. }
  7549. // + NK 06.02.2001
  7550. // if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (IsNullStr(Slot[SlotNb].GetPin())))
  7551. lRet = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  7552. NULL,
  7553. &dwPinLength );
  7554. if ( (lRet != ERROR_SUCCESS) && (lRet != ERROR_EMPTY) )
  7555. RETURN (CRYPT_FAILED, lRet);
  7556. if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (lRet == ERROR_EMPTY))
  7557. // - NK
  7558. {
  7559. RETURN (CRYPT_FAILED, NTE_SILENT_CONTEXT);
  7560. }
  7561. if (!PublicEFExists(hProv))
  7562. {
  7563. if (!gen_key_on_board(hProv))
  7564. {
  7565. return CRYPT_FAILED;
  7566. }
  7567. else
  7568. {
  7569. if (!read_gpk_objects(hProv, FALSE))
  7570. return CRYPT_FAILED;
  7571. Slot[SlotNb].Read_Public = TRUE;
  7572. Slot[SlotNb].Read_Priv = FALSE;
  7573. }
  7574. }
  7575. if (!Read_Priv_Obj(hProv))
  7576. return CRYPT_FAILED;
  7577. if (HIWORD(dwFlags) != 0x0000)
  7578. {
  7579. KeyLen = HIWORD(dwFlags) / 8;
  7580. //check for the keylen, only 512 or 1024 key are supported for now
  7581. if (( KeyLen != 64 && KeyLen != 128 ) || (HIWORD(dwFlags) & 7))
  7582. {
  7583. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7584. }
  7585. // [FP] +
  7586. switch(Slot[SlotNb].NbKeyFile)
  7587. {
  7588. case 2:
  7589. if ((Slot[SlotNb].GpkPubKeys[0].KeySize == 64) &&
  7590. (Slot[SlotNb].GpkPubKeys[1].KeySize == 64) && // GPK4K Intl
  7591. (KeyLen == 128))
  7592. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7593. break;
  7594. case 4:
  7595. if ((Slot[SlotNb].GpkPubKeys[0].KeySize == 64) &&
  7596. (Slot[SlotNb].GpkPubKeys[1].KeySize == 64) &&
  7597. (Slot[SlotNb].GpkPubKeys[2].KeySize == 64) &&
  7598. (Slot[SlotNb].GpkPubKeys[3].KeySize == 128) && // GPK8K Intl
  7599. (KeyLen == 128))
  7600. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7601. break;
  7602. default:
  7603. RETURN (CRYPT_FAILED, NTE_FAIL);
  7604. }
  7605. // [FP] +
  7606. }
  7607. else
  7608. {
  7609. KeyLen = 0;
  7610. // Read key file lengths
  7611. nbKey = Slot[SlotNb].NbKeyFile;
  7612. for (i = 0; i<nbKey; ++i)
  7613. KeyLenFile[i] = Slot[SlotNb].GpkPubKeys[i].KeySize;
  7614. // If all keys have the same size, use that size
  7615. bAllSameSize = TRUE;
  7616. for (i = 1; i<nbKey; ++i)
  7617. {
  7618. if (KeyLenFile[i] != KeyLenFile[0])
  7619. {
  7620. bAllSameSize = FALSE;
  7621. break;
  7622. }
  7623. }
  7624. if (bAllSameSize)
  7625. KeyLen = KeyLenFile[0];
  7626. else
  7627. {
  7628. // TT - BUG #1504: If only one key size is available, try to use it
  7629. b512avail = find_gpk_obj_tag_type( hProv, TAG_RSA_PUBLIC, 0, 512/8, TRUE, FALSE ) != 0;
  7630. b1024avail = find_gpk_obj_tag_type( hProv, TAG_RSA_PUBLIC, 0, 1024/8, TRUE, FALSE ) != 0;
  7631. if (!b512avail && !b1024avail)
  7632. {
  7633. RETURN (CRYPT_FAILED, NTE_FAIL );
  7634. }
  7635. if (b512avail && !b1024avail) KeyLen = 512/8;
  7636. else if (!b512avail && b1024avail) KeyLen = 1024/8;
  7637. else
  7638. {
  7639. // TT - END
  7640. // Check if default key length is available
  7641. for (i = 0; i<nbKey; ++i)
  7642. {
  7643. if (KeyLenFile[i] == RSA_KEK_Size)
  7644. {
  7645. KeyLen = RSA_KEK_Size;
  7646. break;
  7647. }
  7648. }
  7649. if (KeyLen==0)
  7650. {
  7651. // Take smallest key size available
  7652. KeyLen = KeyLenFile[0];
  7653. for (i = 1; i<nbKey; ++i)
  7654. {
  7655. if (KeyLenFile[i] < KeyLen)
  7656. KeyLen = KeyLenFile[i];
  7657. }
  7658. }
  7659. }
  7660. }
  7661. }
  7662. if (KeyLen > RSA_KEK_Size)
  7663. {
  7664. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7665. }
  7666. // AT_EXCHANGE
  7667. hKey = find_gpk_obj_tag_type(hProv, TAG_RSA_PUBLIC, 0x00, KeyLen, TRUE, FALSE);
  7668. if ((hKey != 0)
  7669. &&(find_gpk_obj_tag_type(hProv, TAG_RSA_PUBLIC, AT_KEYEXCHANGE, 0x00, TRUE, FALSE) == 0)
  7670. &&(find_gpk_obj_tag_type(hProv, TAG_CERTIFICATE, AT_KEYEXCHANGE, 0x00, FALSE, FALSE) == 0)
  7671. )
  7672. {
  7673. *phKey = hKey;
  7674. }
  7675. else
  7676. {
  7677. RETURN (CRYPT_FAILED, NTE_FAIL );
  7678. }
  7679. // TT 24/09/99: On board key generation for GPK8000
  7680. if (ProvCont[hProv].bGPK8000)
  7681. {
  7682. if (!gen_key_on_board8000( hProv, Slot[SlotNb].GpkObject[hKey].FileId ))
  7683. {
  7684. RETURN( CRYPT_FAILED, NTE_FAIL );
  7685. }
  7686. }
  7687. // TT - END -
  7688. hKeyPriv = find_gpk_obj_tag_file(hProv,
  7689. TAG_RSA_PRIVATE,
  7690. Slot[SlotNb].GpkObject[hKey].FileId,
  7691. TRUE
  7692. );
  7693. if ( hKeyPriv == 0 )
  7694. {
  7695. RETURN (CRYPT_FAILED, NTE_SIGNATURE_FILE_BAD);
  7696. }
  7697. if ((HIWORD(dwFlags) != 0) &&
  7698. (Slot[SlotNb].GpkObject[hKeyPriv].PubKey.KeySize != (HIWORD(dwFlags) / 8))
  7699. )
  7700. {
  7701. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7702. }
  7703. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue = (BYTE*)GMEM_Alloc(1);
  7704. if (IsNull (Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue))
  7705. {
  7706. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  7707. }
  7708. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].pValue = (BYTE*)GMEM_Alloc(1);
  7709. if (IsNull (Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].pValue))
  7710. {
  7711. GMEM_Free (Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue);
  7712. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  7713. }
  7714. Slot[SlotNb].GpkObject[hKey].IsCreated = TRUE;
  7715. Slot[SlotNb].GpkObject[hKey].Flags = Slot[SlotNb].GpkObject[hKey].Flags | FLAG_KEY_TYPE;
  7716. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].Len = 1;
  7717. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0] = AT_KEYEXCHANGE;
  7718. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].bReal = TRUE;
  7719. /* Set Flags of automatic fields for PKCS#11 compatibility */
  7720. Slot[SlotNb].GpkObject[hKey].Flags = Slot[SlotNb].GpkObject[hKey].Flags | FLAG_ID;
  7721. Slot[SlotNb].GpkObject[hKey].Field[POS_ID].Len = 0;
  7722. Slot[SlotNb].GpkObject[hKey].Field[POS_ID].bReal = FALSE;
  7723. Slot[SlotNb].GpkObject[hKeyPriv].IsCreated = TRUE;
  7724. Slot[SlotNb].GpkObject[hKeyPriv].Flags = Slot[SlotNb].GpkObject[hKeyPriv].Flags | FLAG_KEY_TYPE;
  7725. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].Len = 1;
  7726. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].pValue[0] = AT_KEYEXCHANGE;
  7727. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEY_TYPE].bReal = TRUE;
  7728. /* Set Flags of automatic fields for PKCS#11 compatibility */
  7729. Slot[SlotNb].GpkObject[hKeyPriv].Flags = Slot[SlotNb].GpkObject[hKeyPriv].Flags | FLAG_ID;
  7730. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_ID].Len = 0;
  7731. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_ID].bReal = FALSE;
  7732. if (!ProvCont[hProv].bLegacyKeyset)
  7733. {
  7734. Slot[SlotNb].GpkObject[hKey].Flags |= FLAG_KEYSET;
  7735. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].Len = 1;
  7736. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].pValue = (BYTE*)GMEM_Alloc(1);
  7737. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].pValue[0] = ProvCont[hProv].keysetID;
  7738. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].bReal = TRUE;
  7739. Slot[SlotNb].GpkObject[hKeyPriv].Flags |= FLAG_KEYSET;
  7740. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].Len = 1;
  7741. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].pValue = (BYTE*)GMEM_Alloc(1);
  7742. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].pValue[0] = ProvCont[hProv].keysetID;
  7743. Slot[SlotNb].GpkObject[hKeyPriv].Field[POS_KEYSET].bReal = TRUE;
  7744. }
  7745. // Set the file containing the key to USE, add "- GPK_FIRST_KEY" here, version 2.00.002
  7746. Slot[SlotNb].UseFile [Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY] = TRUE;
  7747. break;
  7748. case CALG_RC2:
  7749. KeyLen = RC2_Key_Size;
  7750. SaltLen = 0;
  7751. if (dwFlags & CRYPT_CREATE_SALT)
  7752. {
  7753. SaltLen = RC2_128_SIZE - RC2_Key_Size;
  7754. }
  7755. bSessKey = TRUE;
  7756. break;
  7757. case CALG_RC4:
  7758. KeyLen = RC2_Key_Size;
  7759. SaltLen = 0;
  7760. if (dwFlags & CRYPT_CREATE_SALT)
  7761. {
  7762. SaltLen = RC2_128_SIZE - RC2_Key_Size;
  7763. }
  7764. bSessKey = TRUE;
  7765. break;
  7766. case CALG_DES:
  7767. KeyLen = DES_SIZE;
  7768. SaltLen = 0;
  7769. if (dwFlags & CRYPT_CREATE_SALT)
  7770. {
  7771. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7772. }
  7773. bSessKey = TRUE;
  7774. break;
  7775. case CALG_3DES_112:
  7776. KeyLen = DES3_112_SIZE;
  7777. SaltLen = 0;
  7778. if (dwFlags & CRYPT_CREATE_SALT)
  7779. {
  7780. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7781. }
  7782. bSessKey = TRUE;
  7783. break;
  7784. case CALG_3DES:
  7785. KeyLen = DES3_SIZE;
  7786. SaltLen = 0;
  7787. if (dwFlags & CRYPT_CREATE_SALT)
  7788. {
  7789. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7790. }
  7791. bSessKey = TRUE;
  7792. break;
  7793. default:
  7794. RETURN (CRYPT_FAILED, NTE_BAD_ALGID);
  7795. }
  7796. if (!bSessKey)
  7797. {
  7798. CspFlags = ProvCont[hProv].Flags;
  7799. pbBuff1 = (BYTE*)GMEM_Alloc (MAX_GPK_PUBLIC);
  7800. if (IsNull(pbBuff1))
  7801. {
  7802. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  7803. }
  7804. dwBuff1Len = MAX_GPK_PUBLIC;
  7805. if (!prepare_write_gpk_objects (hProv, pbBuff1, &dwBuff1Len, FALSE))
  7806. {
  7807. lRet = GetLastError();
  7808. GMEM_Free (pbBuff1);
  7809. RETURN (CRYPT_FAILED, lRet);
  7810. }
  7811. if (!write_gpk_objects(hProv, pbBuff1, dwBuff1Len, FALSE, FALSE))
  7812. {
  7813. lRet = GetLastError();
  7814. GMEM_Free (pbBuff1);
  7815. RETURN (CRYPT_FAILED, lRet);
  7816. }
  7817. GMEM_Free (pbBuff1);
  7818. pbBuff1 = (BYTE*)GMEM_Alloc (MAX_GPK_PRIVATE);
  7819. if (IsNull(pbBuff1))
  7820. {
  7821. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  7822. }
  7823. dwBuff1Len = MAX_GPK_PRIVATE;
  7824. if (!prepare_write_gpk_objects (hProv, pbBuff1, &dwBuff1Len, TRUE))
  7825. {
  7826. lRet = GetLastError();
  7827. GMEM_Free (pbBuff1);
  7828. RETURN (CRYPT_FAILED, lRet);
  7829. }
  7830. if (!write_gpk_objects(hProv, pbBuff1, dwBuff1Len, FALSE, TRUE))
  7831. {
  7832. lRet = GetLastError();
  7833. GMEM_Free (pbBuff1);
  7834. RETURN (CRYPT_FAILED, lRet);
  7835. }
  7836. GMEM_Free (pbBuff1);
  7837. /* Copy Gpk Key in Microsoft RSA base Module */
  7838. Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[*phKey].FileId - GPK_FIRST_KEY].KeySize = 0;
  7839. if (!read_gpk_pub_key( hProv, *phKey, &Slot[SlotNb].GpkObject[*phKey].PubKey ))
  7840. return CRYPT_FAILED;
  7841. if (!copy_gpk_key(hProv, *phKey, Algid))
  7842. return CRYPT_FAILED;
  7843. }
  7844. else
  7845. {
  7846. hKey = find_tmp_free();
  7847. if (hKey == 0)
  7848. {
  7849. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  7850. }
  7851. if (KeyLen > AuxMaxSessionKeyLength)
  7852. {
  7853. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  7854. }
  7855. // Notice: Implicitly we also need in this case to establish a transaction
  7856. // with the card. OK done by the wrapper
  7857. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  7858. (ProvCont[hProv].isContNameNullBlank))
  7859. {
  7860. if (!CryptGenKey (hProvBase, Algid, dwFlags, &(TmpObject[hKey].hKeyBase)))
  7861. return CRYPT_FAILED;
  7862. TmpObject[hKey].hProv = hProv;
  7863. *phKey = hKey + MAX_GPK_OBJ;
  7864. RETURN (CRYPT_SUCCEED, 0);
  7865. }
  7866. if (!MyCPGenRandom(hProv, KeyLen, KeyBuff))
  7867. return CRYPT_FAILED;
  7868. if (SaltLen != 0)
  7869. {
  7870. if (!MyCPGenRandom(hProv, SaltLen, SaltBuff))
  7871. return CRYPT_FAILED;
  7872. }
  7873. /* Copy Session Key in Microsoft RSA base Module*/
  7874. if (dwFlags & CRYPT_CREATE_SALT) // CryptImport does not deal with that flag
  7875. dwFlags ^= CRYPT_CREATE_SALT; // however, it is consider anyhow with the
  7876. // SaltLen parameter.
  7877. if (!copy_tmp_key(hProv, hKey, dwFlags, Algid, KeyBuff, KeyLen, SaltBuff, SaltLen))
  7878. return CRYPT_FAILED;
  7879. *phKey = hKey + MAX_GPK_OBJ;
  7880. }
  7881. RETURN (CRYPT_SUCCEED, 0);
  7882. }
  7883. /*
  7884. - MyCPGenRandom
  7885. -
  7886. * Purpose:
  7887. * Used to fill a buffer with random bytes
  7888. *
  7889. *
  7890. * Parameters:
  7891. * IN hProv - Handle to the user identifcation
  7892. * OUT pbBuffer - Pointer to the buffer where the random
  7893. * bytes are to be placed
  7894. * IN dwLen - Number of bytes of random data requested
  7895. *
  7896. * Returns:
  7897. */
  7898. BOOL WINAPI MyCPGenRandom(IN HCRYPTPROV hProv,
  7899. IN DWORD dwLen,
  7900. IN OUT BYTE *pbBuffer
  7901. )
  7902. {
  7903. DWORD i, dwMod, dwLastCommandLen, lRet;
  7904. if (!Context_exist(hProv))
  7905. {
  7906. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  7907. }
  7908. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  7909. (ProvCont[hProv].isContNameNullBlank))
  7910. {
  7911. RETURN (CRYPT_FAILED, NTE_PERM);
  7912. }
  7913. if (dwLen==0)
  7914. {
  7915. RETURN (CRYPT_SUCCEED, 0);
  7916. }
  7917. /* Generate random by blocks of 32 bytes */
  7918. dwMod = (dwLen-1)/32 + 1;
  7919. dwLastCommandLen = dwLen%32;
  7920. if (dwLastCommandLen == 0)
  7921. {
  7922. dwLastCommandLen = 32;
  7923. }
  7924. for (i=0 ; i < dwMod ; i++)
  7925. {
  7926. /* Ask card for a 32 bytes random number */
  7927. bSendBuffer[0] = 0x80; //CLA
  7928. bSendBuffer[1] = 0x84; //INS
  7929. bSendBuffer[2] = 0x00; //P1
  7930. bSendBuffer[3] = 0x00; //P2
  7931. bSendBuffer[4] = 0x20; //Lo
  7932. cbSendLength = 5;
  7933. cbRecvLength = sizeof(bRecvBuffer);
  7934. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  7935. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  7936. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  7937. {
  7938. RETURN (CRYPT_FAILED, SCARD_E_UNSUPPORTED_FEATURE);
  7939. }
  7940. memcpy(&pbBuffer[i*32],
  7941. bRecvBuffer,
  7942. ((i == dwMod - 1) ? dwLastCommandLen : 32)
  7943. );
  7944. }
  7945. RETURN (CRYPT_SUCCEED, 0);
  7946. }
  7947. /*
  7948. - MyCPGetKeyParam
  7949. -
  7950. * Purpose:
  7951. * Allows applications to get various aspects of the
  7952. * operations of a key
  7953. *
  7954. * Parameters:
  7955. * IN hProv - Handle to a CSP
  7956. * IN hKey - Handle to a key
  7957. * IN dwParam - Parameter number
  7958. * IN pbData - Pointer to data
  7959. * IN pdwDataLen - Length of parameter data
  7960. * IN dwFlags - Flags values
  7961. *
  7962. * Returns:
  7963. */
  7964. BOOL WINAPI MyCPGetKeyParam(IN HCRYPTPROV hProv,
  7965. IN HCRYPTKEY hKey,
  7966. IN DWORD dwParam,
  7967. IN BYTE *pbData,
  7968. IN DWORD *pdwDataLen,
  7969. IN DWORD dwFlags
  7970. )
  7971. {
  7972. BOOL CryptResp;
  7973. BYTE hCert;
  7974. BYTE KeyType;
  7975. BYTE KeyId;
  7976. BYTE GpkKeySize;
  7977. DWORD SlotNb;
  7978. if (!Context_exist(hProv))
  7979. {
  7980. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  7981. }
  7982. SlotNb = ProvCont[hProv].Slot;
  7983. /* Resident Key */
  7984. if (hKey == 0)
  7985. {
  7986. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  7987. }
  7988. else if (hKey <= MAX_GPK_OBJ)
  7989. {
  7990. if (dwFlags != 0)
  7991. {
  7992. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  7993. }
  7994. // [mv - 15/05/98]
  7995. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  7996. (ProvCont[hProv].isContNameNullBlank))
  7997. {
  7998. RETURN (CRYPT_FAILED, NTE_PERM);
  7999. }
  8000. if (Slot[SlotNb].GpkObject[hKey].FileId == 0)
  8001. {
  8002. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  8003. }
  8004. if (Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].Len == 0)
  8005. {
  8006. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  8007. }
  8008. KeyId = Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0];
  8009. switch (dwParam)
  8010. {
  8011. case KP_ALGID:
  8012. if (IsNotNull(pbData))
  8013. {
  8014. DWORD dwAlgid;
  8015. if (*pdwDataLen < sizeof(DWORD))
  8016. {
  8017. *pdwDataLen = sizeof(DWORD);
  8018. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  8019. }
  8020. switch (KeyId)
  8021. {
  8022. case AT_KEYEXCHANGE:
  8023. dwAlgid = CALG_RSA_KEYX;
  8024. break;
  8025. case AT_SIGNATURE:
  8026. dwAlgid = CALG_RSA_SIGN;
  8027. break;
  8028. default:
  8029. RETURN (CRYPT_FAILED, NTE_BAD_TYPE);
  8030. }
  8031. memcpy(pbData, &dwAlgid, sizeof(DWORD));
  8032. }
  8033. *pdwDataLen = sizeof(DWORD);
  8034. break;
  8035. case KP_BLOCKLEN:
  8036. case KP_KEYLEN:
  8037. if (IsNotNull(pbData))
  8038. {
  8039. DWORD dwBlockLen;
  8040. if (*pdwDataLen < sizeof(DWORD))
  8041. {
  8042. *pdwDataLen = sizeof(DWORD);
  8043. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  8044. }
  8045. GpkKeySize = Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY].KeySize;
  8046. if (GpkKeySize == 0)
  8047. {
  8048. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  8049. }
  8050. dwBlockLen = GpkKeySize*8;
  8051. memcpy(pbData, &dwBlockLen, sizeof(DWORD));
  8052. }
  8053. *pdwDataLen = sizeof(DWORD);
  8054. break;
  8055. case KP_PERMISSIONS:
  8056. if (IsNotNull(pbData))
  8057. {
  8058. DWORD dwPerm;
  8059. if (*pdwDataLen < sizeof(DWORD))
  8060. {
  8061. *pdwDataLen = sizeof(DWORD);
  8062. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  8063. }
  8064. switch (KeyId)
  8065. {
  8066. case AT_KEYEXCHANGE:
  8067. dwPerm = 0
  8068. | CRYPT_ENCRYPT // Allow encryption
  8069. | CRYPT_DECRYPT // Allow decryption
  8070. // CRYPT_EXPORT // Allow key to be exported
  8071. | CRYPT_READ // Allow parameters to be read
  8072. | CRYPT_WRITE // Allow parameters to be set
  8073. | CRYPT_MAC // Allow MACs to be used with key
  8074. | CRYPT_EXPORT_KEY// Allow key to be used for exporting keys
  8075. | CRYPT_IMPORT_KEY// Allow key to be used for importing keys
  8076. ;
  8077. break;
  8078. case AT_SIGNATURE:
  8079. dwPerm = 0
  8080. // CRYPT_ENCRYPT // Allow encryption
  8081. // CRYPT_DECRYPT // Allow decryption
  8082. // CRYPT_EXPORT // Allow key to be exported
  8083. | CRYPT_READ // Allow parameters to be read
  8084. | CRYPT_WRITE // Allow parameters to be set
  8085. | CRYPT_MAC // Allow MACs to be used with key
  8086. // CRYPT_EXPORT_KEY// Allow key to be used for exporting keys
  8087. // CRYPT_IMPORT_KEY// Allow key to be used for importing keys
  8088. ;
  8089. break;
  8090. default:
  8091. RETURN (CRYPT_FAILED, NTE_BAD_TYPE);
  8092. }
  8093. memcpy(pbData, &dwPerm, sizeof(DWORD));
  8094. }
  8095. *pdwDataLen = sizeof(DWORD);
  8096. break;
  8097. case KP_CERTIFICATE:
  8098. KeyType = Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0];
  8099. hCert = find_gpk_obj_tag_type( hProv, TAG_CERTIFICATE, KeyType,
  8100. 0x00, FALSE, FALSE );
  8101. if (hCert == 0)
  8102. {
  8103. RETURN( CRYPT_FAILED, SCARD_E_NO_SUCH_CERTIFICATE );
  8104. }
  8105. /* Retrieve Certificate Value */
  8106. if (IsNotNull(pbData))
  8107. {
  8108. if (*pdwDataLen < Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len)
  8109. {
  8110. *pdwDataLen = Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len;
  8111. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  8112. }
  8113. memcpy(pbData,
  8114. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue,
  8115. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len
  8116. );
  8117. }
  8118. *pdwDataLen = Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len;
  8119. break;
  8120. default:
  8121. RETURN (CRYPT_FAILED, NTE_BAD_TYPE);
  8122. }
  8123. }
  8124. /* Session Key */
  8125. else if (key_exist (hKey-MAX_GPK_OBJ, hProv))
  8126. {
  8127. CryptResp = CryptGetKeyParam (TmpObject[hKey-MAX_GPK_OBJ].hKeyBase,
  8128. dwParam,
  8129. pbData,
  8130. pdwDataLen,
  8131. dwFlags);
  8132. if (!CryptResp)
  8133. return CRYPT_FAILED;
  8134. }
  8135. /* Bad Key */
  8136. else
  8137. {
  8138. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  8139. }
  8140. RETURN (CRYPT_SUCCEED, 0);
  8141. }
  8142. /*
  8143. - MyCPGetUserKey
  8144. -
  8145. * Purpose:
  8146. * Gets a handle to a permanent user key
  8147. *
  8148. *
  8149. * Parameters:
  8150. * IN hProv - Handle to the user identifcation
  8151. * IN dwKeySpec - Specification of the key to retrieve
  8152. * OUT phUserKey - Pointer to key handle of retrieved key
  8153. *
  8154. * Returns:
  8155. */
  8156. BOOL WINAPI MyCPGetUserKey(IN HCRYPTPROV hProv,
  8157. IN DWORD dwKeySpec,
  8158. OUT HCRYPTKEY *phUserKey
  8159. )
  8160. {
  8161. HCRYPTKEY hKey;
  8162. GPK_EXP_KEY aPubKey;
  8163. DWORD dwLen;
  8164. *phUserKey = 0;
  8165. if (!Context_exist(hProv))
  8166. {
  8167. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  8168. }
  8169. /* Bug # 1103
  8170. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  8171. (ProvCont[hProv].isContNameNullBlank))
  8172. */
  8173. if ( ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT )
  8174. {
  8175. RETURN (CRYPT_FAILED, NTE_PERM);
  8176. }
  8177. if (!PublicEFExists(hProv))
  8178. {
  8179. RETURN (CRYPT_FAILED, NTE_NO_KEY);
  8180. }
  8181. if (dwKeySpec == AT_KEYEXCHANGE)
  8182. {
  8183. hKey = find_gpk_obj_tag_type(hProv,
  8184. TAG_RSA_PUBLIC,
  8185. (BYTE)dwKeySpec,
  8186. 0x00,
  8187. TRUE,
  8188. FALSE
  8189. );
  8190. // get the key length
  8191. if (hKey != 0)
  8192. {
  8193. if (!read_gpk_pub_key(hProv, hKey, &aPubKey))
  8194. {
  8195. hKey = 0;
  8196. }
  8197. else
  8198. {
  8199. dwLen = aPubKey.KeySize;
  8200. if (dwLen > RSA_KEK_Size)
  8201. {
  8202. hKey = 0;
  8203. }
  8204. }
  8205. }
  8206. }
  8207. else
  8208. {
  8209. hKey = find_gpk_obj_tag_type(hProv,
  8210. TAG_RSA_PUBLIC,
  8211. (BYTE)dwKeySpec,
  8212. 0x00,
  8213. FALSE,
  8214. FALSE
  8215. );
  8216. }
  8217. if (hKey == 0)
  8218. {
  8219. RETURN (CRYPT_FAILED, NTE_NO_KEY);
  8220. }
  8221. *phUserKey = hKey;
  8222. RETURN (CRYPT_SUCCEED, 0);
  8223. }
  8224. /*
  8225. - MyCPImportKey
  8226. -
  8227. * Purpose:
  8228. * Import cryptographic keys
  8229. *
  8230. *
  8231. * Parameters:
  8232. * IN hProv - Handle to the CSP user
  8233. * IN pbData - Key blob data
  8234. * IN dwDataLen - Length of the key blob data
  8235. * IN hPubKey - Handle to the exchange public key value of
  8236. * the destination user
  8237. * IN dwFlags - Flags values
  8238. * OUT phKey - Pointer to the handle to the key which was
  8239. * Imported
  8240. *
  8241. * Returns:
  8242. */
  8243. BOOL WINAPI MyCPImportKey(IN HCRYPTPROV hProv,
  8244. IN CONST BYTE *pbData,
  8245. IN DWORD dwDataLen,
  8246. IN HCRYPTKEY hPubKey,
  8247. IN DWORD dwFlags,
  8248. OUT HCRYPTKEY *phKey
  8249. )
  8250. {
  8251. DWORD lRet;
  8252. BOOL CryptResp;
  8253. HCRYPTKEY hTmpKey, hPrivKey;
  8254. BLOBHEADER BlobHeader;
  8255. DWORD dwAlgid, dwBlobLen;
  8256. BYTE* pBlob;
  8257. BYTE* pBlobOut;
  8258. DWORD SlotNb;
  8259. // + [FP] for PRIVATEKEYBLOB
  8260. BOOL GpkObj;
  8261. GPK_EXP_KEY aPubKey;
  8262. DWORD dwKeyLen;
  8263. BYTE bKeyType;
  8264. BOOL IsExchange;
  8265. HCRYPTKEY hKey;
  8266. BYTE bSfi;
  8267. BYTE *pbBuff1 = 0;
  8268. DWORD dwBuff1Len;
  8269. // - [FP]
  8270. // + NK 07.02.2001
  8271. DWORD dwPinLength;
  8272. // -NK
  8273. if (!Context_exist(hProv))
  8274. {
  8275. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  8276. }
  8277. SlotNb = ProvCont[hProv].Slot;
  8278. if ((IsNull(pbData)) || (dwDataLen < sizeof(BLOBHEADER)+sizeof(RSAPUBKEY)))
  8279. {
  8280. RETURN (CRYPT_FAILED, NTE_BAD_DATA);
  8281. }
  8282. memcpy(&BlobHeader, pbData, sizeof(BLOBHEADER));
  8283. if (BlobHeader.bVersion != CUR_BLOB_VERSION)
  8284. {
  8285. RETURN (CRYPT_FAILED, NTE_BAD_VER);
  8286. }
  8287. switch (BlobHeader.bType)
  8288. {
  8289. case PUBLICKEYBLOB:
  8290. {
  8291. hTmpKey = find_tmp_free();
  8292. if (hTmpKey == 0)
  8293. {
  8294. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8295. }
  8296. /* Copy Session Key in Microsoft RSA base Module */
  8297. CryptResp = CryptImportKey(hProvBase,
  8298. pbData,
  8299. dwDataLen,
  8300. 0,
  8301. dwFlags,
  8302. &(TmpObject[hTmpKey].hKeyBase));
  8303. if (!CryptResp)
  8304. return CRYPT_FAILED;
  8305. TmpObject[hTmpKey].hProv = hProv;
  8306. *phKey = hTmpKey+MAX_GPK_OBJ;
  8307. }
  8308. break;
  8309. case SIMPLEBLOB:
  8310. {
  8311. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT)
  8312. {
  8313. RETURN (CRYPT_FAILED, NTE_PERM);
  8314. }
  8315. // + NK 06.02.2001
  8316. // if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (IsNullStr(Slot[SlotNb].GetPin())))
  8317. lRet = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  8318. NULL,
  8319. &dwPinLength );
  8320. if ( (lRet != ERROR_SUCCESS) && (lRet != ERROR_EMPTY) )
  8321. RETURN (CRYPT_FAILED, lRet);
  8322. if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (lRet == ERROR_EMPTY))
  8323. // - NK
  8324. {
  8325. RETURN (CRYPT_FAILED, NTE_SILENT_CONTEXT);
  8326. }
  8327. // Verify the PINs
  8328. if (!PIN_Validation(hProv))
  8329. return CRYPT_FAILED;
  8330. if (!VerifyDivPIN(hProv, TRUE))
  8331. return CRYPT_FAILED;
  8332. switch (BlobHeader.aiKeyAlg)
  8333. {
  8334. case CALG_RC2:
  8335. case CALG_RC4:
  8336. case CALG_DES:
  8337. case CALG_3DES_112:
  8338. case CALG_3DES: break;
  8339. default:
  8340. RETURN (CRYPT_FAILED, NTE_BAD_ALGID);
  8341. }
  8342. memcpy( &dwAlgid, &pbData[sizeof(BlobHeader)], sizeof(DWORD) );
  8343. switch (dwAlgid)
  8344. {
  8345. case CALG_RSA_KEYX:
  8346. CryptResp = MyCPGetUserKey(hProv, AT_KEYEXCHANGE, &hPrivKey);
  8347. if ((!CryptResp) || (hPrivKey == 0))
  8348. {
  8349. RETURN (CRYPT_FAILED, NTE_BAD_DATA);
  8350. }
  8351. break;
  8352. case CALG_RSA_SIGN:
  8353. RETURN (CRYPT_FAILED, NTE_BAD_DATA);
  8354. break;
  8355. default:
  8356. RETURN (CRYPT_FAILED, NTE_BAD_DATA);
  8357. }
  8358. dwBlobLen = dwDataLen-sizeof(BLOBHEADER)-sizeof(DWORD);
  8359. pBlob = (BYTE*)GMEM_Alloc(dwBlobLen);
  8360. if (IsNull(pBlob))
  8361. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8362. pBlobOut = (BYTE*)GMEM_Alloc(dwBlobLen);
  8363. if (IsNull(pBlobOut))
  8364. {
  8365. GMEM_Free (pBlob);
  8366. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8367. }
  8368. __try
  8369. {
  8370. memcpy( pBlob, &pbData[sizeof(BLOBHEADER)+sizeof(DWORD)], dwBlobLen );
  8371. hTmpKey = find_tmp_free();
  8372. if (hTmpKey == 0)
  8373. RETURN( CRYPT_FAILED, NTE_NO_MEMORY );
  8374. CryptResp = key_unwrap( hProv, hPrivKey, pBlob, dwBlobLen, pBlobOut, &dwBlobLen );
  8375. if (!CryptResp)
  8376. return CRYPT_FAILED;
  8377. if (dwBlobLen > AuxMaxSessionKeyLength)
  8378. RETURN( CRYPT_FAILED, NTE_BAD_KEY );
  8379. /* Copy Session Key in Microsoft RSA base Module */
  8380. if (!copy_tmp_key(hProv, hTmpKey, dwFlags, BlobHeader.aiKeyAlg, pBlobOut, dwBlobLen, 0, 0))
  8381. return CRYPT_FAILED;
  8382. *phKey = hTmpKey+MAX_GPK_OBJ;
  8383. }
  8384. __finally
  8385. {
  8386. GMEM_Free(pBlob);
  8387. GMEM_Free(pBlobOut);
  8388. }
  8389. }
  8390. break;
  8391. // + [FP]
  8392. case PRIVATEKEYBLOB:
  8393. {
  8394. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT)
  8395. {
  8396. RETURN (CRYPT_FAILED, NTE_PERM);
  8397. }
  8398. // + NK 06.02.2001
  8399. // if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (IsNullStr(Slot[SlotNb].GetPin())))
  8400. lRet = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  8401. NULL,
  8402. &dwPinLength );
  8403. if ( (lRet != ERROR_SUCCESS) && (lRet != ERROR_EMPTY) )
  8404. RETURN (CRYPT_FAILED, lRet);
  8405. if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (lRet == ERROR_EMPTY))
  8406. // - NK
  8407. {
  8408. RETURN (CRYPT_FAILED, NTE_SILENT_CONTEXT);
  8409. }
  8410. if (Slot[SlotNb].NbKeyFile == 0 || Slot[SlotNb].NbKeyFile > MAX_REAL_KEY)
  8411. {
  8412. RETURN (CRYPT_FAILED, SCARD_E_FILE_NOT_FOUND); // should not bigger than MAX_REAL_KEY
  8413. }
  8414. // get the key type
  8415. bKeyType = (BlobHeader.aiKeyAlg == CALG_RSA_KEYX) ? AT_KEYEXCHANGE : AT_SIGNATURE;
  8416. IsExchange = (BlobHeader.aiKeyAlg == CALG_RSA_KEYX) ? TRUE : FALSE;
  8417. // get the key size (in bits)
  8418. memcpy(&dwKeyLen,
  8419. &pbData[sizeof(BlobHeader)+ sizeof(DWORD)],
  8420. sizeof(DWORD)
  8421. );
  8422. if (bKeyType == AT_KEYEXCHANGE)
  8423. {
  8424. if ((dwKeyLen / 8) > RSA_KEK_Size)
  8425. {
  8426. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  8427. }
  8428. }
  8429. GpkObj = TRUE;
  8430. hKey = find_gpk_obj_tag_type(hProv, TAG_RSA_PUBLIC, bKeyType, 0x00, IsExchange, FALSE);
  8431. if (hKey != 0)
  8432. {
  8433. if (!read_gpk_pub_key(hProv, hKey, &aPubKey))
  8434. {
  8435. RETURN (CRYPT_FAILED, NTE_FAIL);
  8436. }
  8437. if ((dwKeyLen / 8) != aPubKey.KeySize)
  8438. {
  8439. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  8440. }
  8441. }
  8442. else
  8443. {
  8444. GpkObj = FALSE;
  8445. // find a file on the card
  8446. hKey = find_gpk_obj_tag_type(hProv, TAG_RSA_PUBLIC, 0x00, (BYTE)(dwKeyLen / 8), IsExchange, FALSE);
  8447. if ((hKey != 0)
  8448. &&(find_gpk_obj_tag_type(hProv, TAG_RSA_PUBLIC, bKeyType, 0x00, IsExchange, FALSE) == 0)
  8449. &&(find_gpk_obj_tag_type(hProv, TAG_CERTIFICATE, bKeyType, 0x00, FALSE, FALSE) == 0)
  8450. )
  8451. {
  8452. *phKey = hKey;
  8453. }
  8454. else
  8455. {
  8456. RETURN (CRYPT_FAILED, NTE_FAIL);
  8457. }
  8458. }
  8459. bSfi = Slot[SlotNb].GpkObject[hKey].FileId;
  8460. if (!Read_Priv_Obj(hProv))
  8461. return CRYPT_FAILED;
  8462. if (!VerifyDivPIN(hProv, TRUE))
  8463. return CRYPT_FAILED;
  8464. // load the public key in the card
  8465. // Update record 2 (modulus)
  8466. bSendBuffer[0] = 0x00; //CLA
  8467. bSendBuffer[1] = 0xDC; //INS
  8468. bSendBuffer[2] = 0x02; //P1
  8469. bSendBuffer[3] = (BYTE)(bSfi << 3) + 0x04; //P2
  8470. bSendBuffer[4] = (BYTE)(TAG_LEN + (dwKeyLen / 8)); //Li
  8471. bSendBuffer[5] = TAG_MODULUS;
  8472. memcpy(&bSendBuffer[6], &pbData[sizeof(BlobHeader) + sizeof(RSAPUBKEY)], dwKeyLen / 8);
  8473. cbSendLength = 5 + bSendBuffer[4];
  8474. cbRecvLength = sizeof(bRecvBuffer);
  8475. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  8476. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  8477. if(SCARDPROBLEM(lRet, 0x9000, 0x00))
  8478. {
  8479. RETURN (CRYPT_FAILED, NTE_FAIL);
  8480. }
  8481. // Update record 3 (public exponent)
  8482. bSendBuffer[0] = 0x00; //CLA
  8483. bSendBuffer[1] = 0xDC; //INS
  8484. bSendBuffer[2] = 0x03; //P1
  8485. bSendBuffer[3] = (BYTE)(bSfi << 3) + 0x04; //P2
  8486. bSendBuffer[4] = (BYTE)(TAG_LEN + PUB_EXP_LEN); //Li
  8487. bSendBuffer[5] = TAG_PUB_EXP;
  8488. memcpy(&bSendBuffer[6], &pbData[sizeof(BlobHeader) + (2 * sizeof(DWORD))], PUB_EXP_LEN);
  8489. cbSendLength = 5 + bSendBuffer[4];
  8490. cbRecvLength = sizeof(bRecvBuffer);
  8491. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  8492. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  8493. if(SCARDPROBLEM(lRet, 0x9000, 0x00))
  8494. {
  8495. RETURN (CRYPT_FAILED, NTE_FAIL);
  8496. }
  8497. // load the private key in the card
  8498. if (dwKeyLen == 512)
  8499. {
  8500. if (!LoadPrivateKey(ProvCont[hProv].hCard,
  8501. bSfi,
  8502. (WORD)(dwKeyLen / 16 * 5),
  8503. &pbData[sizeof(BlobHeader)+ sizeof(RSAPUBKEY) + (dwKeyLen/8)],
  8504. 168
  8505. )
  8506. )
  8507. {
  8508. RETURN (CRYPT_FAILED, NTE_FAIL);
  8509. }
  8510. }
  8511. else if (dwKeyLen == 1024)
  8512. {
  8513. // PRIME 1 CRT part
  8514. if (!LoadPrivateKey(ProvCont[hProv].hCard,
  8515. bSfi,
  8516. (WORD)(dwKeyLen / 16),
  8517. &pbData[sizeof(BlobHeader)+ sizeof(RSAPUBKEY) + (dwKeyLen/8)],
  8518. 72
  8519. )
  8520. )
  8521. {
  8522. RETURN (CRYPT_FAILED, NTE_FAIL);
  8523. }
  8524. // PRIME 2 CRT part
  8525. if (!LoadPrivateKey(ProvCont[hProv].hCard,
  8526. bSfi,
  8527. (WORD)(dwKeyLen / 16),
  8528. &pbData[sizeof(BlobHeader)+ sizeof(RSAPUBKEY) + (dwKeyLen/8) + 72],
  8529. 72
  8530. )
  8531. )
  8532. {
  8533. RETURN (CRYPT_FAILED, NTE_FAIL);
  8534. }
  8535. // COEFFICIENT CRT part
  8536. if (!LoadPrivateKey(ProvCont[hProv].hCard,
  8537. bSfi,
  8538. (WORD)(dwKeyLen / 16),
  8539. &pbData[sizeof(BlobHeader)+ sizeof(RSAPUBKEY) + (dwKeyLen/8) + 144],
  8540. 72
  8541. )
  8542. )
  8543. {
  8544. RETURN (CRYPT_FAILED, NTE_FAIL);
  8545. }
  8546. // EXPONENT 1 CRT part
  8547. if (!LoadPrivateKey(ProvCont[hProv].hCard,
  8548. bSfi,
  8549. (WORD)(dwKeyLen / 16),
  8550. &pbData[sizeof(BlobHeader)+ sizeof(RSAPUBKEY) + (dwKeyLen/8) + 216],
  8551. 72
  8552. )
  8553. )
  8554. {
  8555. RETURN (CRYPT_FAILED, NTE_FAIL);
  8556. }
  8557. // EXPONENT 2 CRT part
  8558. if (!LoadPrivateKey(ProvCont[hProv].hCard,
  8559. bSfi,
  8560. (WORD)(dwKeyLen / 16),
  8561. &pbData[sizeof(BlobHeader)+ sizeof(RSAPUBKEY) + (dwKeyLen/8) + 288],
  8562. 72
  8563. )
  8564. )
  8565. {
  8566. RETURN (CRYPT_FAILED, NTE_FAIL);
  8567. }
  8568. }
  8569. else
  8570. {
  8571. RETURN (CRYPT_FAILED, NTE_BAD_LEN);
  8572. }
  8573. if (!GpkObj)
  8574. {
  8575. hPrivKey = find_gpk_obj_tag_file(hProv, TAG_RSA_PRIVATE, Slot[SlotNb].GpkObject[hKey].FileId, TRUE);
  8576. if ( hPrivKey == 0 )
  8577. {
  8578. RETURN (CRYPT_FAILED, NTE_SIGNATURE_FILE_BAD);
  8579. }
  8580. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue = (BYTE*)GMEM_Alloc(1);
  8581. if (IsNull(Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue))
  8582. {
  8583. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8584. }
  8585. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEY_TYPE].pValue = (BYTE*)GMEM_Alloc(1);
  8586. if (IsNull(Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEY_TYPE].pValue))
  8587. {
  8588. GMEM_Free(Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue);
  8589. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8590. }
  8591. Slot[SlotNb].GpkObject[hKey].IsCreated = TRUE;
  8592. Slot[SlotNb].GpkObject[hKey].Flags = Slot[SlotNb].GpkObject[hKey].Flags | FLAG_KEY_TYPE;
  8593. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].Len = 1;
  8594. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0] = bKeyType;
  8595. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].bReal = TRUE;
  8596. /* Set Flags of automatic fields for PKCS#11 compatibility */
  8597. Slot[SlotNb].GpkObject[hKey].Flags = Slot[SlotNb].GpkObject[hKey].Flags | FLAG_ID;
  8598. Slot[SlotNb].GpkObject[hKey].Field[POS_ID].Len = 0;
  8599. Slot[SlotNb].GpkObject[hKey].Field[POS_ID].bReal = FALSE;
  8600. Slot[SlotNb].GpkObject[hPrivKey].IsCreated = TRUE;
  8601. Slot[SlotNb].GpkObject[hPrivKey].Flags = Slot[SlotNb].GpkObject[hPrivKey].Flags | FLAG_KEY_TYPE;
  8602. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEY_TYPE].Len = 1;
  8603. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEY_TYPE].pValue[0] = bKeyType;
  8604. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEY_TYPE].bReal = TRUE;
  8605. /* Set Flags of automatic fields for PKCS#11 compatibility */
  8606. Slot[SlotNb].GpkObject[hPrivKey].Flags = Slot[SlotNb].GpkObject[hPrivKey].Flags | FLAG_ID;
  8607. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_ID].Len = 0;
  8608. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_ID].bReal = FALSE;
  8609. if (!ProvCont[hProv].bLegacyKeyset)
  8610. {
  8611. Slot[SlotNb].GpkObject[hKey].Flags |= FLAG_KEYSET;
  8612. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].Len = 1;
  8613. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].pValue = (BYTE*)GMEM_Alloc(1);
  8614. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].pValue[0] = ProvCont[hProv].keysetID;
  8615. Slot[SlotNb].GpkObject[hKey].Field[POS_KEYSET].bReal = TRUE;
  8616. Slot[SlotNb].GpkObject[hPrivKey].Flags |= FLAG_KEYSET;
  8617. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEYSET].Len = 1;
  8618. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEYSET].pValue = (BYTE*)GMEM_Alloc(1);
  8619. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEYSET].pValue[0] = ProvCont[hProv].keysetID;
  8620. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_KEYSET].bReal = TRUE;
  8621. }
  8622. // set the file containing the key to USE, add "- GPK_FIRST_KEY" here, version 2.00.002
  8623. Slot[SlotNb].UseFile[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY] = TRUE;
  8624. pbBuff1 = (BYTE*)GMEM_Alloc (MAX_GPK_PUBLIC);
  8625. if (IsNull(pbBuff1))
  8626. {
  8627. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8628. }
  8629. dwBuff1Len = MAX_GPK_PUBLIC;
  8630. if (!prepare_write_gpk_objects (hProv, pbBuff1, &dwBuff1Len, FALSE))
  8631. {
  8632. lRet = GetLastError();
  8633. GMEM_Free (pbBuff1);
  8634. RETURN (CRYPT_FAILED, lRet);
  8635. }
  8636. if (!write_gpk_objects(hProv, pbBuff1, dwBuff1Len, FALSE, FALSE))
  8637. {
  8638. lRet = GetLastError();
  8639. GMEM_Free (pbBuff1);
  8640. RETURN (CRYPT_FAILED, lRet);
  8641. }
  8642. GMEM_Free (pbBuff1);
  8643. pbBuff1 = (BYTE*)GMEM_Alloc (MAX_GPK_PRIVATE);
  8644. if (IsNull(pbBuff1))
  8645. {
  8646. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8647. }
  8648. dwBuff1Len = MAX_GPK_PRIVATE;
  8649. if (!prepare_write_gpk_objects (hProv, pbBuff1, &dwBuff1Len, TRUE))
  8650. {
  8651. lRet = GetLastError();
  8652. GMEM_Free (pbBuff1);
  8653. RETURN (CRYPT_FAILED, lRet);
  8654. }
  8655. if (!write_gpk_objects(hProv, pbBuff1, dwBuff1Len, FALSE, TRUE))
  8656. {
  8657. lRet = GetLastError();
  8658. GMEM_Free (pbBuff1);
  8659. RETURN (CRYPT_FAILED, lRet);
  8660. }
  8661. GMEM_Free (pbBuff1);
  8662. // copy Gpk Key in Microsoft RSA base Module
  8663. if (!copy_gpk_key(hProv, *phKey, bKeyType))
  8664. return CRYPT_FAILED;
  8665. }
  8666. break;
  8667. }
  8668. // - [FP]
  8669. default:
  8670. {
  8671. RETURN (CRYPT_FAILED, NTE_BAD_TYPE);
  8672. }
  8673. }
  8674. RETURN (CRYPT_SUCCEED, 0);
  8675. }
  8676. /*
  8677. - CPSetKeyParam
  8678. -
  8679. * Purpose:
  8680. * Allows applications to customize various aspects of the
  8681. * operations of a key
  8682. *
  8683. * Parameters:
  8684. * IN hProv - Handle to a CSP
  8685. * IN hKey - Handle to a key
  8686. * IN dwParam - Parameter number
  8687. * IN pbData - Pointer to data
  8688. * IN dwFlags - Flags values
  8689. *
  8690. * Returns:
  8691. */
  8692. BOOL WINAPI MyCPSetKeyParam(IN HCRYPTPROV hProv,
  8693. IN HCRYPTKEY hKey,
  8694. IN DWORD dwParam,
  8695. IN CONST BYTE *pbData,
  8696. IN DWORD dwFlags
  8697. )
  8698. {
  8699. BOOL bNew;
  8700. BOOL WriteCert;
  8701. BOOL CryptResp;
  8702. BYTE hCert;
  8703. BYTE KeyType;
  8704. BYTE hPrivKey;
  8705. BYTE *pbLabel;
  8706. BYTE *pbBuff1 = 0, *pbBuff2 = 0;
  8707. WORD wLabelLen, i;
  8708. DWORD lRet,
  8709. dwBuff1Len,
  8710. dwBuff2Len,
  8711. SlotNb;
  8712. GPK_OBJ TmpCert, TmpPrivKey;
  8713. // + NK 07.02.2001
  8714. PINCACHE_PINS Pins;
  8715. DWORD dwPinLength;
  8716. // -NK
  8717. if (!Context_exist(hProv))
  8718. {
  8719. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  8720. }
  8721. SlotNb = ProvCont[hProv].Slot;
  8722. /* Resident Key */
  8723. if (hKey == 0)
  8724. {
  8725. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  8726. }
  8727. else if (hKey <= MAX_GPK_OBJ)
  8728. {
  8729. if (ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT)
  8730. {
  8731. RETURN (CRYPT_FAILED, NTE_PERM);
  8732. }
  8733. if ((!Slot[SlotNb].GpkObject[hKey].IsCreated) ||
  8734. ( Slot[SlotNb].GpkObject[hKey].FileId == 0))
  8735. {
  8736. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  8737. }
  8738. switch (dwParam)
  8739. {
  8740. case KP_ADMIN_PIN:
  8741. RETURN(CRYPT_FAILED, E_NOTIMPL);
  8742. break;
  8743. case KP_KEYEXCHANGE_PIN:
  8744. case KP_SIGNATURE_PIN:
  8745. // Slot[SlotNb].ClearPin();
  8746. // Slot[SlotNb].SetPin( (char*)pbData );
  8747. PopulatePins( &Pins, (BYTE *)pbData, strlen( (char*)pbData ), NULL, 0 );
  8748. CallbackData sCallbackData;
  8749. sCallbackData.hProv = hProv;
  8750. sCallbackData.IsCoherent = TRUE;
  8751. if ( (lRet = Add_MSPinCache( &(Slot[SlotNb].hPinCacheHandle),
  8752. &Pins,
  8753. Callback_VerifyChangePin,
  8754. (void*)&sCallbackData )) != ERROR_SUCCESS )
  8755. {
  8756. RETURN (CRYPT_FAILED, lRet);
  8757. }
  8758. break;
  8759. case KP_CERTIFICATE:
  8760. if (!Read_Priv_Obj(hProv))
  8761. return CRYPT_FAILED;
  8762. // + NK 06.02.2001
  8763. // if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (IsNullStr(Slot[SlotNb].GetPin())))
  8764. lRet = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  8765. NULL,
  8766. &dwPinLength );
  8767. if ( (lRet != ERROR_SUCCESS) && (lRet != ERROR_EMPTY) )
  8768. RETURN (CRYPT_FAILED, lRet);
  8769. if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (lRet == ERROR_EMPTY))
  8770. // - NK
  8771. {
  8772. RETURN (CRYPT_FAILED, NTE_SILENT_CONTEXT);
  8773. }
  8774. // Supports only X509 certificats
  8775. if ((IsNull(pbData)) || (pbData[0] != 0x30) ||(pbData[1] != 0x82))
  8776. {
  8777. RETURN (CRYPT_FAILED, NTE_BAD_DATA);
  8778. }
  8779. /* Store Certificate value */
  8780. /* Try to found existing certificate */
  8781. KeyType = Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue[0];
  8782. hCert = find_gpk_obj_tag_type(hProv,
  8783. TAG_CERTIFICATE,
  8784. KeyType,
  8785. 0x00,
  8786. FALSE,
  8787. FALSE);
  8788. /* If not found create new object */
  8789. bNew = FALSE;
  8790. if (hCert == 0)
  8791. {
  8792. if (Slot[SlotNb].NbGpkObject >= MAX_GPK_OBJ)
  8793. {
  8794. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8795. }
  8796. Slot[SlotNb].NbGpkObject++;
  8797. hCert = Slot[SlotNb].NbGpkObject;
  8798. bNew = TRUE;
  8799. }
  8800. else
  8801. {
  8802. DialogBox(g_hInstRes, TEXT("CONTDIALOG"), GetAppWindow(), (DLGPROC)ContDlgProc);
  8803. if (ContainerStatus == ABORT_OPERATION)
  8804. {
  8805. RETURN (CRYPT_FAILED, SCARD_W_CANCELLED_BY_USER);
  8806. }
  8807. }
  8808. /* Search associated private RSA key part */
  8809. if (KeyType == AT_KEYEXCHANGE)
  8810. {
  8811. hPrivKey = find_gpk_obj_tag_type(hProv,
  8812. TAG_RSA_PRIVATE,
  8813. KeyType,
  8814. 0x00,
  8815. TRUE, // Exchange key
  8816. TRUE
  8817. );
  8818. }
  8819. else
  8820. {
  8821. hPrivKey = find_gpk_obj_tag_type(hProv,
  8822. TAG_RSA_PRIVATE,
  8823. KeyType,
  8824. 0x00,
  8825. FALSE, // Signature key
  8826. TRUE
  8827. );
  8828. }
  8829. TmpCert = Slot[SlotNb].GpkObject[hCert];
  8830. for (i = 0; i < MAX_FIELD; i++)
  8831. {
  8832. Slot[SlotNb].GpkObject[hCert].Field[i].bReal = TRUE;
  8833. }
  8834. Slot[SlotNb].GpkObject[hCert].Tag = TAG_CERTIFICATE;
  8835. Slot[SlotNb].GpkObject[hCert].Flags = FLAG_VALUE | FLAG_KEY_TYPE | FLAG_LABEL |
  8836. FLAG_SUBJECT | FLAG_SERIAL_NUMBER |
  8837. FLAG_ISSUER | FLAG_ID | FLAG_MODIFIABLE;
  8838. if (bNew)
  8839. {
  8840. Slot[SlotNb].GpkObject[hCert].ObjId = Slot[SlotNb].NbGpkObject-1;
  8841. }
  8842. Slot[SlotNb].GpkObject[hCert].FileId = Slot[SlotNb].GpkObject[hKey].FileId;
  8843. Slot[SlotNb].GpkObject[hCert].PubKey = Slot[SlotNb].GpkObject[hKey].PubKey;
  8844. Slot[SlotNb].GpkObject[hCert].IsCreated = TRUE;
  8845. Slot[SlotNb].GpkObject[hCert].IsPrivate = FALSE;
  8846. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len = (pbData[2] * 256) + pbData[3] + 4;
  8847. // TT 12/08/99: Keyset ID
  8848. if (!ProvCont[hProv].bLegacyKeyset)
  8849. {
  8850. Slot[SlotNb].GpkObject[hCert].Flags |= FLAG_KEYSET;
  8851. Slot[SlotNb].GpkObject[hCert].Field[POS_KEYSET].Len = 1;
  8852. Slot[SlotNb].GpkObject[hCert].Field[POS_KEYSET].pValue = (BYTE*)GMEM_Alloc(1);
  8853. Slot[SlotNb].GpkObject[hCert].Field[POS_KEYSET].pValue[0] = ProvCont[hProv].keysetID;
  8854. Slot[SlotNb].GpkObject[hCert].Field[POS_KEYSET].bReal = TRUE;
  8855. }
  8856. // TT: END
  8857. // if (IsNotNull(GpkObject[hCert].Field[POS_VALUE].pValue))
  8858. // {
  8859. // This will be free later with TmpCert
  8860. // }
  8861. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue =
  8862. (BYTE*)GMEM_Alloc(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len);
  8863. if (IsNull(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue))
  8864. {
  8865. Slot[SlotNb].GpkObject[hCert] = TmpCert;
  8866. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  8867. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8868. }
  8869. memcpy(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue,
  8870. pbData,
  8871. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len
  8872. );
  8873. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].bReal = TRUE;
  8874. /* Type = Type of associated key */
  8875. Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].Len =
  8876. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].Len;
  8877. // if (IsNotNull(GpkObject[hCert].Field[POS_KEY_TYPE].pValue))
  8878. // {
  8879. // This will be free later with TmpCert
  8880. // }
  8881. Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue =
  8882. (BYTE*)GMEM_Alloc(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].Len);
  8883. if (IsNull(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue))
  8884. {
  8885. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue);
  8886. Slot[SlotNb].GpkObject[hCert] = TmpCert;
  8887. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  8888. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8889. }
  8890. memcpy(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue,
  8891. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].pValue,
  8892. Slot[SlotNb].GpkObject[hKey].Field[POS_KEY_TYPE].Len
  8893. );
  8894. Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].bReal = TRUE;
  8895. /* Derive Label from certificate value for PKCS#11 compatibility */
  8896. if (MakeLabel( Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue,
  8897. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len,
  8898. 0, &wLabelLen ) == RV_SUCCESS)
  8899. {
  8900. pbLabel = (BYTE*)GMEM_Alloc(wLabelLen);
  8901. if (IsNull(pbLabel))
  8902. {
  8903. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue);
  8904. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue);
  8905. Slot[SlotNb].GpkObject[hCert] = TmpCert;
  8906. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  8907. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8908. }
  8909. MakeLabel(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue,
  8910. Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].Len,
  8911. pbLabel,
  8912. &wLabelLen
  8913. );
  8914. }
  8915. else
  8916. {
  8917. wLabelLen = 17;
  8918. pbLabel = (BYTE*)GMEM_Alloc(wLabelLen);
  8919. if (IsNull(pbLabel))
  8920. {
  8921. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue);
  8922. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue);
  8923. Slot[SlotNb].GpkObject[hCert] = TmpCert;
  8924. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  8925. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8926. }
  8927. memcpy(pbLabel, "User's Digital ID", 17);
  8928. }
  8929. Slot[SlotNb].GpkObject[hCert].Field[POS_LABEL].Len = wLabelLen;
  8930. // if (IsNotNull(GpkObject[hCert].Field[POS_LABEL].pValue))
  8931. // {
  8932. // This will be free later with TmpCert
  8933. // }
  8934. Slot[SlotNb].GpkObject[hCert].Field[POS_LABEL].pValue = (BYTE*)GMEM_Alloc(wLabelLen);
  8935. if (IsNull(Slot[SlotNb].GpkObject[hCert].Field[POS_LABEL].pValue))
  8936. {
  8937. GMEM_Free(pbLabel);
  8938. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue);
  8939. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue);
  8940. Slot[SlotNb].GpkObject[hCert] = TmpCert;
  8941. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  8942. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8943. }
  8944. memcpy(Slot[SlotNb].GpkObject[hCert].Field[POS_LABEL].pValue,
  8945. pbLabel,
  8946. wLabelLen
  8947. );
  8948. Slot[SlotNb].GpkObject[hCert].Field[POS_LABEL].bReal = TRUE;
  8949. TmpPrivKey = Slot[SlotNb].GpkObject[hPrivKey];
  8950. Slot[SlotNb].GpkObject[hPrivKey].Flags = Slot[SlotNb].GpkObject[hPrivKey].Flags | FLAG_LABEL;
  8951. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_LABEL].Len = wLabelLen;
  8952. // if (IsNotNull(GpkObject[hPrivKey].Field[POS_LABEL].pValue))
  8953. // {
  8954. // This will be free later with TmpPrivKey
  8955. // }
  8956. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_LABEL].pValue = (BYTE*)GMEM_Alloc(wLabelLen);
  8957. if (IsNull(Slot[SlotNb].GpkObject[hPrivKey].Field[POS_LABEL].pValue))
  8958. {
  8959. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_LABEL].pValue);
  8960. GMEM_Free(pbLabel);
  8961. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue);
  8962. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue);
  8963. Slot[SlotNb].GpkObject[hPrivKey] = TmpPrivKey;
  8964. Slot[SlotNb].GpkObject[hCert] = TmpCert;
  8965. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  8966. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  8967. }
  8968. memcpy(Slot[SlotNb].GpkObject[hPrivKey].Field[POS_LABEL].pValue,
  8969. pbLabel,
  8970. wLabelLen
  8971. );
  8972. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_LABEL].bReal = TRUE;
  8973. GMEM_Free(pbLabel);
  8974. /* Set automatic fields for PKCS#11 compatibility */
  8975. Slot[SlotNb].GpkObject[hCert].Field[POS_ID].Len = 0;
  8976. Slot[SlotNb].GpkObject[hCert].Field[POS_ID].bReal = FALSE;
  8977. Slot[SlotNb].GpkObject[hCert].Field[POS_SUBJECT].Len = 0;
  8978. Slot[SlotNb].GpkObject[hCert].Field[POS_SUBJECT].bReal = FALSE;
  8979. Slot[SlotNb].GpkObject[hCert].Field[POS_ISSUER].Len = 0;
  8980. Slot[SlotNb].GpkObject[hCert].Field[POS_ISSUER].bReal = FALSE;
  8981. Slot[SlotNb].GpkObject[hCert].Field[POS_SERIAL_NUMBER].Len = 0;
  8982. Slot[SlotNb].GpkObject[hCert].Field[POS_SERIAL_NUMBER].bReal = FALSE;
  8983. /* Set automatic fields of assocoiated key for PKCS#11 */
  8984. Slot[SlotNb].GpkObject[hPrivKey].Flags = Slot[SlotNb].GpkObject[hPrivKey].Flags | FLAG_SUBJECT;
  8985. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_SUBJECT].Len = 0;
  8986. Slot[SlotNb].GpkObject[hPrivKey].Field[POS_SUBJECT].bReal = FALSE;
  8987. CspFlags = ProvCont[hProv].Flags;
  8988. WriteCert = TRUE;
  8989. pbBuff1 = (BYTE*)GMEM_Alloc (MAX_GPK_PUBLIC);
  8990. if (IsNull(pbBuff1))
  8991. {
  8992. WriteCert = FALSE;
  8993. }
  8994. dwBuff1Len = MAX_GPK_PUBLIC;
  8995. if (WriteCert && (!prepare_write_gpk_objects (hProv, pbBuff1, &dwBuff1Len, FALSE)))
  8996. {
  8997. WriteCert = FALSE;
  8998. GMEM_Free (pbBuff1);
  8999. }
  9000. if (WriteCert)
  9001. {
  9002. pbBuff2 = (BYTE*)GMEM_Alloc (MAX_GPK_PRIVATE);
  9003. if (IsNull(pbBuff2))
  9004. {
  9005. WriteCert = FALSE;
  9006. GMEM_Free (pbBuff1);
  9007. }
  9008. }
  9009. dwBuff2Len = MAX_GPK_PRIVATE;
  9010. if (WriteCert && (!prepare_write_gpk_objects (hProv, pbBuff2, &dwBuff2Len, TRUE)))
  9011. {
  9012. WriteCert = FALSE;
  9013. GMEM_Free (pbBuff1);
  9014. GMEM_Free (pbBuff2);
  9015. }
  9016. if (!WriteCert)
  9017. {
  9018. // restore the info. the new certificate is too large
  9019. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_VALUE].pValue);
  9020. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_KEY_TYPE].pValue);
  9021. GMEM_Free(Slot[SlotNb].GpkObject[hCert].Field[POS_LABEL].pValue);
  9022. GMEM_Free(Slot[SlotNb].GpkObject[hPrivKey].Field[POS_LABEL].pValue);
  9023. Slot[SlotNb].GpkObject[hCert] = TmpCert;
  9024. Slot[SlotNb].GpkObject[hPrivKey] = TmpPrivKey;
  9025. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  9026. RETURN (CRYPT_FAILED, SCARD_E_WRITE_TOO_MANY);
  9027. }
  9028. if (IsNotNull(TmpCert.Field[POS_VALUE].pValue))
  9029. {
  9030. GMEM_Free(TmpCert.Field[POS_VALUE].pValue);
  9031. }
  9032. if (IsNotNull(TmpCert.Field[POS_KEY_TYPE].pValue))
  9033. {
  9034. GMEM_Free(TmpCert.Field[POS_KEY_TYPE].pValue);
  9035. }
  9036. if (IsNotNull(TmpCert.Field[POS_LABEL].pValue))
  9037. {
  9038. GMEM_Free(TmpCert.Field[POS_LABEL].pValue);
  9039. }
  9040. if (IsNotNull(TmpPrivKey.Field[POS_LABEL].pValue))
  9041. {
  9042. GMEM_Free(TmpPrivKey.Field[POS_LABEL].pValue);
  9043. }
  9044. if (!write_gpk_objects(hProv, pbBuff1, dwBuff1Len, FALSE, FALSE))
  9045. {
  9046. lRet = GetLastError();
  9047. GMEM_Free (pbBuff1);
  9048. GMEM_Free (pbBuff2);
  9049. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  9050. RETURN (CRYPT_FAILED, lRet);
  9051. }
  9052. if (!write_gpk_objects(hProv, pbBuff2, dwBuff2Len, FALSE, TRUE))
  9053. {
  9054. lRet = GetLastError();
  9055. Select_MF(hProv);
  9056. GMEM_Free (pbBuff1);
  9057. GMEM_Free (pbBuff2);
  9058. --Slot[SlotNb].NbGpkObject; // Bug #1675/1676
  9059. RETURN (CRYPT_FAILED, lRet);
  9060. }
  9061. GMEM_Free (pbBuff1);
  9062. GMEM_Free (pbBuff2);
  9063. break;
  9064. default:
  9065. RETURN (CRYPT_FAILED, NTE_BAD_TYPE);
  9066. }
  9067. }
  9068. /* Session Key */
  9069. else if (key_exist(hKey-MAX_GPK_OBJ, hProv))
  9070. {
  9071. /* Set Key Parameter in Microsoft RSA Base Module */
  9072. CryptResp = CryptSetKeyParam(TmpObject[hKey-MAX_GPK_OBJ].hKeyBase,
  9073. dwParam,
  9074. pbData,
  9075. dwFlags
  9076. );
  9077. if (!CryptResp)
  9078. return CRYPT_FAILED;
  9079. }
  9080. /* Bad Key */
  9081. else
  9082. {
  9083. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9084. }
  9085. RETURN (CRYPT_SUCCEED, 0);
  9086. }
  9087. /*******************************************************************************
  9088. Data Encryption Functions
  9089. *******************************************************************************/
  9090. /*
  9091. - CPDecrypt
  9092. -
  9093. * Purpose:
  9094. * Decrypt data
  9095. *
  9096. *
  9097. * Parameters:
  9098. * IN hProv - Handle to the CSP user
  9099. * IN hKey - Handle to the key
  9100. * IN hHash - Optional handle to a hash
  9101. * IN Final - Boolean indicating if this is the final
  9102. * block of ciphertext
  9103. * IN dwFlags - Flags values
  9104. * IN OUT pbData - Data to be decrypted
  9105. * IN OUT pdwDataLen - Pointer to the length of the data to be
  9106. * decrypted
  9107. *
  9108. * Returns:
  9109. */
  9110. BOOL WINAPI MyCPDecrypt(IN HCRYPTPROV hProv,
  9111. IN HCRYPTKEY hKey,
  9112. IN HCRYPTHASH hHash,
  9113. IN BOOL Final,
  9114. IN DWORD dwFlags,
  9115. IN OUT BYTE *pbData,
  9116. IN OUT DWORD *pdwDataLen
  9117. )
  9118. {
  9119. BOOL CryptResp;
  9120. HCRYPTKEY hDecKey;
  9121. if (!Context_exist(hProv))
  9122. {
  9123. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9124. }
  9125. if ((hKey <= MAX_GPK_OBJ) || (!key_exist(hKey-MAX_GPK_OBJ, hProv)))
  9126. {
  9127. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9128. }
  9129. else
  9130. {
  9131. hDecKey = TmpObject[hKey-MAX_GPK_OBJ].hKeyBase;
  9132. }
  9133. if (!hash_exist(hHash, hProv))
  9134. {
  9135. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9136. }
  9137. CryptResp = CryptDecrypt(hDecKey,
  9138. hHashGpk[hHash].hHashBase,
  9139. Final,
  9140. dwFlags,
  9141. pbData,
  9142. pdwDataLen
  9143. );
  9144. if (!CryptResp)
  9145. return CRYPT_FAILED;
  9146. RETURN (CRYPT_SUCCEED, 0);
  9147. }
  9148. /*
  9149. - CPEncrypt
  9150. -
  9151. * Purpose:
  9152. * Encrypt data
  9153. *
  9154. *
  9155. * Parameters:
  9156. * IN hProv - Handle to the CSP user
  9157. * IN hKey - Handle to the key
  9158. * IN hHash - Optional handle to a hash
  9159. * IN Final - Boolean indicating if this is the final
  9160. * block of plaintext
  9161. * IN dwFlags - Flags values
  9162. * IN OUT pbData - Data to be encrypted
  9163. * IN OUT pdwDataLen - Pointer to the length of the data to be
  9164. * encrypted
  9165. * IN dwBufLen - Size of Data buffer
  9166. *
  9167. * Returns:
  9168. */
  9169. BOOL WINAPI MyCPEncrypt(IN HCRYPTPROV hProv,
  9170. IN HCRYPTKEY hKey,
  9171. IN HCRYPTHASH hHash,
  9172. IN BOOL Final,
  9173. IN DWORD dwFlags,
  9174. IN OUT BYTE *pbData,
  9175. IN OUT DWORD *pdwDataLen,
  9176. IN DWORD dwBufLen
  9177. )
  9178. {
  9179. BOOL CryptResp;
  9180. HCRYPTKEY hEncKey;
  9181. if (!Context_exist(hProv))
  9182. {
  9183. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9184. }
  9185. if ((hKey <= MAX_GPK_OBJ) || (!key_exist(hKey-MAX_GPK_OBJ, hProv)))
  9186. {
  9187. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9188. }
  9189. else
  9190. {
  9191. hEncKey = TmpObject[hKey-MAX_GPK_OBJ].hKeyBase;
  9192. }
  9193. if (!hash_exist(hHash, hProv))
  9194. {
  9195. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9196. }
  9197. CryptResp = CryptEncrypt(hEncKey,
  9198. hHashGpk[hHash].hHashBase,
  9199. Final,
  9200. dwFlags,
  9201. pbData,
  9202. pdwDataLen,
  9203. dwBufLen
  9204. );
  9205. if (!CryptResp)
  9206. return CRYPT_FAILED;
  9207. RETURN (CRYPT_SUCCEED, 0);
  9208. }
  9209. /*******************************************************************************
  9210. Hashing and Digital Signature Functions
  9211. *******************************************************************************/
  9212. /*
  9213. - MyCPCreateHash
  9214. -
  9215. * Purpose:
  9216. * initate the hashing of a stream of data
  9217. *
  9218. *
  9219. * Parameters:
  9220. * IN hUID - Handle to the user identifcation
  9221. * IN Algid - Algorithm identifier of the hash algorithm
  9222. * to be used
  9223. * IN hKey - Optional key for MAC algorithms
  9224. * IN dwFlags - Flags values
  9225. * OUT pHash - Handle to hash object
  9226. *
  9227. * Returns:
  9228. */
  9229. BOOL WINAPI MyCPCreateHash(IN HCRYPTPROV hProv,
  9230. IN ALG_ID Algid,
  9231. IN HCRYPTKEY hKey,
  9232. IN DWORD dwFlags,
  9233. OUT HCRYPTHASH *phHash
  9234. )
  9235. {
  9236. BOOL CryptResp;
  9237. HCRYPTKEY hKeyMac;
  9238. if (!Context_exist(hProv))
  9239. {
  9240. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9241. }
  9242. *phHash = find_hash_free();
  9243. if ((*phHash) == 0)
  9244. {
  9245. RETURN (CRYPT_FAILED, NTE_NO_MEMORY);
  9246. }
  9247. hKeyMac = 0;
  9248. if ((Algid == CALG_MAC) || (Algid == CALG_HMAC) )
  9249. {
  9250. if ((hKey <= MAX_GPK_OBJ) || (!key_exist(hKey - MAX_GPK_OBJ, hProv)))
  9251. {
  9252. *phHash = 0;
  9253. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9254. }
  9255. else
  9256. {
  9257. hKeyMac = TmpObject[hKey-MAX_GPK_OBJ].hKeyBase;
  9258. }
  9259. }
  9260. CryptResp = CryptCreateHash(hProvBase,
  9261. Algid,
  9262. hKeyMac,
  9263. dwFlags,
  9264. &(hHashGpk[*phHash].hHashBase)
  9265. );
  9266. if (!CryptResp)
  9267. {
  9268. *phHash = 0;
  9269. return CRYPT_FAILED;
  9270. }
  9271. hHashGpk[*phHash].hProv = hProv;
  9272. RETURN (CRYPT_SUCCEED, 0);
  9273. }
  9274. /*
  9275. - MyCPDestroyHash
  9276. -
  9277. * Purpose:
  9278. * Destroy the hash object
  9279. *
  9280. *
  9281. * Parameters:
  9282. * IN hProv - Handle to the user identifcation
  9283. * IN hHash - Handle to hash object
  9284. *
  9285. * Returns:
  9286. */
  9287. BOOL WINAPI MyCPDestroyHash(IN HCRYPTPROV hProv,
  9288. IN HCRYPTHASH hHash
  9289. )
  9290. {
  9291. BOOL CryptResp;
  9292. if (!Context_exist(hProv))
  9293. {
  9294. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9295. }
  9296. if (!hash_exist(hHash, hProv))
  9297. {
  9298. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9299. }
  9300. /* Destroy Microsoft RSA Base Hash */
  9301. CryptResp = CryptDestroyHash(hHashGpk[hHash].hHashBase);
  9302. if (!CryptResp)
  9303. return CRYPT_FAILED;
  9304. hHashGpk[hHash].hHashBase = 0;
  9305. hHashGpk[hHash].hProv = 0;
  9306. RETURN (CRYPT_SUCCEED, 0);
  9307. }
  9308. /*
  9309. - MyCPGetHashParam
  9310. -
  9311. * Purpose:
  9312. * Allows applications to get various aspects of the
  9313. * operations of a hash
  9314. *
  9315. * Parameters:
  9316. * IN hProv - Handle to a CSP
  9317. * IN hHash - Handle to a hash
  9318. * IN dwParam - Parameter number
  9319. * IN pbData - Pointer to data
  9320. * IN pdwDataLen - Length of parameter data
  9321. * IN dwFlags - Flags values
  9322. *
  9323. * Returns:
  9324. */
  9325. BOOL WINAPI MyCPGetHashParam(IN HCRYPTPROV hProv,
  9326. IN HCRYPTHASH hHash,
  9327. IN DWORD dwParam,
  9328. IN BYTE *pbData,
  9329. IN DWORD *pdwDataLen,
  9330. IN DWORD dwFlags
  9331. )
  9332. {
  9333. BOOL CryptResp;
  9334. if (!Context_exist(hProv))
  9335. {
  9336. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9337. }
  9338. if (!hash_exist(hHash, hProv))
  9339. {
  9340. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9341. }
  9342. CryptResp = CryptGetHashParam(hHashGpk[hHash].hHashBase,
  9343. dwParam,
  9344. pbData,
  9345. pdwDataLen,
  9346. dwFlags
  9347. );
  9348. if (!CryptResp)
  9349. return CRYPT_FAILED;
  9350. RETURN (CRYPT_SUCCEED, 0);
  9351. }
  9352. /*
  9353. - MyCPHashData
  9354. -
  9355. * Purpose:
  9356. * Compute the cryptograghic hash on a stream of data
  9357. *
  9358. *
  9359. * Parameters:
  9360. * IN hProv - Handle to the user identifcation
  9361. * IN hHash - Handle to hash object
  9362. * IN pbData - Pointer to data to be hashed
  9363. * IN dwDataLen - Length of the data to be hashed
  9364. * IN dwFlags - Flags values
  9365. * IN pdwMaxLen - Maximum length of the data stream the CSP
  9366. * module may handle
  9367. *
  9368. * Returns:
  9369. */
  9370. BOOL WINAPI MyCPHashData(IN HCRYPTPROV hProv,
  9371. IN HCRYPTHASH hHash,
  9372. IN CONST BYTE *pbData,
  9373. IN DWORD dwDataLen,
  9374. IN DWORD dwFlags
  9375. )
  9376. {
  9377. BOOL CryptResp;
  9378. if (!Context_exist(hProv))
  9379. {
  9380. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9381. }
  9382. if (!hash_exist(hHash, hProv))
  9383. {
  9384. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9385. }
  9386. /* Hash Data with Microsoft RSA Base */
  9387. CryptResp = CryptHashData(hHashGpk[hHash].hHashBase,
  9388. pbData,
  9389. dwDataLen,
  9390. dwFlags);
  9391. if (!CryptResp)
  9392. return CRYPT_FAILED;
  9393. RETURN (CRYPT_SUCCEED, 0);
  9394. }
  9395. /*
  9396. - CPHashSessionKey
  9397. -
  9398. * Purpose:
  9399. * Compute the cryptograghic hash on a key object.
  9400. *
  9401. *
  9402. * Parameters:
  9403. * IN hProv - Handle to the user identifcation
  9404. * IN hHash - Handle to hash object
  9405. * IN hKey - Handle to a key object
  9406. * IN dwFlags - Flags values
  9407. *
  9408. * Returns:
  9409. * CRYPT_FAILED
  9410. * CRYPT_SUCCEED
  9411. */
  9412. BOOL WINAPI MyCPHashSessionKey(IN HCRYPTPROV hProv,
  9413. IN HCRYPTHASH hHash,
  9414. IN HCRYPTKEY hKey,
  9415. IN DWORD dwFlags
  9416. )
  9417. {
  9418. BOOL CryptResp;
  9419. HCRYPTKEY hTmpKey;
  9420. if (!Context_exist(hProv))
  9421. {
  9422. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9423. }
  9424. if (!hash_exist(hHash, hProv))
  9425. {
  9426. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9427. }
  9428. if (hKey <= MAX_GPK_OBJ)
  9429. {
  9430. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9431. }
  9432. hTmpKey = hKey - MAX_GPK_OBJ;
  9433. if (!key_exist(hTmpKey, hProv))
  9434. {
  9435. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9436. }
  9437. /* Hash Data with Microsoft RSA Base */
  9438. CryptResp = CryptHashSessionKey(hHashGpk[hHash].hHashBase,
  9439. TmpObject[hTmpKey].hKeyBase,
  9440. dwFlags
  9441. );
  9442. if (!CryptResp)
  9443. return CRYPT_FAILED;
  9444. RETURN (CRYPT_SUCCEED, 0);
  9445. }
  9446. /*
  9447. - MyCPSetHashParam
  9448. -
  9449. * Purpose:
  9450. * Allows applications to customize various aspects of the
  9451. * operations of a hash
  9452. *
  9453. * Parameters:
  9454. * IN hProv - Handle to a CSP
  9455. * IN hHash - Handle to a hash
  9456. * IN dwParam - Parameter number
  9457. * IN pbData - Pointer to data
  9458. * IN dwFlags - Flags values
  9459. *
  9460. * Returns:
  9461. */
  9462. BOOL WINAPI MyCPSetHashParam(IN HCRYPTPROV hProv,
  9463. IN HCRYPTHASH hHash,
  9464. IN DWORD dwParam,
  9465. IN CONST BYTE *pbData,
  9466. IN DWORD dwFlags
  9467. )
  9468. {
  9469. BOOL CryptResp;
  9470. if (!Context_exist(hProv))
  9471. {
  9472. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9473. }
  9474. if (!hash_exist(hHash, hProv))
  9475. {
  9476. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9477. }
  9478. /* Set Hash parameter with Microsoft RSA Base */
  9479. CryptResp = CryptSetHashParam(hHashGpk[hHash].hHashBase,
  9480. dwParam,
  9481. pbData,
  9482. dwFlags
  9483. );
  9484. if (!CryptResp)
  9485. return CRYPT_FAILED;
  9486. RETURN (CRYPT_SUCCEED, 0);
  9487. }
  9488. /*
  9489. - MyCPSignHash
  9490. -
  9491. * Purpose:
  9492. * Create a digital signature from a hash
  9493. *
  9494. *
  9495. * Parameters:
  9496. * IN hProv - Handle to the user identifcation
  9497. * IN hHash - Handle to hash object
  9498. * IN Algid - Algorithm identifier of the signature
  9499. * algorithm to be used
  9500. * IN sDescription - Description of data to be signed
  9501. * IN dwFlags - Flags values
  9502. * OUT pbSignture - Pointer to signature data
  9503. * OUT dwHashLen - Pointer to the len of the signature data
  9504. *
  9505. * Returns:
  9506. */
  9507. BOOL WINAPI MyCPSignHash(IN HCRYPTPROV hProv,
  9508. IN HCRYPTHASH hHash,
  9509. IN DWORD dwKeySpec,
  9510. IN LPCWSTR sDescription,
  9511. IN DWORD dwFlags,
  9512. OUT BYTE *pbSignature,
  9513. OUT DWORD *pdwSigLen
  9514. )
  9515. {
  9516. DWORD lRet;
  9517. DWORD SlotNb;
  9518. BOOL CryptResp;
  9519. DWORD dwLen;
  9520. BYTE GpkKeySize;
  9521. BYTE HashMode;
  9522. HCRYPTKEY hKey;
  9523. BYTE TmpHashValue[64];
  9524. // + NK 07.02.2001
  9525. DWORD dwPinLength;
  9526. // -NK
  9527. if (!Context_exist(hProv))
  9528. {
  9529. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9530. }
  9531. SlotNb = ProvCont[hProv].Slot;
  9532. if (dwFlags != 0)
  9533. {
  9534. RETURN (CRYPT_FAILED, NTE_BAD_FLAGS);
  9535. }
  9536. /* sDescription is not supported */
  9537. if (IsNotNullStr(sDescription))
  9538. {
  9539. RETURN(CRYPT_FAILED, ERROR_INVALID_PARAMETER);
  9540. }
  9541. if (!hash_exist(hHash, hProv))
  9542. {
  9543. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9544. }
  9545. HashMode = GPKHashMode (hHash);
  9546. if (HashMode == 0x00)
  9547. {
  9548. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9549. }
  9550. /* Select Key */
  9551. CryptResp = MyCPGetUserKey(hProv, dwKeySpec, &hKey);
  9552. if (!CryptResp)
  9553. return CRYPT_FAILED;
  9554. if (!(Slot[SlotNb].GpkObject[hKey].Flags & FLAG_SIGN))
  9555. {
  9556. *pdwSigLen = 0;
  9557. RETURN(CRYPT_FAILED, NTE_BAD_KEY);
  9558. }
  9559. GpkKeySize = Slot[SlotNb].GpkPubKeys[Slot[SlotNb].GpkObject[hKey].FileId - GPK_FIRST_KEY].KeySize;
  9560. if (GpkKeySize == 0)
  9561. {
  9562. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9563. }
  9564. if (IsNull(pbSignature) || (0 == *pdwSigLen))
  9565. {
  9566. *pdwSigLen = GpkKeySize;
  9567. RETURN (CRYPT_SUCCEED, 0 );
  9568. }
  9569. if (GpkKeySize > *pdwSigLen)
  9570. {
  9571. *pdwSigLen = GpkKeySize;
  9572. RETURN (CRYPT_FAILED, ERROR_MORE_DATA);
  9573. }
  9574. // + NK 06.02.2001
  9575. // if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (IsNullStr(Slot[SlotNb].GetPin())))
  9576. lRet = Query_MSPinCache( Slot[SlotNb].hPinCacheHandle,
  9577. NULL,
  9578. &dwPinLength );
  9579. if ( (lRet != ERROR_SUCCESS) && (lRet != ERROR_EMPTY) )
  9580. RETURN (CRYPT_FAILED, lRet);
  9581. if ((ProvCont[hProv].Flags & CRYPT_SILENT) && (lRet == ERROR_EMPTY))
  9582. // - NK
  9583. {
  9584. RETURN (CRYPT_FAILED, NTE_SILENT_CONTEXT);
  9585. }
  9586. // Verify the PINs
  9587. if (!PIN_Validation(hProv)) {
  9588. return CRYPT_FAILED;
  9589. }
  9590. if (!VerifyDivPIN(hProv, TRUE))
  9591. return CRYPT_FAILED;
  9592. /* Card Select Context for RSA with specified Hash type */
  9593. bSendBuffer[0] = 0x80; //CLA
  9594. bSendBuffer[1] = 0xA6; //INS
  9595. bSendBuffer[2] = Slot[SlotNb].GpkObject[hKey].FileId; //P1
  9596. bSendBuffer[3] = HashMode; //P2
  9597. cbSendLength = 4;
  9598. cbRecvLength = sizeof(bRecvBuffer);
  9599. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  9600. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  9601. if (SCARDPROBLEM(lRet,0x9000,0x00))
  9602. {
  9603. RETURN (CRYPT_FAILED, NTE_BAD_KEY_STATE);
  9604. }
  9605. /* Force Calculation of Hash Value */
  9606. dwLen = sizeof(TmpHashValue);
  9607. CryptResp = CryptGetHashParam(hHashGpk[hHash].hHashBase,
  9608. HP_HASHVAL,
  9609. TmpHashValue,
  9610. &dwLen,
  9611. 0);
  9612. if (!CryptResp)
  9613. return CRYPT_FAILED;
  9614. r_memcpy(&bSendBuffer[5], TmpHashValue, dwLen);
  9615. /* Send hash Data with only one command */
  9616. bSendBuffer[0] = 0x80; //CLA
  9617. bSendBuffer[1] = 0xEA; //INS
  9618. bSendBuffer[2] = 0x00; //P1
  9619. bSendBuffer[3] = 0x00; //P2
  9620. bSendBuffer[4] = (BYTE)dwLen; //Li
  9621. cbSendLength = dwLen + 5;
  9622. cbRecvLength = sizeof(bRecvBuffer);
  9623. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  9624. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  9625. if (SCARDPROBLEM(lRet,0x9000,0x00))
  9626. {
  9627. RETURN (CRYPT_FAILED, NTE_BAD_SIGNATURE);
  9628. }
  9629. /* Get signature */
  9630. bSendBuffer[0] = 0x80; //CLA
  9631. bSendBuffer[1] = 0x86; //INS
  9632. bSendBuffer[2] = 0x00; //P1
  9633. bSendBuffer[3] = 0x00; //P2
  9634. bSendBuffer[4] = GpkKeySize; //Lo
  9635. cbSendLength = 5;
  9636. cbRecvLength = sizeof(bRecvBuffer);
  9637. lRet = SCardTransmit( ProvCont[hProv].hCard, SCARD_PCI_T0, bSendBuffer,
  9638. cbSendLength, 0, bRecvBuffer, &cbRecvLength );
  9639. if (SCARDPROBLEM(lRet,0x9000,bSendBuffer[4]))
  9640. {
  9641. RETURN (CRYPT_FAILED, NTE_BAD_SIGNATURE);
  9642. }
  9643. cbRecvLength = cbRecvLength - 2;
  9644. *pdwSigLen = cbRecvLength;
  9645. memcpy(pbSignature, bRecvBuffer, cbRecvLength);
  9646. RETURN (CRYPT_SUCCEED, 0);
  9647. }
  9648. /*
  9649. - MyCPVerifySignature
  9650. -
  9651. * Purpose:
  9652. * Used to verify a signature against a hash object
  9653. *
  9654. *
  9655. * Parameters:
  9656. * IN hProv - Handle to the user identifcation
  9657. * IN hHash - Handle to hash object
  9658. * IN pbSignture - Pointer to signature data
  9659. * IN dwSigLen - Length of the signature data
  9660. * IN hPubKey - Handle to the public key for verifying
  9661. * the signature
  9662. * IN Algid - Algorithm identifier of the signature
  9663. * algorithm to be used
  9664. * IN sDescription - Description of data to be signed
  9665. * IN dwFlags - Flags values
  9666. *
  9667. * Returns:
  9668. */
  9669. BOOL WINAPI MyCPVerifySignature(IN HCRYPTPROV hProv,
  9670. IN HCRYPTHASH hHash,
  9671. IN CONST BYTE *pbSignature,
  9672. IN DWORD dwSigLen,
  9673. IN HCRYPTKEY hPubKey,
  9674. IN LPCWSTR sDescription,
  9675. IN DWORD dwFlags
  9676. )
  9677. {
  9678. DWORD SlotNb;
  9679. BOOL CryptResp;
  9680. HCRYPTKEY hTmpKey;
  9681. if (!Context_exist(hProv))
  9682. {
  9683. RETURN (CRYPT_FAILED, NTE_BAD_UID);
  9684. }
  9685. SlotNb = ProvCont[hProv].Slot;
  9686. if (!hash_exist(hHash, hProv))
  9687. {
  9688. RETURN (CRYPT_FAILED, NTE_BAD_HASH);
  9689. }
  9690. if (hPubKey <= MAX_GPK_OBJ)
  9691. {
  9692. if ((ProvCont[hProv].Flags & CRYPT_VERIFYCONTEXT) &&
  9693. (ProvCont[hProv].isContNameNullBlank))
  9694. {
  9695. RETURN (CRYPT_FAILED, NTE_PERM);
  9696. }
  9697. if (( !Slot[SlotNb].GpkObject[hPubKey].IsCreated) ||
  9698. ( (Slot[SlotNb].GpkObject[hPubKey].Tag != TAG_RSA_PUBLIC ) &&
  9699. (Slot[SlotNb].GpkObject[hPubKey].Tag != TAG_RSA_PRIVATE) )
  9700. )
  9701. {
  9702. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9703. }
  9704. HCRYPTKEY hVerKey;
  9705. if ((Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].Len == 0) ||
  9706. ((Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].pValue[0] != AT_KEYEXCHANGE) &&
  9707. (Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].pValue[0] != AT_SIGNATURE)))
  9708. {
  9709. RETURN(CRYPT_FAILED, NTE_BAD_KEY);
  9710. }
  9711. if (Slot[SlotNb].GpkObject[hPubKey].Field[POS_KEY_TYPE].pValue[0] == AT_KEYEXCHANGE)
  9712. {
  9713. hVerKey = ProvCont[hProv].hRSAKEK;
  9714. }
  9715. else
  9716. {
  9717. hVerKey = ProvCont[hProv].hRSASign;
  9718. }
  9719. CryptResp = CryptVerifySignature(hHashGpk[hHash].hHashBase,
  9720. pbSignature,
  9721. dwSigLen,
  9722. hVerKey, //Slot[SlotNb].GpkObject[hPubKey].hKeyBase,
  9723. (LPCTSTR)sDescription,
  9724. dwFlags);
  9725. if (!CryptResp)
  9726. return CRYPT_FAILED;
  9727. }
  9728. else
  9729. {
  9730. hTmpKey = hPubKey - MAX_GPK_OBJ;
  9731. if (!key_exist(hTmpKey, hProv))
  9732. {
  9733. RETURN (CRYPT_FAILED, NTE_BAD_KEY);
  9734. }
  9735. /* Verify Signature with Microsoft RSA Base Module */
  9736. CryptResp = CryptVerifySignature(hHashGpk[hHash].hHashBase,
  9737. pbSignature,
  9738. dwSigLen,
  9739. TmpObject[hTmpKey].hKeyBase,
  9740. (LPCTSTR)sDescription,
  9741. dwFlags);
  9742. if (!CryptResp)
  9743. return CRYPT_FAILED;
  9744. }
  9745. RETURN (CRYPT_SUCCEED, 0);
  9746. }