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.

828 lines
19 KiB

  1. #include <windows.h>
  2. #include <wincrypt.h>
  3. #include <winscard.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include "basecsp.h"
  8. #include <des.h>
  9. #include <tripldes.h>
  10. #include <modes.h>
  11. #define TEST_CASE(X) { if (ERROR_SUCCESS != (dwSts = X)) { printf("%s", #X); goto Ret; } }
  12. #ifndef cbCHALLENGE_RESPONSE_DATA
  13. #define cbCHALLENGE_RESPONSE_DATA 8
  14. #endif
  15. //
  16. // Defines for Admin challenge-response key
  17. //
  18. BYTE rgbAdminKey [] = {
  19. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  20. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  21. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  22. };
  23. BYTE rgbNewAdminKey [] = {
  24. 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
  25. 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC,
  26. 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC
  27. };
  28. #define USE_DEFAULT_ADMIN_KEY 1
  29. #define USE_NEW_ADMIN_KEY 2
  30. BYTE rgbUserPin [] = {
  31. 0x30, 0x30, 0x30, 0x30
  32. };
  33. BYTE rgbNewUserPin [] = {
  34. 0x41, 0x62, 0x63, 0x64
  35. };
  36. //
  37. // Function: CspAllocH
  38. //
  39. LPVOID WINAPI CspAllocH(
  40. IN SIZE_T cBytes)
  41. {
  42. return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cBytes);
  43. }
  44. //
  45. // Function: CspFreeH
  46. //
  47. void WINAPI CspFreeH(
  48. IN LPVOID pMem)
  49. {
  50. HeapFree(GetProcessHeap(), 0, pMem);
  51. }
  52. //
  53. // Function: CspReAllocH
  54. //
  55. LPVOID WINAPI CspReAllocH(
  56. IN LPVOID pMem,
  57. IN SIZE_T cBytes)
  58. {
  59. return HeapReAlloc(
  60. GetProcessHeap(), HEAP_ZERO_MEMORY, pMem, cBytes);
  61. }
  62. DWORD WINAPI CspCacheAddFile(
  63. IN PVOID pvCacheContext,
  64. IN LPWSTR wszTag,
  65. IN DWORD dwFlags,
  66. IN PBYTE pbData,
  67. IN DWORD cbData)
  68. {
  69. return ERROR_SUCCESS;
  70. }
  71. DWORD WINAPI CspCacheLookupFile(
  72. IN PVOID pvCacheContext,
  73. IN LPWSTR wszTag,
  74. IN DWORD dwFlags,
  75. IN PBYTE *ppbData,
  76. IN PDWORD pcbData)
  77. {
  78. return ERROR_NOT_FOUND;
  79. }
  80. DWORD WINAPI CspCacheDeleteFile(
  81. IN PVOID pvCacheContext,
  82. IN LPWSTR wszTag,
  83. IN DWORD dwFlags)
  84. {
  85. return ERROR_SUCCESS;
  86. }
  87. //
  88. // Function: TestCreateCertificates
  89. //
  90. DWORD
  91. WINAPI
  92. TestCreateCertificates(
  93. IN PCARD_DATA pCardData)
  94. {
  95. DWORD dwSts = ERROR_SUCCESS;
  96. LPWSTR rgwszCertFiles [] = {
  97. L"1",
  98. L"2",
  99. L"3"
  100. };
  101. #define cCERT_FILES (sizeof(rgwszCertFiles) / sizeof(rgwszCertFiles[0]))
  102. WCHAR rgrgFiles [cCERT_FILES][200];
  103. DWORD iFile = 0;
  104. LPWSTR mwszFiles = NULL;
  105. CARD_FILE_ACCESS_CONDITION Acl = EveryoneReadUserWriteAc;
  106. DWORD iCurrent = 0;
  107. printf("Creating and deleting %d test certificate files ...\n", cCERT_FILES);
  108. for ( iFile = 0;
  109. iFile < cCERT_FILES;
  110. iFile++)
  111. {
  112. wsprintf(
  113. rgrgFiles[iFile],
  114. L"%s%s",
  115. wszUSER_KEYEXCHANGE_CERT_PREFIX,
  116. rgwszCertFiles[iFile]);
  117. TEST_CASE(pCardData->pfnCardCreateFile(
  118. pCardData,
  119. rgrgFiles[iFile],
  120. Acl));
  121. }
  122. /*
  123. TODO - when CardEnumFiles has been implemented, re-enable this test
  124. mwszFiles = (LPWSTR) CspAllocH(
  125. sizeof(WCHAR) * (1 + wcslen(wszUSER_CERTS_DIR_FULL_PATH)));
  126. if (NULL == mwszFiles)
  127. {
  128. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  129. goto Ret;
  130. }
  131. wcscpy(mwszFiles, wszUSER_CERTS_DIR_FULL_PATH);
  132. TEST_CASE(pCardData->pfnCardEnumFiles(
  133. pCardData,
  134. 0,
  135. &mwszFiles));
  136. while (L'\0' != mwszFiles[iCurrent])
  137. {
  138. wprintf(L" %s\n", mwszFiles + iCurrent);
  139. iCurrent += wcslen(mwszFiles + iCurrent) + 1;
  140. }
  141. */
  142. Ret:
  143. for ( iFile = 0;
  144. iFile < cCERT_FILES;
  145. iFile++)
  146. {
  147. pCardData->pfnCardDeleteFile(
  148. pCardData,
  149. 0,
  150. rgrgFiles[iFile]);
  151. }
  152. if (mwszFiles)
  153. CspFreeH(mwszFiles);
  154. return dwSts;
  155. }
  156. //
  157. // Function: TestCreateContainers
  158. //
  159. // Notes: The pbKey parameter must be an AT_KEYEXCHANGE private key blob.
  160. //
  161. DWORD
  162. WINAPI
  163. TestCreateContainers(
  164. IN PCARD_DATA pCardData,
  165. IN PBYTE pbKey,
  166. IN DWORD cbKey)
  167. {
  168. DWORD dwSts = ERROR_SUCCESS;
  169. BYTE iContainer = 0;
  170. printf("Creating and deleting 3 key containers ...\n");
  171. for (iContainer = 0; iContainer < 3; iContainer++)
  172. {
  173. TEST_CASE(pCardData->pfnCardCreateContainer(
  174. pCardData,
  175. iContainer,
  176. CARD_CREATE_CONTAINER_KEY_IMPORT,
  177. AT_KEYEXCHANGE,
  178. cbKey,
  179. pbKey));
  180. }
  181. Ret:
  182. for (iContainer = 0; iContainer < 3; iContainer++)
  183. {
  184. pCardData->pfnCardDeleteContainer(
  185. pCardData,
  186. iContainer,
  187. 0);
  188. }
  189. return dwSts;
  190. }
  191. DWORD GetAdminAuthResponse(
  192. IN PCARD_DATA pCardData,
  193. IN OUT PBYTE pbResponse,
  194. IN DWORD cbResponse,
  195. IN DWORD dwWhichKey)
  196. {
  197. DES3TABLE des3Table;
  198. PBYTE pbKey = NULL;
  199. PBYTE pbChallenge = NULL;
  200. DWORD cbChallenge = 0;
  201. DWORD dwSts = ERROR_SUCCESS;
  202. memset(&des3Table, 0, sizeof(des3Table));
  203. if (cbCHALLENGE_RESPONSE_DATA != cbResponse)
  204. {
  205. dwSts = ERROR_INVALID_PARAMETER;
  206. goto Ret;
  207. }
  208. switch (dwWhichKey)
  209. {
  210. case USE_DEFAULT_ADMIN_KEY:
  211. pbKey = rgbAdminKey;
  212. break;
  213. case USE_NEW_ADMIN_KEY:
  214. pbKey = rgbNewAdminKey;
  215. break;
  216. default:
  217. return (DWORD) NTE_BAD_DATA;
  218. }
  219. // Get the challenge
  220. TEST_CASE(pCardData->pfnCardGetChallenge(
  221. pCardData,
  222. &pbChallenge,
  223. &cbChallenge));
  224. // Build a des key using the admin auth key
  225. tripledes3key(&des3Table, pbKey);
  226. // Encrypt the challenge to compute the response
  227. tripledes(pbResponse, pbChallenge, (PVOID) &des3Table, ENCRYPT);
  228. Ret:
  229. if (pbChallenge)
  230. pCardData->pfnCspFree(pbChallenge);
  231. return dwSts;
  232. }
  233. //
  234. // Tests authenticating to the card as admin
  235. //
  236. DWORD
  237. WINAPI
  238. TestCardAuthenticateChallenge(
  239. IN PCARD_DATA pCardData)
  240. {
  241. DWORD dwSts = ERROR_SUCCESS;
  242. BYTE rgbResponse [cbCHALLENGE_RESPONSE_DATA];
  243. printf("Testing CardAuthenticateChallenge ...\n");
  244. // Get a challenge-response
  245. dwSts = GetAdminAuthResponse(
  246. pCardData,
  247. rgbResponse,
  248. sizeof(rgbResponse),
  249. USE_DEFAULT_ADMIN_KEY);
  250. if (ERROR_SUCCESS != dwSts)
  251. goto Ret;
  252. TEST_CASE(pCardData->pfnCardAuthenticateChallenge(
  253. pCardData,
  254. rgbResponse,
  255. sizeof(rgbResponse),
  256. NULL));
  257. TEST_CASE(pCardData->pfnCardDeauthenticate(
  258. pCardData,
  259. wszCARD_USER_ADMIN,
  260. 0));
  261. Ret:
  262. return dwSts;
  263. }
  264. //
  265. // Tests changing the admin challenge-response key
  266. //
  267. DWORD
  268. WINAPI
  269. TestCardChangeAuthenticator(
  270. IN PCARD_DATA pCardData)
  271. {
  272. DWORD dwSts = ERROR_SUCCESS;
  273. BYTE rgbResponse [cbCHALLENGE_RESPONSE_DATA];
  274. printf("Testing CardChangeAuthenticator ...\n");
  275. // Get a challenge-response
  276. dwSts = GetAdminAuthResponse(
  277. pCardData,
  278. rgbResponse,
  279. sizeof(rgbResponse),
  280. USE_DEFAULT_ADMIN_KEY);
  281. if (ERROR_SUCCESS != dwSts)
  282. goto Ret;
  283. // Change the admin key
  284. TEST_CASE(pCardData->pfnCardChangeAuthenticator(
  285. pCardData,
  286. wszCARD_USER_ADMIN,
  287. rgbResponse,
  288. sizeof(rgbResponse),
  289. rgbNewAdminKey,
  290. sizeof(rgbNewAdminKey),
  291. 0,
  292. NULL));
  293. // Get a challenge-response
  294. dwSts = GetAdminAuthResponse(
  295. pCardData,
  296. rgbResponse,
  297. sizeof(rgbResponse),
  298. USE_NEW_ADMIN_KEY);
  299. if (ERROR_SUCCESS != dwSts)
  300. goto Ret;
  301. // Change the admin key back
  302. TEST_CASE(pCardData->pfnCardChangeAuthenticator(
  303. pCardData,
  304. wszCARD_USER_ADMIN,
  305. rgbResponse,
  306. sizeof(rgbResponse),
  307. rgbAdminKey,
  308. sizeof(rgbAdminKey),
  309. 0,
  310. NULL));
  311. TEST_CASE(pCardData->pfnCardDeauthenticate(
  312. pCardData,
  313. wszCARD_USER_ADMIN,
  314. 0));
  315. Ret:
  316. return dwSts;
  317. }
  318. //
  319. // Tests unblocking the user account
  320. //
  321. DWORD
  322. WINAPI
  323. TestCardUnblockPin(
  324. IN PCARD_DATA pCardData)
  325. {
  326. DWORD dwSts = ERROR_SUCCESS;
  327. BYTE rgbResponse [cbCHALLENGE_RESPONSE_DATA];
  328. printf("Testing CardUnblockPin ...\n");
  329. dwSts = GetAdminAuthResponse(
  330. pCardData,
  331. rgbResponse,
  332. sizeof(rgbResponse),
  333. USE_DEFAULT_ADMIN_KEY);
  334. if (ERROR_SUCCESS != dwSts)
  335. goto Ret;
  336. // Unblock the user account
  337. TEST_CASE(pCardData->pfnCardUnblockPin(
  338. pCardData,
  339. wszCARD_USER_USER,
  340. rgbResponse,
  341. sizeof(rgbResponse),
  342. rgbNewUserPin,
  343. sizeof(rgbNewUserPin),
  344. 0,
  345. CARD_UNBLOCK_PIN_CHALLENGE_RESPONSE));
  346. // Change the user account back to the default pin
  347. TEST_CASE(pCardData->pfnCardChangeAuthenticator(
  348. pCardData,
  349. wszCARD_USER_USER,
  350. rgbNewUserPin,
  351. sizeof(rgbNewUserPin),
  352. rgbUserPin,
  353. sizeof(rgbUserPin),
  354. 0,
  355. NULL));
  356. TEST_CASE(pCardData->pfnCardDeauthenticate(
  357. pCardData,
  358. wszCARD_USER_USER,
  359. 0));
  360. Ret:
  361. return dwSts;
  362. }
  363. int _cdecl main(int argc, char * argv[])
  364. {
  365. PCARD_DATA pCardData = NULL;
  366. DWORD dwSts = ERROR_SUCCESS;
  367. PFN_CARD_ACQUIRE_CONTEXT pfnCardAcquireContext = NULL;
  368. SCARDCONTEXT hSCardContext = 0;
  369. SCARDHANDLE hSCardHandle = 0;
  370. LPWSTR mszReaders = NULL;
  371. DWORD cchReaders = SCARD_AUTOALLOCATE;
  372. LPWSTR mszCards = NULL;
  373. DWORD cchCards = SCARD_AUTOALLOCATE;
  374. DWORD dwActiveProtocol = 0;
  375. DWORD dwState = 0;
  376. BYTE rgbAtr [32];
  377. DWORD cbAtr = sizeof(rgbAtr);
  378. LPWSTR pszProvider = NULL;
  379. DWORD cchProvider = SCARD_AUTOALLOCATE;
  380. HMODULE hMod = INVALID_HANDLE_VALUE;
  381. DATA_BLOB FileContents;
  382. HCRYPTPROV hProv = 0;
  383. HCRYPTKEY hKey = 0;
  384. PBYTE pbKey = NULL;
  385. DWORD cbKey = 0;
  386. BYTE rgbData[2000];
  387. DWORD cbData = 0;
  388. DATA_BLOB Pin;
  389. CONTAINER_INFO ContainerInfo;
  390. BLOBHEADER *pBlobHeader = NULL;
  391. BYTE bContainerIndex = 0;
  392. CARD_PRIVATE_KEY_DECRYPT_INFO CardPrivateKeyDecryptInfo;
  393. memset(&ContainerInfo, 0, sizeof(ContainerInfo));
  394. memset(&Pin, 0, sizeof(Pin));
  395. memset(rgbData, 0, sizeof(rgbData));
  396. memset(rgbAtr, 0, sizeof(rgbAtr));
  397. memset(&FileContents, 0, sizeof(FileContents));
  398. memset(&CardPrivateKeyDecryptInfo, 0, sizeof(CardPrivateKeyDecryptInfo));
  399. Pin.cbData = sizeof(rgbUserPin);
  400. Pin.pbData = rgbUserPin;
  401. //
  402. // Initialization
  403. //
  404. dwSts = SCardEstablishContext(
  405. SCARD_SCOPE_USER, NULL, NULL, &hSCardContext);
  406. if (FAILED(dwSts))
  407. goto Ret;
  408. dwSts = SCardListReadersW(
  409. hSCardContext, NULL, (LPWSTR) (&mszReaders), &cchReaders);
  410. if (FAILED(dwSts) || NULL == mszReaders)
  411. goto Ret;
  412. dwSts = SCardConnect(
  413. hSCardContext,
  414. mszReaders,
  415. SCARD_SHARE_SHARED,
  416. SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
  417. &hSCardHandle,
  418. &dwActiveProtocol);
  419. if (FAILED(dwSts))
  420. goto Ret;
  421. dwSts = SCardFreeMemory(hSCardContext, mszReaders);
  422. if (FAILED(dwSts))
  423. goto Ret;
  424. mszReaders = NULL;
  425. cchReaders = SCARD_AUTOALLOCATE;
  426. dwSts = SCardStatusW(
  427. hSCardHandle,
  428. (LPWSTR) (&mszReaders),
  429. &cchReaders,
  430. &dwState,
  431. &dwActiveProtocol,
  432. rgbAtr,
  433. &cbAtr);
  434. if (FAILED(dwSts))
  435. goto Ret;
  436. dwSts = SCardListCardsW(
  437. hSCardContext,
  438. rgbAtr,
  439. NULL,
  440. 0,
  441. (LPWSTR) (&mszCards),
  442. &cchCards);
  443. if (FAILED(dwSts))
  444. goto Ret;
  445. dwSts = SCardGetCardTypeProviderNameW(
  446. hSCardContext,
  447. mszCards,
  448. SCARD_PROVIDER_CARD_MODULE,
  449. (LPWSTR) (&pszProvider),
  450. &cchProvider);
  451. if (FAILED(dwSts))
  452. goto Ret;
  453. hMod = LoadLibraryW(pszProvider);
  454. if (INVALID_HANDLE_VALUE == hMod)
  455. {
  456. wprintf(L"LoadLibrary %s", pszProvider);
  457. dwSts = GetLastError();
  458. goto Ret;
  459. }
  460. pfnCardAcquireContext =
  461. (PFN_CARD_ACQUIRE_CONTEXT) GetProcAddress(
  462. hMod,
  463. "CardAcquireContext");
  464. if (NULL == pfnCardAcquireContext)
  465. {
  466. printf("GetProcAddress");
  467. dwSts = GetLastError();
  468. goto Ret;
  469. }
  470. pCardData = (PCARD_DATA) CspAllocH(sizeof(CARD_DATA));
  471. if (NULL == pCardData)
  472. {
  473. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  474. goto Ret;
  475. }
  476. pCardData->pbAtr = rgbAtr;
  477. pCardData->cbAtr = cbAtr;
  478. pCardData->pwszCardName = mszCards;
  479. pCardData->dwVersion = CARD_DATA_CURRENT_VERSION;
  480. pCardData->pfnCspAlloc = CspAllocH;
  481. pCardData->pfnCspReAlloc = CspReAllocH;
  482. pCardData->pfnCspFree = CspFreeH;
  483. pCardData->pfnCspCacheAddFile = CspCacheAddFile;
  484. pCardData->pfnCspCacheDeleteFile = CspCacheDeleteFile;
  485. pCardData->pfnCspCacheLookupFile = CspCacheLookupFile;
  486. pCardData->hScard = hSCardHandle;
  487. hSCardHandle = 0;
  488. //
  489. // Now start tests
  490. //
  491. // First, connect to the card
  492. TEST_CASE(pfnCardAcquireContext(pCardData, 0));
  493. //
  494. // Try to read a file from the card
  495. //
  496. TEST_CASE(pCardData->pfnCardReadFile(
  497. pCardData,
  498. wszCARD_IDENTIFIER_FILE_FULL_PATH,
  499. 0,
  500. &FileContents.pbData,
  501. &FileContents.cbData));
  502. //
  503. // Create a private key blob to import to the card
  504. //
  505. if (! CryptAcquireContext(
  506. &hProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  507. {
  508. dwSts = GetLastError();
  509. goto Ret;
  510. }
  511. //
  512. // For now, make this key really small so we're sure to not run out of
  513. // space on wimpy test cards.
  514. //
  515. if (! CryptGenKey(
  516. hProv, AT_KEYEXCHANGE, (1024 << 16) | CRYPT_EXPORTABLE, &hKey))
  517. {
  518. dwSts = GetLastError();
  519. goto Ret;
  520. }
  521. if (! CryptExportKey(
  522. hKey, 0, PRIVATEKEYBLOB, 0, NULL, &cbKey))
  523. {
  524. dwSts = GetLastError();
  525. goto Ret;
  526. }
  527. pbKey = (PBYTE) CspAllocH(cbKey);
  528. if (NULL == pbKey)
  529. {
  530. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  531. goto Ret;
  532. }
  533. if (! CryptExportKey(
  534. hKey, 0, PRIVATEKEYBLOB, 0, pbKey, &cbKey))
  535. {
  536. dwSts = GetLastError();
  537. goto Ret;
  538. }
  539. CryptDestroyKey(hKey);
  540. hKey = 0;
  541. //
  542. // Test challenge-response pin change and unblock
  543. //
  544. TEST_CASE(TestCardAuthenticateChallenge(pCardData));
  545. TEST_CASE(TestCardChangeAuthenticator(pCardData));
  546. TEST_CASE(TestCardUnblockPin(pCardData));
  547. //
  548. // Authenticate User
  549. //
  550. TEST_CASE(pCardData->pfnCardSubmitPin(
  551. pCardData,
  552. wszCARD_USER_USER,
  553. Pin.pbData,
  554. Pin.cbData,
  555. NULL));
  556. //
  557. // Now create a new container on the card via Key Import
  558. //
  559. TEST_CASE(pCardData->pfnCardCreateContainer(
  560. pCardData,
  561. bContainerIndex,
  562. CARD_CREATE_CONTAINER_KEY_IMPORT,
  563. AT_KEYEXCHANGE,
  564. cbKey,
  565. pbKey));
  566. //
  567. // Now create a signature key in the same container
  568. //
  569. pBlobHeader = (BLOBHEADER *) pbKey;
  570. pBlobHeader->aiKeyAlg = CALG_RSA_SIGN;
  571. TEST_CASE(pCardData->pfnCardCreateContainer(
  572. pCardData,
  573. bContainerIndex,
  574. CARD_CREATE_CONTAINER_KEY_IMPORT,
  575. AT_SIGNATURE,
  576. cbKey,
  577. pbKey));
  578. //
  579. // Get the Container Info for the new container
  580. //
  581. ContainerInfo.dwVersion = CONTAINER_INFO_CURRENT_VERSION;
  582. TEST_CASE(pCardData->pfnCardGetContainerInfo(
  583. pCardData,
  584. bContainerIndex,
  585. 0,
  586. &ContainerInfo));
  587. //
  588. // Use the public key blob that we got from the card and import it
  589. // into the software CSP.
  590. //
  591. if (! CryptImportKey(
  592. hProv,
  593. ContainerInfo.pbKeyExPublicKey,
  594. ContainerInfo.cbKeyExPublicKey,
  595. 0, 0, &hKey))
  596. {
  597. dwSts = GetLastError();
  598. goto Ret;
  599. }
  600. //
  601. // RSA Encrypt some data using the public key in the software
  602. // CSP.
  603. //
  604. cbData = 20;
  605. while (cbData--)
  606. rgbData[cbData] = (BYTE) cbData;
  607. cbData = 20;
  608. if (! CryptEncrypt(
  609. hKey, 0, TRUE, 0, rgbData, &cbData, sizeof(rgbData)))
  610. {
  611. dwSts = GetLastError();
  612. goto Ret;
  613. }
  614. CardPrivateKeyDecryptInfo.bContainerIndex = bContainerIndex;
  615. CardPrivateKeyDecryptInfo.dwKeySpec = AT_KEYEXCHANGE;
  616. CardPrivateKeyDecryptInfo.dwVersion =
  617. CARD_PRIVATE_KEY_DECRYPT_INFO_CURRENT_VERSION;
  618. CardPrivateKeyDecryptInfo.pbData = rgbData;
  619. CardPrivateKeyDecryptInfo.cbData = 1024 / 8;
  620. TEST_CASE(pCardData->pfnCardPrivateKeyDecrypt(
  621. pCardData,
  622. &CardPrivateKeyDecryptInfo));
  623. // CryptEncrypt byte-reversed the input portion of the plaintext, per
  624. // PKCS2.
  625. cbData = 20;
  626. while (cbData--)
  627. {
  628. if (cbData != rgbData[20 - (cbData + 1)])
  629. {
  630. printf("RSA decrypted blob doesn't match\n");
  631. dwSts = -1;
  632. goto Ret;
  633. }
  634. }
  635. //
  636. // Now delete the container
  637. //
  638. TEST_CASE(pCardData->pfnCardDeleteContainer(
  639. pCardData,
  640. bContainerIndex,
  641. 0));
  642. //
  643. // Create a few containers, enumerate them, then delete them.
  644. //
  645. TEST_CASE(TestCreateContainers(
  646. pCardData,
  647. pbKey,
  648. cbKey));
  649. //
  650. // Create a few "certificate" files, enumerate them, then delete them.
  651. //
  652. TEST_CASE(TestCreateCertificates(
  653. pCardData));
  654. //
  655. // Cleanup the card context
  656. //
  657. TEST_CASE(pCardData->pfnCardDeleteContext(pCardData));
  658. Ret:
  659. if (ContainerInfo.pbKeyExPublicKey)
  660. CspFreeH(ContainerInfo.pbKeyExPublicKey);
  661. if (ContainerInfo.pbSigPublicKey)
  662. CspFreeH(ContainerInfo.pbSigPublicKey);
  663. if (pbKey)
  664. CspFreeH(pbKey);
  665. if (hKey)
  666. CryptDestroyKey(hKey);
  667. if (hProv)
  668. CryptReleaseContext(hProv, 0);
  669. if (mszCards)
  670. SCardFreeMemory(hSCardContext, mszCards);
  671. if (mszReaders)
  672. SCardFreeMemory(hSCardContext, mszReaders);
  673. if (pszProvider)
  674. SCardFreeMemory(hSCardContext, pszProvider);
  675. if (hSCardHandle)
  676. SCardDisconnect(hSCardHandle, SCARD_RESET_CARD);
  677. if (FileContents.pbData)
  678. CspFreeH(FileContents.pbData);
  679. if (pCardData)
  680. {
  681. if (pCardData->hScard)
  682. SCardDisconnect(pCardData->hScard, SCARD_RESET_CARD);
  683. CspFreeH(pCardData);
  684. pCardData = NULL;
  685. }
  686. if (hSCardContext)
  687. SCardReleaseContext(hSCardContext);
  688. if (ERROR_SUCCESS != dwSts)
  689. printf(" failed, 0x%x\n", dwSts);
  690. else
  691. printf("Success.\n");
  692. return 0;
  693. }