Leaked source code of windows server 2003
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.

1662 lines
41 KiB

  1. // wfscproto - Prototyping code for the Windows for Smart Card Card Module
  2. //
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <crypt.h>
  7. #include <windows.h>
  8. #include "cardmod.h"
  9. #include "wpscproxy.h"
  10. #include <malloc.h>
  11. #include <stdio.h>
  12. #include <rsa.h>
  13. #include <stdlib.h>
  14. #include "carddbg.h"
  15. //
  16. // Need to define the dsys debug symbols since we're linking directly to the
  17. // proxy lib which requires them.
  18. //
  19. DEFINE_DEBUG2(Cardmod)
  20. #define SC_FAILED(X) (0 != (X))
  21. #define SCW_CALL(X) { \
  22. if ((status = X) != SCW_S_OK) { \
  23. dwError = (DWORD) status; \
  24. goto Ret; \
  25. }}
  26. //
  27. // Using Crypto API, the RSA public exponent is always 0x10001, which can
  28. // be represented in three bytes.
  29. //
  30. #define cbCAPI_PUBLIC_EXPONENT 3
  31. #define wszTEST_CARD_NAME L"SCWUnnamed"
  32. #define wszDEFAULT_ACL_FILE L"/s/a/uw"
  33. #define wszKEY_ACL_FILE L"/s/a/ux"
  34. #define wszNEW_FILE L"/dan"
  35. #define wszRSA_KEY_FILE L"/CK0"
  36. //
  37. // Card module applet instruction codes
  38. //
  39. #define PIN_CHANGE_CLA 0x00
  40. #define PIN_CHANGE_INS 0x52
  41. #define PIN_CHANGE_P1 0x00
  42. #define PIN_CHANGE_P2 0x00
  43. #define PIN_UNBLOCK_CLA 0x00
  44. #define PIN_UNBLOCK_INS 0x52
  45. #define PIN_UNBLOCK_P1 0x01
  46. #define PIN_UNBLOCK_P2 0x00
  47. #define PIN_RETRY_COUNTER_CLA 0x00
  48. #define PIN_RETRY_COUNTER_INS 0x50
  49. #define PIN_RETRY_COUNTER_P1 0x00
  50. #define PIN_RETRY_COUNTER_P2 0x00
  51. SCARDHANDLE g_hWfscHandle = 0;
  52. #define ScwAuthenticateName(X, Y, Z) (hScwAuthenticateName(g_hWfscHandle, X, Y, Z))
  53. #define ScwDeauthenticateName(X) (hScwDeauthenticateName(g_hWfscHandle, X))
  54. #define ScwCreateFile(X, Y, Z) (hScwCreateFile(g_hWfscHandle, X, Y, Z))
  55. #define ScwCloseFile(X) (hScwCloseFile(g_hWfscHandle, X))
  56. #define ScwWriteFile(X, Y, Z, A) (hScwWriteFile(g_hWfscHandle, X, Y, Z, A))
  57. #define ScwWriteFile32(X, Y, Z, A) (hScwWriteFile32(g_hWfscHandle, X, Y, Z, A))
  58. #define ScwEnumFile(X, Y, Z, A) (hScwEnumFile(g_hWfscHandle, X, Y, Z, A))
  59. #define ScwGetFileLength(X, Y) (hScwGetFileLength(g_hWfscHandle, X, Y))
  60. #define ScwReadFile32(X, Y, Z, A) (hScwReadFile32(g_hWfscHandle, X, Y, Z, A))
  61. #define ScwAttachToCard(X, Y) (hScwAttachToCard(X, Y, &g_hWfscHandle))
  62. #define ScwCryptoInitialize(X, Y) (hScwCryptoInitialize(g_hWfscHandle, X, Y))
  63. #define ScwCryptoAction(X, Y, Z, A) (hScwCryptoAction(g_hWfscHandle, X, Y, Z, A))
  64. #define ScwDetachFromCard() (hScwDetachFromCard(g_hWfscHandle))
  65. #define ScwDeleteFile(X) (hScwDeleteFile(g_hWfscHandle, X))
  66. #define ScwExecute(A, B, C, D, E, F) (hScwExecute(g_hWfscHandle, A, B, C, D, E, F))
  67. #define ScwSetFilePointer(A, B, C) (hScwSetFilePointer(g_hWfscHandle, A, B, C))
  68. //
  69. // Required for linking to rsa32
  70. //
  71. unsigned int
  72. RSA32API
  73. NewGenRandom(
  74. IN OUT unsigned char **ppbRandSeed /*unused*/,
  75. IN unsigned long *pcbRandSeed /*unused*/,
  76. IN OUT unsigned char *pbBuffer,
  77. IN unsigned long dwLength
  78. )
  79. {
  80. return (unsigned int)RtlGenRandom( pbBuffer, dwLength );
  81. }
  82. void MyRngFunc(
  83. IN PVOID pvInfo,
  84. IN OUT unsigned char **ppbRandSeed /*unused*/,
  85. IN unsigned long *pcbRandSeed /*unused*/,
  86. IN OUT unsigned char *pbBuffer,
  87. IN unsigned long dwLength)
  88. {
  89. NewGenRandom(ppbRandSeed, pcbRandSeed, pbBuffer, dwLength);
  90. }
  91. typedef struct _Principal
  92. {
  93. BYTE rgbPin[4];
  94. LPWSTR pwszUser;
  95. } Principal;
  96. Principal Principals [] = {
  97. { { 0x00, 0x00, 0x00, 0x00 }, L"Everyone" },
  98. { { 0x00, 0x00, 0x00, 0x00 }, L"user" },
  99. { { 0x01, 0x02, 0x03, 0x04 }, L"admin" }
  100. };
  101. #define PRINCIPAL_USER 1
  102. #define PRINCIPAL_ADMIN 2
  103. BYTE rgbUserNewPin [] = {
  104. 0x01, 0x01, 0x01, 0x01
  105. };
  106. DWORD Authenticate(
  107. DWORD dwId)
  108. {
  109. return (DWORD) ScwAuthenticateName(
  110. Principals[dwId].pwszUser,
  111. Principals[dwId].rgbPin,
  112. sizeof(Principals[dwId].rgbPin));
  113. }
  114. DWORD Deauthenticate(
  115. DWORD dwId)
  116. {
  117. return (DWORD) ScwDeauthenticateName(Principals[dwId].pwszUser);
  118. }
  119. #define CROW 16
  120. void PrintBytes(LPWSTR pwszHdr, BYTE *pb, DWORD cbSize)
  121. {
  122. ULONG cb, i;
  123. if (cbSize == 0) {
  124. wprintf(L"%s NO Value Bytes\n", pwszHdr);
  125. return;
  126. }
  127. if (NULL != pwszHdr)
  128. wprintf(L"%s\n", pwszHdr);
  129. while (cbSize > 0)
  130. {
  131. wprintf(L" ");
  132. cb = min(CROW, cbSize);
  133. cbSize -= cb;
  134. for (i = 0; i<cb; i++)
  135. wprintf(L" %02X", pb[i]);
  136. for (i = cb; i<CROW; i++)
  137. wprintf(L" ");
  138. wprintf(L" '");
  139. for (i = 0; i<cb; i++)
  140. if (pb[i] >= 0x20 && pb[i] <= 0x7f)
  141. wprintf(L"%c", pb[i]);
  142. else
  143. wprintf(L".");
  144. pb += cb;
  145. wprintf(L"'\n");
  146. }
  147. }
  148. void I_DebugPrintBytes(LPWSTR pwszHdr, BYTE *pb, DWORD cbSize)
  149. {
  150. PrintBytes(pwszHdr, pb, cbSize);
  151. }
  152. DWORD WriteKeyToCard(
  153. IN LPWSTR pwszKeyFile,
  154. IN LPWSTR pwszAclFile,
  155. IN PBYTE pbKey,
  156. IN DWORD cbKey)
  157. {
  158. HFILE hFile = 0;
  159. DWORD cbCheck = 0;
  160. SCODE status = 0;
  161. DWORD dwError = 0;
  162. PrintBytes(L"Key file to write to card", pbKey, cbKey);
  163. //
  164. // Write the private key to the card
  165. //
  166. status = Authenticate(PRINCIPAL_USER);
  167. if (SCW_S_OK != status)
  168. {
  169. dwError = (DWORD) status;
  170. goto Ret;
  171. }
  172. // Delete the key if it already exists
  173. status = ScwCreateFile(pwszKeyFile, NULL, &hFile);
  174. if (SCW_S_OK == status)
  175. {
  176. SCW_CALL(ScwCloseFile(hFile));
  177. hFile = 0;
  178. SCW_CALL(ScwDeleteFile(pwszKeyFile));
  179. }
  180. SCW_CALL(ScwCreateFile(pwszKeyFile, pwszAclFile, &hFile));
  181. SCW_CALL(ScwWriteFile32(hFile, pbKey, cbKey, &cbCheck));
  182. if (cbKey != cbCheck)
  183. {
  184. printf(
  185. "ERROR - expected to write %d key bytes, but only wrote %d\n",
  186. cbKey,
  187. cbCheck);
  188. dwError = -1;
  189. goto Ret;
  190. }
  191. Ret:
  192. if (hFile)
  193. ScwCloseFile(hFile);
  194. return dwError;
  195. }
  196. //
  197. // Generates a new RSA key using rsa32 (BSafe) primitives, then writes
  198. // the key to the card in the card's key format.
  199. //
  200. DWORD GenKeyOnCardWithRsa32(
  201. IN LPWSTR pwszKeyFile,
  202. IN LPWSTR pwszAclFile,
  203. IN DWORD cKeySizeBits)
  204. {
  205. DWORD dwError = ERROR_SUCCESS;
  206. DWORD cbPublic = 0;
  207. DWORD cbPrivate = 0;
  208. DWORD cLocalBits = cKeySizeBits;
  209. BSAFE_PUB_KEY *pPub = NULL;
  210. BSAFE_PRV_KEY *pPrv = NULL;
  211. BSAFE_OTHER_INFO OtherInfo;
  212. DWORD cbTmpLen = 0;
  213. DWORD cbHalfTmpLen = 0;
  214. DWORD cbHalfModLen = 0;
  215. BYTE rgbCardKey [1000];
  216. DWORD cbKey = 0;
  217. PBYTE pbKey = NULL;
  218. DWORD cBitlenBytes = cKeySizeBits / 8;
  219. PBYTE pbIn = NULL;
  220. memset(&OtherInfo, 0, sizeof(OtherInfo));
  221. OtherInfo.pFuncRNG = MyRngFunc;
  222. //
  223. // Figure out how big the key buffers need to be
  224. //
  225. if (! BSafeComputeKeySizes(&cbPublic, &cbPrivate, &cLocalBits))
  226. {
  227. dwError = ERROR_INTERNAL_ERROR;
  228. goto Ret;
  229. }
  230. //
  231. // Alloc the key buffers
  232. //
  233. pPub = (BSAFE_PUB_KEY *) malloc(cbPublic);
  234. if (NULL == pPub)
  235. {
  236. dwError = ERROR_NOT_ENOUGH_MEMORY;
  237. goto Ret;
  238. }
  239. pPrv = (BSAFE_PRV_KEY *) malloc(cbPrivate);
  240. if (NULL == pPrv)
  241. {
  242. dwError = ERROR_NOT_ENOUGH_MEMORY;
  243. goto Ret;
  244. }
  245. //
  246. // Generate the key pair
  247. //
  248. if (!BSafeMakeKeyPairEx2(
  249. &OtherInfo, pPub, pPrv, cKeySizeBits, 0x3))
  250. {
  251. dwError = ERROR_INTERNAL_ERROR;
  252. goto Ret;
  253. }
  254. //
  255. // Copy the private key out of the BSafe format into the card format
  256. //
  257. // This code is copied from rsaenh.dll sources
  258. //
  259. cbHalfModLen = (pPrv->bitlen + 15) / 16;
  260. // figure out the number of overflow bytes which are in the private
  261. // key structure
  262. cbTmpLen = (sizeof(DWORD) * 2)
  263. - (((pPrv->bitlen + 7) / 8) % (sizeof(DWORD) * 2));
  264. if ((sizeof(DWORD) * 2) != cbTmpLen)
  265. cbTmpLen += sizeof(DWORD) * 2;
  266. cbHalfTmpLen = cbTmpLen / 2;
  267. pbKey = rgbCardKey;
  268. // Key mode
  269. pbKey[cbKey] = MODE_RSA_SIGN;
  270. cbKey++;
  271. // size of public exponent
  272. pbKey[cbKey] = 1;
  273. cbKey++;
  274. // public exponent
  275. pbKey[cbKey] = 0x3;
  276. cbKey++;
  277. // RSA key length
  278. pbKey[cbKey] = (BYTE) cBitlenBytes;
  279. cbKey++;
  280. pbIn = (PBYTE) pPrv + sizeof(BSAFE_PRV_KEY);
  281. // Public modulus
  282. memcpy(pbKey + cbKey, pbIn, cBitlenBytes);
  283. pbIn += cBitlenBytes + cbTmpLen;
  284. cbKey += cBitlenBytes;
  285. // Fast-forward to the end of the private key structure to grab the
  286. // private exponent.
  287. pbIn += 5 * (cbHalfModLen + cbHalfTmpLen);
  288. memcpy(pbKey + cbKey, pbIn, cBitlenBytes);
  289. cbKey += cBitlenBytes;
  290. dwError = WriteKeyToCard(
  291. pwszKeyFile, pwszAclFile, rgbCardKey, cbKey);
  292. Ret:
  293. if (pPub)
  294. free(pPub);
  295. if (pPrv)
  296. free(pPrv);
  297. return dwError;
  298. }
  299. //
  300. // Generates a new RSA key using Crypto API, then exports the key and
  301. // writes it to the card. The key is stored in a format that allows
  302. // the use of Chinese Remainder Theorem parameters for faster RSA perf.
  303. //
  304. DWORD GenKeyOnCardCRT(
  305. IN LPWSTR pwszKeyFile,
  306. IN LPWSTR pwszAclFile,
  307. IN DWORD cKeySizeBits)
  308. {
  309. HCRYPTPROV hProv = 0;
  310. HCRYPTKEY hKey = 0;
  311. BYTE rgbCapiKey [1000];
  312. BYTE rgbCardKey [1000];
  313. DWORD dwError = ERROR_SUCCESS;
  314. DWORD cbCapiKey = 0;
  315. BLOBHEADER *pBlobHeader = NULL;
  316. RSAPUBKEY *pPubKey = NULL;
  317. BYTE *pbKey = NULL;
  318. DWORD cbKey = 0;
  319. DWORD cBitlenBytes = 0;
  320. if (! CryptAcquireContext(
  321. &hProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  322. {
  323. dwError = GetLastError();
  324. goto Ret;
  325. }
  326. if (! CryptGenKey(
  327. hProv, AT_KEYEXCHANGE, (cKeySizeBits << 16) | CRYPT_EXPORTABLE, &hKey))
  328. {
  329. dwError = GetLastError();
  330. goto Ret;
  331. }
  332. cbCapiKey = sizeof(rgbCapiKey);
  333. if (! CryptExportKey(
  334. hKey, 0, PRIVATEKEYBLOB, 0, rgbCapiKey, &cbCapiKey))
  335. {
  336. dwError = GetLastError();
  337. goto Ret;
  338. }
  339. pBlobHeader = (BLOBHEADER *) rgbCapiKey;
  340. pPubKey = (RSAPUBKEY *) (rgbCapiKey + sizeof(BLOBHEADER));
  341. cBitlenBytes = pPubKey->bitlen / 8;
  342. pbKey = rgbCardKey;
  343. //
  344. // Build the private key in the card's format
  345. //
  346. // Key mode
  347. pbKey[cbKey] = MODE_RSA_SIGN;
  348. cbKey++;
  349. // size of public exponent
  350. pbKey[cbKey] = cbCAPI_PUBLIC_EXPONENT;
  351. cbKey++;
  352. // public exponent
  353. memcpy(
  354. pbKey + cbKey,
  355. (PBYTE) &pPubKey->pubexp,
  356. cbCAPI_PUBLIC_EXPONENT);
  357. cbKey += cbCAPI_PUBLIC_EXPONENT;
  358. // RSA key length
  359. pbKey[cbKey] = (BYTE) cBitlenBytes;
  360. cbKey++;
  361. // public key
  362. memcpy(
  363. pbKey + cbKey,
  364. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
  365. cBitlenBytes);
  366. cbKey += cBitlenBytes;
  367. // prime 1
  368. memcpy(
  369. pbKey + cbKey,
  370. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
  371. cBitlenBytes,
  372. cBitlenBytes / 2);
  373. cbKey += cBitlenBytes / 2;
  374. // prime 2
  375. memcpy(
  376. pbKey + cbKey,
  377. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
  378. (3 * cBitlenBytes / 2),
  379. cBitlenBytes / 2);
  380. cbKey += cBitlenBytes / 2;
  381. // Exp1 (D mod (P-1)) (m/2 bytes)
  382. memcpy(
  383. pbKey + cbKey,
  384. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
  385. 2 * cBitlenBytes,
  386. cBitlenBytes / 2);
  387. cbKey += cBitlenBytes / 2;
  388. // Exp2 (D mod (Q-1)) (m/2 bytes)
  389. memcpy(
  390. pbKey + cbKey,
  391. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
  392. (5 * cBitlenBytes / 2),
  393. cBitlenBytes / 2);
  394. cbKey += cBitlenBytes / 2;
  395. // Coef ((Q^(-1)) mod p) (m/2 bytes)
  396. memcpy(
  397. pbKey + cbKey,
  398. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
  399. 3 * cBitlenBytes,
  400. cBitlenBytes / 2);
  401. cbKey += cBitlenBytes / 2;
  402. // private exponent
  403. memcpy(
  404. pbKey + cbKey,
  405. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
  406. (7 * cBitlenBytes / 2),
  407. cBitlenBytes);
  408. cbKey += cBitlenBytes;
  409. dwError = WriteKeyToCard(
  410. pwszKeyFile, pwszAclFile, rgbCardKey, cbKey);
  411. Ret:
  412. if (hKey)
  413. CryptDestroyKey(hKey);
  414. if (hProv)
  415. CryptReleaseContext(hProv, 0);
  416. return dwError;
  417. }
  418. //
  419. // Generates a new RSA key in Crypto API (in software), then exports the
  420. // key and writes it to the card in a format usable by the card's RSA
  421. // engine.
  422. //
  423. DWORD GenKeyOnCardWithCapi(
  424. IN LPWSTR pwszKeyFile,
  425. IN LPWSTR pwszAclFile,
  426. IN DWORD cKeySizeBits)
  427. {
  428. HCRYPTPROV hProv = 0;
  429. HCRYPTKEY hKey = 0;
  430. BYTE rgbCapiKey [1000];
  431. BYTE rgbCardKey [1000];
  432. DWORD dwError = ERROR_SUCCESS;
  433. DWORD cbCapiKey = 0;
  434. BLOBHEADER *pBlobHeader = NULL;
  435. RSAPUBKEY *pPubKey = NULL;
  436. BYTE *pbKey = NULL;
  437. DWORD cbKey = 0;
  438. DWORD cBitlenBytes = 0;
  439. if (! CryptAcquireContext(
  440. &hProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  441. {
  442. dwError = GetLastError();
  443. goto Ret;
  444. }
  445. if (! CryptGenKey(
  446. hProv, AT_KEYEXCHANGE, (cKeySizeBits << 16) | CRYPT_EXPORTABLE, &hKey))
  447. {
  448. dwError = GetLastError();
  449. goto Ret;
  450. }
  451. cbCapiKey = sizeof(rgbCapiKey);
  452. if (! CryptExportKey(
  453. hKey, 0, PRIVATEKEYBLOB, 0, rgbCapiKey, &cbCapiKey))
  454. {
  455. dwError = GetLastError();
  456. goto Ret;
  457. }
  458. pBlobHeader = (BLOBHEADER *) rgbCapiKey;
  459. pPubKey = (RSAPUBKEY *) (rgbCapiKey + sizeof(BLOBHEADER));
  460. cBitlenBytes = pPubKey->bitlen / 8;
  461. pbKey = rgbCardKey;
  462. //
  463. // Build the private key in the card's format
  464. //
  465. // Key mode
  466. pbKey[cbKey] = MODE_RSA_SIGN;
  467. cbKey++;
  468. // size of public exponent
  469. pbKey[cbKey] = cbCAPI_PUBLIC_EXPONENT;
  470. cbKey++;
  471. // public exponent
  472. memcpy(
  473. pbKey + cbKey,
  474. (PBYTE) &pPubKey->pubexp,
  475. cbCAPI_PUBLIC_EXPONENT);
  476. cbKey += cbCAPI_PUBLIC_EXPONENT;
  477. // RSA key length
  478. pbKey[cbKey] = (BYTE) cBitlenBytes;
  479. cbKey++;
  480. // public key
  481. memcpy(
  482. pbKey + cbKey,
  483. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
  484. cBitlenBytes);
  485. cbKey += cBitlenBytes;
  486. // private exponent
  487. memcpy(
  488. pbKey + cbKey,
  489. rgbCapiKey + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
  490. (7 * cBitlenBytes / 2),
  491. cBitlenBytes);
  492. cbKey += cBitlenBytes;
  493. dwError = WriteKeyToCard(
  494. pwszKeyFile, pwszAclFile, rgbCardKey, cbKey);
  495. Ret:
  496. if (hKey)
  497. CryptDestroyKey(hKey);
  498. if (hProv)
  499. CryptReleaseContext(hProv, 0);
  500. return dwError;
  501. }
  502. DWORD SetupRsaKeyOnCardSimulator(
  503. IN LPWSTR pwszKeyFile,
  504. IN LPWSTR pwszAclFile,
  505. IN BOOL fUseSimulator)
  506. {
  507. FILE *fh = NULL;
  508. UINT16 NLen, D1Len, DLen;
  509. BYTE buffer[1000];
  510. DWORD dwError = ERROR_SUCCESS;
  511. SCODE status = 0;
  512. HFILE hFile = 0;
  513. TCOUNT bytecheck = 0;
  514. BOOL fReAuthenticated = FALSE;
  515. status = ScwCreateFile(pwszKeyFile, NULL, &hFile);
  516. if (SCW_S_OK == status)
  517. {
  518. // Key file already exists, so we're done
  519. status = ScwCloseFile(hFile);
  520. return (DWORD) status;
  521. }
  522. fh=fopen("SimKeys.RSA", "rb");
  523. if (NULL == fh)
  524. {
  525. dwError = ERROR_FILE_NOT_FOUND;
  526. goto Ret;
  527. }
  528. dwError = Authenticate(PRINCIPAL_USER);
  529. if (ERROR_SUCCESS != dwError)
  530. goto Ret;
  531. fReAuthenticated = TRUE;
  532. status = ScwCreateFile(pwszKeyFile, pwszAclFile, &hFile);
  533. if (SC_FAILED(status))
  534. {
  535. dwError = (DWORD) status;
  536. goto Ret;
  537. }
  538. buffer[0]=0; //mode=0
  539. ScwWriteFile(hFile, buffer, 1, &bytecheck);
  540. NLen = (UINT16) fgetc(fh);
  541. buffer[0]=(BYTE) NLen;
  542. NLen += 0x14;
  543. ScwWriteFile(hFile, buffer, 1, &bytecheck);
  544. DLen = (UINT16) fgetc(fh);
  545. buffer[0]=(BYTE) DLen;
  546. ScwWriteFile(hFile, buffer, 1, &bytecheck);
  547. D1Len = (UINT16) fgetc(fh);
  548. buffer[0]=(BYTE) D1Len;
  549. ScwWriteFile(hFile, buffer, 1, &bytecheck);
  550. DLen=DLen*256+D1Len+0x14;
  551. //write the keys to file
  552. while(NLen>0) {
  553. buffer[0] = (BYTE) fgetc(fh);
  554. buffer[1] = (BYTE) fgetc(fh);
  555. ScwWriteFile(hFile, buffer, 2, &bytecheck);
  556. NLen-=2;
  557. }
  558. while(DLen>0) {
  559. buffer[0] = (BYTE) fgetc(fh);
  560. buffer[1] = (BYTE) fgetc(fh);
  561. ScwWriteFile(hFile, buffer, 2, &bytecheck);
  562. DLen-=2;
  563. }
  564. Ret:
  565. if (fh)
  566. fclose(fh);
  567. if (hFile)
  568. ScwCloseFile(hFile);
  569. if (fReAuthenticated)
  570. Deauthenticate(PRINCIPAL_USER);
  571. return dwError;
  572. }
  573. DWORD DisplayFileContents(
  574. IN LPWSTR pwszFileName)
  575. {
  576. HFILE hFile = 0;
  577. SCODE status = 0;
  578. DWORD dwError = 0;
  579. PBYTE pbContents = NULL;
  580. DWORD cbContents = 0;
  581. DWORD cbActual = 0;
  582. status = ScwCreateFile(
  583. pwszFileName, NULL, &hFile);
  584. if (SC_FAILED(status))
  585. goto Ret;
  586. status = ScwGetFileLength(
  587. hFile, (TOFFSET *) &cbContents);
  588. if (SC_FAILED(status))
  589. goto Ret;
  590. pbContents = (PBYTE) malloc(cbContents);
  591. if (NULL == pbContents)
  592. {
  593. dwError = ERROR_NOT_ENOUGH_MEMORY;
  594. goto Ret;
  595. }
  596. status = ScwReadFile32(
  597. hFile, pbContents, cbContents, &cbActual);
  598. if (SC_FAILED(status))
  599. goto Ret;
  600. PrintBytes(pwszFileName, pbContents, cbActual);
  601. Ret:
  602. if (SCW_S_OK != status)
  603. dwError = (DWORD) status;
  604. if (hFile)
  605. ScwCloseFile(hFile);
  606. if (pbContents)
  607. free(pbContents);
  608. return dwError;
  609. }
  610. DWORD EnumFilesInDirectory(
  611. IN LPWSTR pwszBaseDir,
  612. IN LPWSTR pwszCurrent)
  613. {
  614. SCODE status = 0;
  615. DWORD dwError = 0;
  616. BOOL fFirst = TRUE;
  617. UINT16 EnumState = 0;
  618. WCHAR rgwsz[64];
  619. WCHAR rgwszDir[64];
  620. if ( L'/' != pwszCurrent[0] &&
  621. 0 != wcscmp(L"/", pwszBaseDir))
  622. swprintf(
  623. rgwszDir, L"%s/%s", pwszBaseDir, pwszCurrent);
  624. else
  625. swprintf(
  626. rgwszDir, L"%s%s", pwszBaseDir, pwszCurrent);
  627. EnumState = 0;
  628. status = ScwEnumFile(rgwszDir, &EnumState, rgwsz, sizeof(rgwsz) / sizeof(WCHAR));
  629. switch (status)
  630. {
  631. case SCW_S_OK:
  632. // pwszDir is indeed a directory. Keep enumerating.
  633. wprintf(L"%s - DIR\n", rgwszDir);
  634. do
  635. {
  636. dwError = EnumFilesInDirectory(rgwszDir, rgwsz);
  637. }
  638. while (
  639. SCW_S_OK == dwError &&
  640. SCW_S_OK == (status = ScwEnumFile(
  641. rgwszDir, &EnumState, rgwsz, sizeof(rgwsz) / sizeof(WCHAR))));
  642. break;
  643. case SCW_E_NOMOREFILES:
  644. // Empty directory
  645. wprintf(L"%s - DIR\n", rgwszDir);
  646. status = SCW_S_OK;
  647. break;
  648. case SCW_E_BADDIR:
  649. // pwszDir is not a directory. Stop.
  650. wprintf(L"%s - FILE\n", rgwszDir);
  651. DisplayFileContents(rgwszDir);
  652. status = SCW_S_OK;
  653. break;
  654. case SCW_E_NOTAUTHORIZED:
  655. // Not authenticated. Stop with error.
  656. wprintf(L"%s - NOT AUTHORIZED\n", rgwszDir);
  657. break;
  658. case SCW_E_FILENOTFOUND:
  659. // What the hell does this mean?
  660. wprintf(L"%s - FILE NOT FOUND\n", rgwszDir);
  661. status = SCW_S_OK;
  662. break;
  663. default:
  664. // Other error. We're done.
  665. dwError = (DWORD) status;
  666. break;
  667. }
  668. return dwError;
  669. }
  670. //
  671. // Resets the user's pin using the VB applet on the card
  672. //
  673. DWORD TestPinUnblock(
  674. IN PBYTE pbNewPin,
  675. IN DWORD cbNewPin)
  676. {
  677. ISO_HEADER IsoHeader;
  678. BYTE rgbDataIn [256];
  679. UINT16 wStatusWord = 0;
  680. TCOUNT cbDataIn = 0;
  681. BYTE cbUser = (BYTE) ((wcslen(L"user") + 1) * sizeof(WCHAR));
  682. SCODE status = 0;
  683. memset(&IsoHeader, 0, sizeof(IsoHeader));
  684. memset(rgbDataIn, 0, sizeof(rgbDataIn));
  685. // Setup User Name TLV
  686. rgbDataIn[cbDataIn] = 0;
  687. cbDataIn++;
  688. rgbDataIn[cbDataIn] = cbUser;
  689. cbDataIn++;
  690. memcpy(rgbDataIn + cbDataIn, (PBYTE) L"user", cbUser);
  691. cbDataIn += cbUser;
  692. // Setup New Pin TLV
  693. rgbDataIn[cbDataIn] = 2;
  694. cbDataIn++;
  695. rgbDataIn[cbDataIn] = (BYTE) cbNewPin;
  696. cbDataIn++;
  697. memcpy(rgbDataIn + cbDataIn, pbNewPin, cbNewPin);
  698. cbDataIn += (TCOUNT) cbNewPin;
  699. // Build the command
  700. IsoHeader.INS = PIN_UNBLOCK_INS;
  701. IsoHeader.CLA = PIN_UNBLOCK_CLA;
  702. IsoHeader.P1 = PIN_UNBLOCK_P1;
  703. IsoHeader.P2 = PIN_UNBLOCK_P2;
  704. //
  705. // Send the pin change command to the card
  706. //
  707. status = ScwExecute(
  708. &IsoHeader,
  709. rgbDataIn,
  710. cbDataIn,
  711. NULL,
  712. NULL,
  713. &wStatusWord);
  714. if (SCW_S_OK == status)
  715. {
  716. // Reminder: Status words returned by this RTE app are in the form:
  717. // 9000 -> Success
  718. // 6Fyy -> An API failed with return code yy
  719. // 6Ezz -> An exception was raised (zz is the err number)
  720. switch (wStatusWord >> 8)
  721. {
  722. case 0x90:
  723. printf("Pin unblock was successful\n");
  724. break;
  725. case 0x6F:
  726. case 0x6E:
  727. // Make it a 32 bits error code so the message can be retrieved from
  728. // scwapi.dll
  729. status = 0x80000000L | (BYTE) wStatusWord;
  730. break;
  731. default:
  732. printf(
  733. "ERROR: unexpected status word received from card, %04X\n",
  734. wStatusWord);
  735. status = (SCODE) SCARD_F_INTERNAL_ERROR;
  736. break;
  737. }
  738. }
  739. return status;
  740. }
  741. //
  742. // Changes the user's pin using the VB applet on the card
  743. //
  744. DWORD TestPinChange(
  745. IN PBYTE pbCurrentPin,
  746. IN DWORD cbCurrentPin,
  747. IN PBYTE pbNewPin,
  748. IN DWORD cbNewPin)
  749. {
  750. ISO_HEADER IsoHeader;
  751. BYTE rgbDataIn [256];
  752. UINT16 wStatusWord = 0;
  753. TCOUNT cbDataIn = 0;
  754. BYTE cbUser = (BYTE) ((wcslen(L"user") + 1) * sizeof(WCHAR));
  755. SCODE status = 0;
  756. memset(&IsoHeader, 0, sizeof(IsoHeader));
  757. memset(rgbDataIn, 0, sizeof(rgbDataIn));
  758. // Setup User Name TLV
  759. rgbDataIn[cbDataIn] = 0;
  760. cbDataIn++;
  761. rgbDataIn[cbDataIn] = cbUser;
  762. cbDataIn++;
  763. memcpy(rgbDataIn + cbDataIn, (PBYTE) L"user", cbUser);
  764. cbDataIn += cbUser;
  765. // Setup Current Pin TLV
  766. rgbDataIn[cbDataIn] = 1;
  767. cbDataIn++;
  768. rgbDataIn[cbDataIn] = (BYTE) cbCurrentPin;
  769. cbDataIn++;
  770. memcpy(rgbDataIn + cbDataIn, pbCurrentPin, cbCurrentPin);
  771. cbDataIn += (TCOUNT) cbCurrentPin;
  772. // Setup New Pin TLV
  773. rgbDataIn[cbDataIn] = 2;
  774. cbDataIn++;
  775. rgbDataIn[cbDataIn] = (BYTE) cbNewPin;
  776. cbDataIn++;
  777. memcpy(rgbDataIn + cbDataIn, pbNewPin, cbNewPin);
  778. cbDataIn += (TCOUNT) cbNewPin;
  779. // Build the command
  780. IsoHeader.INS = PIN_CHANGE_INS;
  781. IsoHeader.CLA = PIN_CHANGE_CLA;
  782. IsoHeader.P1 = PIN_CHANGE_P1;
  783. IsoHeader.P2 = PIN_CHANGE_P2;
  784. //
  785. // Send the pin change command to the card
  786. //
  787. status = ScwExecute(
  788. &IsoHeader,
  789. rgbDataIn,
  790. cbDataIn,
  791. NULL,
  792. NULL,
  793. &wStatusWord);
  794. if (SCW_S_OK == status)
  795. {
  796. // Reminder: Status words returned by this RTE app are in the form:
  797. // 9000 -> Success
  798. // 6Fyy -> An API failed with return code yy
  799. // 6Ezz -> An exception was raised (zz is the err number)
  800. switch (wStatusWord >> 8)
  801. {
  802. case 0x90:
  803. printf("Pin was changed successfully\n");
  804. break;
  805. case 0x6F:
  806. case 0x6E:
  807. // Make it a 32 bits error code so the message can be retrieved from
  808. // scwapi.dll
  809. status = 0x80000000L | (BYTE) wStatusWord;
  810. break;
  811. default:
  812. printf(
  813. "ERROR: unexpected status word received from card, %04X\n",
  814. wStatusWord);
  815. status = (SCODE) SCARD_F_INTERNAL_ERROR;
  816. break;
  817. }
  818. }
  819. return status;
  820. }
  821. //
  822. // Retrieves the number of attempts remaining on the specified principal's
  823. // pin from the card, via the Pin Retry Counter applet.
  824. //
  825. DWORD TestPinRetryCounter(
  826. IN LPWSTR wszUserName)
  827. {
  828. ISO_HEADER IsoHeader;
  829. BYTE rgbDataIn [256];
  830. UINT16 wStatusWord = 0;
  831. TCOUNT cbDataIn = (TCOUNT) ((wcslen(wszUserName) + 1) * sizeof(WCHAR));
  832. SCODE status = 0;
  833. memset(&IsoHeader, 0, sizeof(IsoHeader));
  834. memset(rgbDataIn, 0, sizeof(rgbDataIn));
  835. // Setup the user name that we'll send to the card
  836. memcpy(rgbDataIn, (PBYTE) wszUserName, cbDataIn);
  837. // Setup the command
  838. IsoHeader.CLA = PIN_RETRY_COUNTER_CLA;
  839. IsoHeader.INS = PIN_RETRY_COUNTER_INS;
  840. IsoHeader.P1 = PIN_RETRY_COUNTER_P1;
  841. IsoHeader.P2 = PIN_RETRY_COUNTER_P2;
  842. //
  843. // Call the retry counter applet on the card
  844. //
  845. status = ScwExecute(
  846. &IsoHeader,
  847. rgbDataIn,
  848. cbDataIn,
  849. NULL,
  850. NULL,
  851. &wStatusWord);
  852. if (SCW_S_OK == status)
  853. {
  854. // Reminder: Status words returned by this RTE app are in the form:
  855. // 9000 -> Success
  856. // 6Fyy -> An API failed with return code yy
  857. // 6Ezz -> An exception was raised (zz is the err number)
  858. switch (wStatusWord >> 8)
  859. {
  860. case 0x90:
  861. wprintf(
  862. L"Current pin attempts remaining for %s: %02X\n",
  863. wszUserName,
  864. (BYTE) wStatusWord);
  865. break;
  866. case 0x6F:
  867. case 0x6E:
  868. // Make it a 32 bits error code so the message can be retrieved from
  869. // scwapi.dll
  870. status = 0x80000000L | (BYTE) wStatusWord;
  871. break;
  872. default:
  873. printf(
  874. "ERROR: unexpected status word received from card, %04X\n",
  875. wStatusWord);
  876. status = (SCODE) SCARD_F_INTERNAL_ERROR;
  877. break;
  878. }
  879. }
  880. return status;
  881. }
  882. DWORD UpdateT1Atr(void)
  883. {
  884. SCODE status = 0;
  885. DWORD cbFile = 0;
  886. DWORD cbRead = 0;
  887. BYTE rgbAtr [36];
  888. HFILE hFile = 0;
  889. BYTE rgbNewAtr [36];
  890. /*
  891. BYTE rgbNewAtr2 [] = {
  892. 0x11, 0x00,
  893. 0x9C, 0x13, 0x81, 0x31, 0x20, 0x55, 0x42,
  894. 0x61, 0x73, 0x65, 0x43, 0x53, 0x50, 0x2D, 0x54,
  895. 0x31, 0x2D, 0x31, 0x6B
  896. };
  897. */
  898. BYTE rgbNewAtr2 [] = {
  899. 0x11, 0x00,
  900. 0xDC, 0x13, 0x0A, 0x81, 0x31, 0x20, 0x55, 0x42,
  901. 0x61, 0x73, 0x65, 0x43, 0x53, 0x50, 0x2D, 0x54,
  902. 0x31, 0x2D, 0x31, 0x21
  903. };
  904. //
  905. // Get the current ATR and display it
  906. //
  907. status = ScwCreateFile(
  908. L"/T0",
  909. NULL,
  910. &hFile);
  911. if (SCW_S_OK != status)
  912. goto Ret;
  913. status = ScwWriteFile32(
  914. hFile, rgbNewAtr2, sizeof(rgbNewAtr2), &cbRead);
  915. if (SCW_S_OK != status)
  916. goto Ret;
  917. /*
  918. status = ScwGetFileLength(
  919. hFile, (TOFFSET *) &cbFile);
  920. if (SCW_S_OK != status)
  921. goto Ret;
  922. if (cbFile > sizeof(rgbAtr))
  923. {
  924. status = (SCODE) SCARD_F_INTERNAL_ERROR;
  925. goto Ret;
  926. }
  927. status = ScwReadFile32(
  928. hFile, rgbAtr, cbFile, &cbRead);
  929. if (SCW_S_OK != status)
  930. goto Ret;
  931. if (cbFile != cbRead)
  932. {
  933. status = (SCODE) SCARD_W_EOF;
  934. goto Ret;
  935. }
  936. PrintBytes(L"Current ATR", rgbAtr + 2, cbFile - 2);
  937. if (rgbAtr[2] & 0x10)
  938. {
  939. printf("Upgrade not necessary\n");
  940. goto Ret;
  941. }
  942. //
  943. // Build the new high data rate T1 ATR, display it, and write
  944. // it to the card.
  945. //
  946. rgbNewAtr[0] = rgbAtr[0];
  947. rgbNewAtr[1] = rgbAtr[1];
  948. rgbNewAtr[2] = rgbAtr[2] | 0x10;
  949. rgbNewAtr[3] = 0x12;
  950. memcpy(rgbNewAtr + 4, rgbAtr + 3, cbFile - 3);
  951. rgbNewAtr[cbFile] ^= 0x02;
  952. status = ScwSetFilePointer(hFile, 0, FILE_BEGIN);
  953. if (SCW_S_OK != status)
  954. goto Ret;
  955. status = ScwWriteFile32(
  956. hFile, rgbNewAtr, cbFile + 1, &cbRead);
  957. if (SCW_S_OK != status)
  958. goto Ret;
  959. if (cbRead != cbFile + 1)
  960. {
  961. status = (SCODE) SCARD_W_EOF;
  962. goto Ret;
  963. }
  964. PrintBytes(L"New ATR", rgbNewAtr + 2, cbRead - 2);
  965. */
  966. Ret:
  967. if (hFile)
  968. ScwCloseFile(hFile);
  969. return (DWORD) status;
  970. }
  971. void ShowHelp(void)
  972. {
  973. printf("wfscproto <options>\n");
  974. printf(" Options:\n");
  975. printf(" -a : Update the ATR for a T=1 card\n");
  976. printf(" -g : Generate a new private key on the card\n");
  977. printf(" -k [bits] : Key size in bits (default is 512)\n");
  978. printf(" -c : Use Crypto API to generate key (default is to use rsa32.lib directly)\n");
  979. printf(" -t : Use Crypto API to generate key with CRT parameters\n");
  980. printf(" -e : Enumerate all directories and files on card\n");
  981. printf(" -p : Pin change\n");
  982. printf(" -u : Pin unblock\n");
  983. printf(" -r : Query pin retry counter\n");
  984. }
  985. int __cdecl main(int argc, char* argv[])
  986. {
  987. SCODE status = 0;
  988. BOOL fSuccess = FALSE;
  989. HFILE hFile = 0;
  990. BYTE rgb[65];
  991. BYTE rgbData[1024];
  992. BYTE rgbResult[1024];
  993. DWORD cb = 0;
  994. DWORD dw = 0;
  995. UINT16 EnumState = 0;
  996. WCHAR rgwsz[64];
  997. PBYTE pb = NULL;
  998. TCOUNT tcount = 0;
  999. DWORD dwError = 0;
  1000. SCARDCONTEXT hSCardContext = 0;
  1001. SCARDHANDLE hSCardHandle = 0;
  1002. LPSTR mszReaders = NULL;
  1003. DWORD cchReaders = SCARD_AUTOALLOCATE;
  1004. DWORD dwActiveProtocol = 0;
  1005. BOOL fAuthenticatedUser = FALSE;
  1006. BOOL fAuthenticatedAdmin = FALSE;
  1007. BOOL fUseSimulator = FALSE;
  1008. BOOL fEnumFiles = FALSE;
  1009. BOOL fGenKey = FALSE;
  1010. DWORD dwState = 0;
  1011. BYTE rgbAtr [32];
  1012. DWORD cbAtr = sizeof(rgbAtr);
  1013. DWORD fUseCapi = FALSE;
  1014. DWORD cKeyBits = 512;
  1015. BOOL fShowHelp = FALSE;
  1016. BOOL fPinChange = FALSE;
  1017. BOOL fPinUnblock = FALSE;
  1018. BOOL fGetPinRetryCounter = FALSE;
  1019. BOOL fGenKeyCRT = FALSE;
  1020. BOOL fUpdateT1Atr = FALSE;
  1021. memset(rgbData, 0, sizeof(rgbData));
  1022. memset(rgbResult, 0, sizeof(rgbResult));
  1023. while (--argc>0)
  1024. {
  1025. if (**++argv == '-')
  1026. {
  1027. switch(argv[0][1])
  1028. {
  1029. case 'a':
  1030. fUpdateT1Atr = TRUE;
  1031. break;
  1032. case 'c':
  1033. fUseCapi = TRUE;
  1034. break;
  1035. case 'k':
  1036. --argc;
  1037. ++argv;
  1038. cKeyBits = atoi(*argv);
  1039. break;
  1040. case 'g':
  1041. fGenKey = TRUE;
  1042. break;
  1043. case 'e':
  1044. fEnumFiles = TRUE;
  1045. break;
  1046. case 'p':
  1047. fPinChange = TRUE;
  1048. break;
  1049. case 'u':
  1050. fPinUnblock = TRUE;
  1051. break;
  1052. case 'r':
  1053. fGetPinRetryCounter = TRUE;
  1054. break;
  1055. case 't':
  1056. fGenKeyCRT = TRUE;
  1057. break;
  1058. case '?':
  1059. fShowHelp = TRUE;
  1060. goto Ret;
  1061. default:
  1062. fShowHelp = TRUE;
  1063. goto Ret;
  1064. }
  1065. }
  1066. else
  1067. goto Ret;
  1068. }
  1069. //
  1070. // Attach to the card
  1071. //
  1072. if (fUseSimulator)
  1073. {
  1074. // For connecting to the simulator
  1075. status = ScwAttachToCard(NULL_TX, wszTEST_CARD_NAME);
  1076. if (SC_FAILED(status))
  1077. goto Ret;
  1078. }
  1079. else
  1080. {
  1081. status = SCardEstablishContext(
  1082. SCARD_SCOPE_USER, NULL, NULL, &hSCardContext);
  1083. if (SC_FAILED(status))
  1084. goto Ret;
  1085. status = SCardListReadersA(
  1086. hSCardContext, NULL, (LPSTR) (&mszReaders), &cchReaders);
  1087. if (SC_FAILED(status) || NULL == mszReaders)
  1088. goto Ret;
  1089. status = SCardConnectA(
  1090. hSCardContext,
  1091. mszReaders,
  1092. SCARD_SHARE_SHARED,
  1093. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_DEFAULT,
  1094. &hSCardHandle,
  1095. &dwActiveProtocol);
  1096. if (SC_FAILED(status))
  1097. goto Ret;
  1098. if (mszReaders)
  1099. {
  1100. SCardFreeMemory(hSCardContext, mszReaders);
  1101. mszReaders = NULL;
  1102. }
  1103. cchReaders = SCARD_AUTOALLOCATE;
  1104. status = SCardStatusA(
  1105. hSCardHandle,
  1106. (LPSTR) (&mszReaders),
  1107. &cchReaders,
  1108. &dwState,
  1109. &dwActiveProtocol,
  1110. rgbAtr,
  1111. &cbAtr);
  1112. if (SC_FAILED(status))
  1113. goto Ret;
  1114. status = ScwAttachToCard(
  1115. hSCardHandle, NULL);
  1116. if (SC_FAILED(status))
  1117. goto Ret;
  1118. }
  1119. status = Authenticate(PRINCIPAL_USER);
  1120. if (SC_FAILED(status))
  1121. goto Ret;
  1122. fAuthenticatedUser = TRUE;
  1123. if (fUpdateT1Atr)
  1124. {
  1125. dwError = UpdateT1Atr();
  1126. if (ERROR_SUCCESS != dwError)
  1127. goto Ret;
  1128. }
  1129. //
  1130. // Enumerate all files
  1131. //
  1132. if (fEnumFiles)
  1133. {
  1134. status = (DWORD) EnumFilesInDirectory(L"", L"/");
  1135. if (SC_FAILED(status))
  1136. goto Ret;
  1137. }
  1138. //
  1139. // RSA Operation
  1140. //
  1141. if (fGenKey)
  1142. {
  1143. if (fUseSimulator)
  1144. {
  1145. dwError = SetupRsaKeyOnCardSimulator(
  1146. wszRSA_KEY_FILE, wszKEY_ACL_FILE, fUseSimulator);
  1147. if (ERROR_SUCCESS != dwError)
  1148. goto Ret;
  1149. }
  1150. else
  1151. {
  1152. printf(
  1153. "Using %s to generate %d bit key\n",
  1154. fUseCapi ? "Crypto API" : "rsa32.lib",
  1155. cKeyBits);
  1156. if (FALSE == fUseCapi)
  1157. dwError = GenKeyOnCardWithRsa32(
  1158. wszRSA_KEY_FILE, wszKEY_ACL_FILE, cKeyBits);
  1159. else
  1160. dwError = GenKeyOnCardWithCapi(
  1161. wszRSA_KEY_FILE, wszKEY_ACL_FILE, cKeyBits);
  1162. if (ERROR_SUCCESS != dwError)
  1163. goto Ret;
  1164. }
  1165. // Initialize
  1166. pb = rgb;
  1167. *pb++ = 0x00; // Tag
  1168. cb = (wcslen(wszRSA_KEY_FILE) + 1) * sizeof(WCHAR);
  1169. *pb++ = (BYTE) (1 + cb + 2);
  1170. // Length
  1171. // Number of following bytes:
  1172. // filename len, filename + NULL, key data offset
  1173. *pb++ = (BYTE) cb / sizeof(WCHAR); // Value
  1174. wcscpy((LPWSTR) pb, wszRSA_KEY_FILE);
  1175. pb += cb;
  1176. *(WORD*)pb = 0x0000;
  1177. status = ScwCryptoInitialize(
  1178. CM_RSA | CM_KEY_INFILE,
  1179. rgb);
  1180. if (SC_FAILED(status))
  1181. goto Ret;
  1182. // RSA Sign
  1183. memset(rgbData, 0, sizeof(rgbData));
  1184. for (dw = 0; dw < 16; dw++)
  1185. rgbData[dw] = (BYTE) dw;
  1186. PrintBytes(L"Plaintext", rgbData, 16);
  1187. tcount = (TCOUNT) (cKeyBits / 8);
  1188. status = ScwCryptoAction(
  1189. rgbData,
  1190. 16,
  1191. rgbResult,
  1192. &tcount);
  1193. if (SC_FAILED(status))
  1194. goto Ret;
  1195. PrintBytes(L"Ciphertext", rgbResult, tcount);
  1196. }
  1197. if (fGenKeyCRT)
  1198. {
  1199. printf(
  1200. "Using Crypto API to generate %d bit key with CRT params\n",
  1201. cKeyBits);
  1202. dwError = GenKeyOnCardCRT(
  1203. wszRSA_KEY_FILE, wszKEY_ACL_FILE, cKeyBits);
  1204. if (ERROR_SUCCESS != dwError)
  1205. goto Ret;
  1206. // Initialize
  1207. pb = rgb;
  1208. *pb++ = 0x00; // Tag
  1209. cb = (wcslen(wszRSA_KEY_FILE) + 1) * sizeof(WCHAR);
  1210. *pb++ = (BYTE) (1 + cb + 2);
  1211. // Length
  1212. // Number of following bytes:
  1213. // filename len, filename + NULL, key data offset
  1214. *pb++ = (BYTE) cb / sizeof(WCHAR); // Value
  1215. wcscpy((LPWSTR) pb, wszRSA_KEY_FILE);
  1216. pb += cb;
  1217. *(WORD*)pb = 0x0000;
  1218. status = ScwCryptoInitialize(
  1219. CM_RSA_CRT | CM_KEY_INFILE,
  1220. rgb);
  1221. if (SC_FAILED(status))
  1222. goto Ret;
  1223. // RSA Sign
  1224. memset(rgbData, 0, sizeof(rgbData));
  1225. for (dw = 0; dw < 16; dw++)
  1226. rgbData[dw] = (BYTE) dw;
  1227. PrintBytes(L"Plaintext", rgbData, 16);
  1228. tcount = (TCOUNT) (cKeyBits / 8);
  1229. status = ScwCryptoAction(
  1230. rgbData,
  1231. 16,
  1232. rgbResult,
  1233. &tcount);
  1234. if (SC_FAILED(status))
  1235. goto Ret;
  1236. PrintBytes(L"Ciphertext", rgbResult, tcount);
  1237. }
  1238. if (fPinChange)
  1239. {
  1240. //
  1241. // Test the on-card pin change applet
  1242. //
  1243. if (fAuthenticatedUser)
  1244. {
  1245. status = (DWORD) Deauthenticate(PRINCIPAL_USER);
  1246. if (SC_FAILED(status))
  1247. goto Ret;
  1248. fAuthenticatedUser = FALSE;
  1249. }
  1250. status = (DWORD) TestPinChange(
  1251. Principals[PRINCIPAL_USER].rgbPin,
  1252. sizeof(Principals[PRINCIPAL_USER].rgbPin),
  1253. rgbUserNewPin,
  1254. sizeof(rgbUserNewPin));
  1255. if (SC_FAILED(status))
  1256. goto Ret;
  1257. // Now change the pin back
  1258. status = (DWORD) TestPinChange(
  1259. rgbUserNewPin,
  1260. sizeof(rgbUserNewPin),
  1261. Principals[PRINCIPAL_USER].rgbPin,
  1262. sizeof(Principals[PRINCIPAL_USER].rgbPin));
  1263. if (SC_FAILED(status))
  1264. goto Ret;
  1265. }
  1266. if (fPinUnblock)
  1267. {
  1268. //
  1269. // Test the on-card pin unblock applet
  1270. //
  1271. // Need to authenticate the Admin first
  1272. if (fAuthenticatedUser)
  1273. {
  1274. status = (DWORD) Deauthenticate(PRINCIPAL_USER);
  1275. if (SC_FAILED(status))
  1276. goto Ret;
  1277. fAuthenticatedUser = FALSE;
  1278. }
  1279. status = (DWORD) Authenticate(PRINCIPAL_ADMIN);
  1280. if (SC_FAILED(status))
  1281. goto Ret;
  1282. fAuthenticatedAdmin = TRUE;
  1283. status = (DWORD) TestPinUnblock(
  1284. rgbUserNewPin,
  1285. sizeof(rgbUserNewPin));
  1286. if (SC_FAILED(status))
  1287. goto Ret;
  1288. // Now change the User pin back to its original value
  1289. status = (DWORD) Deauthenticate(PRINCIPAL_ADMIN);
  1290. if (SC_FAILED(status))
  1291. goto Ret;
  1292. fAuthenticatedAdmin = FALSE;
  1293. status = (DWORD) TestPinChange(
  1294. rgbUserNewPin,
  1295. sizeof(rgbUserNewPin),
  1296. Principals[PRINCIPAL_USER].rgbPin,
  1297. sizeof(Principals[PRINCIPAL_USER].rgbPin));
  1298. if (SC_FAILED(status))
  1299. goto Ret;
  1300. }
  1301. if (fGetPinRetryCounter)
  1302. {
  1303. //
  1304. // Test the on-card pin retry counter applet
  1305. //
  1306. status = (DWORD) TestPinRetryCounter(
  1307. Principals[PRINCIPAL_USER].pwszUser);
  1308. if (SC_FAILED(status))
  1309. goto Ret;
  1310. }
  1311. fSuccess = TRUE;
  1312. Ret:
  1313. if (! fSuccess)
  1314. {
  1315. if (fShowHelp)
  1316. ShowHelp();
  1317. else
  1318. printf("ERROR: 0x%x\n", status);
  1319. }
  1320. else
  1321. printf("Success\n");
  1322. if (fAuthenticatedAdmin)
  1323. Deauthenticate(PRINCIPAL_ADMIN);
  1324. if (fAuthenticatedUser)
  1325. Deauthenticate(PRINCIPAL_USER);
  1326. ScwDetachFromCard();
  1327. if (mszReaders)
  1328. status = SCardFreeMemory(hSCardContext, mszReaders);
  1329. if (hSCardHandle)
  1330. status = SCardDisconnect(hSCardHandle, SCARD_RESET_CARD);
  1331. if (hSCardContext)
  1332. status = SCardReleaseContext(hSCardContext);
  1333. return 0;
  1334. }