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.

9310 lines
243 KiB

  1. /*
  2. CSPTestSuite.c
  3. 4/23/00 dangriff created
  4. ---Introduction---
  5. This is the framework code for the Cryptographic Service Provider Test Suite.
  6. External CSP types (such as PROV_RSA_SIG, defined in wincrypt.h) are internally assigned
  7. both a CSP_TYPE and a CLASS value (defined below). This combination of values determines
  8. which test cases and algorithms will be used to exercise a given CSP.
  9. ---Sample Test Execution---
  10. For a sample PROV_RSA_FULL CSP called "MyCSP", the test suite would be run with the following
  11. options:
  12. csptestsuite -n MyCSP -t 1
  13. The flow of the test in this example would be:
  14. * Lookup the test suite mappings for PROV_RSA_FULL. They are CSP_TYPE_RSA and
  15. CLASS_SIG_ONLY | CLASS_SIG_KEYX | CLASS_FULL.
  16. * Begin running all tests for CLASS_SIG_ONLY
  17. * Begin running all TEST_LEVEL_CSP tests for this class. For example, this test level
  18. consists of the API's CryptAcquireContext (partial; some CryptAcquireContext tests
  19. are TEST_LEVEL_CONTAINER), CryptGetProvParam, CryptSetProvParam, and CryptReleaseContext.
  20. Note that some TEST_LEVEL test case sets may be empty for a given class.
  21. * Begin running all TEST_LEVEL_PROV tests for this class
  22. * Begin running all TEST_LEVEL_HASH tests for this class
  23. * Begin running all TEST_LEVEL_KEY tests for this class
  24. * Begin running all TEST_LEVEL_CONTAINER tests for this class
  25. * Begin running all tests for CLASS_SIG_KEYX
  26. * Begin running all TEST_LEVEL_CSP tests for this class. Note that each TEST_LEVEL set of
  27. test cases for a given CLASS is unique. No individual test case will be run twice.
  28. * Similarly for TEST_LEVEL_PROV, TEST_LEVEL_HASH, TEST_LEVEL_KEY, and TEST_LEVEL_CONTAINER.
  29. * Begin running all tests for CLASS_FULL
  30. * As above for TEST_LEVEL_CSP, TEST_LEVEL_PROV, TEST_LEVEL_HASH, TEST_LEVEL_KEY,
  31. and TEST_LEVEL_CONTAINER.
  32. * End. Report the test results.
  33. ---Supported CSP Types---
  34. PROV_RSA_SIG
  35. PROV_RSA_FULL
  36. */
  37. #include <windows.h>
  38. #include <wincrypt.h>
  39. #include <stdlib.h>
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include "csptestsuite.h"
  43. #include "logging.h"
  44. #include "interop.h"
  45. #include "utils.h"
  46. //
  47. // Function: Usage
  48. // Purpose: Display list of command line options to console
  49. //
  50. void Usage()
  51. {
  52. WCHAR rgwsz [BUFFER_SIZE];
  53. wprintf(
  54. L"Usage: %s -c <CSP> [ -t <Test> ] [ -i <Interop CSP> ]\n",
  55. TEST_APP_NAME);
  56. wprintf(L"\n<Test> options:\n");
  57. TestCaseTypeToString(TEST_CASES_POSITIVE, rgwsz);
  58. wprintf(
  59. L" %d: %s (default)\n",
  60. TEST_CASES_POSITIVE,
  61. rgwsz);
  62. TestCaseTypeToString(TEST_CASES_NEGATIVE, rgwsz);
  63. wprintf(
  64. L" %d: %s\n",
  65. TEST_CASES_NEGATIVE,
  66. rgwsz);
  67. TestCaseTypeToString(TEST_CASES_SCENARIO, rgwsz);
  68. wprintf(
  69. L" %d: %s\n",
  70. TEST_CASES_SCENARIO,
  71. rgwsz);
  72. TestCaseTypeToString(TEST_CASES_INTEROP, rgwsz);
  73. wprintf(
  74. L" %d: %s\n",
  75. TEST_CASES_INTEROP,
  76. rgwsz);
  77. wprintf(L"\nLog file is %s in the current directory.\n", LOGFILE);
  78. }
  79. //
  80. // Function: IsVersionCorrect
  81. //
  82. //
  83. BOOL IsVersionCorrect(
  84. IN DWORD dwMajorVersion,
  85. IN DWORD dwMinorVersion,
  86. IN DWORD dwServicePackMajor,
  87. IN DWORD dwServicePackMinor)
  88. {
  89. DWORDLONG dwlConditionMask = 0;
  90. OSVERSIONINFOEX OsviEx;
  91. memset(&OsviEx, 0, sizeof(OsviEx));
  92. OsviEx.dwOSVersionInfoSize = sizeof(OsviEx);
  93. OsviEx.dwMajorVersion = dwMajorVersion;
  94. OsviEx.dwMinorVersion = dwMinorVersion;
  95. OsviEx.wServicePackMajor = (WORD) dwServicePackMajor;
  96. OsviEx.wServicePackMinor = (WORD) dwServicePackMinor;
  97. //
  98. // We want to check that the system has a less than
  99. // or equal Rev to the caller parameters.
  100. //
  101. dwlConditionMask =
  102. VerSetConditionMask(0, VER_MAJORVERSION, VER_LESS_EQUAL);
  103. dwlConditionMask =
  104. VerSetConditionMask(dwlConditionMask, VER_MINORVERSION, VER_LESS_EQUAL);
  105. dwlConditionMask =
  106. VerSetConditionMask(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_LESS_EQUAL);
  107. dwlConditionMask =
  108. VerSetConditionMask(dwlConditionMask, VER_SERVICEPACKMINOR, VER_LESS_EQUAL);
  109. return VerifyVersionInfo(
  110. &OsviEx,
  111. VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
  112. dwlConditionMask);
  113. }
  114. //
  115. // Function: GetNextRegisteredCSP
  116. //
  117. DWORD GetNextRegisteredCSP(
  118. OUT LPWSTR pwszCsp,
  119. IN OUT PDWORD pcbCsp,
  120. OUT PDWORD pdwProvType,
  121. IN DWORD dwRequestedIndex)
  122. {
  123. static DWORD dwNextEnumIndex = 0;
  124. DWORD dwActualIndex = 0;
  125. DWORD dwError = 0;
  126. dwActualIndex =
  127. (ENUMERATE_REGISTERED_CSP == dwRequestedIndex) ? dwNextEnumIndex : dwRequestedIndex;
  128. if (! CryptEnumProviders(
  129. dwActualIndex,
  130. NULL,
  131. 0,
  132. pdwProvType,
  133. pwszCsp,
  134. pcbCsp))
  135. {
  136. dwError = GetLastError();
  137. switch (dwError)
  138. {
  139. case ERROR_NO_MORE_ITEMS:
  140. dwNextEnumIndex = 0;
  141. break;
  142. }
  143. }
  144. else
  145. {
  146. if (ENUMERATE_REGISTERED_CSP == dwRequestedIndex)
  147. {
  148. dwNextEnumIndex++;
  149. }
  150. }
  151. return dwError;
  152. }
  153. //
  154. // -----------------
  155. // Utility functions
  156. // -----------------
  157. //
  158. //
  159. // Function: IsRequiredAlg
  160. //
  161. BOOL IsRequiredAlg(
  162. IN ALG_ID ai,
  163. IN DWORD dwInternalProvType)
  164. {
  165. DWORD cItems = 0;
  166. PALGID_TABLE pTable = NULL;
  167. switch (dwInternalProvType)
  168. {
  169. case CSP_TYPE_RSA:
  170. {
  171. cItems = sizeof(g_RequiredAlgs_RSA) / sizeof(ALGID_TABLE);
  172. pTable = g_RequiredAlgs_RSA;
  173. break;
  174. }
  175. case CSP_TYPE_AES:
  176. {
  177. cItems = sizeof(g_RequiredAlgs_AES) / sizeof(ALGID_TABLE);
  178. pTable = g_RequiredAlgs_AES;
  179. break;
  180. }
  181. default:
  182. {
  183. return FALSE;
  184. }
  185. }
  186. while (cItems > 0)
  187. {
  188. if (ai == pTable[cItems - 1].ai)
  189. {
  190. return TRUE;
  191. }
  192. else
  193. {
  194. cItems--;
  195. }
  196. }
  197. return FALSE;
  198. }
  199. //
  200. // Function: IsKnownAlg
  201. //
  202. BOOL IsKnownAlg(ALG_ID ai, DWORD dwInternalProvType)
  203. {
  204. DWORD cItems = 0;
  205. PALGID_TABLE pTable = NULL;
  206. switch (dwInternalProvType)
  207. {
  208. case CSP_TYPE_RSA:
  209. {
  210. cItems = sizeof(g_OtherKnownAlgs_RSA) / sizeof(ALGID_TABLE);
  211. pTable = g_OtherKnownAlgs_RSA;
  212. break;
  213. }
  214. case CSP_TYPE_AES:
  215. {
  216. cItems = sizeof(g_OtherKnownAlgs_AES) / sizeof(ALGID_TABLE);
  217. pTable = g_OtherKnownAlgs_AES;
  218. break;
  219. }
  220. default:
  221. {
  222. return FALSE;
  223. }
  224. }
  225. while (cItems > 0)
  226. {
  227. if (ai == pTable[cItems - 1].ai)
  228. {
  229. return TRUE;
  230. }
  231. else
  232. {
  233. cItems--;
  234. }
  235. }
  236. return FALSE;
  237. }
  238. //
  239. // -------------------
  240. // Crypto API wrappers
  241. // -------------------
  242. //
  243. //
  244. // Function: TAcquire
  245. // Purpose: Call CryptAcquireContext with the supplied parameters and pass
  246. // the result to the logging routine.
  247. //
  248. BOOL TAcquire(
  249. HCRYPTPROV *phProv,
  250. LPWSTR pszContainer,
  251. LPWSTR pszProvider,
  252. DWORD dwProvType,
  253. DWORD dwFlags,
  254. PTESTCASE ptc)
  255. {
  256. BOOL fApiSuccessful = FALSE;
  257. //BOOL fUnexpected = TRUE;
  258. BOOL fContinue = FALSE;
  259. DWORD cbData = sizeof(HCRYPTPROV);
  260. API_PARAM_INFO ParamInfo [] = {
  261. { L"phProv", Pointer, 0, NULL, TRUE, &cbData, NULL },
  262. { L"pszContainer", String, 0, NULL, FALSE, NULL, NULL },
  263. { L"pszProvider", String, 0, NULL, FALSE, NULL, NULL },
  264. { L"dwProvType", Dword, dwProvType, NULL, FALSE, NULL, NULL },
  265. { L"dwFlags", Dword, dwFlags, AcquireContextFlagToString, FALSE, NULL, NULL }
  266. };
  267. ParamInfo[0].pbParam = (PBYTE) phProv;
  268. ParamInfo[1].pwszParam = pszContainer;
  269. ParamInfo[2].pwszParam = pszProvider;
  270. if (NULL == phProv)
  271. {
  272. fApiSuccessful =
  273. CryptAcquireContext(
  274. NULL,
  275. pszContainer,
  276. pszProvider,
  277. dwProvType,
  278. dwFlags);
  279. }
  280. else
  281. {
  282. fApiSuccessful =
  283. CryptAcquireContext(
  284. phProv,
  285. pszContainer,
  286. pszProvider,
  287. dwProvType,
  288. dwFlags);
  289. }
  290. fContinue = CheckAndLogStatus(
  291. API_CRYPTACQUIRECONTEXT,
  292. fApiSuccessful,
  293. ptc,
  294. ParamInfo,
  295. APIPARAMINFO_SIZE(ParamInfo));
  296. return fContinue;
  297. }
  298. //
  299. // Function: TGetProv
  300. // Purpose: Call CryptGetProvParam with the supplied parameters and pass
  301. // the result to the logging routine.
  302. //
  303. BOOL TGetProv(
  304. HCRYPTPROV hProv,
  305. DWORD dwParam,
  306. BYTE *pbData,
  307. DWORD *pdwDataLen,
  308. DWORD dwFlags,
  309. PTESTCASE ptc)
  310. {
  311. BOOL fApiSuccessful = FALSE;
  312. //BOOL fUnexpected = TRUE;
  313. BOOL fContinue = FALSE;
  314. DWORD cbData = sizeof(DWORD);
  315. API_PARAM_INFO ParamInfo [] = {
  316. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  317. { L"dwParam", Dword, dwParam, GetProvParamToString, FALSE, NULL, NULL },
  318. { L"pbData", Pointer, 0, NULL, TRUE, pdwDataLen, NULL },
  319. { L"pdwDataLen", Pointer, 0, NULL, TRUE, &cbData, NULL },
  320. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL }
  321. };
  322. ParamInfo[0].pulParam = hProv;
  323. ParamInfo[2].pbParam = pbData;
  324. ParamInfo[3].pbParam = (PBYTE) pdwDataLen;
  325. switch (dwParam)
  326. {
  327. case PP_ENUMALGS:
  328. case PP_ENUMALGS_EX:
  329. case PP_ENUMCONTAINERS:
  330. {
  331. ParamInfo[4].pfnFlagToString = ProvParamEnumFlagToString;
  332. break;
  333. }
  334. case PP_KEYSET_SEC_DESCR:
  335. {
  336. ParamInfo[4].pfnFlagToString = ProvParamSecDescrFlagToString;
  337. break;
  338. }
  339. case PP_IMPTYPE:
  340. {
  341. ParamInfo[4].pfnFlagToString = ProvParamImpTypeToString;
  342. break;
  343. }
  344. }
  345. if (! ptc->fEnumerating)
  346. {
  347. if (! LogInitParamInfo(
  348. ParamInfo,
  349. APIPARAMINFO_SIZE(ParamInfo),
  350. ptc))
  351. {
  352. return FALSE;
  353. }
  354. }
  355. fApiSuccessful = CryptGetProvParam(hProv, dwParam, pbData, pdwDataLen, dwFlags);
  356. if (ptc->fEnumerating)
  357. {
  358. return fApiSuccessful;
  359. }
  360. fContinue = CheckAndLogStatus(
  361. API_CRYPTGETPROVPARAM,
  362. fApiSuccessful,
  363. ptc,
  364. ParamInfo,
  365. APIPARAMINFO_SIZE(ParamInfo));
  366. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  367. return fContinue;
  368. }
  369. //
  370. // Function: TSetProv
  371. // Purpose: Call CryptSetProvParam with the supplied parameters and pass
  372. // the result to the logging routine.
  373. //
  374. BOOL TSetProv(
  375. HCRYPTPROV hProv,
  376. DWORD dwParam,
  377. BYTE *pbData,
  378. DWORD dwFlags,
  379. PTESTCASE ptc)
  380. {
  381. BOOL fApiSuccessful = FALSE;
  382. //BOOL fUnexpected = TRUE;
  383. BOOL fContinue = FALSE;
  384. API_PARAM_INFO ParamInfo [] = {
  385. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  386. { L"dwParam", Dword, dwParam, SetProvParamToString, FALSE, NULL, NULL },
  387. { L"pbData", Pointer, 0, NULL, FALSE, NULL, NULL },
  388. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL }
  389. };
  390. ParamInfo[0].pulParam = hProv;
  391. ParamInfo[2].pbParam = pbData;
  392. switch (dwParam)
  393. {
  394. case PP_KEYSET_SEC_DESCR:
  395. {
  396. ParamInfo[3].pfnFlagToString = ProvParamSecDescrFlagToString;
  397. break;
  398. }
  399. case PP_IMPTYPE:
  400. {
  401. ParamInfo[3].pfnFlagToString = ProvParamImpTypeToString;
  402. break;
  403. }
  404. }
  405. fApiSuccessful = CryptSetProvParam(hProv, dwParam, pbData, dwFlags);
  406. fContinue = CheckAndLogStatus(
  407. API_CRYPTSETPROVPARAM,
  408. fApiSuccessful,
  409. ptc,
  410. ParamInfo,
  411. APIPARAMINFO_SIZE(ParamInfo));
  412. return fContinue;
  413. }
  414. //
  415. // Function: TRelease
  416. // Purpose: Call CryptReleaseContext with the supplied parameters and pass
  417. // the result to the logging routine.
  418. //
  419. BOOL TRelease(
  420. HCRYPTPROV hProv,
  421. DWORD dwFlags,
  422. PTESTCASE ptc)
  423. {
  424. BOOL fApiSuccessful = FALSE;
  425. //BOOL fUnexpected = TRUE;
  426. BOOL fContinue = FALSE;
  427. BOOL fSavedExpectSuccess = ptc->fExpectSuccess;
  428. API_PARAM_INFO ParamInfo [] = {
  429. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  430. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL }
  431. };
  432. ParamInfo[0].pulParam = hProv;
  433. if (! ptc->fTestingReleaseContext)
  434. {
  435. ptc->fExpectSuccess = TRUE;
  436. }
  437. fApiSuccessful = CryptReleaseContext(hProv, dwFlags);
  438. fContinue = CheckAndLogStatus(
  439. API_CRYPTRELEASECONTEXT,
  440. fApiSuccessful,
  441. ptc,
  442. ParamInfo,
  443. APIPARAMINFO_SIZE(ParamInfo));
  444. ptc->fExpectSuccess = fSavedExpectSuccess;
  445. return fContinue;
  446. }
  447. //
  448. // Function: TGenRand
  449. // Purpose: Call CryptGenRandom with the supplied parameters and pass
  450. // the result to the logging routine.
  451. //
  452. BOOL TGenRand(
  453. HCRYPTPROV hProv,
  454. DWORD dwLen,
  455. BYTE *pbBuffer,
  456. PTESTCASE ptc)
  457. {
  458. BOOL fApiSuccessful = FALSE;
  459. //BOOL fUnexpected = TRUE;
  460. BOOL fContinue = FALSE;
  461. API_PARAM_INFO ParamInfo [] = {
  462. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  463. { L"dwLen", Dword, dwLen, NULL, FALSE, NULL, NULL },
  464. { L"pbBuffer", Pointer, 0, NULL, FALSE, NULL, NULL }
  465. };
  466. ParamInfo[0].pulParam = hProv;
  467. ParamInfo[2].pbParam = pbBuffer;
  468. fApiSuccessful = CryptGenRandom(hProv, dwLen, pbBuffer);
  469. fContinue = CheckAndLogStatus(
  470. API_CRYPTGENRANDOM,
  471. fApiSuccessful,
  472. ptc,
  473. ParamInfo,
  474. APIPARAMINFO_SIZE(ParamInfo));
  475. return fContinue;
  476. }
  477. //
  478. // Function: TCreateHash
  479. // Purpose: Call CryptCreateHash with the supplied parameters and pass
  480. // the result to the logging routine.
  481. //
  482. BOOL TCreateHash(
  483. HCRYPTPROV hProv,
  484. ALG_ID Algid,
  485. HCRYPTKEY hKey,
  486. DWORD dwFlags,
  487. HCRYPTHASH *phHash,
  488. PTESTCASE ptc)
  489. {
  490. BOOL fApiSuccessful = FALSE;
  491. //BOOL fUnexpected = TRUE;
  492. BOOL fContinue = FALSE;
  493. DWORD cbData = sizeof(HCRYPTHASH);
  494. API_PARAM_INFO ParamInfo [] = {
  495. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  496. { L"Algid", Dword, Algid, AlgidToString, FALSE, NULL, NULL },
  497. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL },
  498. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL },
  499. { L"phHash", Pointer, 0, NULL, TRUE, &cbData, NULL }
  500. };
  501. ParamInfo[0].pulParam = hProv;
  502. ParamInfo[2].pulParam = hKey;
  503. ParamInfo[4].pbParam = (PBYTE) phHash;
  504. fApiSuccessful = CryptCreateHash(hProv, Algid, hKey, dwFlags, phHash);
  505. fContinue = CheckAndLogStatus(
  506. API_CRYPTCREATEHASH,
  507. fApiSuccessful,
  508. ptc,
  509. ParamInfo,
  510. APIPARAMINFO_SIZE(ParamInfo));
  511. return fContinue;
  512. }
  513. //
  514. // Function: TDestroyHash
  515. // Purpose: Call CryptDestroyHash with the supplied parameters and pass
  516. // the result to the logging routine.
  517. //
  518. BOOL TDestroyHash(
  519. HCRYPTHASH hHash,
  520. PTESTCASE ptc)
  521. {
  522. BOOL fApiSuccessful = FALSE;
  523. //BOOL fUnexpected = TRUE;
  524. BOOL fContinue = FALSE;
  525. BOOL fSavedExpectSuccess = ptc->fExpectSuccess;
  526. API_PARAM_INFO ParamInfo [] = {
  527. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL }
  528. };
  529. ParamInfo[0].pulParam = hHash;
  530. if (! ptc->fTestingDestroyHash)
  531. {
  532. ptc->fExpectSuccess = TRUE;
  533. }
  534. fApiSuccessful = CryptDestroyHash(hHash);
  535. fContinue = CheckAndLogStatus(
  536. API_CRYPTDESTROYHASH,
  537. fApiSuccessful,
  538. ptc,
  539. ParamInfo,
  540. APIPARAMINFO_SIZE(ParamInfo));
  541. ptc->fExpectSuccess = fSavedExpectSuccess;
  542. return fContinue;
  543. }
  544. //
  545. // Function: TDuplicateHash
  546. // Purpose: Call CryptDuplicateHash with the supplied parameters and pass
  547. // the result to the logging routine.
  548. //
  549. BOOL TDuplicateHash(
  550. HCRYPTHASH hHash,
  551. DWORD *pdwReserved,
  552. DWORD dwFlags,
  553. HCRYPTHASH *phHash,
  554. PTESTCASE ptc)
  555. {
  556. BOOL fApiSuccessful = FALSE;
  557. //BOOL fUnexpected = TRUE;
  558. BOOL fContinue = FALSE;
  559. API_PARAM_INFO ParamInfo [] = {
  560. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  561. { L"pdwReserved", Pointer, 0, NULL, FALSE, NULL, NULL },
  562. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL },
  563. { L"phHash", Pointer, 0, NULL, FALSE, NULL, NULL }
  564. };
  565. ParamInfo[0].pulParam = hHash;
  566. ParamInfo[1].pbParam = (PBYTE) pdwReserved;
  567. ParamInfo[3].pbParam = (PBYTE) phHash;
  568. fApiSuccessful = CryptDuplicateHash(hHash, pdwReserved, dwFlags, phHash);
  569. fContinue = CheckAndLogStatus(
  570. API_CRYPTDUPLICATEHASH,
  571. fApiSuccessful,
  572. ptc,
  573. ParamInfo,
  574. APIPARAMINFO_SIZE(ParamInfo));
  575. return fContinue;
  576. }
  577. //
  578. // Function: TGetHash
  579. // Purpose: Call CryptGetHashParam with the supplied parameters and pass
  580. // the result to the logging routine.
  581. //
  582. BOOL TGetHash(
  583. HCRYPTHASH hHash,
  584. DWORD dwParam,
  585. BYTE *pbData,
  586. DWORD *pdwDataLen,
  587. DWORD dwFlags,
  588. PTESTCASE ptc)
  589. {
  590. BOOL fApiSuccessful = FALSE;
  591. //BOOL fUnexpected = TRUE;
  592. BOOL fContinue = FALSE;
  593. DWORD cbData = sizeof(DWORD);
  594. API_PARAM_INFO ParamInfo [] = {
  595. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  596. { L"dwParam", Dword, dwParam, HashParamToString, FALSE, NULL, NULL },
  597. { L"pbData", Pointer, 0, NULL, TRUE, pdwDataLen, NULL },
  598. { L"pdwDataLen", Pointer, 0, NULL, TRUE, &cbData, NULL },
  599. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL }
  600. };
  601. ParamInfo[0].pulParam = hHash;
  602. ParamInfo[2].pbParam = pbData;
  603. ParamInfo[3].pbParam = (PBYTE) pdwDataLen;
  604. if (! LogInitParamInfo(
  605. ParamInfo,
  606. APIPARAMINFO_SIZE(ParamInfo),
  607. ptc))
  608. {
  609. return FALSE;
  610. }
  611. fApiSuccessful = CryptGetHashParam(hHash, dwParam, pbData, pdwDataLen, dwFlags);
  612. fContinue = CheckAndLogStatus(
  613. API_CRYPTGETHASHPARAM,
  614. fApiSuccessful,
  615. ptc,
  616. ParamInfo,
  617. APIPARAMINFO_SIZE(ParamInfo));
  618. LogCleanupParamInfo(
  619. ParamInfo,
  620. APIPARAMINFO_SIZE(ParamInfo));
  621. return fContinue;
  622. }
  623. //
  624. // Function: THashData
  625. // Purpose: Call CryptHashData with the supplied parameters and pass
  626. // the result to the logging routine.
  627. //
  628. BOOL THashData(
  629. HCRYPTHASH hHash,
  630. BYTE *pbData,
  631. DWORD dwDataLen,
  632. DWORD dwFlags,
  633. PTESTCASE ptc)
  634. {
  635. BOOL fApiSuccessful = FALSE;
  636. //BOOL fUnexpected = TRUE;
  637. BOOL fContinue = FALSE;
  638. API_PARAM_INFO ParamInfo [] = {
  639. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  640. { L"pbData", Pointer, 0, NULL, TRUE, &dwDataLen, NULL },
  641. { L"dwDataLen", Dword, dwDataLen, NULL, FALSE, NULL, NULL },
  642. { L"dwFlags", Dword, dwFlags, HashDataFlagToString, FALSE, NULL, NULL }
  643. };
  644. ParamInfo[0].pulParam = hHash;
  645. ParamInfo[1].pbParam = pbData;
  646. if (! LogInitParamInfo(
  647. ParamInfo,
  648. APIPARAMINFO_SIZE(ParamInfo),
  649. ptc))
  650. {
  651. return FALSE;
  652. }
  653. fApiSuccessful = CryptHashData(hHash, pbData, dwDataLen, dwFlags);
  654. fContinue = CheckAndLogStatus(
  655. API_CRYPTHASHDATA,
  656. fApiSuccessful,
  657. ptc,
  658. ParamInfo,
  659. APIPARAMINFO_SIZE(ParamInfo));
  660. LogCleanupParamInfo(
  661. ParamInfo,
  662. APIPARAMINFO_SIZE(ParamInfo));
  663. return fContinue;
  664. }
  665. //
  666. // Function: TSetHash
  667. // Purpose: Call CryptSetHashParam with the supplied parameters and pass
  668. // the result to the logging routine.
  669. //
  670. BOOL TSetHash(
  671. HCRYPTHASH hHash,
  672. DWORD dwParam,
  673. BYTE *pbData,
  674. DWORD dwFlags,
  675. PTESTCASE ptc)
  676. {
  677. BOOL fApiSuccessful = FALSE;
  678. //BOOL fUnexpected = TRUE;
  679. BOOL fContinue = FALSE;
  680. API_PARAM_INFO ParamInfo [] = {
  681. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  682. { L"dwParam", Dword, dwParam, HashParamToString, FALSE, NULL, NULL },
  683. { L"pbData", Pointer, 0, NULL, FALSE, NULL, NULL },
  684. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL }
  685. };
  686. ParamInfo[0].pulParam = hHash;
  687. ParamInfo[2].pbParam = pbData;
  688. fApiSuccessful = CryptSetHashParam(hHash, dwParam, pbData, dwFlags);
  689. fContinue = CheckAndLogStatus(
  690. API_CRYPTSETHASHPARAM,
  691. fApiSuccessful,
  692. ptc,
  693. ParamInfo,
  694. APIPARAMINFO_SIZE(ParamInfo));
  695. return fContinue;
  696. }
  697. //
  698. // Function: TDecrypt
  699. // Purpose: Call CryptDecrypt with the supplied parameters and pass
  700. // the result to the logging routine.
  701. //
  702. BOOL TDecrypt(
  703. HCRYPTKEY hKey,
  704. HCRYPTHASH hHash,
  705. BOOL Final,
  706. DWORD dwFlags,
  707. BYTE *pbData,
  708. DWORD *pdwDataLen,
  709. PTESTCASE ptc)
  710. {
  711. BOOL fApiSuccessful = FALSE;
  712. //BOOL fUnexpected = TRUE;
  713. BOOL fContinue = FALSE;
  714. DWORD cbData = sizeof(DWORD);
  715. API_PARAM_INFO ParamInfo [] = {
  716. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL },
  717. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  718. { L"Final", Boolean, 0, NULL, FALSE, NULL, NULL },
  719. { L"dwFlags", Dword, dwFlags, EncryptFlagToString, FALSE, NULL, NULL },
  720. { L"pbData", Pointer, 0, NULL, TRUE, pdwDataLen, NULL },
  721. { L"pdwDataLen", Pointer, 0, NULL, TRUE, &cbData, NULL },
  722. };
  723. ParamInfo[0].pulParam = hKey;
  724. ParamInfo[1].pulParam = hHash;
  725. ParamInfo[2].fParam = Final;
  726. ParamInfo[4].pbParam = pbData;
  727. ParamInfo[5].pbParam = (PBYTE) pdwDataLen;
  728. if (! LogInitParamInfo(
  729. ParamInfo,
  730. APIPARAMINFO_SIZE(ParamInfo),
  731. ptc))
  732. {
  733. return FALSE;
  734. }
  735. fApiSuccessful = CryptDecrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
  736. fContinue = CheckAndLogStatus(
  737. API_CRYPTDECRYPT,
  738. fApiSuccessful,
  739. ptc,
  740. ParamInfo,
  741. APIPARAMINFO_SIZE(ParamInfo));
  742. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  743. return fContinue;
  744. }
  745. //
  746. // Function: TDeriveKey
  747. // Purpose: Call CryptDeriveKey with the supplied parameters and pass
  748. // the result to the logging routine.
  749. //
  750. BOOL TDeriveKey(
  751. HCRYPTPROV hProv,
  752. ALG_ID Algid,
  753. HCRYPTHASH hBaseData,
  754. DWORD dwFlags,
  755. HCRYPTKEY *phKey,
  756. PTESTCASE ptc)
  757. {
  758. BOOL fApiSuccessful = FALSE;
  759. //BOOL fUnexpected = TRUE;
  760. BOOL fContinue = FALSE;
  761. API_PARAM_INFO ParamInfo [] = {
  762. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  763. { L"Algid", Dword, Algid, AlgidToString, FALSE, NULL, NULL },
  764. { L"hBaseData", Handle, 0, NULL, FALSE, NULL, NULL },
  765. { L"dwFlags", Dword, dwFlags, DeriveKeyFlagToString,FALSE, NULL, NULL },
  766. { L"phKey", Pointer, 0, NULL, FALSE, NULL, NULL}
  767. };
  768. ParamInfo[0].pulParam = hProv;
  769. ParamInfo[2].pulParam = hBaseData;
  770. ParamInfo[4].pbParam = (PBYTE) phKey;
  771. fApiSuccessful = CryptDeriveKey(hProv, Algid, hBaseData, dwFlags, phKey);
  772. fContinue = CheckAndLogStatus(
  773. API_CRYPTDERIVEKEY,
  774. fApiSuccessful,
  775. ptc,
  776. ParamInfo,
  777. APIPARAMINFO_SIZE(ParamInfo));
  778. return fContinue;
  779. }
  780. //
  781. // Function: TDestroyKey
  782. // Purpose: Call CryptDestroyKey with the supplied parameters and pass
  783. // the result to the logging routine.
  784. //
  785. BOOL TDestroyKey(
  786. HCRYPTKEY hKey,
  787. PTESTCASE ptc)
  788. {
  789. BOOL fApiSuccessful = FALSE;
  790. //BOOL fUnexpected = TRUE;
  791. BOOL fContinue = FALSE;
  792. BOOL fSavedExpectSuccess = ptc->fExpectSuccess;
  793. API_PARAM_INFO ParamInfo [] = {
  794. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL }
  795. };
  796. ParamInfo[0].pulParam = hKey;
  797. if (! ptc->fTestingDestroyKey)
  798. {
  799. ptc->fExpectSuccess = TRUE;
  800. }
  801. fApiSuccessful = CryptDestroyKey(hKey);
  802. fContinue = CheckAndLogStatus(
  803. API_CRYPTDESTROYKEY,
  804. fApiSuccessful,
  805. ptc,
  806. ParamInfo,
  807. APIPARAMINFO_SIZE(ParamInfo));
  808. ptc->fExpectSuccess = fSavedExpectSuccess;
  809. return fContinue;
  810. }
  811. //
  812. // Function: TEncrypt
  813. // Purpose: Call CryptEncrypt with the supplied parameters and pass
  814. // the result to the logging routine.
  815. //
  816. BOOL TEncrypt(
  817. HCRYPTKEY hKey,
  818. HCRYPTHASH hHash,
  819. BOOL Final,
  820. DWORD dwFlags,
  821. BYTE *pbData,
  822. DWORD *pdwDataLen,
  823. DWORD dwBufLen,
  824. PTESTCASE ptc)
  825. {
  826. BOOL fApiSuccessful = FALSE;
  827. //BOOL fUnexpected = TRUE;
  828. BOOL fContinue = FALSE;
  829. DWORD cbData = sizeof(DWORD);
  830. API_PARAM_INFO ParamInfo [] = {
  831. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL },
  832. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  833. { L"Final", Boolean, 0, NULL, FALSE, NULL, NULL },
  834. { L"dwFlags", Dword, dwFlags, EncryptFlagToString,FALSE, NULL, NULL },
  835. { L"pbData", Pointer, 0, NULL, TRUE, pdwDataLen, NULL },
  836. { L"pdwDataLen", Pointer, 0, NULL, TRUE, &cbData, NULL },
  837. { L"dwBufLen", Dword, dwBufLen, NULL, FALSE, NULL, NULL}
  838. };
  839. ParamInfo[0].pulParam = hKey;
  840. ParamInfo[1].pulParam = hHash;
  841. ParamInfo[2].fParam = Final;
  842. ParamInfo[4].pbParam = pbData;
  843. ParamInfo[5].pbParam = (PBYTE) pdwDataLen;
  844. if (! LogInitParamInfo(
  845. ParamInfo,
  846. APIPARAMINFO_SIZE(ParamInfo),
  847. ptc))
  848. {
  849. return FALSE;
  850. }
  851. fApiSuccessful = CryptEncrypt(hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
  852. fContinue = CheckAndLogStatus(
  853. API_CRYPTENCRYPT,
  854. fApiSuccessful,
  855. ptc,
  856. ParamInfo,
  857. APIPARAMINFO_SIZE(ParamInfo));
  858. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  859. return fContinue;
  860. }
  861. //
  862. // Function: TGenKey
  863. // Purpose: Call CryptGenKey with the supplied parameters and pass
  864. // the result to the logging routine.
  865. //
  866. BOOL TGenKey(
  867. HCRYPTPROV hProv,
  868. ALG_ID Algid,
  869. DWORD dwFlags,
  870. HCRYPTKEY *phKey,
  871. PTESTCASE ptc)
  872. {
  873. BOOL fApiSuccessful = FALSE;
  874. //BOOL fUnexpected = TRUE;
  875. BOOL fContinue = FALSE;
  876. DWORD cbData = sizeof(HCRYPTKEY);
  877. API_PARAM_INFO ParamInfo [] = {
  878. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  879. { L"Algid", Dword, Algid, AlgidToString, FALSE, NULL, NULL },
  880. { L"dwFlags", Dword, dwFlags, GenKeyFlagToString, FALSE, NULL, NULL },
  881. { L"phKey", Pointer, 0, NULL, TRUE, &cbData, NULL }
  882. };
  883. ParamInfo[0].pulParam = hProv;
  884. ParamInfo[3].pbParam = (PBYTE) phKey;
  885. //
  886. // Prompt the user of the test suite when a user protected
  887. // key is being created, UNLESS this is a negative test case.
  888. //
  889. if ( (CRYPT_USER_PROTECTED & dwFlags) &&
  890. ptc->fExpectSuccess)
  891. {
  892. LogCreatingUserProtectedKey();
  893. //LogInfo(L"Creating a User Protected key. You should now see UI.");
  894. }
  895. fApiSuccessful = CryptGenKey(hProv, Algid, dwFlags, phKey);
  896. fContinue = CheckAndLogStatus(
  897. API_CRYPTGENKEY,
  898. fApiSuccessful,
  899. ptc,
  900. ParamInfo,
  901. APIPARAMINFO_SIZE(ParamInfo));
  902. return fContinue;
  903. }
  904. //
  905. // Function: TGetKey
  906. // Purpose: Call CryptGetKeyParam with the supplied parameters and pass
  907. // the result to the logging routine.
  908. //
  909. BOOL TGetKey(
  910. HCRYPTKEY hKey,
  911. DWORD dwParam,
  912. BYTE *pbData,
  913. DWORD *pdwDataLen,
  914. DWORD dwFlags,
  915. PTESTCASE ptc)
  916. {
  917. BOOL fApiSuccessful = FALSE;
  918. //BOOL fUnexpected = TRUE;
  919. BOOL fContinue = FALSE;
  920. DWORD cbData = sizeof(DWORD);
  921. API_PARAM_INFO ParamInfo [] = {
  922. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL },
  923. { L"dwParam", Dword, dwParam, KeyParamToString, FALSE, NULL, NULL },
  924. { L"pbData", Pointer, 0, NULL, TRUE, pdwDataLen, NULL },
  925. { L"pdwDataLen", Pointer, 0, NULL, TRUE, &cbData, NULL },
  926. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL }
  927. };
  928. ParamInfo[0].pulParam = hKey;
  929. ParamInfo[2].pbParam = pbData;
  930. ParamInfo[3].pbParam = (PBYTE) pdwDataLen;
  931. switch (dwParam)
  932. {
  933. case KP_MODE:
  934. {
  935. ParamInfo[4].pfnFlagToString = KeyParamModeToString;
  936. break;
  937. }
  938. case KP_PERMISSIONS:
  939. {
  940. ParamInfo[4].pfnFlagToString = KeyParamPermissionToString;
  941. break;
  942. }
  943. }
  944. if (! LogInitParamInfo(
  945. ParamInfo,
  946. APIPARAMINFO_SIZE(ParamInfo),
  947. ptc))
  948. {
  949. return FALSE;
  950. }
  951. fApiSuccessful = CryptGetKeyParam(hKey, dwParam, pbData, pdwDataLen, dwFlags);
  952. fContinue = CheckAndLogStatus(
  953. API_CRYPTGETKEYPARAM,
  954. fApiSuccessful,
  955. ptc,
  956. ParamInfo,
  957. APIPARAMINFO_SIZE(ParamInfo));
  958. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  959. return fContinue;
  960. }
  961. //
  962. // Function: THashSession
  963. // Purpose: Call CryptHashSessionKey with the supplied parameters and pass
  964. // the result to the logging routine.
  965. //
  966. BOOL THashSession(
  967. HCRYPTHASH hHash,
  968. HCRYPTKEY hKey,
  969. DWORD dwFlags,
  970. PTESTCASE ptc)
  971. {
  972. BOOL fApiSuccessful = FALSE;
  973. //BOOL fUnexpected = TRUE;
  974. BOOL fContinue = FALSE;
  975. API_PARAM_INFO ParamInfo [] = {
  976. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  977. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL },
  978. { L"dwFlags", Dword, dwFlags, HashSessionKeyFlagToString, FALSE, NULL, NULL }
  979. };
  980. ParamInfo[0].pulParam = hHash;
  981. ParamInfo[1].pulParam = hKey;
  982. fApiSuccessful = CryptHashSessionKey(hHash, hKey, dwFlags);
  983. fContinue = CheckAndLogStatus(
  984. API_CRYPTHASHSESSIONKEY,
  985. fApiSuccessful,
  986. ptc,
  987. ParamInfo,
  988. APIPARAMINFO_SIZE(ParamInfo));
  989. return fContinue;
  990. }
  991. //
  992. // Function: TSetKey
  993. // Purpose: Call CryptSetKeyParam with the supplied parameters and pass
  994. // the result to the logging routine.
  995. //
  996. BOOL TSetKey(
  997. HCRYPTKEY hKey,
  998. DWORD dwParam,
  999. BYTE *pbData,
  1000. DWORD dwFlags,
  1001. PTESTCASE ptc)
  1002. {
  1003. BOOL fApiSuccessful = FALSE;
  1004. //BOOL fUnexpected = TRUE;
  1005. BOOL fContinue = FALSE;
  1006. DWORD cbData = 0;
  1007. DWORD cbParam = 0;
  1008. API_PARAM_INFO ParamInfo [] = {
  1009. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL },
  1010. { L"dwParam", Dword, dwParam, KeyParamToString, FALSE, NULL, NULL },
  1011. { L"pbData", Pointer, 0, NULL, FALSE, NULL, NULL },
  1012. { L"dwFlags", Dword, dwFlags, NULL, FALSE, NULL, NULL }
  1013. };
  1014. ParamInfo[0].pulParam = hKey;
  1015. ParamInfo[2].pbParam = pbData;
  1016. switch (dwParam)
  1017. {
  1018. case KP_IV:
  1019. {
  1020. // Try to determine how long the IV buffer should be
  1021. cbData = 0;
  1022. if (CryptGetKeyParam(hKey, KP_IV, NULL, &cbData, 0) && cbData)
  1023. {
  1024. ParamInfo[2].fPrintBytes = TRUE;
  1025. ParamInfo[2].pcbBytes = &cbData;
  1026. }
  1027. break;
  1028. }
  1029. case KP_SALT:
  1030. {
  1031. // Try to determine how long the salt buffer should be
  1032. cbParam = sizeof(cbData);
  1033. if (CryptGetKeyParam(hKey, KP_SALT, (PBYTE) &cbData, &cbParam, 0) && cbData)
  1034. {
  1035. ParamInfo[2].fPrintBytes = TRUE;
  1036. ParamInfo[2].pcbBytes = &cbData;
  1037. }
  1038. break;
  1039. }
  1040. case KP_SALT_EX:
  1041. {
  1042. if (pbData != NULL && pbData != (PBYTE) TEST_INVALID_POINTER)
  1043. {
  1044. cbData = sizeof(DWORD) + ((PDATA_BLOB) pbData)->cbData;
  1045. ParamInfo[2].fPrintBytes = TRUE;
  1046. ParamInfo[2].pcbBytes = &cbData;
  1047. }
  1048. break;
  1049. }
  1050. case KP_PERMISSIONS:
  1051. {
  1052. ParamInfo[3].pfnFlagToString = KeyParamPermissionToString;
  1053. // fall through
  1054. }
  1055. case KP_ALGID:
  1056. case KP_EFFECTIVE_KEYLEN:
  1057. case KP_PADDING:
  1058. case KP_MODE_BITS:
  1059. {
  1060. cbData = sizeof(DWORD);
  1061. ParamInfo[2].fPrintBytes = TRUE;
  1062. ParamInfo[2].pcbBytes = &cbData;
  1063. break;
  1064. }
  1065. case KP_MODE:
  1066. {
  1067. cbData = sizeof(DWORD);
  1068. ParamInfo[2].fPrintBytes = TRUE;
  1069. ParamInfo[2].pcbBytes = &cbData;
  1070. ParamInfo[3].pfnFlagToString = KeyParamModeToString;
  1071. break;
  1072. }
  1073. }
  1074. if (! LogInitParamInfo(
  1075. ParamInfo,
  1076. APIPARAMINFO_SIZE(ParamInfo),
  1077. ptc))
  1078. {
  1079. return FALSE;
  1080. }
  1081. fApiSuccessful = CryptSetKeyParam(hKey, dwParam, pbData, dwFlags);
  1082. fContinue = CheckAndLogStatus(
  1083. API_CRYPTSETKEYPARAM,
  1084. fApiSuccessful,
  1085. ptc,
  1086. ParamInfo,
  1087. APIPARAMINFO_SIZE(ParamInfo));
  1088. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  1089. return fContinue;
  1090. }
  1091. //
  1092. // Function: TExportKey
  1093. // Purpose: Call CryptExportKey with the supplied parameters and pass
  1094. // the result to the logging routine.
  1095. //
  1096. BOOL TExportKey(
  1097. HCRYPTKEY hKey,
  1098. HCRYPTKEY hExpKey,
  1099. DWORD dwBlobType,
  1100. DWORD dwFlags,
  1101. BYTE *pbData,
  1102. DWORD *pdwDataLen,
  1103. PTESTCASE ptc)
  1104. {
  1105. BOOL fApiSuccessful = FALSE;
  1106. //BOOL fUnexpected = TRUE;
  1107. BOOL fContinue = FALSE;
  1108. DWORD cbData = sizeof(DWORD);
  1109. API_PARAM_INFO ParamInfo [] = {
  1110. { L"hKey", Handle, 0, NULL, FALSE, NULL, NULL },
  1111. { L"hExpKey", Handle, 0, NULL, FALSE, NULL, NULL },
  1112. { L"dwBlobType", Dword, dwBlobType, ExportKeyBlobTypeToString, FALSE, NULL, NULL },
  1113. { L"dwFlags", Dword, dwFlags, ExportKeyFlagToString, FALSE, NULL, NULL },
  1114. { L"pbData", Pointer, 0, NULL, TRUE, pdwDataLen, NULL },
  1115. { L"pdwDataLen", Pointer, 0, NULL, TRUE, &cbData, NULL }
  1116. };
  1117. ParamInfo[0].pulParam = hKey;
  1118. ParamInfo[1].pulParam = hExpKey;
  1119. ParamInfo[4].pbParam = pbData;
  1120. ParamInfo[5].pbParam = (PBYTE) pdwDataLen;
  1121. if (! LogInitParamInfo(
  1122. ParamInfo,
  1123. APIPARAMINFO_SIZE(ParamInfo),
  1124. ptc))
  1125. {
  1126. return FALSE;
  1127. }
  1128. fApiSuccessful = CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, pbData, pdwDataLen);
  1129. fContinue = CheckAndLogStatus(
  1130. API_CRYPTEXPORTKEY,
  1131. fApiSuccessful,
  1132. ptc,
  1133. ParamInfo,
  1134. APIPARAMINFO_SIZE(ParamInfo));
  1135. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  1136. return fContinue;
  1137. }
  1138. //
  1139. // Function: TGetUser
  1140. // Purpose: Call CryptGetUserKey with the supplied parameters and pass
  1141. // the result to the logging routine.
  1142. //
  1143. BOOL TGetUser(
  1144. HCRYPTPROV hProv,
  1145. DWORD dwKeySpec,
  1146. HCRYPTKEY *phUserKey,
  1147. PTESTCASE ptc)
  1148. {
  1149. BOOL fApiSuccessful = FALSE;
  1150. //BOOL fUnexpected = TRUE;
  1151. BOOL fContinue = FALSE;
  1152. API_PARAM_INFO ParamInfo [] = {
  1153. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  1154. { L"dwKeySpec", Dword, dwKeySpec, AlgidToString, FALSE, NULL, NULL },
  1155. { L"phUserKey", Pointer, 0, NULL, FALSE, NULL, NULL }
  1156. };
  1157. ParamInfo[0].pulParam = hProv;
  1158. ParamInfo[2].pbParam = (PBYTE) phUserKey;
  1159. fApiSuccessful = CryptGetUserKey(hProv, dwKeySpec, phUserKey);
  1160. fContinue = CheckAndLogStatus(
  1161. API_CRYPTGETUSERKEY,
  1162. fApiSuccessful,
  1163. ptc,
  1164. ParamInfo,
  1165. APIPARAMINFO_SIZE(ParamInfo));
  1166. return fContinue;
  1167. }
  1168. //
  1169. // Function: TImportKey
  1170. // Purpose: Call CryptImportKey with the supplied parameters and pass
  1171. // the result to the logging routine.
  1172. //
  1173. BOOL TImportKey(
  1174. HCRYPTPROV hProv,
  1175. BYTE *pbData,
  1176. DWORD dwDataLen,
  1177. HCRYPTKEY hPubKey,
  1178. DWORD dwFlags,
  1179. HCRYPTKEY *phKey,
  1180. PTESTCASE ptc)
  1181. {
  1182. BOOL fApiSuccessful = FALSE;
  1183. //BOOL fUnexpected = TRUE;
  1184. BOOL fContinue = FALSE;
  1185. DWORD cbData = sizeof(HCRYPTKEY);
  1186. API_PARAM_INFO ParamInfo [] = {
  1187. { L"hProv", Handle, 0, NULL, FALSE, NULL, NULL },
  1188. { L"pbData", Pointer, 0, NULL, TRUE, &dwDataLen, NULL },
  1189. { L"dwDataLen", Dword, dwDataLen, NULL, FALSE, NULL, NULL },
  1190. { L"hPubKey", Handle, 0, NULL, FALSE, NULL, NULL },
  1191. { L"dwFlags", Dword, dwFlags, ImportKeyFlagToString,FALSE,NULL, NULL },
  1192. { L"phKey", Pointer, 0, NULL, TRUE, &cbData, NULL }
  1193. };
  1194. ParamInfo[0].pulParam = hProv;
  1195. ParamInfo[1].pbParam = pbData;
  1196. ParamInfo[3].pulParam = hPubKey;
  1197. ParamInfo[5].pbParam = (PBYTE) phKey;
  1198. if (! LogInitParamInfo(
  1199. ParamInfo,
  1200. APIPARAMINFO_SIZE(ParamInfo),
  1201. ptc))
  1202. {
  1203. return FALSE;
  1204. }
  1205. fApiSuccessful = CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
  1206. fContinue = CheckAndLogStatus(
  1207. API_CRYPTIMPORTKEY,
  1208. fApiSuccessful,
  1209. ptc,
  1210. ParamInfo,
  1211. APIPARAMINFO_SIZE(ParamInfo));
  1212. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  1213. return fContinue;
  1214. }
  1215. //
  1216. // Function: TSignHash
  1217. // Purpose: Call CryptSignHash with the supplied parameters and pass
  1218. // the result to the logging routine.
  1219. //
  1220. BOOL TSignHash(
  1221. HCRYPTHASH hHash,
  1222. DWORD dwKeySpec,
  1223. LPWSTR sDescription,
  1224. DWORD dwFlags,
  1225. BYTE *pbSignature,
  1226. DWORD *pdwSigLen,
  1227. PTESTCASE ptc)
  1228. {
  1229. BOOL fApiSuccessful = FALSE;
  1230. //BOOL fUnexpected = TRUE;
  1231. BOOL fContinue = FALSE;
  1232. DWORD cbData = sizeof(DWORD);
  1233. API_PARAM_INFO ParamInfo [] = {
  1234. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  1235. { L"dwKeySpec", Dword, dwKeySpec, AlgidToString, FALSE, NULL, NULL },
  1236. { L"sDescription", String, 0, NULL, FALSE, NULL, NULL },
  1237. { L"dwFlags", Dword, dwFlags, SignHashFlagToString,FALSE, NULL, NULL },
  1238. { L"pbData", Pointer, 0, NULL, TRUE, pdwSigLen, NULL},
  1239. { L"pdwSigLen", Pointer, 0, NULL, TRUE, &cbData, NULL}
  1240. };
  1241. ParamInfo[0].pulParam = hHash;
  1242. ParamInfo[2].pwszParam = sDescription;
  1243. ParamInfo[4].pbParam = pbSignature;
  1244. ParamInfo[5].pbParam = (PBYTE) pdwSigLen;
  1245. if (! LogInitParamInfo(
  1246. ParamInfo,
  1247. APIPARAMINFO_SIZE(ParamInfo),
  1248. ptc))
  1249. {
  1250. return FALSE;
  1251. }
  1252. fApiSuccessful = CryptSignHash(hHash, dwKeySpec, sDescription, dwFlags, pbSignature, pdwSigLen);
  1253. fContinue = CheckAndLogStatus(
  1254. API_CRYPTSIGNHASH,
  1255. fApiSuccessful,
  1256. ptc,
  1257. ParamInfo,
  1258. APIPARAMINFO_SIZE(ParamInfo));
  1259. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  1260. return fContinue;
  1261. }
  1262. //
  1263. // Function: TVerifySign
  1264. // Purpose: Call CryptVerifySign with the supplied parameters and pass
  1265. // the result to the logging routine.
  1266. //
  1267. BOOL TVerifySign(
  1268. HCRYPTHASH hHash,
  1269. BYTE *pbSignature,
  1270. DWORD dwSigLen,
  1271. HCRYPTKEY hPubKey,
  1272. LPWSTR sDescription,
  1273. DWORD dwFlags,
  1274. PTESTCASE ptc)
  1275. {
  1276. BOOL fApiSuccessful = FALSE;
  1277. //BOOL fUnexpected = TRUE;
  1278. BOOL fContinue = FALSE;
  1279. API_PARAM_INFO ParamInfo [] = {
  1280. { L"hHash", Handle, 0, NULL, FALSE, NULL, NULL },
  1281. { L"pbSignature", Pointer, 0, NULL, TRUE, &dwSigLen, NULL},
  1282. { L"dwSigLen", Dword, dwSigLen, NULL, FALSE, NULL, NULL },
  1283. { L"hPubKey", Handle, 0, NULL, FALSE, NULL, NULL },
  1284. { L"sDescription", String, 0, NULL, FALSE, NULL, NULL },
  1285. { L"dwFlags", Dword, dwFlags, SignHashFlagToString,FALSE, NULL, NULL }
  1286. };
  1287. ParamInfo[0].pulParam = hHash;
  1288. ParamInfo[1].pbParam = pbSignature;
  1289. ParamInfo[3].pulParam = hPubKey;
  1290. ParamInfo[4].pwszParam = sDescription;
  1291. if (! LogInitParamInfo(
  1292. ParamInfo,
  1293. APIPARAMINFO_SIZE(ParamInfo),
  1294. ptc))
  1295. {
  1296. return FALSE;
  1297. }
  1298. fApiSuccessful = CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, sDescription, dwFlags);
  1299. fContinue = CheckAndLogStatus(
  1300. API_CRYPTVERIFYSIGNATURE,
  1301. fApiSuccessful,
  1302. ptc,
  1303. ParamInfo,
  1304. APIPARAMINFO_SIZE(ParamInfo));
  1305. LogCleanupParamInfo(ParamInfo, APIPARAMINFO_SIZE(ParamInfo));
  1306. return fContinue;
  1307. }
  1308. // -------------
  1309. // Test Routines
  1310. // -------------
  1311. //
  1312. // Function: PositiveAcquireContextTests
  1313. // Purpose: Run the appropriate set of positive CryptAcquireContext test cases for
  1314. // the passed in dwCSPClass.
  1315. //
  1316. BOOL PositiveAcquireContextTests(PCSPINFO pCSPInfo)
  1317. {
  1318. BOOL fSuccess = FALSE;
  1319. HCRYPTPROV hProv = 0;
  1320. DWORD dwProvType = LogGetProvType();
  1321. LPWSTR pwszProvName = LogGetProvName();
  1322. LPWSTR pwszContainer = TEST_CONTAINER;
  1323. //LPWSTR pwszContainer2 = TEST_CONTAINER_2;
  1324. //DWORD dwFlags = 0;
  1325. PTESTCASE ptc = &(pCSPInfo->TestCase);
  1326. switch (ptc->dwTestLevel)
  1327. {
  1328. case TEST_LEVEL_CSP:
  1329. {
  1330. //
  1331. // Group 1A
  1332. //
  1333. //
  1334. // Do CSP-level positive CryptAcquireContext tests
  1335. //
  1336. LOG_TRY(TAcquire(&hProv, NULL, pwszProvName, dwProvType, CRYPT_VERIFYCONTEXT, ptc));
  1337. break;
  1338. }
  1339. case TEST_LEVEL_CONTAINER:
  1340. {
  1341. //
  1342. // Group 5A
  1343. //
  1344. //
  1345. // Do Container-level positive CryptAcquireContext tests
  1346. //
  1347. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  1348. LOG_TRY(TRelease(hProv, 0, ptc));
  1349. hProv = 0;
  1350. LOG_TRY(TAcquire(&hProv, pwszContainer, pwszProvName, dwProvType, CRYPT_SILENT, ptc));
  1351. LOG_TRY(TRelease(hProv, 0, ptc));
  1352. LOG_TRY(CreateNewContext(
  1353. &hProv,
  1354. pwszContainer,
  1355. CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET,
  1356. ptc));
  1357. LOG_TRY(TRelease(hProv, 0, ptc));
  1358. hProv = 0;
  1359. LOG_TRY(TAcquire(
  1360. &hProv,
  1361. pwszContainer,
  1362. pwszProvName,
  1363. dwProvType,
  1364. CRYPT_MACHINE_KEYSET | CRYPT_SILENT,
  1365. ptc));
  1366. break;
  1367. }
  1368. }
  1369. fSuccess = TRUE;
  1370. Cleanup:
  1371. if (hProv)
  1372. {
  1373. TRelease(hProv, 0, ptc);
  1374. }
  1375. return fSuccess;
  1376. }
  1377. //
  1378. // Function: NegativeAcquireContextTests
  1379. // Purpose: Run the appropriate set of negative CryptAcquireContext test cases
  1380. // based on the dwTestLevel parameter.
  1381. //
  1382. BOOL NegativeAcquireContextTests(PCSPINFO pCSPInfo)
  1383. {
  1384. BOOL fSuccess = FALSE;
  1385. HCRYPTPROV hProv = 0;
  1386. DWORD dwProvType = LogGetProvType();
  1387. LPWSTR pwszProvName = LogGetProvName();
  1388. LPWSTR pwszContainer = TEST_CONTAINER;
  1389. DWORD dwFlags = 0;
  1390. DWORD dwSavedErrorLevel = 0;
  1391. PTESTCASE ptc = &(pCSPInfo->TestCase);
  1392. switch (ptc->dwTestLevel)
  1393. {
  1394. case TEST_LEVEL_CSP:
  1395. {
  1396. //
  1397. // Do CSP-level negative CryptAcquireContext tests
  1398. //
  1399. dwFlags = CRYPT_VERIFYCONTEXT;
  1400. //
  1401. // This fails on Win2K because the VTable is constructed correctly, but
  1402. // the NULL phProv causes an AV. The bug is that the API returns True
  1403. // anyway.
  1404. //
  1405. // 7/20/00 -- Whistler status for this issue is unknown.
  1406. //
  1407. ptc->pwszErrorHelp = L"CryptAcquireContext should fail when phProv is NULL";
  1408. ptc->KnownErrorID = KNOWN_CRYPTACQUIRECONTEXT_NULLPHPROV;
  1409. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  1410. LOG_TRY(TAcquire(NULL, NULL, pwszProvName, dwProvType, dwFlags, ptc));
  1411. ptc->pwszErrorHelp = NULL;
  1412. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  1413. ptc->dwErrorCode = NTE_BAD_FLAGS;
  1414. LOG_TRY(TAcquire(&hProv, pwszContainer, pwszProvName, dwProvType, dwFlags, ptc));
  1415. //
  1416. // This fails on Win2K because the VERIFYCONTEXT flag is caught first. The API
  1417. // succeeds unexpectedly.
  1418. //
  1419. // 7/20/00 -- Whistler status for this issue is unknown.
  1420. //
  1421. ptc->pwszErrorHelp = L"This is an invalid combination of dwFlags values";
  1422. ptc->KnownErrorID = KNOWN_CRYPTACQUIRECONTEXT_BADFLAGS;
  1423. ptc->dwErrorCode = NTE_BAD_FLAGS;
  1424. LOG_TRY(TAcquire(&hProv, NULL, pwszProvName, dwProvType, CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET, ptc));
  1425. ptc->pwszErrorHelp = NULL;
  1426. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  1427. break;
  1428. }
  1429. case TEST_LEVEL_CONTAINER:
  1430. {
  1431. //
  1432. // Do Container-level negative CryptAcquireContext tests
  1433. //
  1434. ptc->dwErrorCode = NTE_BAD_KEYSET;
  1435. LOG_TRY(TAcquire(
  1436. &hProv,
  1437. TEST_CRYPTACQUIRECONTEXT_CONTAINER,
  1438. pwszProvName,
  1439. dwProvType,
  1440. 0,
  1441. ptc));
  1442. //
  1443. // Test for risky characters in a container name
  1444. //
  1445. dwSavedErrorLevel = ptc->dwErrorLevel;
  1446. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  1447. ptc->pwszErrorHelp = L"Some CSP's may not support container names with backslashes";
  1448. ptc->dwErrorCode = NTE_BAD_KEYSET_PARAM;
  1449. // Make sure this container doesn't already exist
  1450. CryptAcquireContext(&hProv, L"FOO\\BAR", pwszProvName, dwProvType, CRYPT_DELETEKEYSET);
  1451. LOG_TRY(TAcquire(&hProv, L"FOO\\BAR", pwszProvName, dwProvType, CRYPT_NEWKEYSET, ptc));
  1452. ptc->dwErrorLevel = dwSavedErrorLevel;
  1453. ptc->pwszErrorHelp = NULL;
  1454. // Create the keyset
  1455. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  1456. // Try to create the keyset again
  1457. ptc->dwErrorCode = NTE_EXISTS;
  1458. LOG_TRY(TAcquire(&hProv, pwszContainer, pwszProvName, dwProvType, CRYPT_NEWKEYSET, ptc));
  1459. break;
  1460. }
  1461. }
  1462. fSuccess = TRUE;
  1463. Cleanup:
  1464. if (hProv)
  1465. {
  1466. TRelease(hProv, 0, ptc);
  1467. }
  1468. return fSuccess;
  1469. }
  1470. //
  1471. // Function: TestBuildAlgList
  1472. // Purpose: A wrapper for the BuildAlgList function
  1473. //
  1474. BOOL TestBuildAlgList(PCSPINFO pCSPInfo)
  1475. {
  1476. BOOL fSuccess = FALSE;
  1477. HCRYPTPROV hProv = 0;
  1478. PTESTCASE ptc = &(pCSPInfo->TestCase);
  1479. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  1480. LOG_TRY(BuildAlgList(hProv, pCSPInfo));
  1481. fSuccess = TRUE;
  1482. Cleanup:
  1483. if (hProv)
  1484. {
  1485. TRelease(hProv, 0, ptc);
  1486. }
  1487. return fSuccess;
  1488. }
  1489. //
  1490. // Function: CheckEnumalgs
  1491. // Purpose: Call CryptGetProvParam with the PP_ENUMALGS flag to enumerate
  1492. // all the CSP's supported algorithms. Compare the results of this enumeration
  1493. // to the results of the PP_ENUMALGS_EX enumeration contained in the pAlgList
  1494. // param.
  1495. //
  1496. BOOL CheckEnumalgs(
  1497. IN HCRYPTPROV hProv,
  1498. IN PALGNODE pAlgList,
  1499. IN PTESTCASE ptc)
  1500. {
  1501. BOOL fContinue = TRUE;
  1502. //PBYTE pbData = NULL;
  1503. DWORD cbData = 0;
  1504. DWORD dwFlags = CRYPT_FIRST;
  1505. PROV_ENUMALGS ProvEnumalgs;
  1506. DWORD dw = 0;
  1507. //DWORD dwWinError = 0;
  1508. //DWORD dwErrorType = 0;
  1509. WCHAR rgwszError [ BUFFER_SIZE ];
  1510. memset(&ProvEnumalgs, 0, sizeof(ProvEnumalgs));
  1511. cbData = sizeof(ProvEnumalgs);
  1512. ptc->fEnumerating = TRUE;
  1513. LogTestCaseSeparator(FALSE); // Log a blank line first
  1514. LogInfo(L"CryptGetProvParam PP_ENUMALGS: enumerating supported algorithms");
  1515. while( TGetProv(
  1516. hProv,
  1517. PP_ENUMALGS,
  1518. (PBYTE) &ProvEnumalgs,
  1519. &cbData,
  1520. dwFlags,
  1521. ptc))
  1522. {
  1523. // Increment the test case counter for every enumerated alg
  1524. ++ptc->dwTestCaseID;
  1525. if (NULL == pAlgList)
  1526. {
  1527. ptc->pwszErrorHelp = L"PP_ENUMALGS_EX enumerated fewer algorithms than PP_ENUMALGS";
  1528. LOG_TRY(LogApiFailure(
  1529. API_CRYPTGETPROVPARAM,
  1530. ERROR_LIST_TOO_SHORT,
  1531. ptc));
  1532. ptc->pwszErrorHelp = NULL;
  1533. }
  1534. if ( ProvEnumalgs.aiAlgid != pAlgList->ProvEnumalgsEx.aiAlgid ||
  1535. ProvEnumalgs.dwBitLen != pAlgList->ProvEnumalgsEx.dwDefaultLen ||
  1536. ProvEnumalgs.dwNameLen != pAlgList->ProvEnumalgsEx.dwNameLen ||
  1537. 0 != strcmp(ProvEnumalgs.szName, pAlgList->ProvEnumalgsEx.szName) )
  1538. {
  1539. if (CALG_MAC == ProvEnumalgs.aiAlgid)
  1540. {
  1541. ptc->KnownErrorID = KNOWN_CRYPTGETPROVPARAM_MAC;
  1542. }
  1543. wsprintf(
  1544. rgwszError,
  1545. L"%s: %s",
  1546. L"PP_ENUMALGS data doesn't match PP_ENUMALGS_EX data for the following algorithm",
  1547. ProvEnumalgs.szName);
  1548. ptc->pwszErrorHelp = rgwszError;
  1549. LOG_TRY(LogApiFailure(
  1550. API_CRYPTGETPROVPARAM,
  1551. ERROR_BAD_DATA,
  1552. ptc));
  1553. ptc->pwszErrorHelp = NULL;
  1554. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  1555. }
  1556. pAlgList = pAlgList->pAlgNodeNext;
  1557. if (CRYPT_FIRST == dwFlags)
  1558. {
  1559. dwFlags = 0;
  1560. }
  1561. LogProvEnumalgs(&ProvEnumalgs);
  1562. }
  1563. if (ERROR_NO_MORE_ITEMS != (dw = GetLastError()))
  1564. {
  1565. ptc->pwszErrorHelp = L"PP_ENUMALGS failed unexpectedly";
  1566. ptc->dwErrorCode = ERROR_NO_MORE_ITEMS;
  1567. ptc->fExpectSuccess = FALSE;
  1568. LOG_TRY(LogApiFailure(
  1569. API_CRYPTGETPROVPARAM,
  1570. ERROR_WRONG_ERROR_CODE,
  1571. ptc));
  1572. }
  1573. ptc->fEnumerating = FALSE;
  1574. fContinue = TRUE;
  1575. Cleanup:
  1576. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  1577. ptc->pwszErrorHelp = NULL;
  1578. return fContinue;
  1579. }
  1580. //
  1581. // Function: CheckRequiredAlgs
  1582. // Purpose: Verify that all of the required algorithms
  1583. // for CSP's of this type are supported by this CSP.
  1584. //
  1585. BOOL CheckRequiredAlgs(PCSPINFO pCSPInfo)
  1586. {
  1587. BOOL fSuccess = FALSE;
  1588. DWORD dwCSPClass = pCSPInfo->dwCSPInternalClass;
  1589. PTESTCASE ptc = &(pCSPInfo->TestCase);
  1590. PALGNODE pAlgList = pCSPInfo->pAlgList;
  1591. PALGNODE pAlgNode = NULL;
  1592. DWORD iTable = 0;
  1593. BOOL fFound = FALSE;
  1594. WCHAR rgsz[BUFFER_SIZE];
  1595. //
  1596. // For each required alg for dwCSPClass, verify
  1597. // that the alg is listed in pAlgList. If it's not,
  1598. // assume that this CSP doesn't support that alg
  1599. // and flag an error.
  1600. //
  1601. LogTestCaseSeparator(FALSE); // Log a blank line first
  1602. LogInfo(L"List of Required algorithms for this CSP type");
  1603. for (
  1604. iTable = 0;
  1605. iTable < sizeof(g_RequiredAlgs_RSA) / sizeof(ALGID_TABLE);
  1606. iTable++)
  1607. {
  1608. if (! (dwCSPClass & g_RequiredAlgs_RSA[iTable].dwCSPClass))
  1609. {
  1610. continue;
  1611. }
  1612. fFound = FALSE;
  1613. AlgidToString(g_RequiredAlgs_RSA[iTable].ai, rgsz);
  1614. LogInfo(rgsz);
  1615. //
  1616. // Search pAlgList for the current ALG_ID
  1617. //
  1618. for (
  1619. pAlgNode = pAlgList;
  1620. pAlgNode != NULL && (! fFound);
  1621. pAlgNode = pAlgNode->pAlgNodeNext)
  1622. {
  1623. if (g_RequiredAlgs_RSA[iTable].ai == pAlgNode->ProvEnumalgsEx.aiAlgid)
  1624. {
  1625. fFound = TRUE;
  1626. }
  1627. }
  1628. if (! fFound)
  1629. {
  1630. LOG_TRY(LogApiFailure(
  1631. API_CRYPTGETPROVPARAM,
  1632. ERROR_REQUIRED_ALG,
  1633. ptc));
  1634. }
  1635. }
  1636. fSuccess = TRUE;
  1637. Cleanup:
  1638. return fSuccess;
  1639. }
  1640. //
  1641. // Function: PositiveGetProvParamTests
  1642. // Purpose: Run the test cases for CryptGetProvParam
  1643. //
  1644. BOOL PositiveGetProvParamTests(PCSPINFO pCSPInfo)
  1645. {
  1646. BOOL fSuccess = FALSE;
  1647. HCRYPTPROV hProv = 0;
  1648. LPWSTR pwszContainer = TEST_CONTAINER;
  1649. PBYTE pbData = NULL;
  1650. DWORD dwData = 0;
  1651. DWORD dwFlags = CRYPT_FIRST;
  1652. DWORD cbData = 0;
  1653. DWORD dwError = 0;
  1654. DWORD dwSavedErrorLevel = 0;
  1655. LPWSTR pwsz = NULL;
  1656. PTESTCASE ptc = &(pCSPInfo->TestCase);
  1657. switch (ptc->dwTestLevel)
  1658. {
  1659. case TEST_LEVEL_CSP:
  1660. {
  1661. //
  1662. // Group 1B
  1663. //
  1664. //
  1665. // Do CryptGetProvParam positive test cases
  1666. //
  1667. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  1668. LOG_TRY(BuildAlgList(hProv, pCSPInfo));
  1669. LOG_TRY(CheckEnumalgs(hProv, pCSPInfo->pAlgList, ptc));
  1670. ptc->fExpectSuccess = TRUE;
  1671. LOG_TRY(CheckRequiredAlgs(pCSPInfo));
  1672. //
  1673. // Test PP_IMPTYPE
  1674. //
  1675. cbData = sizeof(dwData);
  1676. LOG_TRY(TGetProv(
  1677. hProv,
  1678. PP_IMPTYPE,
  1679. (PBYTE) &dwData,
  1680. &cbData,
  1681. 0,
  1682. ptc));
  1683. if (CRYPT_IMPL_SOFTWARE != dwData)
  1684. {
  1685. // Set the expected behavior for a non-software-only
  1686. // CSP.
  1687. pCSPInfo->fSmartCardCSP = TRUE;
  1688. }
  1689. //
  1690. // Test PP_NAME
  1691. //
  1692. LOG_TRY(TGetProv(
  1693. hProv,
  1694. PP_NAME,
  1695. NULL,
  1696. &cbData,
  1697. 0,
  1698. ptc));
  1699. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  1700. LOG_TRY(TGetProv(
  1701. hProv,
  1702. PP_NAME,
  1703. pbData,
  1704. &cbData,
  1705. 0,
  1706. ptc));
  1707. ptc->KnownErrorID = KNOWN_CRYPTGETPROVPARAM_PPNAME;
  1708. if (0 != wcscmp(
  1709. (LPWSTR) pbData,
  1710. pCSPInfo->pwszCSPName))
  1711. {
  1712. ptc->pwszErrorHelp = L"CryptGetProvParam PP_NAME is not Unicode";
  1713. LOG_TRY(LogApiFailure(
  1714. API_CRYPTGETPROVPARAM,
  1715. ERROR_BAD_DATA,
  1716. ptc));
  1717. ptc->pwszErrorHelp = NULL;
  1718. }
  1719. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  1720. free(pbData);
  1721. pbData = NULL;
  1722. //
  1723. // Test PP_VERSION
  1724. //
  1725. cbData = sizeof(dwData);
  1726. LOG_TRY(TGetProv(
  1727. hProv,
  1728. PP_VERSION,
  1729. (PBYTE) &dwData,
  1730. &cbData,
  1731. 0,
  1732. ptc));
  1733. //
  1734. // Test PP_SIG_KEYSIZE_INC
  1735. //
  1736. cbData = sizeof(dwData);
  1737. LOG_TRY(TGetProv(
  1738. hProv,
  1739. PP_SIG_KEYSIZE_INC,
  1740. (PBYTE) &dwData,
  1741. &cbData,
  1742. 0,
  1743. ptc));
  1744. pCSPInfo->dwSigKeysizeInc = dwData;
  1745. //
  1746. // Test PP_KEYX_KEYSIZE_INC
  1747. //
  1748. cbData = sizeof(dwData);
  1749. LOG_TRY(TGetProv(
  1750. hProv,
  1751. PP_KEYX_KEYSIZE_INC,
  1752. (PBYTE) &dwData,
  1753. &cbData,
  1754. 0,
  1755. ptc));
  1756. pCSPInfo->dwKeyXKeysizeInc = dwData;
  1757. //
  1758. // Test PP_PROVTYPE
  1759. //
  1760. cbData = sizeof(dwData);
  1761. LOG_TRY(TGetProv(
  1762. hProv,
  1763. PP_PROVTYPE,
  1764. (PBYTE) &dwData,
  1765. &cbData,
  1766. 0,
  1767. ptc));
  1768. if (dwData != pCSPInfo->dwExternalProvType)
  1769. {
  1770. ptc->pwszErrorHelp = L"CryptGetProvParam PP_PROVTYPE is incorrect";
  1771. LOG_TRY(LogApiFailure(
  1772. API_CRYPTGETPROVPARAM,
  1773. ERROR_BAD_DATA,
  1774. ptc));
  1775. ptc->pwszErrorHelp = NULL;
  1776. }
  1777. //
  1778. // Test PP_USE_HARDWARE_RNG
  1779. //
  1780. // TODO - dumb down the error level of this test case, since most
  1781. // CSP's will probably return FALSE
  1782. //
  1783. dwSavedErrorLevel = ptc->dwErrorLevel;
  1784. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  1785. ptc->pwszErrorHelp =
  1786. L"CryptGetProvParam reports that this system has no hardware Random Number Generator configured";
  1787. cbData = 0;
  1788. LOG_TRY(TGetProv(
  1789. hProv,
  1790. PP_USE_HARDWARE_RNG,
  1791. NULL,
  1792. &cbData,
  1793. 0,
  1794. ptc));
  1795. ptc->dwErrorLevel = dwSavedErrorLevel;
  1796. ptc->pwszErrorHelp = NULL;
  1797. //
  1798. // Test PP_KEYSPEC
  1799. //
  1800. cbData = sizeof(dwData);
  1801. LOG_TRY(TGetProv(
  1802. hProv,
  1803. PP_KEYSPEC,
  1804. (PBYTE) &dwData,
  1805. &cbData,
  1806. 0,
  1807. ptc));
  1808. pCSPInfo->dwKeySpec = dwData;
  1809. break;
  1810. }
  1811. case TEST_LEVEL_CONTAINER:
  1812. {
  1813. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  1814. //
  1815. // Do PP_ENUMCONTAINERS enumeration
  1816. //
  1817. dwFlags = CRYPT_FIRST;
  1818. ptc->fEnumerating = TRUE;
  1819. LogInfo(L"PP_ENUMCONTAINERS: enumerating user containers");
  1820. while (TEST_INVALID_FLAG != dwFlags)
  1821. {
  1822. while( TGetProv(
  1823. hProv,
  1824. PP_ENUMCONTAINERS,
  1825. NULL,
  1826. &cbData,
  1827. dwFlags,
  1828. ptc))
  1829. {
  1830. if (NULL != pbData)
  1831. {
  1832. free(pbData);
  1833. }
  1834. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  1835. LOG_TRY(TGetProv(
  1836. hProv,
  1837. PP_ENUMCONTAINERS,
  1838. pbData,
  1839. &cbData,
  1840. dwFlags,
  1841. ptc));
  1842. pwsz = MkWStr((LPSTR) pbData);
  1843. if (pwsz)
  1844. {
  1845. LogInfo(pwsz);
  1846. free(pwsz);
  1847. }
  1848. if (CRYPT_FIRST & dwFlags)
  1849. {
  1850. dwFlags ^= CRYPT_FIRST;
  1851. }
  1852. }
  1853. if (ERROR_NO_MORE_ITEMS != (dwError = GetLastError()))
  1854. {
  1855. ptc->fExpectSuccess = FALSE;
  1856. ptc->dwErrorCode = ERROR_NO_MORE_ITEMS;
  1857. ptc->pwszErrorHelp = L"PP_ENUMCONTAINERS failed unexpectedly";
  1858. LOG_TRY(LogApiFailure(
  1859. API_CRYPTGETPROVPARAM,
  1860. ERROR_WRONG_ERROR_CODE,
  1861. ptc));
  1862. ptc->pwszErrorHelp = NULL;
  1863. }
  1864. if (CRYPT_MACHINE_KEYSET != dwFlags)
  1865. {
  1866. dwFlags = CRYPT_MACHINE_KEYSET | CRYPT_FIRST;
  1867. LogInfo(L"PP_ENUMCONTAINERS: enumerating local machine containers");
  1868. }
  1869. else
  1870. {
  1871. dwFlags = TEST_INVALID_FLAG;
  1872. }
  1873. }
  1874. ptc->fEnumerating = FALSE;
  1875. ptc->fExpectSuccess = TRUE;
  1876. //
  1877. // Test PP_KEYSET_SEC_DESCR
  1878. //
  1879. cbData = sizeof(dwData);
  1880. LOG_TRY(TGetProv(
  1881. hProv,
  1882. PP_KEYSET_SEC_DESCR,
  1883. (PBYTE) &dwData,
  1884. &cbData,
  1885. OWNER_SECURITY_INFORMATION,
  1886. ptc));
  1887. cbData = sizeof(dwData);
  1888. LOG_TRY(TGetProv(
  1889. hProv,
  1890. PP_KEYSET_SEC_DESCR,
  1891. (PBYTE) &dwData,
  1892. &cbData,
  1893. GROUP_SECURITY_INFORMATION,
  1894. ptc));
  1895. cbData = sizeof(dwData);
  1896. LOG_TRY(TGetProv(
  1897. hProv,
  1898. PP_KEYSET_SEC_DESCR,
  1899. (PBYTE) &dwData,
  1900. &cbData,
  1901. DACL_SECURITY_INFORMATION,
  1902. ptc));
  1903. cbData = sizeof(dwData);
  1904. LOG_TRY(TGetProv(
  1905. hProv,
  1906. PP_KEYSET_SEC_DESCR,
  1907. (PBYTE) &dwData,
  1908. &cbData,
  1909. SACL_SECURITY_INFORMATION,
  1910. ptc));
  1911. //
  1912. // Test PP_UNIQUE_CONTAINER
  1913. //
  1914. LOG_TRY(TGetProv(
  1915. hProv,
  1916. PP_UNIQUE_CONTAINER,
  1917. NULL,
  1918. &cbData,
  1919. 0,
  1920. ptc));
  1921. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  1922. LOG_TRY(TGetProv(
  1923. hProv,
  1924. PP_UNIQUE_CONTAINER,
  1925. pbData,
  1926. &cbData,
  1927. 0,
  1928. ptc));
  1929. free(pbData);
  1930. pbData = NULL;
  1931. break;
  1932. }
  1933. }
  1934. fSuccess = TRUE;
  1935. Cleanup:
  1936. if (hProv)
  1937. {
  1938. TRelease(hProv, 0, ptc);
  1939. }
  1940. if (pbData)
  1941. {
  1942. free(pbData);
  1943. }
  1944. return fSuccess;
  1945. }
  1946. //
  1947. // Function: NegativeGetProvParamTests
  1948. // Purpose: Run the negative test cases for CryptGetProvParam
  1949. //
  1950. BOOL NegativeGetProvParamTests(PCSPINFO pCSPInfo)
  1951. {
  1952. BOOL fSuccess = FALSE;
  1953. HCRYPTPROV hProv = 0;
  1954. //LPWSTR pwszContainer = TEST_CONTAINER;
  1955. //PBYTE pbData = NULL;
  1956. DWORD dwData = 0;
  1957. DWORD cbData = 0;
  1958. PROV_ENUMALGS_EX ProvEnumalgsEx;
  1959. PTESTCASE ptc = &(pCSPInfo->TestCase);
  1960. //
  1961. // Do CryptGetProvParam negative test cases
  1962. //
  1963. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  1964. LOG_TRY(TGetProv(0, PP_ENUMALGS_EX, (PBYTE) &ProvEnumalgsEx, &cbData, 0, ptc));
  1965. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  1966. LOG_TRY(TGetProv(TEST_INVALID_HANDLE, PP_ENUMALGS_EX, (PBYTE) &ProvEnumalgsEx, &cbData, 0, ptc));
  1967. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  1968. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  1969. LOG_TRY(TGetProv(hProv, PP_VERSION, (PBYTE) &dwData, NULL, 0, ptc));
  1970. ptc->KnownErrorID = KNOWN_CRYPTGETPROVPARAM_MOREDATA;
  1971. cbData = 1;
  1972. ptc->dwErrorCode = ERROR_MORE_DATA;
  1973. LOG_TRY(TGetProv(hProv, PP_CONTAINER, (PBYTE) &dwData, &cbData, 0, ptc));
  1974. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  1975. cbData = sizeof(ProvEnumalgsEx);
  1976. ptc->dwErrorCode = NTE_BAD_FLAGS;
  1977. LOG_TRY(TGetProv(hProv, PP_ENUMALGS_EX, (PBYTE) &ProvEnumalgsEx, &cbData, TEST_INVALID_FLAG, ptc));
  1978. ptc->dwErrorCode = NTE_BAD_TYPE;
  1979. LOG_TRY(TGetProv(hProv, TEST_INVALID_FLAG, (PBYTE) &ProvEnumalgsEx, &cbData, 0, ptc));
  1980. fSuccess = TRUE;
  1981. Cleanup:
  1982. if (hProv)
  1983. {
  1984. TRelease(hProv, 0, ptc);
  1985. }
  1986. return fSuccess;
  1987. }
  1988. //
  1989. // Function: PositiveSetProvParamTests
  1990. // Purpose: Run the test cases for CryptSetProvParam
  1991. //
  1992. BOOL PositiveSetProvParamTests(PCSPINFO pCSPInfo)
  1993. {
  1994. BOOL fSuccess = FALSE;
  1995. HCRYPTPROV hProv = 0;
  1996. LPWSTR pwszContainer = TEST_CONTAINER;
  1997. DWORD cbData = 0;
  1998. DWORD dwData = 0;
  1999. HWND hWnd = 0;
  2000. DWORD dwSavedErrorLevel = 0;
  2001. SECURITY_DESCRIPTOR SecurityDescriptor;
  2002. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2003. memset(&SecurityDescriptor, 0, sizeof(SecurityDescriptor));
  2004. switch (ptc->dwTestLevel)
  2005. {
  2006. case TEST_LEVEL_CSP:
  2007. {
  2008. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2009. //
  2010. // Group 1C
  2011. //
  2012. //
  2013. // Do CryptSetProvParam positive test cases
  2014. //
  2015. //
  2016. // Test PP_CLIENT_HWND
  2017. //
  2018. if (NULL == (hWnd = GetDesktopWindow()))
  2019. {
  2020. LOG_TRY(LogApiFailure(
  2021. API_GETDESKTOPWINDOW,
  2022. ERROR_API_FAILED,
  2023. ptc));
  2024. //LOG_TRY(LogWin32Fail(ptc->dwErrorLevel, ptc->dwTestCaseID));
  2025. }
  2026. cbData = sizeof(hWnd);
  2027. LOG_TRY(TSetProv(
  2028. 0,
  2029. PP_CLIENT_HWND,
  2030. (PBYTE) &hWnd,
  2031. 0,
  2032. ptc));
  2033. //
  2034. // Test PP_USE_HARDWARE_RNG
  2035. //
  2036. // TODO: Dumb down the error level of this test case since
  2037. // some CSP's will not support it.
  2038. //
  2039. // TODO: What effect does this flag have on systems that don't actually
  2040. // have a hardware RNG?
  2041. //
  2042. dwSavedErrorLevel = ptc->dwErrorLevel;
  2043. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  2044. ptc->pwszErrorHelp =
  2045. L"CryptSetProvParam reports that this system has no hardware Random Number Generator";
  2046. LOG_TRY(TSetProv(
  2047. hProv,
  2048. PP_USE_HARDWARE_RNG,
  2049. NULL,
  2050. 0,
  2051. ptc));
  2052. ptc->dwErrorLevel = dwSavedErrorLevel;
  2053. ptc->pwszErrorHelp = NULL;
  2054. break;
  2055. }
  2056. case TEST_LEVEL_CONTAINER:
  2057. {
  2058. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  2059. //
  2060. // Test PP_KEYSET_SEC_DESCR
  2061. //
  2062. cbData = sizeof(dwData);
  2063. LOG_TRY(TGetProv(
  2064. hProv,
  2065. PP_KEYSET_SEC_DESCR,
  2066. (PBYTE) &dwData,
  2067. &cbData,
  2068. OWNER_SECURITY_INFORMATION,
  2069. ptc));
  2070. LOG_TRY(TSetProv(
  2071. hProv,
  2072. PP_KEYSET_SEC_DESCR,
  2073. (PBYTE) &dwData,
  2074. OWNER_SECURITY_INFORMATION,
  2075. ptc));
  2076. cbData = sizeof(dwData);
  2077. LOG_TRY(TGetProv(
  2078. hProv,
  2079. PP_KEYSET_SEC_DESCR,
  2080. (PBYTE) &dwData,
  2081. &cbData,
  2082. GROUP_SECURITY_INFORMATION,
  2083. ptc));
  2084. LOG_TRY(TSetProv(
  2085. hProv,
  2086. PP_KEYSET_SEC_DESCR,
  2087. (PBYTE) &dwData,
  2088. GROUP_SECURITY_INFORMATION,
  2089. ptc));
  2090. cbData = sizeof(dwData);
  2091. LOG_TRY(TGetProv(
  2092. hProv,
  2093. PP_KEYSET_SEC_DESCR,
  2094. (PBYTE) &dwData,
  2095. &cbData,
  2096. DACL_SECURITY_INFORMATION,
  2097. ptc));
  2098. LOG_TRY(TSetProv(
  2099. hProv,
  2100. PP_KEYSET_SEC_DESCR,
  2101. (PBYTE) &dwData,
  2102. DACL_SECURITY_INFORMATION,
  2103. ptc));
  2104. cbData = sizeof(dwData);
  2105. LOG_TRY(TGetProv(
  2106. hProv,
  2107. PP_KEYSET_SEC_DESCR,
  2108. (PBYTE) &dwData,
  2109. &cbData,
  2110. SACL_SECURITY_INFORMATION,
  2111. ptc));
  2112. LOG_TRY(TSetProv(
  2113. hProv,
  2114. PP_KEYSET_SEC_DESCR,
  2115. (PBYTE) &dwData,
  2116. SACL_SECURITY_INFORMATION,
  2117. ptc));
  2118. break;
  2119. }
  2120. }
  2121. fSuccess = TRUE;
  2122. Cleanup:
  2123. if (hProv)
  2124. {
  2125. TRelease(hProv, 0, ptc);
  2126. }
  2127. return fSuccess;
  2128. }
  2129. //
  2130. // Function: NegativeSetProvParamTests
  2131. // Purpose: Run the negative test cases for CryptSetProvParam
  2132. //
  2133. BOOL NegativeSetProvParamTests(PCSPINFO pCSPInfo)
  2134. {
  2135. BOOL fSuccess = FALSE;
  2136. HCRYPTPROV hProv = 0;
  2137. //LPWSTR pwszContainer = TEST_CONTAINER;
  2138. DWORD dwData = 0;
  2139. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2140. SECURITY_DESCRIPTOR SecurityDescriptor;
  2141. memset(&SecurityDescriptor, 0, sizeof(SecurityDescriptor));
  2142. //
  2143. // Group 1C
  2144. //
  2145. //
  2146. // Do CryptSetProvParam negative test cases
  2147. //
  2148. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2149. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2150. LOG_TRY(TSetProv(hProv, PP_CLIENT_HWND, (PBYTE) TEST_INVALID_HANDLE, 0, ptc));
  2151. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2152. LOG_TRY(TSetProv(hProv, PP_KEYSET_SEC_DESCR, NULL, OWNER_SECURITY_INFORMATION, ptc));
  2153. ptc->pwszErrorHelp =
  2154. L"The pbData parameter must be NULL when calling CryptSetProvParam PP_USE_HARDWARE_RNG";
  2155. ptc->KnownErrorID = KNOWN_CRYPTSETPROVPARAM_RNG;
  2156. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2157. LOG_TRY(TSetProv(hProv, PP_USE_HARDWARE_RNG, (PBYTE) &dwData, 0, ptc));
  2158. ptc->pwszErrorHelp = NULL;
  2159. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  2160. ptc->pwszErrorHelp =
  2161. L"The dwFlags parameter must be zero when calling CryptSetProvParam PP_USE_HARDWARE_RNG";
  2162. ptc->KnownErrorID = KNOWN_CRYPTSETPROVPARAM_BADFLAGS;
  2163. ptc->dwErrorCode = NTE_BAD_FLAGS;
  2164. LOG_TRY(TSetProv(hProv, PP_USE_HARDWARE_RNG, NULL, 1, ptc));
  2165. ptc->pwszErrorHelp = NULL;
  2166. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  2167. //
  2168. // 7/25/00 -- This test case is too specific to the Microsoft CSP's.
  2169. //
  2170. /*
  2171. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2172. LOG_TRY(TSetProv(hProv, PP_KEYSET_SEC_DESCR, (PBYTE) &SecurityDescriptor, OWNER_SECURITY_INFORMATION, ptc));
  2173. */
  2174. ptc->dwErrorCode = NTE_BAD_TYPE;
  2175. LOG_TRY(TSetProv(hProv, TEST_INVALID_FLAG, (PBYTE) &dwData, 0, ptc));
  2176. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2177. LOG_TRY(TSetProv(0, PP_USE_HARDWARE_RNG, NULL, 0, ptc));
  2178. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2179. LOG_TRY(TSetProv(TEST_INVALID_HANDLE, PP_USE_HARDWARE_RNG, NULL, 0, ptc));
  2180. fSuccess = TRUE;
  2181. Cleanup:
  2182. if (hProv)
  2183. {
  2184. TRelease(hProv, 0, ptc);
  2185. }
  2186. return fSuccess;
  2187. }
  2188. //
  2189. // Function: PositiveReleaseContextTests
  2190. // Purpose: Run the test cases for CryptReleaseContext
  2191. //
  2192. BOOL PositiveReleaseContextTests(PCSPINFO pCSPInfo)
  2193. {
  2194. BOOL fSuccess = FALSE;
  2195. HCRYPTPROV hProv = 0;
  2196. //LPWSTR pwszContainer = TEST_CONTAINER;
  2197. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2198. //
  2199. // Group 1D
  2200. //
  2201. //
  2202. // Do CryptReleaseContext positive test cases
  2203. //
  2204. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2205. if (! CryptContextAddRef(hProv, NULL, 0))
  2206. {
  2207. LOG_TRY(LogApiFailure(
  2208. API_CRYPTCONTEXTADDREF,
  2209. ERROR_API_FAILED,
  2210. ptc));
  2211. //LOG_TRY(LogWin32Fail(ptc->dwErrorLevel, ptc->dwTestCaseID));
  2212. }
  2213. LOG_TRY(TRelease(hProv, 0, ptc));
  2214. LOG_TRY(TRelease(hProv, 0, ptc));
  2215. fSuccess = TRUE;
  2216. Cleanup:
  2217. return fSuccess;
  2218. }
  2219. //
  2220. // Function: NegativeReleaseContextTests
  2221. // Purpose: Run the negative test cases for CryptReleaseContext
  2222. //
  2223. BOOL NegativeReleaseContextTests(PCSPINFO pCSPInfo)
  2224. {
  2225. BOOL fSuccess = FALSE;
  2226. HCRYPTPROV hProv = 0;
  2227. //LPWSTR pwszContainer = TEST_CONTAINER;
  2228. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2229. //
  2230. // Group 1D
  2231. //
  2232. //
  2233. // Do CryptReleaseContext negative test cases
  2234. //
  2235. ptc->fTestingReleaseContext = TRUE;
  2236. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2237. LOG_TRY(TRelease(0, 0, ptc));
  2238. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2239. LOG_TRY(TRelease(TEST_INVALID_HANDLE, 0, ptc));
  2240. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2241. ptc->dwErrorCode = NTE_BAD_FLAGS;
  2242. LOG_TRY(TRelease(hProv, 1, ptc));
  2243. fSuccess = TRUE;
  2244. Cleanup:
  2245. ptc->fTestingReleaseContext = FALSE;
  2246. return fSuccess;
  2247. }
  2248. //
  2249. // Function: PositiveGenRandomTests
  2250. // Purpose: Run the test cases for CryptGenRandom
  2251. //
  2252. BOOL PositiveGenRandomTests(PCSPINFO pCSPInfo)
  2253. {
  2254. BOOL fSuccess = FALSE;
  2255. //LPWSTR pwszContainer = TEST_CONTAINER;
  2256. HCRYPTPROV hProv = 0;
  2257. DWORD cb = GENRANDOM_BYTE_COUNT;
  2258. BYTE rgBuffer[GENRANDOM_BYTE_COUNT];
  2259. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2260. //
  2261. // Group 2A
  2262. //
  2263. //
  2264. // Do CryptGenRandom positive test cases
  2265. //
  2266. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2267. LOG_TRY(TGenRand(hProv, cb, rgBuffer, ptc));
  2268. fSuccess = TRUE;
  2269. Cleanup:
  2270. if (hProv)
  2271. {
  2272. TRelease(hProv, 0, ptc);
  2273. }
  2274. return fSuccess;
  2275. }
  2276. //
  2277. // Function: NegativeGenRandomTests
  2278. // Purpose: Run the negative test cases for CryptGenRandom
  2279. //
  2280. BOOL NegativeGenRandomTests(PCSPINFO pCSPInfo)
  2281. {
  2282. BOOL fSuccess = FALSE;
  2283. //LPWSTR pwszContainer = TEST_CONTAINER;
  2284. HCRYPTPROV hProv = 0;
  2285. //DWORD dw = 0;
  2286. PBYTE pb = NULL;
  2287. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2288. //
  2289. // Group 2A
  2290. //
  2291. //
  2292. // Do CryptGenRandom negative test cases
  2293. //
  2294. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2295. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2296. LOG_TRY(TGenRand(hProv, 1, NULL, ptc));
  2297. LOG_TRY(TestAlloc(&pb, GENRANDOM_BYTE_COUNT, ptc));
  2298. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2299. LOG_TRY(TGenRand(hProv, 2 * GENRANDOM_BYTE_COUNT, pb, ptc));
  2300. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2301. LOG_TRY(TGenRand(0, GENRANDOM_BYTE_COUNT, pb, ptc));
  2302. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2303. LOG_TRY(TGenRand(TEST_INVALID_HANDLE, GENRANDOM_BYTE_COUNT, pb, ptc));
  2304. fSuccess = TRUE;
  2305. Cleanup:
  2306. if (hProv)
  2307. {
  2308. TRelease(hProv, 0, ptc);
  2309. }
  2310. if (pb)
  2311. {
  2312. free(pb);
  2313. }
  2314. return fSuccess;
  2315. }
  2316. //
  2317. // Function: TestCreateHashProc
  2318. // Purpose: This function verifies that CryptCreateHash is successful
  2319. // for the hash algorithm specified in the pAlgNode parameter.
  2320. //
  2321. // For known MAC algorithms (ALG_SID_MAC and ALG_SIG_HMAC), a block
  2322. // cipher key (provided via pvTestCreateHashInfo) is provided when creating
  2323. // the hash handle.
  2324. //
  2325. // For other, non-keyed, hash algorithms, the cipher key will not
  2326. // be used.
  2327. //
  2328. BOOL TestCreateHashProc(
  2329. PALGNODE pAlgNode,
  2330. PTESTCASE ptc,
  2331. PVOID pvTestCreateHashInfo)
  2332. {
  2333. BOOL fSuccess = FALSE;
  2334. HCRYPTHASH hHash = 0;
  2335. DWORD dwSavedErrorLevel = ptc->dwErrorLevel;
  2336. PTEST_CREATE_HASH_INFO pTestCreateHashInfo = (PTEST_CREATE_HASH_INFO) pvTestCreateHashInfo;
  2337. if (pAlgNode->fIsRequiredAlg)
  2338. {
  2339. ptc->dwErrorLevel = CSP_ERROR_CONTINUE;
  2340. }
  2341. else
  2342. {
  2343. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  2344. }
  2345. if (MacAlgFilter(pAlgNode))
  2346. {
  2347. LOG_TRY(TCreateHash(
  2348. pTestCreateHashInfo->hProv,
  2349. pAlgNode->ProvEnumalgsEx.aiAlgid,
  2350. pTestCreateHashInfo->hBlockCipherKey,
  2351. 0,
  2352. &hHash,
  2353. ptc));
  2354. }
  2355. else
  2356. {
  2357. LOG_TRY(TCreateHash(
  2358. pTestCreateHashInfo->hProv,
  2359. pAlgNode->ProvEnumalgsEx.aiAlgid,
  2360. 0,
  2361. 0,
  2362. &hHash,
  2363. ptc));
  2364. }
  2365. fSuccess = TRUE;
  2366. Cleanup:
  2367. ptc->dwErrorLevel = dwSavedErrorLevel;
  2368. if (hHash)
  2369. {
  2370. TDestroyHash(hHash, ptc);
  2371. }
  2372. return fSuccess;
  2373. }
  2374. //
  2375. // Function: PositiveCreateHashTests
  2376. // Purpose: Run the test cases for CryptCreateHash based on the CSP class being tested
  2377. // as specified in the dwCSPClass parameter.
  2378. //
  2379. BOOL PositiveCreateHashTests(PCSPINFO pCSPInfo)
  2380. {
  2381. BOOL fSuccess = FALSE;
  2382. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2383. TEST_CREATE_HASH_INFO TestCreateHashInfo;
  2384. memset(&TestCreateHashInfo, 0, sizeof(TestCreateHashInfo));
  2385. LOG_TRY(CreateNewContext(
  2386. &(TestCreateHashInfo.hProv),
  2387. NULL,
  2388. CRYPT_VERIFYCONTEXT,
  2389. ptc));
  2390. //
  2391. // Create an RC2 key for testing keyed-hashes (MAC). RC2 is a required algorithm,
  2392. // but if this fails, and the CSP does support one or more MAC algs, the creation
  2393. // of the MAC hash handles (see TestCreateHashProc) may fail as well.
  2394. //
  2395. /*
  2396. LOG_TRY(CreateNewKey(
  2397. TestCreateHashInfo.hProv,
  2398. CALG_RC2,
  2399. 0,
  2400. &(TestCreateHashInfo.hBlockCipherKey),
  2401. ptc));
  2402. */
  2403. //
  2404. // Group 3A
  2405. //
  2406. //
  2407. // Do CryptCreateHash positive test cases
  2408. //
  2409. //
  2410. // Iterate through the ENUMALGS_EX structs stored in the ALGNODE list.
  2411. // Create a hash of each type supported by this CSP.
  2412. //
  2413. LOG_TRY(AlgListIterate(
  2414. pCSPInfo->pAlgList,
  2415. HashAlgFilter,
  2416. TestCreateHashProc,
  2417. (PVOID) &TestCreateHashInfo,
  2418. ptc));
  2419. // This test case set probably doesn't belong here, since
  2420. // symmetric keys haven't been tested at this point.
  2421. /*
  2422. LOG_TRY(AlgListIterate(
  2423. pCSPInfo->pAlgList,
  2424. MacAlgFilter,
  2425. TestCreateHashProc,
  2426. (PVOID) &TestCreateHashInfo,
  2427. ptc));
  2428. */
  2429. fSuccess = TRUE;
  2430. Cleanup:
  2431. if (TestCreateHashInfo.hBlockCipherKey)
  2432. {
  2433. TDestroyKey(TestCreateHashInfo.hBlockCipherKey, ptc);
  2434. }
  2435. if (TestCreateHashInfo.hProv)
  2436. {
  2437. TRelease(TestCreateHashInfo.hProv, 0, ptc);
  2438. }
  2439. return fSuccess;
  2440. }
  2441. //
  2442. // Function: NegativeCreateHashTests
  2443. // Purpose: Run the test cases for CryptCreateHash based on the CSP class being tested
  2444. // as specified in the dwCSPClass parameter.
  2445. //
  2446. BOOL NegativeCreateHashTests(PCSPINFO pCSPInfo)
  2447. {
  2448. BOOL fSuccess = FALSE;
  2449. HCRYPTPROV hProv = 0;
  2450. HCRYPTHASH hHash = 0;
  2451. HCRYPTKEY hKey = 0;
  2452. //LPWSTR pwszContainer = TEST_CONTAINER;
  2453. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2454. //
  2455. // Group 3A
  2456. //
  2457. //
  2458. // Do CryptGenRandom negative test cases
  2459. //
  2460. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2461. LOG_TRY(TCreateHash(0, CALG_SHA1, 0, 0, &hHash, ptc));
  2462. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2463. LOG_TRY(TCreateHash(TEST_INVALID_HANDLE, CALG_SHA1, 0, 0, &hHash, ptc));
  2464. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2465. ptc->dwErrorCode = NTE_BAD_FLAGS;
  2466. LOG_TRY(TCreateHash(hProv, CALG_SHA1, 0, TEST_INVALID_FLAG, &hHash, ptc));
  2467. ptc->dwErrorCode = NTE_BAD_KEY;
  2468. LOG_TRY(TCreateHash(hProv, CALG_HMAC, 0, 0, &hHash, ptc));
  2469. // HMAC requires a block cipher, so use a stream cipher and expect failure
  2470. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  2471. ptc->pwszErrorHelp =
  2472. L"CryptCreateHash CALG_HMAC should fail when not using a block cipher key";
  2473. ptc->KnownErrorID = KNOWN_CRYPTCREATEHASH_BADKEY;
  2474. ptc->dwErrorCode = NTE_BAD_KEY;
  2475. LOG_TRY(TCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash, ptc));
  2476. ptc->pwszErrorHelp = NULL;
  2477. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  2478. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2479. LOG_TRY(TCreateHash(hProv, CALG_SHA1, 0, 0, NULL, ptc));
  2480. ptc->dwErrorCode = NTE_BAD_ALGID;
  2481. LOG_TRY(TCreateHash(hProv, CALG_RC4, 0, 0, &hHash, ptc));
  2482. fSuccess = TRUE;
  2483. Cleanup:
  2484. if (hKey)
  2485. {
  2486. TDestroyKey(hKey, ptc);
  2487. }
  2488. if (hProv)
  2489. {
  2490. TRelease(hProv, 0, ptc);
  2491. }
  2492. return fSuccess;
  2493. }
  2494. //
  2495. // Function: PositiveDestroyHashTests
  2496. // Purpose: Run the test cases for CryptDestroyHash
  2497. //
  2498. BOOL PositiveDestroyHashTests(PCSPINFO pCSPInfo)
  2499. {
  2500. BOOL fSuccess = FALSE;
  2501. //LPWSTR pwszContainer = TEST_CONTAINER;
  2502. HCRYPTPROV hProv = 0;
  2503. HCRYPTHASH hHash = 0;
  2504. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2505. //
  2506. // Group 3B
  2507. //
  2508. //
  2509. // Do CryptDestroyHash positive test cases
  2510. //
  2511. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2512. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  2513. LOG_TRY(TDestroyHash(hHash, ptc));
  2514. hHash = 0;
  2515. fSuccess = TRUE;
  2516. Cleanup:
  2517. if (hHash)
  2518. {
  2519. TDestroyHash(hHash, ptc);
  2520. }
  2521. if (hProv)
  2522. {
  2523. TRelease(hProv, 0, ptc);
  2524. }
  2525. return fSuccess;
  2526. }
  2527. //
  2528. // Function: NegativeDestroyHashTests
  2529. // Purpose: Run the test cases for CryptDestroyHash
  2530. //
  2531. BOOL NegativeDestroyHashTests(PCSPINFO pCSPInfo)
  2532. {
  2533. BOOL fSuccess = FALSE;
  2534. //LPWSTR pwszContainer = TEST_CONTAINER;
  2535. HCRYPTPROV hProv = 0;
  2536. HCRYPTHASH hHash = 0;
  2537. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2538. //
  2539. // Group 3B
  2540. //
  2541. //
  2542. // Do CryptDestroyHash negative test cases
  2543. //
  2544. ptc->fTestingDestroyHash = TRUE;
  2545. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2546. LOG_TRY(TDestroyHash(0, ptc));
  2547. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2548. LOG_TRY(TDestroyHash(TEST_INVALID_HANDLE, ptc));
  2549. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2550. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  2551. /*
  2552. LOG_TRY(TRelease(hProv, 0, ptc));
  2553. hProv = 0;
  2554. // Provider handle used to create hHash is now invalid
  2555. ptc->dwErrorCode = NTE_BAD_UID;
  2556. LOG_TRY(TDestroyHash(hHash, ptc));
  2557. */
  2558. fSuccess = TRUE;
  2559. Cleanup:
  2560. ptc->fTestingDestroyHash = FALSE;
  2561. if (hHash)
  2562. {
  2563. TDestroyHash(hHash, ptc);
  2564. }
  2565. if (hProv)
  2566. {
  2567. TRelease(hProv, 0, ptc);
  2568. }
  2569. return fSuccess;
  2570. }
  2571. //
  2572. // Function: PositiveGetHashParamTests
  2573. // Purpose: Run the test cases for CryptGetHashParam
  2574. //
  2575. BOOL PositiveGetHashParamTests(PCSPINFO pCSPInfo)
  2576. {
  2577. BOOL fSuccess = FALSE;
  2578. //LPWSTR pwszContainer = TEST_CONTAINER;
  2579. HCRYPTPROV hProv = 0;
  2580. HCRYPTHASH hHash = 0;
  2581. DWORD dwData = 0;
  2582. DWORD cbData = 0;
  2583. PBYTE pbData = 0;
  2584. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2585. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2586. //
  2587. // Group 3D
  2588. //
  2589. //
  2590. // Do CryptGetHashParam positive test cases
  2591. //
  2592. //
  2593. // Test HP_ALGID
  2594. //
  2595. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  2596. cbData = sizeof(dwData);
  2597. LOG_TRY(TGetHash(
  2598. hHash,
  2599. HP_ALGID,
  2600. (PBYTE) &dwData,
  2601. &cbData,
  2602. 0,
  2603. ptc));
  2604. if (CALG_SHA1 != dwData)
  2605. {
  2606. ptc->pwszErrorHelp = L"CryptGetHashParam HP_ALGID returned incorrect ALG_ID";
  2607. LOG_TRY(LogApiFailure(
  2608. API_CRYPTGETHASHPARAM,
  2609. ERROR_BAD_DATA,
  2610. ptc));
  2611. ptc->pwszErrorHelp = NULL;
  2612. }
  2613. //
  2614. // Test HP_HASHSIZE
  2615. //
  2616. cbData = sizeof(dwData);
  2617. LOG_TRY(TGetHash(
  2618. hHash,
  2619. HP_HASHSIZE,
  2620. (PBYTE) &dwData,
  2621. &cbData,
  2622. 0,
  2623. ptc));
  2624. if (HASH_LENGTH_SHA1 != dwData)
  2625. {
  2626. ptc->pwszErrorHelp = L"CryptGetHashParam HP_HASHSIZE returned incorrect length";
  2627. LOG_TRY(LogApiFailure(
  2628. API_CRYPTGETHASHPARAM,
  2629. ERROR_WRONG_SIZE,
  2630. ptc));
  2631. ptc->pwszErrorHelp = NULL;
  2632. }
  2633. //
  2634. // Test HP_HASHVAL
  2635. //
  2636. cbData = HASH_LENGTH_SHA1;
  2637. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  2638. LOG_TRY(TGetHash(
  2639. hHash,
  2640. HP_HASHVAL,
  2641. pbData,
  2642. &cbData,
  2643. 0,
  2644. ptc));
  2645. fSuccess = TRUE;
  2646. Cleanup:
  2647. if (hHash)
  2648. {
  2649. TDestroyHash(hHash, ptc);
  2650. }
  2651. if (hProv)
  2652. {
  2653. TRelease(hProv, 0, ptc);
  2654. }
  2655. if (pbData)
  2656. {
  2657. free(pbData);
  2658. }
  2659. return fSuccess;
  2660. }
  2661. //
  2662. // Function: NegativeGetHashParamTests
  2663. // Purpose: Run the negative test cases for CryptGetHashParam
  2664. //
  2665. BOOL NegativeGetHashParamTests(PCSPINFO pCSPInfo)
  2666. {
  2667. BOOL fSuccess = FALSE;
  2668. //LPWSTR pwszContainer = TEST_CONTAINER;
  2669. HCRYPTPROV hProv = 0;
  2670. HCRYPTHASH hHash = 0;
  2671. DWORD dw = 0;
  2672. DWORD cb = 0;
  2673. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2674. //
  2675. // Group 3D
  2676. //
  2677. //
  2678. // Do CryptGetHashParam negative test cases
  2679. //
  2680. cb = sizeof(dw);
  2681. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2682. LOG_TRY(TGetHash(0, HP_HASHSIZE, (PBYTE) &dw, &cb, 0, ptc));
  2683. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  2684. LOG_TRY(TGetHash(TEST_INVALID_HANDLE, HP_HASHSIZE, (PBYTE) &dw, &cb, 0, ptc));
  2685. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  2686. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  2687. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2688. LOG_TRY(TGetHash(hHash, HP_HASHSIZE, (PBYTE) &dw, NULL, 0, ptc));
  2689. //
  2690. // This corrupts memory since it doesn't immediately AV
  2691. //
  2692. /*
  2693. cb = HASH_LENGTH_SHA1;
  2694. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  2695. LOG_TRY(TGetHash(hHash, HP_HASHVAL, (PBYTE) &dw, &cb, 0, ptc));
  2696. */
  2697. cb = HASH_LENGTH_SHA1 - 1;
  2698. ptc->dwErrorCode = ERROR_MORE_DATA;
  2699. LOG_TRY(TGetHash(hHash, HP_HASHVAL, (PBYTE) &dw, &cb, 0, ptc));
  2700. cb = sizeof(dw);
  2701. ptc->dwErrorCode = NTE_BAD_FLAGS;
  2702. LOG_TRY(TGetHash(hHash, HP_HASHSIZE, (PBYTE) &dw, &cb, TEST_INVALID_FLAG, ptc));
  2703. ptc->dwErrorCode = NTE_BAD_TYPE;
  2704. LOG_TRY(TGetHash(hHash, TEST_INVALID_FLAG, (PBYTE) &dw, &cb, 0, ptc));
  2705. /*
  2706. LOG_TRY(TRelease(hProv, 0, ptc));
  2707. hProv = 0;
  2708. // Provider handle used to create hHash is now invalid
  2709. ptc->dwErrorCode = NTE_BAD_UID;
  2710. LOG_TRY(TGetHash(hHash, HP_HASHSIZE, (PBYTE) &dw, &cb, 0, ptc));
  2711. */
  2712. fSuccess = TRUE;
  2713. Cleanup:
  2714. if (hHash)
  2715. {
  2716. TDestroyHash(hHash, ptc);
  2717. }
  2718. if (hProv)
  2719. {
  2720. TRelease(hProv, 0, ptc);
  2721. }
  2722. return fSuccess;
  2723. }
  2724. //
  2725. // Function: TestMacDataWithKeyProc
  2726. // Purpose: This function tests MAC functionality. First, a session key
  2727. // is created of the block-cipher algorithm indicated in pAlgNode.
  2728. // Then a keyed hash is created using that key and the hash algorithm
  2729. // specified in pvTestHashDataInfo.
  2730. //
  2731. // After the base data (in pvTestHashDataInfo) is hashed, the result is
  2732. // passed to CheckHashedData to verify that the same result is attained
  2733. // with a second, separate CSP.
  2734. //
  2735. BOOL TestMacDataWithKeyProc(
  2736. PALGNODE pAlgNode,
  2737. PTESTCASE ptc,
  2738. PVOID pvTestHashDataInfo)
  2739. {
  2740. BOOL fSuccess = FALSE;
  2741. PTEST_HASH_DATA_INFO pTestHashDataInfo = (PTEST_HASH_DATA_INFO) pvTestHashDataInfo;
  2742. HCRYPTHASH hHash = 0;
  2743. HCRYPTKEY hKey = 0;
  2744. HASH_INFO HashInfo;
  2745. TEST_MAC_INFO MacInfo;
  2746. memset(&HashInfo, 0, sizeof(HashInfo));
  2747. memset(&MacInfo, 0, sizeof(MacInfo));
  2748. HashInfo.aiHash = pTestHashDataInfo->aiMac;
  2749. HashInfo.dbBaseData.cbData = pTestHashDataInfo->dbBaseData.cbData;
  2750. HashInfo.dbBaseData.pbData = pTestHashDataInfo->dbBaseData.pbData;
  2751. LOG_TRY(TGenKey(
  2752. pTestHashDataInfo->hProv,
  2753. pAlgNode->ProvEnumalgsEx.aiAlgid,
  2754. CRYPT_EXPORTABLE,
  2755. &hKey,
  2756. ptc));
  2757. LOG_TRY(ExportPlaintextSessionKey(
  2758. hKey,
  2759. pTestHashDataInfo->hProv,
  2760. &(MacInfo.dbKey),
  2761. ptc));
  2762. memcpy(&(MacInfo.HmacInfo), &(pTestHashDataInfo->HmacInfo), sizeof(HMAC_INFO));
  2763. LOG_TRY(CreateHashAndAddData(
  2764. pTestHashDataInfo->hProv,
  2765. &hHash,
  2766. &HashInfo,
  2767. ptc,
  2768. hKey,
  2769. &(MacInfo.HmacInfo)));
  2770. LOG_TRY(TGetHash(
  2771. hHash,
  2772. HP_HASHVAL,
  2773. NULL,
  2774. &(HashInfo.dbHashValue.cbData),
  2775. 0,
  2776. ptc));
  2777. LOG_TRY(TestAlloc(
  2778. &(HashInfo.dbHashValue.pbData),
  2779. HashInfo.dbHashValue.cbData,
  2780. ptc));
  2781. LOG_TRY(TGetHash(
  2782. hHash,
  2783. HP_HASHVAL,
  2784. HashInfo.dbHashValue.pbData,
  2785. &(HashInfo.dbHashValue.cbData),
  2786. 0,
  2787. ptc));
  2788. LOG_TRY(CheckHashedData(
  2789. &HashInfo,
  2790. pTestHashDataInfo->hInteropProv,
  2791. ptc,
  2792. &MacInfo));
  2793. fSuccess = TRUE;
  2794. Cleanup:
  2795. if (MacInfo.dbKey.pbData)
  2796. {
  2797. free(MacInfo.dbKey.pbData);
  2798. }
  2799. if (HashInfo.dbHashValue.pbData)
  2800. {
  2801. free(HashInfo.dbHashValue.pbData);
  2802. }
  2803. if (hHash)
  2804. {
  2805. TDestroyHash(hHash, ptc);
  2806. }
  2807. if (hKey)
  2808. {
  2809. TDestroyKey(hKey, ptc);
  2810. }
  2811. return fSuccess;
  2812. }
  2813. //
  2814. // Function: TestMacDataProc
  2815. //
  2816. BOOL TestMacDataProc(
  2817. PALGNODE pAlgNode,
  2818. PTESTCASE ptc,
  2819. PVOID pvTestHashDataInfo)
  2820. {
  2821. //
  2822. // Because of the filter used before calling this function,
  2823. // we know that pAlgNode contains a ProvEnumalgsEx structure that
  2824. // corresponds to a MAC'ing algorithm. Save the ALG_ID for the current
  2825. // MAC algorithm and pass it through to the TestMacDataWithKeyProc, which
  2826. // will do the real work of creating the keyed hash.
  2827. //
  2828. ((PTEST_HASH_DATA_INFO) pvTestHashDataInfo)->aiMac = pAlgNode->ProvEnumalgsEx.aiAlgid;
  2829. return AlgListIterate(
  2830. ((PTEST_HASH_DATA_INFO) pvTestHashDataInfo)->pAlgList,
  2831. BlockCipherFilter,
  2832. TestMacDataWithKeyProc,
  2833. pvTestHashDataInfo,
  2834. ptc);
  2835. }
  2836. //
  2837. // Function: TestHashDataProc
  2838. //
  2839. BOOL TestHashDataProc(
  2840. PALGNODE pAlgNode,
  2841. PTESTCASE ptc,
  2842. PVOID pvTestHashDataInfo)
  2843. {
  2844. HCRYPTHASH hHash = 0;
  2845. BOOL fSuccess = FALSE;
  2846. DWORD dwSavedErrorLevel = ptc->dwErrorLevel;
  2847. HASH_INFO HashInfo;
  2848. PTEST_HASH_DATA_INFO pTestHashDataInfo = (PTEST_HASH_DATA_INFO) pvTestHashDataInfo;
  2849. memset(&HashInfo, 0, sizeof(HashInfo));
  2850. if (! pAlgNode->fIsRequiredAlg)
  2851. {
  2852. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  2853. }
  2854. HashInfo.aiHash = pAlgNode->ProvEnumalgsEx.aiAlgid;
  2855. HashInfo.dbBaseData.cbData = pTestHashDataInfo->dbBaseData.cbData;
  2856. HashInfo.dbBaseData.pbData = pTestHashDataInfo->dbBaseData.pbData;
  2857. //
  2858. // Call CreateHashAndAddData with the required parameters
  2859. // for a non-keyed hash alg.
  2860. //
  2861. LOG_TRY(CreateHashAndAddData(
  2862. pTestHashDataInfo->hProv,
  2863. &hHash,
  2864. &HashInfo,
  2865. ptc,
  2866. 0, NULL));
  2867. LOG_TRY(TGetHash(
  2868. hHash,
  2869. HP_HASHVAL,
  2870. NULL,
  2871. &(HashInfo.dbHashValue.cbData),
  2872. 0,
  2873. ptc));
  2874. LOG_TRY(TestAlloc(
  2875. &(HashInfo.dbHashValue.pbData),
  2876. HashInfo.dbHashValue.cbData,
  2877. ptc));
  2878. LOG_TRY(TGetHash(
  2879. hHash,
  2880. HP_HASHVAL,
  2881. HashInfo.dbHashValue.pbData,
  2882. &(HashInfo.dbHashValue.cbData),
  2883. 0,
  2884. ptc));
  2885. //
  2886. // Call CheckHashedData with the required information
  2887. // for a non-keyed hash.
  2888. //
  2889. LOG_TRY(CheckHashedData(
  2890. &HashInfo,
  2891. pTestHashDataInfo->hInteropProv,
  2892. ptc,
  2893. NULL));
  2894. fSuccess = TRUE;
  2895. Cleanup:
  2896. ptc->dwErrorLevel = dwSavedErrorLevel;
  2897. if (HashInfo.dbHashValue.pbData)
  2898. {
  2899. free(HashInfo.dbHashValue.pbData);
  2900. }
  2901. if (hHash)
  2902. {
  2903. TDestroyHash(hHash, ptc);
  2904. }
  2905. return fSuccess;
  2906. }
  2907. //
  2908. // Function: InteropHashDataTests
  2909. // Purpose: Run the interop test scenarios for CryptHashData
  2910. //
  2911. BOOL InteropHashDataTests(PCSPINFO pCSPInfo)
  2912. {
  2913. BOOL fSuccess = FALSE;
  2914. //LPWSTR pwszContainer = TEST_CONTAINER;
  2915. PTESTCASE ptc = &(pCSPInfo->TestCase);
  2916. PALGNODE pAlgList = pCSPInfo->pAlgList;
  2917. TEST_HASH_DATA_INFO TestHashDataInfo;
  2918. memset(&TestHashDataInfo, 0, sizeof(TestHashDataInfo));
  2919. LOG_TRY(CreateNewContext(
  2920. &(TestHashDataInfo.hProv),
  2921. NULL,
  2922. CRYPT_VERIFYCONTEXT,
  2923. ptc));
  2924. LOG_TRY(CreateNewInteropContext(
  2925. &(TestHashDataInfo.hInteropProv),
  2926. NULL,
  2927. CRYPT_VERIFYCONTEXT,
  2928. ptc));
  2929. //
  2930. // Initialize the test data to be hashed
  2931. //
  2932. TestHashDataInfo.dbBaseData.cbData = wcslen(TEST_HASH_DATA) * sizeof(WCHAR);
  2933. LOG_TRY(TestAlloc(
  2934. &(TestHashDataInfo.dbBaseData.pbData),
  2935. TestHashDataInfo.dbBaseData.cbData,
  2936. ptc));
  2937. memcpy(
  2938. TestHashDataInfo.dbBaseData.pbData,
  2939. TEST_HASH_DATA,
  2940. TestHashDataInfo.dbBaseData.cbData);
  2941. //
  2942. // Non-keyed Hashes
  2943. //
  2944. // Iterate through the ENUMALGS_EX structs stored in the ALGNODE list.
  2945. // Create a hash of each type supported by this CSP.
  2946. //
  2947. LOG_TRY(AlgListIterate(
  2948. pAlgList,
  2949. HashAlgFilter,
  2950. TestHashDataProc,
  2951. (PVOID) (&TestHashDataInfo),
  2952. ptc));
  2953. //
  2954. // Keyed Hashes
  2955. //
  2956. // TODO: Currently using SHA1 as the only HMAC test case. Is
  2957. // there a problem with that? The alternative would be
  2958. // to make the below AlgListIterate loop longer.
  2959. //
  2960. TestHashDataInfo.HmacInfo.HashAlgid = CALG_SHA1;
  2961. //
  2962. // Iterate through all required hash algorithms and all
  2963. // required block cipher algorithms.
  2964. //
  2965. TestHashDataInfo.pAlgList = pCSPInfo->pAlgList;
  2966. LOG_TRY(AlgListIterate(
  2967. pAlgList,
  2968. MacAlgFilter,
  2969. TestMacDataProc,
  2970. (PVOID) (&TestHashDataInfo),
  2971. ptc));
  2972. fSuccess = TRUE;
  2973. Cleanup:
  2974. if (TestHashDataInfo.hProv)
  2975. {
  2976. TRelease(TestHashDataInfo.hProv, 0, ptc);
  2977. }
  2978. if (TestHashDataInfo.dbBaseData.pbData)
  2979. {
  2980. free(TestHashDataInfo.dbBaseData.pbData);
  2981. }
  2982. if (TestHashDataInfo.hInteropProv)
  2983. {
  2984. TRelease(TestHashDataInfo.hInteropProv, 0, ptc);
  2985. }
  2986. return fSuccess;
  2987. }
  2988. //
  2989. // Function: PositiveHashDataTests
  2990. // Purpose: Run the test cases for CryptHashData
  2991. //
  2992. BOOL PositiveHashDataTests(PCSPINFO pCSPInfo)
  2993. {
  2994. BOOL fSuccess = FALSE;
  2995. //LPWSTR pwszContainer = TEST_CONTAINER;
  2996. HCRYPTHASH hHash = 0;
  2997. HCRYPTPROV hProv = 0;
  2998. DWORD cb = 0;
  2999. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3000. BYTE rgbHashSha[HASH_LENGTH_SHA1];
  3001. BYTE rgbHashMD5[HASH_LENGTH_MD5];
  3002. memset(rgbHashSha, 0, HASH_LENGTH_SHA1);
  3003. memset(rgbHashMD5, 0, HASH_LENGTH_MD5);
  3004. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3005. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  3006. LOG_TRY(THashData(hHash, KNOWN_HASH_DATA, KNOWN_HASH_DATALEN, 0, ptc));
  3007. cb = HASH_LENGTH_SHA1;
  3008. LOG_TRY(TGetHash(hHash, HP_HASHVAL, rgbHashSha, &cb, 0, ptc));
  3009. if (0 != memcmp(rgbHashSha, g_rgbKnownSHA1, HASH_LENGTH_SHA1))
  3010. {
  3011. LOG_TRY(LogBadParam(
  3012. API_CRYPTHASHDATA,
  3013. L"Incorrect SHA1 hash value",
  3014. ptc));
  3015. }
  3016. LOG_TRY(TDestroyHash(hHash, ptc));
  3017. hHash = 0;
  3018. LOG_TRY(CreateNewHash(hProv, CALG_MD5, &hHash, ptc));
  3019. LOG_TRY(THashData(hHash, KNOWN_HASH_DATA, KNOWN_HASH_DATALEN, 0, ptc));
  3020. cb = HASH_LENGTH_MD5;
  3021. LOG_TRY(TGetHash(hHash, HP_HASHVAL, rgbHashMD5, &cb, 0, ptc));
  3022. if (0 != memcmp(rgbHashMD5, g_rgbKnownMD5, HASH_LENGTH_MD5))
  3023. {
  3024. LOG_TRY(LogBadParam(
  3025. API_CRYPTHASHDATA,
  3026. L"Incorrect MD5 hash value",
  3027. ptc));
  3028. }
  3029. LOG_TRY(TDestroyHash(hHash, ptc));
  3030. hHash = 0;
  3031. fSuccess = TRUE;
  3032. Cleanup:
  3033. if (hHash)
  3034. {
  3035. TDestroyHash(hHash, ptc);
  3036. }
  3037. if (hProv)
  3038. {
  3039. TRelease(hProv, 0, ptc);
  3040. }
  3041. return fSuccess;
  3042. }
  3043. //
  3044. // Function: NegativeHashDataTests
  3045. // Purpose: Run the negative test cases for CryptHashData
  3046. //
  3047. BOOL NegativeHashDataTests(PCSPINFO pCSPInfo)
  3048. {
  3049. BOOL fSuccess = FALSE;
  3050. //LPWSTR pwszContainer = TEST_CONTAINER;
  3051. HCRYPTPROV hProv = 0;
  3052. HCRYPTHASH hHash = 0;
  3053. PBYTE pb = NULL;
  3054. DWORD cb = 0;
  3055. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3056. DWORD dwSavedErrorLevel = 0;
  3057. //
  3058. // Group 3E
  3059. //
  3060. //
  3061. // Do CryptHashData negative test cases
  3062. //
  3063. pb = (PBYTE) TEST_HASH_DATA;
  3064. // Not hashing terminating Null
  3065. cb = wcslen(TEST_HASH_DATA) * sizeof(WCHAR);
  3066. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3067. LOG_TRY(THashData(0, pb, cb, 0, ptc));
  3068. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3069. LOG_TRY(THashData(TEST_INVALID_HANDLE, pb, cb, 0, ptc));
  3070. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3071. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  3072. ptc->dwErrorCode = NTE_BAD_DATA;
  3073. LOG_TRY(THashData(hHash, NULL, cb, 0, ptc));
  3074. //
  3075. // 7/25/00 -- leaving this test case out, since the current
  3076. // behavior seems friendlier.
  3077. //
  3078. /*
  3079. ptc->dwErrorCode = NTE_BAD_LEN;
  3080. LOG_TRY(THashData(hHash, pb, 0, 0, ptc));
  3081. */
  3082. ptc->dwErrorCode = NTE_BAD_FLAGS;
  3083. LOG_TRY(THashData(hHash, pb, cb, TEST_INVALID_FLAG, ptc));
  3084. // For CSP's that support CRYPT_USERDATA, cbData must be zero, or error
  3085. dwSavedErrorLevel = ptc->dwErrorLevel;
  3086. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  3087. ptc->pwszErrorHelp =
  3088. L"CryptHashData CRYPT_USERDATA should fail when dwDataLen is not zero (optional)";
  3089. ptc->dwErrorCode = NTE_BAD_LEN;
  3090. LOG_TRY(THashData(hHash, pb, 1, CRYPT_USERDATA, ptc));
  3091. ptc->dwErrorLevel = dwSavedErrorLevel;
  3092. ptc->pwszErrorHelp = NULL;
  3093. /*
  3094. LOG_TRY(TRelease(hProv, 0, ptc));
  3095. hProv = 0;
  3096. // Provider handle used to create hHash is now invalid
  3097. ptc->dwErrorCode = NTE_BAD_UID;
  3098. LOG_TRY(THashData(hHash, pb, cb, 0, ptc));
  3099. */
  3100. fSuccess = TRUE;
  3101. Cleanup:
  3102. if (hHash)
  3103. {
  3104. TDestroyHash(hHash, ptc);
  3105. }
  3106. if (hProv)
  3107. {
  3108. TRelease(hProv, 0, ptc);
  3109. }
  3110. return fSuccess;
  3111. }
  3112. //
  3113. // Function: PositiveSetHashParamTests
  3114. // Purpose: Run the test cases for CryptSetHashParam
  3115. //
  3116. BOOL PositiveSetHashParamTests(PCSPINFO pCSPInfo)
  3117. {
  3118. BOOL fSuccess = FALSE;
  3119. //LPWSTR pwszContainer = TEST_CONTAINER;
  3120. HCRYPTPROV hProv = 0;
  3121. HCRYPTHASH hHash = 0;
  3122. BYTE rgHashVal[HASH_LENGTH_SHA1];
  3123. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3124. memset(rgHashVal, 0, sizeof(rgHashVal));
  3125. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3126. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  3127. //
  3128. // Group 3F
  3129. //
  3130. //
  3131. // Do CryptSetHashParam positive test cases
  3132. //
  3133. //
  3134. // Skip testing HP_HMAC_INFO here. It's only an interesting test
  3135. // if the CSP supports a MAC alg. This is already covered in the
  3136. // CryptHashData tests.
  3137. //
  3138. //
  3139. // Test HP_HASHVAL
  3140. //
  3141. LOG_TRY(TSetHash(
  3142. hHash,
  3143. HP_HASHVAL,
  3144. rgHashVal,
  3145. 0,
  3146. ptc));
  3147. fSuccess = TRUE;
  3148. Cleanup:
  3149. if (hHash)
  3150. {
  3151. TDestroyHash(hHash, ptc);
  3152. }
  3153. if (hProv)
  3154. {
  3155. TRelease(hProv, 0, ptc);
  3156. }
  3157. return fSuccess;
  3158. }
  3159. //
  3160. // Function: NegativeSetHashParamTests
  3161. // Purpose: Run the negative test cases for CryptSetHashParam
  3162. //
  3163. BOOL NegativeSetHashParamTests(PCSPINFO pCSPInfo)
  3164. {
  3165. BOOL fSuccess = FALSE;
  3166. LPWSTR pwszContainer = TEST_CONTAINER;
  3167. HCRYPTPROV hProv = 0;
  3168. HCRYPTHASH hHash = 0;
  3169. DWORD dw = 0;
  3170. //DWORD cb = 0;
  3171. BYTE rgHashVal[HASH_LENGTH_SHA1];
  3172. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3173. memset(rgHashVal, 0, sizeof(rgHashVal));
  3174. //
  3175. // Group 3F
  3176. //
  3177. //
  3178. // Do CryptSetHashParam negative test cases
  3179. //
  3180. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3181. LOG_TRY(TSetHash(0, HP_HASHVAL, rgHashVal, 0, ptc));
  3182. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3183. LOG_TRY(TSetHash(TEST_INVALID_HANDLE, HP_HASHVAL, rgHashVal, 0, ptc));
  3184. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3185. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  3186. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  3187. LOG_TRY(TSetHash(hHash, HP_HASHVAL, NULL, 0, ptc));
  3188. // Hash value buffer is too short
  3189. /*
  3190. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  3191. LOG_TRY(TSetHash(hHash, HP_HASHVAL, (PBYTE) &dw, 0, ptc));
  3192. */
  3193. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  3194. LOG_TRY(TSetHash(hHash, HP_HASHVAL, (PBYTE) TEST_INVALID_POINTER, 0, ptc));
  3195. ptc->dwErrorCode = NTE_BAD_TYPE;
  3196. LOG_TRY(TSetHash(hHash, HP_HMAC_INFO, (PBYTE) &dw, 0, ptc));
  3197. ptc->dwErrorCode = NTE_BAD_FLAGS;
  3198. LOG_TRY(TSetHash(hHash, HP_HASHVAL, rgHashVal, TEST_INVALID_FLAG, ptc));
  3199. ptc->dwErrorCode = NTE_BAD_TYPE;
  3200. LOG_TRY(TSetHash(hHash, TEST_INVALID_FLAG, rgHashVal, 0, ptc));
  3201. /*
  3202. LOG_TRY(TRelease(hProv, 0, ptc));
  3203. hProv = 0;
  3204. // Provider handle used to create hHash is now invalid
  3205. ptc->dwErrorCode = NTE_BAD_UID;
  3206. LOG_TRY(TSetHash(hHash, HP_HASHVAL, rgHashVal, 0, ptc));
  3207. */
  3208. fSuccess = TRUE;
  3209. Cleanup:
  3210. if (hHash)
  3211. {
  3212. TDestroyHash(hHash, ptc);
  3213. }
  3214. if (hProv)
  3215. {
  3216. TRelease(hProv, 0, ptc);
  3217. }
  3218. return fSuccess;
  3219. }
  3220. //
  3221. // Function: TestDecryptProc
  3222. //
  3223. BOOL TestDecryptProc(
  3224. PALGNODE pAlgNode,
  3225. PTESTCASE ptc,
  3226. PVOID pvTestDecryptInfo)
  3227. {
  3228. BOOL fSuccess = FALSE;
  3229. PTEST_DECRYPT_INFO pTestDecryptInfo = (PTEST_DECRYPT_INFO) pvTestDecryptInfo;
  3230. TEST_ENCRYPT_INFO TestEncryptInfo;
  3231. memset(&TestEncryptInfo, 0, sizeof(TestEncryptInfo));
  3232. //
  3233. // TODO: There are a lot more permutations possible when calling
  3234. // ProcessCipherData.
  3235. //
  3236. // 1) Modulate key sizes
  3237. // 2) Switch cipher modes
  3238. // 3) Use salt
  3239. // 4) Use IV's
  3240. //
  3241. TestEncryptInfo.aiKeyAlg = pAlgNode->ProvEnumalgsEx.aiAlgid;
  3242. TestEncryptInfo.dwKeySize = pAlgNode->ProvEnumalgsEx.dwMaxLen;
  3243. TestEncryptInfo.Operation = pTestDecryptInfo->fDecrypt ? OP_Decrypt : OP_Encrypt;
  3244. LOG_TRY(ProcessCipherData(
  3245. pTestDecryptInfo->hProv,
  3246. &TestEncryptInfo,
  3247. ptc));
  3248. LOG_TRY(VerifyCipherData(
  3249. pTestDecryptInfo->hInteropProv,
  3250. &TestEncryptInfo,
  3251. ptc));
  3252. fSuccess = TRUE;
  3253. Cleanup:
  3254. return fSuccess;
  3255. }
  3256. //
  3257. // Function: ScenarioDecryptTests
  3258. // Purpose: Run decrypt/encryption scenarios for this CSP
  3259. //
  3260. BOOL ScenarioDecryptTests(PCSPINFO pCSPInfo)
  3261. {
  3262. BOOL fSuccess = FALSE;
  3263. LPWSTR pwszContainer = TEST_CONTAINER;
  3264. LPWSTR pwszContainer2 = TEST_CONTAINER_2;
  3265. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3266. TEST_DECRYPT_INFO TestDecryptInfo;
  3267. memset(&TestDecryptInfo, 0, sizeof(TestDecryptInfo));
  3268. LOG_TRY(CreateNewContext(
  3269. &(TestDecryptInfo.hProv),
  3270. pwszContainer,
  3271. CRYPT_NEWKEYSET,
  3272. ptc));
  3273. LOG_TRY(CreateNewContext(
  3274. &(TestDecryptInfo.hInteropProv),
  3275. pwszContainer2,
  3276. CRYPT_NEWKEYSET,
  3277. ptc));
  3278. LOG_TRY(AlgListIterate(
  3279. pCSPInfo->pAlgList,
  3280. DataEncryptFilter,
  3281. TestDecryptProc,
  3282. (PVOID) (&TestDecryptInfo),
  3283. ptc));
  3284. fSuccess = TRUE;
  3285. Cleanup:
  3286. if (TestDecryptInfo.hProv)
  3287. {
  3288. TRelease(TestDecryptInfo.hProv, 0, ptc);
  3289. }
  3290. if (TestDecryptInfo.hInteropProv)
  3291. {
  3292. TRelease(TestDecryptInfo.hInteropProv, 0, ptc);
  3293. }
  3294. return fSuccess;
  3295. }
  3296. //
  3297. // Function: InteropDecryptTests
  3298. // Purpose: Run decrypt/encryption interop scenarios for this
  3299. // and a second CSP.
  3300. //
  3301. BOOL InteropDecryptTests(PCSPINFO pCSPInfo)
  3302. {
  3303. BOOL fSuccess = FALSE;
  3304. LPWSTR pwszContainer = TEST_CONTAINER;
  3305. LPWSTR pwszInteropContainer = TEST_CONTAINER_2;
  3306. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3307. TEST_DECRYPT_INFO TestDecryptInfo;
  3308. memset(&TestDecryptInfo, 0, sizeof(TestDecryptInfo));
  3309. LOG_TRY(CreateNewContext(
  3310. &(TestDecryptInfo.hProv),
  3311. pwszContainer,
  3312. CRYPT_NEWKEYSET,
  3313. ptc));
  3314. LOG_TRY(CreateNewInteropContext(
  3315. &(TestDecryptInfo.hInteropProv),
  3316. pwszInteropContainer,
  3317. CRYPT_NEWKEYSET,
  3318. ptc));
  3319. LOG_TRY(AlgListIterate(
  3320. pCSPInfo->pAlgList,
  3321. DataEncryptFilter,
  3322. TestDecryptProc,
  3323. (PVOID) (&TestDecryptInfo),
  3324. ptc));
  3325. fSuccess = TRUE;
  3326. Cleanup:
  3327. if (TestDecryptInfo.hProv)
  3328. {
  3329. TRelease(TestDecryptInfo.hProv, 0, ptc);
  3330. }
  3331. if (TestDecryptInfo.hInteropProv)
  3332. {
  3333. TRelease(TestDecryptInfo.hInteropProv, 0, ptc);
  3334. }
  3335. return fSuccess;
  3336. }
  3337. //
  3338. // RSA Key-exchange private key blob. Used
  3339. // by PositiveDecryptTests, below.
  3340. //
  3341. BYTE g_rgbRSAPrivateKeyXBlob [] =
  3342. {
  3343. 0x07, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
  3344. 0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00,
  3345. 0x01, 0x00, 0x01, 0x00, 0x13, 0x98, 0xf3, 0x0d,
  3346. 0x08, 0x86, 0x14, 0x94, 0xc8, 0x7b, 0x29, 0x71,
  3347. 0xa4, 0x5f, 0xdf, 0xf4, 0xf4, 0x8f, 0x29, 0x00,
  3348. 0x07, 0xfa, 0xb0, 0x39, 0xe2, 0x36, 0x09, 0x7e,
  3349. 0xff, 0x89, 0xea, 0xb9, 0xac, 0xcd, 0xdd, 0xc6,
  3350. 0xce, 0x14, 0x21, 0x42, 0x85, 0x93, 0x7a, 0x63,
  3351. 0x79, 0xdc, 0x21, 0xf3, 0x8c, 0x42, 0x5e, 0xdb,
  3352. 0xe1, 0x72, 0x42, 0x81, 0xdb, 0xc6, 0xc9, 0x1e,
  3353. 0xd5, 0x45, 0x2a, 0xb9, 0x91, 0x0a, 0xaa, 0x2c,
  3354. 0x9f, 0x41, 0xde, 0x0e, 0x31, 0x0a, 0xee, 0x17,
  3355. 0x24, 0xb9, 0xe6, 0x61, 0x88, 0x15, 0x69, 0x1e,
  3356. 0x24, 0xea, 0x54, 0x1d, 0xbe, 0xc9, 0x6f, 0x1d,
  3357. 0x74, 0xf8, 0xa7, 0xe4, 0x63, 0x62, 0xc6, 0x44,
  3358. 0x2e, 0xfa, 0x19, 0x89, 0xdf, 0x1d, 0x97, 0x70,
  3359. 0x4a, 0x7a, 0xef, 0x92, 0x22, 0xff, 0xcc, 0xae,
  3360. 0x4e, 0x58, 0x77, 0xff, 0x78, 0xcb, 0x03, 0x6e,
  3361. 0xc3, 0xe0, 0x4e, 0xcf, 0x21, 0xdf, 0x91, 0x35,
  3362. 0x3e, 0xf3, 0xa0, 0x92, 0xc5, 0x3f, 0xd9, 0xa1,
  3363. 0x00, 0x1a, 0x3e, 0x72, 0xbe, 0x22, 0x10, 0xe5,
  3364. 0xb3, 0xda, 0xa0, 0x95, 0x45, 0xc7, 0x92, 0x99,
  3365. 0x87, 0xa4, 0x8d, 0x43, 0x55, 0xca, 0xa5, 0x8d,
  3366. 0x80, 0xec, 0xb5, 0xe2, 0x1f, 0xc8, 0x9c, 0x54,
  3367. 0x07, 0xfa, 0x7a, 0x4c, 0xfe, 0xf9, 0x9f, 0xe5,
  3368. 0x2b, 0xb8, 0x85, 0x3c, 0x0f, 0xe9, 0x41, 0xb1,
  3369. 0x74, 0x8f, 0x48, 0x99, 0x7c, 0x70, 0x40, 0x05,
  3370. 0xe1, 0xb2, 0x75, 0x9a, 0xb7, 0x70, 0x40, 0xd2,
  3371. 0x2e, 0xc1, 0xbb, 0xc1, 0x63, 0xbf, 0x5a, 0x59,
  3372. 0x4d, 0xcf, 0xec, 0x05, 0xfb, 0x1d, 0xab, 0x5d,
  3373. 0x45, 0x1c, 0x69, 0x14, 0x21, 0x56, 0x31, 0xd6,
  3374. 0x86, 0x99, 0x32, 0x59, 0xd6, 0x88, 0x53, 0x12,
  3375. 0x54, 0xe3, 0xe5, 0x07, 0x5b, 0xcc, 0x5e, 0xbd,
  3376. 0x83, 0xea, 0x38, 0x56, 0x45, 0x74, 0x39, 0x0b,
  3377. 0x30, 0xf6, 0xe2, 0x56, 0x4d, 0xae, 0x69, 0xf5,
  3378. 0xb4, 0xf6, 0x35, 0x6f, 0xa8, 0x6f, 0x87, 0xb0,
  3379. 0x52, 0x5b, 0x33, 0xea, 0xdc, 0xd8, 0x83, 0xa3,
  3380. 0xec, 0xda, 0x2c, 0xdd, 0xb5, 0x0a, 0xea, 0x15,
  3381. 0x1c, 0x68, 0xaa, 0x8b
  3382. };
  3383. //
  3384. // Cipher text encrypted with the g_rgbRSAPrivateKeyXBlob
  3385. // above. Used by PositiveDecryptTests.
  3386. //
  3387. BYTE g_rgbRSACipherText [] =
  3388. {
  3389. 0xd8, 0x9f, 0xcd, 0xd2, 0x77, 0x45, 0x76, 0x77,
  3390. 0x66, 0x32, 0x4c, 0x88, 0x2d, 0xcf, 0xdc, 0xfd,
  3391. 0xe5, 0x03, 0xfc, 0x4e, 0x65, 0xd1, 0x77, 0xd5,
  3392. 0x90, 0x3d, 0x71, 0x88, 0x1e, 0xff, 0x3b, 0x27,
  3393. 0xff, 0x4c, 0xb9, 0xc5, 0x6b, 0x6b, 0x4d, 0xd9,
  3394. 0x9e, 0x11, 0x88, 0xcb, 0xb8, 0xbb, 0x48, 0xc8,
  3395. 0xc3, 0x7e, 0xb0, 0xd5, 0x0d, 0x1a, 0x2e, 0xed,
  3396. 0x6a, 0x4a, 0x45, 0xb1, 0xdc, 0x6e, 0x65, 0x42
  3397. };
  3398. //
  3399. // Function: PositiveDecryptTests
  3400. // Purpose: Run the test cases for CryptDecrypt
  3401. //
  3402. BOOL PositiveDecryptTests(PCSPINFO pCSPInfo)
  3403. {
  3404. BOOL fSuccess = FALSE;
  3405. HCRYPTPROV hProv = 0;
  3406. HCRYPTKEY hKey = 0;
  3407. LPWSTR pwszContainer = TEST_CONTAINER;
  3408. PBYTE pbData = NULL;
  3409. DWORD cbData = 0;
  3410. //DWORD dw = 0;
  3411. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3412. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3413. //
  3414. // Group 4A
  3415. //
  3416. //
  3417. // Do CryptDecrypt positive test cases
  3418. //
  3419. switch( pCSPInfo->TestCase.dwTestLevel )
  3420. {
  3421. case TEST_LEVEL_KEY:
  3422. {
  3423. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3424. //
  3425. // Run some basic decryption tests for a stream cipher
  3426. //
  3427. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  3428. cbData = wcslen(TEST_DECRYPT_DATA) * sizeof(WCHAR);
  3429. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  3430. memcpy(pbData, TEST_DECRYPT_DATA, cbData);
  3431. LOG_TRY(TDecrypt(hKey, 0, TRUE, 0, pbData, &cbData, ptc));
  3432. break;
  3433. }
  3434. case TEST_LEVEL_CONTAINER:
  3435. {
  3436. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_NEWKEYSET, ptc));
  3437. //
  3438. // Import a known RSA key-exchange key pair.
  3439. //
  3440. LOG_TRY(TImportKey(
  3441. hProv,
  3442. g_rgbRSAPrivateKeyXBlob,
  3443. sizeof(g_rgbRSAPrivateKeyXBlob),
  3444. 0,
  3445. 0,
  3446. &hKey,
  3447. ptc));
  3448. cbData = sizeof(g_rgbRSACipherText);
  3449. LOG_TRY(TDecrypt(
  3450. hKey,
  3451. 0,
  3452. TRUE,
  3453. 0,
  3454. g_rgbRSACipherText,
  3455. &cbData,
  3456. ptc));
  3457. break;
  3458. }
  3459. default:
  3460. {
  3461. goto Cleanup;
  3462. }
  3463. }
  3464. fSuccess = TRUE;
  3465. Cleanup:
  3466. if (hKey)
  3467. {
  3468. TDestroyKey(hKey, ptc);
  3469. }
  3470. if (hProv)
  3471. {
  3472. TRelease(hProv, 0, ptc);
  3473. }
  3474. return fSuccess;
  3475. }
  3476. //
  3477. // Function: NegativeDecryptTests
  3478. // Purpose: Run the negative test cases for CryptDecrypt
  3479. //
  3480. BOOL NegativeDecryptTests(PCSPINFO pCSPInfo)
  3481. {
  3482. BOOL fSuccess = FALSE;
  3483. //LPWSTR pwszContainer = TEST_CONTAINER;
  3484. HCRYPTPROV hProv = 0;
  3485. HCRYPTKEY hKey = 0;
  3486. DWORD cb = 0;
  3487. //DWORD dw = 0;
  3488. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3489. DWORD dwSavedErrorLevel = 0;
  3490. BYTE rgCipherText[TEST_CIPHER_LENGTH_RC4];
  3491. BYTE rgRC2CipherText[TEST_RC2_BUFFER_LEN];
  3492. memset(rgCipherText, 0, sizeof(rgCipherText));
  3493. memset(rgRC2CipherText, 0, sizeof(rgRC2CipherText));
  3494. //
  3495. // Group 4A
  3496. //
  3497. //
  3498. // Do CryptDecrypt negative test cases
  3499. //
  3500. cb = sizeof(rgCipherText);
  3501. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3502. LOG_TRY(TDecrypt(0, 0, TRUE, 0, rgCipherText, &cb, ptc));
  3503. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3504. LOG_TRY(TDecrypt(TEST_INVALID_HANDLE, 0, TRUE, 0, rgCipherText, &cb, ptc));
  3505. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3506. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  3507. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  3508. LOG_TRY(TDecrypt(hKey, 0, TRUE, 0, (PBYTE) TEST_INVALID_POINTER, &cb, ptc));
  3509. cb = sizeof(rgCipherText);
  3510. ptc->dwErrorCode = NTE_BAD_FLAGS;
  3511. LOG_TRY(TDecrypt(hKey, 0, TRUE, TEST_INVALID_FLAG, rgCipherText, &cb, ptc));
  3512. ptc->dwErrorCode = NTE_BAD_HASH;
  3513. LOG_TRY(TDecrypt(hKey, TEST_INVALID_HANDLE, TRUE, 0, rgCipherText, &cb, ptc));
  3514. cb = 0;
  3515. ptc->dwErrorCode = NTE_BAD_LEN;
  3516. LOG_TRY(TDecrypt(hKey, 0, TRUE, 0, rgCipherText, &cb, ptc));
  3517. ptc->fExpectSuccess = TRUE;
  3518. cb = sizeof(rgCipherText);
  3519. LOG_TRY(TDecrypt(hKey, 0, TRUE, 0, rgCipherText, &cb, ptc));
  3520. ptc->fExpectSuccess = FALSE;
  3521. // This will only fail on no-export CSP's
  3522. dwSavedErrorLevel = ptc->dwErrorLevel;
  3523. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  3524. ptc->pwszErrorHelp = L"This CSP supports double-decryption";
  3525. ptc->dwErrorCode = NTE_DOUBLE_ENCRYPT;
  3526. LOG_TRY(TDecrypt(hKey, 0, TRUE, 0, rgCipherText, &cb, ptc));
  3527. ptc->dwErrorLevel = dwSavedErrorLevel;
  3528. ptc->pwszErrorHelp = NULL;
  3529. //
  3530. // Test block cipher issues with an RC2 key
  3531. //
  3532. LOG_TRY(TDestroyKey(hKey, ptc));
  3533. hKey = 0;
  3534. LOG_TRY(CreateNewKey(hProv, CALG_RC2, 0, &hKey, ptc));
  3535. cb = TEST_RC2_DATA_LEN;
  3536. ptc->fExpectSuccess = TRUE;
  3537. LOG_TRY(TEncrypt(
  3538. hKey,
  3539. 0,
  3540. TRUE,
  3541. 0,
  3542. rgRC2CipherText,
  3543. &cb,
  3544. sizeof(rgRC2CipherText),
  3545. ptc));
  3546. ptc->fExpectSuccess = FALSE;
  3547. cb--;
  3548. ptc->dwErrorCode = NTE_BAD_DATA;
  3549. LOG_TRY(TDecrypt(hKey, 0, TRUE, 0, rgRC2CipherText, &cb, ptc));
  3550. /*
  3551. LOG_TRY(TRelease(hProv, 0, ptc));
  3552. hProv = 0;
  3553. cb = sizeof(rgCipherText);
  3554. memset(rgCipherText, 0, cb);
  3555. ptc->dwErrorCode = NTE_BAD_UID;
  3556. LOG_TRY(TDecrypt(hKey, 0, TRUE, 0, rgCipherText, &cb, ptc));
  3557. */
  3558. fSuccess = TRUE;
  3559. Cleanup:
  3560. if (hKey)
  3561. {
  3562. TDestroyKey(hKey, ptc);
  3563. }
  3564. if (hProv)
  3565. {
  3566. TRelease(hProv, 0, ptc);
  3567. }
  3568. return fSuccess;
  3569. }
  3570. //
  3571. // Function: TestDeriveKeyProc
  3572. //
  3573. BOOL TestDeriveKeyProc(
  3574. PALGNODE pAlgNode,
  3575. PTESTCASE ptc,
  3576. PVOID pvTestDeriveKeyInfo)
  3577. {
  3578. BOOL fSuccess = FALSE;
  3579. HCRYPTHASH hHash = 0;
  3580. HCRYPTKEY hKey = 0;
  3581. DERIVED_KEY_INFO DerivedKeyInfo;
  3582. PTEST_DERIVE_KEY_INFO pTestDeriveKeyInfo = (PTEST_DERIVE_KEY_INFO) pvTestDeriveKeyInfo;
  3583. memset(&DerivedKeyInfo, 0, sizeof(DerivedKeyInfo));
  3584. //
  3585. // Initialize base hash information
  3586. //
  3587. DerivedKeyInfo.HashInfo.aiHash = CALG_SHA1;
  3588. DerivedKeyInfo.HashInfo.dbBaseData.pbData = (PBYTE) TEST_HASH_DATA;
  3589. DerivedKeyInfo.HashInfo.dbBaseData.cbData = wcslen(TEST_HASH_DATA) * sizeof(WCHAR);
  3590. LOG_TRY(CreateHashAndAddData(
  3591. pTestDeriveKeyInfo->hProv,
  3592. &hHash,
  3593. &(DerivedKeyInfo.HashInfo),
  3594. ptc,
  3595. 0, NULL));
  3596. // Debugging
  3597. /*
  3598. DerivedKeyInfo.cbHA = sizeof(DerivedKeyInfo.rgbHashValA);
  3599. LOG_TRY(CryptGetHashParam(hHash, HP_HASHVAL, DerivedKeyInfo.rgbHashValA, &(DerivedKeyInfo.cbHA), 0));
  3600. */
  3601. //
  3602. // Initialize the key information in DerivedKeyInfo and create the
  3603. // derived key.
  3604. //
  3605. DerivedKeyInfo.aiKey = pAlgNode->ProvEnumalgsEx.aiAlgid;
  3606. DerivedKeyInfo.dwKeySize = pAlgNode->ProvEnumalgsEx.dwDefaultLen;
  3607. LOG_TRY(TDeriveKey(
  3608. pTestDeriveKeyInfo->hProv,
  3609. DerivedKeyInfo.aiKey,
  3610. hHash,
  3611. CRYPT_EXPORTABLE | (DerivedKeyInfo.dwKeySize) << 16,
  3612. &hKey,
  3613. ptc));
  3614. // Debug
  3615. /*
  3616. DerivedKeyInfo.cbCA = 10;
  3617. LOG_TRY(CryptEncrypt(hKey, 0, TRUE, 0, DerivedKeyInfo.rgbCipherA, &(DerivedKeyInfo.cbCA), sizeof(DerivedKeyInfo.rgbCipherA)));
  3618. */
  3619. //
  3620. // Export the derived key in plaintext and verify the resulting key
  3621. // against a second CSP.
  3622. //
  3623. LOG_TRY(ExportPlaintextSessionKey(
  3624. hKey,
  3625. pTestDeriveKeyInfo->hProv,
  3626. &(DerivedKeyInfo.dbKey),
  3627. ptc));
  3628. LOG_TRY(CheckDerivedKey(
  3629. &DerivedKeyInfo,
  3630. pTestDeriveKeyInfo->hInteropProv,
  3631. ptc));
  3632. fSuccess = TRUE;
  3633. Cleanup:
  3634. if (hHash)
  3635. {
  3636. TDestroyHash(hHash, ptc);
  3637. }
  3638. if (hKey)
  3639. {
  3640. TDestroyKey(hKey, ptc);
  3641. }
  3642. if (DerivedKeyInfo.HashInfo.dbHashValue.pbData)
  3643. {
  3644. free(DerivedKeyInfo.HashInfo.dbHashValue.pbData);
  3645. }
  3646. if (DerivedKeyInfo.dbKey.pbData)
  3647. {
  3648. free(DerivedKeyInfo.dbKey.pbData);
  3649. }
  3650. return fSuccess;
  3651. }
  3652. //
  3653. // Function: InteropDeriveKeyTests
  3654. // Purpose: Run TestDeriveKeyProc for each session key algorithm
  3655. // supported by this CSP. A second CSP is used to verify
  3656. // that the key has been derived correctly.
  3657. //
  3658. BOOL InteropDeriveKeyTests(PCSPINFO pCSPInfo)
  3659. {
  3660. BOOL fSuccess = FALSE;
  3661. //LPWSTR pwszContainer = TEST_CONTAINER;
  3662. //LPWSTR pwszInteropContainer = TEST_CONTAINER_2;
  3663. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3664. TEST_DERIVE_KEY_INFO TestDeriveKeyInfo;
  3665. memset(&TestDeriveKeyInfo, 0, sizeof(TestDeriveKeyInfo));
  3666. LOG_TRY(CreateNewContext(
  3667. &(TestDeriveKeyInfo.hProv),
  3668. NULL,
  3669. CRYPT_VERIFYCONTEXT,
  3670. ptc));
  3671. LOG_TRY(CreateNewInteropContext(
  3672. &(TestDeriveKeyInfo.hInteropProv),
  3673. NULL,
  3674. CRYPT_VERIFYCONTEXT,
  3675. ptc));
  3676. //
  3677. // TestDeriveKeyProc will create, export, and verify a derived
  3678. // key for each session key algorithm supported by the CSP
  3679. // under test. Use of the CRYPT_EXPORTABLE flag is covered
  3680. // by that routine.
  3681. //
  3682. LOG_TRY(AlgListIterate(
  3683. pCSPInfo->pAlgList,
  3684. DataEncryptFilter,
  3685. TestDeriveKeyProc,
  3686. (PVOID) (&TestDeriveKeyInfo),
  3687. ptc));
  3688. fSuccess = TRUE;
  3689. Cleanup:
  3690. if (TestDeriveKeyInfo.hProv)
  3691. {
  3692. TRelease(TestDeriveKeyInfo.hProv, 0, ptc);
  3693. }
  3694. if (TestDeriveKeyInfo.hInteropProv)
  3695. {
  3696. TRelease(TestDeriveKeyInfo.hInteropProv, 0, ptc);
  3697. }
  3698. return fSuccess;
  3699. }
  3700. //
  3701. // Function: PositiveDeriveKeyTests
  3702. // Purpose: Run the test cases for CryptDeriveKey. The set of positive test cases
  3703. // to be executed depends on the dwCSPClass and dwTestLevel parameters.
  3704. //
  3705. // Note: Since the Microsoft RSA CSP only supports derived session keys and not
  3706. // derived public keys, the PositiveDeriveKeyTests() belong in TEST_LEVEL_KEY
  3707. // only.
  3708. //
  3709. BOOL PositiveDeriveKeyTests(PCSPINFO pCSPInfo)
  3710. {
  3711. BOOL fSuccess = FALSE;
  3712. //LPWSTR pwszContainer = TEST_CONTAINER;
  3713. HCRYPTPROV hProv = 0;
  3714. HCRYPTHASH hHash = 0;
  3715. HCRYPTKEY hKey = 0;
  3716. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3717. HASH_INFO HashInfo;
  3718. memset(&HashInfo, 0, sizeof(HashInfo));
  3719. //
  3720. // Group 4B
  3721. //
  3722. //
  3723. // Do CryptDeriveKey positive test cases
  3724. //
  3725. LOG_TRY(CreateNewContext(
  3726. &hProv,
  3727. NULL,
  3728. CRYPT_VERIFYCONTEXT,
  3729. ptc));
  3730. //
  3731. // Tests for basic use of CryptDeriveKey, then the flags CRYPT_CREATE_SALT,
  3732. // CRYPT_NO_SALT, and
  3733. // CRYPT_UPDATE_KEY (the latter is currently not supported by the Microsoft
  3734. // CSP's) follow. Create a simple hash from which the derived keys will be
  3735. // generated.
  3736. //
  3737. HashInfo.aiHash = CALG_SHA1;
  3738. HashInfo.dbBaseData.pbData = (PBYTE) TEST_HASH_DATA;
  3739. HashInfo.dbBaseData.cbData = wcslen(TEST_HASH_DATA) * sizeof(WCHAR);
  3740. LOG_TRY(CreateHashAndAddData(
  3741. hProv,
  3742. &hHash,
  3743. &HashInfo,
  3744. ptc,
  3745. 0, NULL));
  3746. //
  3747. // Base test
  3748. //
  3749. LOG_TRY(TDeriveKey(
  3750. hProv,
  3751. CALG_RC4,
  3752. hHash,
  3753. 0,
  3754. &hKey,
  3755. ptc));
  3756. LOG_TRY(TDestroyKey(hKey, ptc));
  3757. hKey = 0;
  3758. //
  3759. // Test CRYPT_CREATE_SALT
  3760. //
  3761. // Derive a 40 bit RC4 key. Specifying a small key size is interesting
  3762. // because the Microsoft CSP's will not, by default, add any salt
  3763. // to a 128 bit key.
  3764. //
  3765. LOG_TRY(TDeriveKey(
  3766. hProv,
  3767. CALG_RC4,
  3768. hHash,
  3769. CRYPT_CREATE_SALT | (0x28 << 16),
  3770. &hKey,
  3771. ptc));
  3772. LOG_TRY(TDestroyKey(hKey, ptc));
  3773. hKey = 0;
  3774. //
  3775. // Test CRYPT_NO_SALT
  3776. //
  3777. LOG_TRY(TDeriveKey(
  3778. hProv,
  3779. CALG_RC4,
  3780. hHash,
  3781. CRYPT_NO_SALT | (0x28 << 16),
  3782. &hKey,
  3783. ptc));
  3784. LOG_TRY(TDestroyKey(hKey, ptc));
  3785. hKey = 0;
  3786. //
  3787. // Test CRYPT_UPDATE_KEY
  3788. //
  3789. LOG_TRY(TDeriveKey(
  3790. hProv,
  3791. CALG_RC4,
  3792. hHash,
  3793. 0,
  3794. &hKey,
  3795. ptc));
  3796. //
  3797. // Using the key handle just created, attempt to update the key
  3798. // data with the same hash data. The Microsoft CSP currently ignores
  3799. // this flag.
  3800. //
  3801. LOG_TRY(TDeriveKey(
  3802. hProv,
  3803. CALG_RC4,
  3804. hHash,
  3805. CRYPT_UPDATE_KEY,
  3806. &hKey,
  3807. ptc));
  3808. fSuccess = TRUE;
  3809. Cleanup:
  3810. if (hHash)
  3811. {
  3812. TDestroyHash(hHash, ptc);
  3813. }
  3814. if (hKey)
  3815. {
  3816. TDestroyKey(hKey, ptc);
  3817. }
  3818. if (hProv)
  3819. {
  3820. TRelease(hProv, 0, ptc);
  3821. }
  3822. return fSuccess;
  3823. }
  3824. //
  3825. // Function: NegativeDeriveKeyTests
  3826. // Purpose: Run the negative test cases for CryptDeriveKey. These test cases
  3827. // will only execute for TEST_LEVEL_KEY, based on the dwTestLevel parameter.
  3828. //
  3829. BOOL NegativeDeriveKeyTests(PCSPINFO pCSPInfo)
  3830. {
  3831. BOOL fSuccess = FALSE;
  3832. //LPWSTR pwszContainer = TEST_CONTAINER;
  3833. //LPWSTR pwszContainer2 = TEST_CONTAINER_2;
  3834. HCRYPTPROV hProv = 0;
  3835. HCRYPTPROV hProv2 = 0;
  3836. HCRYPTKEY hKey = 0;
  3837. HCRYPTHASH hHash = 0;
  3838. HCRYPTHASH hHash2 = 0;
  3839. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3840. //
  3841. // Group 4B
  3842. //
  3843. // Only run the negative test cases for TEST_LEVEL_KEY. This ensures that the same cases won't be
  3844. // re-run for TEST_LEVEL_CONTAINER. Only the positive cases are different.
  3845. if (TEST_LEVEL_KEY == ptc->dwTestLevel)
  3846. {
  3847. //
  3848. // Do CryptDeriveKey negative test cases
  3849. //
  3850. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3851. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  3852. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3853. LOG_TRY(TDeriveKey(0, CALG_RC4, hHash, 0, &hKey, ptc));
  3854. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3855. LOG_TRY(TDeriveKey(TEST_INVALID_HANDLE, CALG_RC4, hHash, 0, &hKey, ptc));
  3856. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  3857. LOG_TRY(TDeriveKey(hProv, CALG_RC4, hHash, 0, NULL, ptc));
  3858. ptc->dwErrorCode = NTE_BAD_ALGID;
  3859. LOG_TRY(TDeriveKey(hProv, CALG_MD5, hHash, 0, &hKey, ptc));
  3860. ptc->dwErrorCode = NTE_BAD_FLAGS;
  3861. LOG_TRY(TDeriveKey(hProv, CALG_RC4, hHash, TEST_INVALID_FLAG, &hKey, ptc));
  3862. ptc->dwErrorCode = NTE_BAD_HASH;
  3863. LOG_TRY(TDeriveKey(hProv, CALG_RC4, TEST_INVALID_HANDLE, 0, &hKey, ptc));
  3864. ptc->dwErrorCode = NTE_SILENT_CONTEXT;
  3865. LOG_TRY(TDeriveKey(hProv, CALG_RC4, hHash, CRYPT_USER_PROTECTED, &hKey, ptc));
  3866. LOG_TRY(CreateNewContext(&hProv2, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3867. LOG_TRY(CreateNewHash(hProv2, CALG_SHA1, &hHash2, ptc));
  3868. // Hash handle not created from same context as hProv
  3869. ptc->dwErrorCode = NTE_BAD_HASH;
  3870. LOG_TRY(TDeriveKey(hProv, CALG_RC4, hHash2, 0, &hKey, ptc));
  3871. }
  3872. fSuccess = TRUE;
  3873. Cleanup:
  3874. if (hHash)
  3875. {
  3876. TDestroyHash(hHash, ptc);
  3877. }
  3878. if (hHash2)
  3879. {
  3880. TDestroyHash(hHash2, ptc);
  3881. }
  3882. if (hProv)
  3883. {
  3884. TRelease(hProv, 0, ptc);
  3885. }
  3886. if (hProv2)
  3887. {
  3888. TRelease(hProv2, 0, ptc);
  3889. }
  3890. return fSuccess;
  3891. }
  3892. //
  3893. // Function: PositiveDestroyKeyTests
  3894. // Purpose: Run the test cases for CryptDestroyKey
  3895. //
  3896. BOOL PositiveDestroyKeyTests(PCSPINFO pCSPInfo)
  3897. {
  3898. BOOL fSuccess = FALSE;
  3899. LPWSTR pwszContainer = TEST_CONTAINER;
  3900. HCRYPTPROV hProv = 0;
  3901. HCRYPTKEY hKey = 0;
  3902. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3903. //
  3904. // Group 4C
  3905. //
  3906. //
  3907. // Do CryptDestroyKey positive test cases
  3908. //
  3909. switch (pCSPInfo->TestCase.dwTestLevel)
  3910. {
  3911. case TEST_LEVEL_KEY:
  3912. {
  3913. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3914. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  3915. LOG_TRY(TDestroyKey(hKey, ptc));
  3916. hKey = 0;
  3917. break;
  3918. }
  3919. case TEST_LEVEL_CONTAINER:
  3920. {
  3921. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  3922. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  3923. LOG_TRY(TDestroyKey(hKey, ptc));
  3924. hKey = 0;
  3925. break;
  3926. }
  3927. default:
  3928. {
  3929. goto Cleanup;
  3930. }
  3931. }
  3932. fSuccess = TRUE;
  3933. Cleanup:
  3934. if (hKey)
  3935. {
  3936. TDestroyKey(hKey, ptc);
  3937. }
  3938. if (hProv)
  3939. {
  3940. TRelease(hProv, 0, ptc);
  3941. }
  3942. return fSuccess;
  3943. }
  3944. //
  3945. // Function: NegativeDestroyKeyTests
  3946. // Purpose: Run the negative test cases for CryptDestroyKey
  3947. //
  3948. BOOL NegativeDestroyKeyTests(PCSPINFO pCSPInfo)
  3949. {
  3950. BOOL fSuccess = FALSE;
  3951. //LPWSTR pwszContainer = TEST_CONTAINER;
  3952. HCRYPTPROV hProv = 0;
  3953. HCRYPTKEY hKey = 0;
  3954. PTESTCASE ptc = &(pCSPInfo->TestCase);
  3955. //
  3956. // Group 4C
  3957. //
  3958. //
  3959. // Do CryptDestroyKey negative test cases
  3960. //
  3961. ptc->fTestingDestroyKey = TRUE;
  3962. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3963. LOG_TRY(TDestroyKey(0, ptc));
  3964. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  3965. LOG_TRY(TDestroyKey(TEST_INVALID_HANDLE, ptc));
  3966. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  3967. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  3968. /*
  3969. LOG_TRY(TRelease(hProv, 0, ptc));
  3970. hProv = 0;
  3971. // Provider handle used to create hKey is now invalid
  3972. ptc->dwErrorCode = NTE_BAD_UID;
  3973. LOG_TRY(TDestroyKey(hKey, ptc));
  3974. */
  3975. fSuccess = TRUE;
  3976. Cleanup:
  3977. ptc->fTestingDestroyKey = FALSE;
  3978. if (hKey)
  3979. {
  3980. TDestroyKey(hKey, ptc);
  3981. }
  3982. if (hProv)
  3983. {
  3984. TRelease(hProv, 0, ptc);
  3985. }
  3986. return fSuccess;
  3987. }
  3988. //
  3989. // Function: PositiveEncryptTests
  3990. // Purpose: Run the test cases for CryptEncrypt
  3991. //
  3992. BOOL PositiveEncryptTests(PCSPINFO pCSPInfo)
  3993. {
  3994. BOOL fSuccess = FALSE;
  3995. HCRYPTPROV hProv = 0;
  3996. HCRYPTKEY hKey = 0;
  3997. //LPWSTR pwszContainer = TEST_CONTAINER;
  3998. DWORD cbData = 0;
  3999. PBYTE pbData = NULL;
  4000. DWORD dw = 0;
  4001. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4002. BYTE rgb [] = {
  4003. 0x00, 0x00, 0x00, 0x00,
  4004. 0x00, 0x00, 0x00, 0x00,
  4005. 0x00, 0x00, 0x00, 0x00,
  4006. 0x00, 0x00, 0x00, 0x00
  4007. };
  4008. //
  4009. // Group 4E
  4010. //
  4011. //
  4012. // Do CryptEncrypt positive test cases
  4013. //
  4014. switch( pCSPInfo->TestCase.dwTestLevel )
  4015. {
  4016. case TEST_LEVEL_KEY:
  4017. {
  4018. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  4019. //
  4020. // Try a simple stream cipher encryption
  4021. //
  4022. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  4023. cbData = wcslen(TEST_DECRYPT_DATA) * sizeof(WCHAR);
  4024. dw = cbData;
  4025. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  4026. memcpy(pbData, TEST_DECRYPT_DATA, cbData);
  4027. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, pbData, &cbData, dw, ptc));
  4028. //
  4029. // Verify that ciphertext is not same as plaintext
  4030. //
  4031. if (0 == memcmp(pbData, TEST_DECRYPT_DATA, dw))
  4032. {
  4033. ptc->pwszErrorHelp = L"CryptEncrypt ciphertext matches original plaintext";
  4034. LOG_TRY(LogApiFailure(
  4035. API_CRYPTENCRYPT,
  4036. ERROR_BAD_DATA,
  4037. ptc));
  4038. ptc->pwszErrorHelp = NULL;
  4039. }
  4040. LOG_TRY(TDestroyKey(hKey, ptc));
  4041. hKey = 0;
  4042. //
  4043. // Try a simple block cipher encryption
  4044. //
  4045. LOG_TRY(CreateNewKey(hProv, CALG_RC2, 0, &hKey, ptc));
  4046. cbData = sizeof(rgb) / 2;
  4047. dw = sizeof(rgb);
  4048. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, rgb, &cbData, dw, ptc));
  4049. //
  4050. // Verify that ciphertext is not still zeros
  4051. //
  4052. while (dw-- && (0 == rgb[dw - 1]));
  4053. if (0 == dw)
  4054. {
  4055. ptc->pwszErrorHelp = L"CryptEncrypt ciphertext matches original plaintext";
  4056. LOG_TRY(LogApiFailure(
  4057. API_CRYPTENCRYPT,
  4058. ERROR_BAD_DATA,
  4059. ptc));
  4060. ptc->pwszErrorHelp = NULL;
  4061. }
  4062. break;
  4063. }
  4064. case TEST_LEVEL_CONTAINER:
  4065. {
  4066. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_NEWKEYSET, ptc));
  4067. //
  4068. // Test direct direct RSA encryption using an key-exchange public key.
  4069. //
  4070. // Not all CSP's will support this, so the error level may need to
  4071. // be adjusted.
  4072. //
  4073. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hKey, ptc));
  4074. cbData = wcslen(TEST_DECRYPT_DATA) * sizeof(WCHAR);
  4075. dw = cbData;
  4076. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, NULL, &dw, 0, ptc));
  4077. LOG_TRY(TestAlloc(&pbData, dw, ptc));
  4078. memcpy(pbData, TEST_DECRYPT_DATA, cbData);
  4079. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, pbData, &cbData, dw, ptc));
  4080. //
  4081. // Verify that ciphertext is not same as plaintext
  4082. //
  4083. if (0 == memcmp(pbData, TEST_DECRYPT_DATA, dw))
  4084. {
  4085. ptc->pwszErrorHelp = L"CryptEncrypt ciphertext matches original plaintext";
  4086. LOG_TRY(LogApiFailure(
  4087. API_CRYPTENCRYPT,
  4088. ERROR_BAD_DATA,
  4089. ptc));
  4090. ptc->pwszErrorHelp = NULL;
  4091. }
  4092. break;
  4093. }
  4094. default:
  4095. {
  4096. goto Cleanup;
  4097. }
  4098. }
  4099. fSuccess = TRUE;
  4100. Cleanup:
  4101. if (hKey)
  4102. {
  4103. TDestroyKey(hKey, ptc);
  4104. }
  4105. if (hProv)
  4106. {
  4107. TRelease(hProv, 0, ptc);
  4108. }
  4109. return fSuccess;
  4110. }
  4111. //
  4112. // Function: NegativeEncryptTests
  4113. // Purpose: Run the negative test cases for CryptEncrypt
  4114. //
  4115. BOOL NegativeEncryptTests(PCSPINFO pCSPInfo)
  4116. {
  4117. BOOL fSuccess = FALSE;
  4118. //LPWSTR pwszContainer = TEST_CONTAINER;
  4119. //LPWSTR pwszContainer2 = TEST_CONTAINER_2;
  4120. HCRYPTPROV hProv = 0;
  4121. HCRYPTPROV hProv2 = 0;
  4122. HCRYPTKEY hKey = 0;
  4123. HCRYPTHASH hHash = 0;
  4124. DWORD cb = 0;
  4125. DWORD dw = 0;
  4126. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4127. DWORD dwSavedErrorLevel = 0;
  4128. BYTE rgPlainText[TEST_CIPHER_LENGTH_RC4];
  4129. BYTE rgRC2PlainText[TEST_RC2_BUFFER_LEN];
  4130. BYTE rgHashVal[HASH_LENGTH_SHA1];
  4131. memset(rgHashVal, 0, sizeof(rgHashVal));
  4132. memset(rgPlainText, 0, sizeof(rgPlainText));
  4133. memset(rgRC2PlainText, 0, sizeof(rgRC2PlainText));
  4134. //
  4135. // Group 4E
  4136. //
  4137. //
  4138. // Do CryptEncrypt negative test cases
  4139. //
  4140. cb = sizeof(rgPlainText);
  4141. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  4142. LOG_TRY(TEncrypt(0, 0, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4143. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  4144. LOG_TRY(TEncrypt(TEST_INVALID_HANDLE, 0, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4145. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  4146. //
  4147. // Create a block encryption key to test invalid buffer
  4148. // lengths.
  4149. //
  4150. LOG_TRY(CreateNewKey(hProv, CALG_RC2, 0, &hKey, ptc));
  4151. dw = cb = TEST_RC2_DATA_LEN;
  4152. ptc->fExpectSuccess = TRUE;
  4153. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, NULL, &cb, 0, ptc));
  4154. ptc->fExpectSuccess = FALSE;
  4155. cb--;
  4156. // dwBufLen param is now too short
  4157. ptc->dwErrorCode = ERROR_MORE_DATA;
  4158. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, rgRC2PlainText, &dw, cb, ptc));
  4159. // Done with block cipher key
  4160. LOG_TRY(TDestroyKey(hKey, ptc));
  4161. hKey = 0;
  4162. //
  4163. // Continue tests using a stream cipher key
  4164. //
  4165. cb = sizeof(rgPlainText);
  4166. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  4167. // pbData buffer is too short and will AV
  4168. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  4169. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, (PBYTE) TEST_INVALID_POINTER, &cb, cb, ptc));
  4170. // Invalid flag
  4171. ptc->dwErrorCode = NTE_BAD_FLAGS;
  4172. LOG_TRY(TEncrypt(hKey, 0, TRUE, TEST_INVALID_FLAG, rgPlainText, &cb, cb, ptc));
  4173. ptc->fExpectSuccess = TRUE;
  4174. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4175. ptc->fExpectSuccess = FALSE;
  4176. // Not all providers prohibit double-encryption
  4177. dwSavedErrorLevel = ptc->dwErrorLevel;
  4178. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  4179. ptc->pwszErrorHelp = L"This CSP supports double-encryption";
  4180. ptc->dwErrorCode = NTE_DOUBLE_ENCRYPT;
  4181. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4182. ptc->dwErrorLevel = dwSavedErrorLevel;
  4183. ptc->pwszErrorHelp = NULL;
  4184. memset(rgPlainText, 0, cb);
  4185. // Invalid, non-zero, hash handle
  4186. ptc->dwErrorCode = NTE_BAD_HASH;
  4187. LOG_TRY(TEncrypt(hKey, TEST_INVALID_HANDLE, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4188. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  4189. ptc->fExpectSuccess = TRUE;
  4190. cb = sizeof(rgHashVal);
  4191. LOG_TRY(TGetHash(hHash, HP_HASHVAL, rgHashVal, &cb, 0, ptc));
  4192. ptc->fExpectSuccess = FALSE;
  4193. cb = sizeof(rgPlainText);
  4194. ptc->dwErrorCode = NTE_BAD_HASH_STATE;
  4195. LOG_TRY(TEncrypt(hKey, hHash, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4196. TDestroyHash(hHash, ptc);
  4197. hHash = 0;
  4198. LOG_TRY(CreateNewContext(&hProv2, NULL, CRYPT_VERIFYCONTEXT, ptc));
  4199. // Create a new hash from a different cryptographic context
  4200. LOG_TRY(CreateNewHash(hProv2, CALG_SHA1, &hHash, ptc));
  4201. // API should not allow hKey and hHash from two different contexts
  4202. ptc->dwErrorCode = NTE_BAD_HASH;
  4203. LOG_TRY(TEncrypt(hKey, hHash, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4204. // Delete the original context, hKey derived from it should now be unusable
  4205. /*
  4206. LOG_TRY(TRelease(hProv, 0, ptc));
  4207. hProv = 0;
  4208. ptc->dwErrorCode = NTE_BAD_UID;
  4209. LOG_TRY(TEncrypt(hKey, 0, TRUE, 0, rgPlainText, &cb, cb, ptc));
  4210. */
  4211. fSuccess = TRUE;
  4212. Cleanup:
  4213. if (hHash)
  4214. {
  4215. TDestroyHash(hHash, ptc);
  4216. }
  4217. if (hKey)
  4218. {
  4219. TDestroyKey(hKey, ptc);
  4220. }
  4221. if (hProv)
  4222. {
  4223. TRelease(hProv, 0, ptc);
  4224. }
  4225. if (hProv2)
  4226. {
  4227. TRelease(hProv2, 0, ptc);
  4228. }
  4229. return fSuccess;
  4230. }
  4231. //
  4232. // Function: TestGenKeyProc
  4233. //
  4234. BOOL TestGenKeyProc(
  4235. PALGNODE pAlgNode,
  4236. PTESTCASE ptc,
  4237. PVOID pvTestGenKeyInfo)
  4238. {
  4239. HCRYPTKEY hKey = 0;
  4240. BOOL fSuccess = FALSE;
  4241. DWORD dwSize = 0;
  4242. DWORD dwFlags = 0;
  4243. HCRYPTPROV hTestProv = 0;
  4244. DWORD dwSavedErrorLevel = ptc->dwErrorLevel;
  4245. PTEST_GEN_KEY_INFO pTestGenKeyInfo = (PTEST_GEN_KEY_INFO) pvTestGenKeyInfo;
  4246. if (pAlgNode->fIsRequiredAlg)
  4247. {
  4248. ptc->dwErrorLevel = CSP_ERROR_CONTINUE;
  4249. }
  4250. else
  4251. {
  4252. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  4253. }
  4254. //
  4255. // Create four different keys for the specified alg:
  4256. //
  4257. // 1) Minimum key size, with the CRYPT_NO_SALT flag.
  4258. // 2) Minimum key size, with the CRYPT_CREATE_SALT flag.
  4259. // 3) (Public keys only) Minimum key size + incremental key size
  4260. // 4) Default key size, with the CRYPT_EXPORTABLE flag
  4261. // 5) Maximum key size (Session keys only. Otherwise, use a
  4262. // reasonably large key size for public key pairs.), with the
  4263. // CRYPT_USER_PROTECTED flag set.
  4264. //
  4265. // 1
  4266. dwSize = pAlgNode->ProvEnumalgsEx.dwMinLen;
  4267. LOG_TRY(TGenKey(
  4268. pTestGenKeyInfo->hProv,
  4269. pAlgNode->ProvEnumalgsEx.aiAlgid,
  4270. CRYPT_NO_SALT | (dwSize << 16),
  4271. &hKey,
  4272. ptc));
  4273. LOG_TRY(TDestroyKey(hKey, ptc));
  4274. hKey = 0;
  4275. //
  4276. // The Microsoft CSP's do not permit salting DES
  4277. // keys.
  4278. //
  4279. // 2
  4280. if ( CALG_DES == pAlgNode->ProvEnumalgsEx.aiAlgid ||
  4281. CALG_3DES == pAlgNode->ProvEnumalgsEx.aiAlgid ||
  4282. CALG_3DES_112 == pAlgNode->ProvEnumalgsEx.aiAlgid)
  4283. {
  4284. ptc->KnownErrorID = KNOWN_CRYPTGENKEY_SALTDES;
  4285. }
  4286. LOG_TRY(TGenKey(
  4287. pTestGenKeyInfo->hProv,
  4288. pAlgNode->ProvEnumalgsEx.aiAlgid,
  4289. CRYPT_CREATE_SALT | (dwSize << 16),
  4290. &hKey,
  4291. ptc));
  4292. LOG_TRY(TDestroyKey(hKey, ptc));
  4293. hKey = 0;
  4294. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  4295. //
  4296. // Is this a public key alg?
  4297. //
  4298. if (RSAAlgFilter(pAlgNode))
  4299. {
  4300. switch (pAlgNode->ProvEnumalgsEx.aiAlgid)
  4301. {
  4302. case CALG_RSA_SIGN:
  4303. {
  4304. dwSize = pAlgNode->ProvEnumalgsEx.dwMinLen + pTestGenKeyInfo->pCSPInfo->dwSigKeysizeInc;
  4305. break;
  4306. }
  4307. case CALG_RSA_KEYX:
  4308. {
  4309. dwSize = pAlgNode->ProvEnumalgsEx.dwMinLen + pTestGenKeyInfo->pCSPInfo->dwSigKeysizeInc;
  4310. break;
  4311. }
  4312. default:
  4313. {
  4314. goto Cleanup;
  4315. }
  4316. }
  4317. // 3
  4318. LOG_TRY(TGenKey(
  4319. pTestGenKeyInfo->hProv,
  4320. pAlgNode->ProvEnumalgsEx.aiAlgid,
  4321. dwSize << 16,
  4322. &hKey,
  4323. ptc));
  4324. LOG_TRY(TDestroyKey(hKey, ptc));
  4325. hKey = 0;
  4326. }
  4327. // 4
  4328. LOG_TRY(TGenKey(
  4329. pTestGenKeyInfo->hProv,
  4330. pAlgNode->ProvEnumalgsEx.aiAlgid,
  4331. CRYPT_EXPORTABLE,
  4332. &hKey,
  4333. ptc));
  4334. LOG_TRY(TDestroyKey(hKey, ptc));
  4335. hKey = 0;
  4336. // 5
  4337. if (RSAAlgFilter(pAlgNode))
  4338. {
  4339. dwFlags = CRYPT_USER_PROTECTED;
  4340. dwSize = (pAlgNode->ProvEnumalgsEx.dwMaxLen >= TEST_MAX_RSA_KEYSIZE) ? TEST_MAX_RSA_KEYSIZE : pAlgNode->ProvEnumalgsEx.dwMaxLen;
  4341. hTestProv = pTestGenKeyInfo->hNotSilentProv;
  4342. }
  4343. else
  4344. {
  4345. dwSize = pAlgNode->ProvEnumalgsEx.dwMaxLen;
  4346. hTestProv = pTestGenKeyInfo->hProv;
  4347. }
  4348. LOG_TRY(TGenKey(
  4349. hTestProv,
  4350. pAlgNode->ProvEnumalgsEx.aiAlgid,
  4351. dwFlags | (dwSize << 16),
  4352. &hKey,
  4353. ptc));
  4354. fSuccess = TRUE;
  4355. Cleanup:
  4356. ptc->dwErrorLevel = dwSavedErrorLevel;
  4357. if (hKey)
  4358. {
  4359. TDestroyKey(hKey, ptc);
  4360. }
  4361. return fSuccess;
  4362. }
  4363. //
  4364. // Function: PositiveGenKeyTests
  4365. // Purpose: Run the test cases for CryptGenKey. The set of positive
  4366. // test cases executed depends on the dwCSPClass and dwTestLevel parameters.
  4367. //
  4368. BOOL PositiveGenKeyTests(PCSPINFO pCSPInfo)
  4369. {
  4370. BOOL fSuccess = FALSE;
  4371. LPWSTR pwszContainer = TEST_CONTAINER;
  4372. LPWSTR pwszContainer2 = TEST_CONTAINER_2;
  4373. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4374. HCRYPTKEY hKey = 0;
  4375. //PALGNODE pAlgNode = NULL;
  4376. TEST_GEN_KEY_INFO TestGenKeyInfo;
  4377. memset(&TestGenKeyInfo, 0, sizeof(TestGenKeyInfo));
  4378. TestGenKeyInfo.pCSPInfo = pCSPInfo;
  4379. //
  4380. // Do CryptGenKey positive test cases
  4381. //
  4382. switch (pCSPInfo->TestCase.dwTestLevel)
  4383. {
  4384. case TEST_LEVEL_KEY:
  4385. {
  4386. //
  4387. // Run the TestGenKeyProc test for each session key alg
  4388. // supported by this CSP.
  4389. //
  4390. LOG_TRY(CreateNewContext(&(TestGenKeyInfo.hProv), NULL, CRYPT_VERIFYCONTEXT, ptc));
  4391. LOG_TRY(AlgListIterate(
  4392. pCSPInfo->pAlgList,
  4393. DataEncryptFilter,
  4394. TestGenKeyProc,
  4395. (PVOID) &TestGenKeyInfo,
  4396. ptc));
  4397. //
  4398. // Test that a signature public key pair can be created from a
  4399. // VERIFYCONTEXT provider handle. The key will not be persisted.
  4400. //
  4401. LOG_TRY(TGenKey(
  4402. TestGenKeyInfo.hProv,
  4403. AT_SIGNATURE,
  4404. 0,
  4405. &hKey,
  4406. ptc));
  4407. break;
  4408. }
  4409. case TEST_LEVEL_CONTAINER:
  4410. {
  4411. LOG_TRY(CreateNewContext(
  4412. &(TestGenKeyInfo.hProv),
  4413. pwszContainer,
  4414. CRYPT_NEWKEYSET,
  4415. ptc));
  4416. // We are not currently supporting multiple containers
  4417. // on a single smartcard, so the following test case can't
  4418. // use two different context handles for Smartcard scenario.
  4419. if (pCSPInfo->fSmartCardCSP)
  4420. {
  4421. TestGenKeyInfo.hNotSilentProv = TestGenKeyInfo.hProv;
  4422. }
  4423. else
  4424. {
  4425. //
  4426. // Set the flag so that CreateNewContext will not create a CRYPT_SILENT context
  4427. // handle.
  4428. //
  4429. ptc->fTestingUserProtected = TRUE;
  4430. LOG_TRY(CreateNewContext(
  4431. &(TestGenKeyInfo.hNotSilentProv),
  4432. pwszContainer2,
  4433. CRYPT_NEWKEYSET,
  4434. ptc));
  4435. ptc->fTestingUserProtected = FALSE;
  4436. }
  4437. if (CLASS_SIG_ONLY == pCSPInfo->TestCase.dwCSPClass)
  4438. {
  4439. LOG_TRY(TGenKey(
  4440. TestGenKeyInfo.hProv,
  4441. AT_SIGNATURE,
  4442. 0,
  4443. &hKey,
  4444. ptc));
  4445. }
  4446. else
  4447. {
  4448. LOG_TRY(TGenKey(
  4449. TestGenKeyInfo.hProv,
  4450. AT_KEYEXCHANGE,
  4451. 0,
  4452. &hKey,
  4453. ptc));
  4454. LOG_TRY(AlgListIterate(
  4455. pCSPInfo->pAlgList,
  4456. RSAAlgFilter,
  4457. TestGenKeyProc,
  4458. (PVOID) &TestGenKeyInfo,
  4459. ptc));
  4460. }
  4461. if (pCSPInfo->fSmartCardCSP)
  4462. {
  4463. TestGenKeyInfo.hProv = 0;
  4464. }
  4465. break;
  4466. }
  4467. default:
  4468. {
  4469. goto Cleanup;
  4470. }
  4471. }
  4472. fSuccess = TRUE;
  4473. Cleanup:
  4474. if (hKey)
  4475. {
  4476. TDestroyKey(hKey, ptc);
  4477. }
  4478. if (TestGenKeyInfo.hProv)
  4479. {
  4480. TRelease(TestGenKeyInfo.hProv, 0, ptc);
  4481. }
  4482. if (TestGenKeyInfo.hNotSilentProv)
  4483. {
  4484. TRelease(TestGenKeyInfo.hNotSilentProv, 0, ptc);
  4485. }
  4486. return fSuccess;
  4487. }
  4488. //
  4489. // Function: NegativeGenKeyTests
  4490. // Purpose: Run the negative test cases for CryptGenKey. The set of
  4491. // test cases executed depends on the dwTestLevel parameter.
  4492. //
  4493. BOOL NegativeGenKeyTests(PCSPINFO pCSPInfo)
  4494. {
  4495. BOOL fSuccess = FALSE;
  4496. LPWSTR pwszContainer = TEST_CONTAINER;
  4497. HCRYPTPROV hProv = 0;
  4498. HCRYPTKEY hKey = 0;
  4499. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4500. // The appropriate set of negative test cases to run depends on the current Test Level
  4501. switch (ptc->dwTestLevel)
  4502. {
  4503. case TEST_LEVEL_KEY:
  4504. {
  4505. //
  4506. // Group 4F (negative)
  4507. //
  4508. //
  4509. // Do CryptGenKey TEST_LEVEL_KEY negative test cases
  4510. //
  4511. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  4512. LOG_TRY(TGenKey(0, CALG_RC4, 0, &hKey, ptc));
  4513. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  4514. LOG_TRY(TGenKey(TEST_INVALID_HANDLE, CALG_RC4, 0, &hKey, ptc));
  4515. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  4516. ptc->dwErrorCode = NTE_BAD_ALGID;
  4517. LOG_TRY(TGenKey(hProv, CALG_SHA1, 0, &hKey, ptc));
  4518. ptc->dwErrorCode = NTE_BAD_FLAGS;
  4519. LOG_TRY(TGenKey(hProv, CALG_RC4, TEST_INVALID_FLAG, &hKey, ptc));
  4520. break;
  4521. }
  4522. case TEST_LEVEL_CONTAINER:
  4523. {
  4524. //
  4525. // Group 5D (negative)
  4526. //
  4527. //
  4528. // Do CryptGenKey TEST_LEVEL_CONTAINER negative test cases
  4529. //
  4530. //
  4531. // Test that CRYPT_USER_PROTECTED fails with a CRYPT_SILENT context
  4532. //
  4533. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET | CRYPT_SILENT, ptc));
  4534. ptc->dwErrorCode = NTE_SILENT_CONTEXT;
  4535. LOG_TRY(TGenKey(hProv, AT_SIGNATURE, CRYPT_USER_PROTECTED, &hKey, ptc));
  4536. LOG_TRY(TRelease(hProv, 0, ptc));
  4537. hProv = 0;
  4538. //
  4539. // Test that CRYPT_USER_PROTECTED fails with a CRYPT_VERIFYCONTEXT context
  4540. //
  4541. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  4542. //
  4543. // In Windows 2000, the Microsoft CSP's ignore the USER_PROTECTED flag
  4544. // because the VERIFYCONTEXT flag is set. Therefore the following
  4545. // call succeeds unexpectedly. That usage should be flagged as an
  4546. // error.
  4547. //
  4548. ptc->KnownErrorID = KNOWN_CRYPTGENKEY_SILENTCONTEXT;
  4549. ptc->pwszErrorHelp =
  4550. L"The CRYPT_USER_PROTECTED flag should fail when a VERIFYCONTEXT provider handle is used";
  4551. ptc->dwErrorCode = NTE_SILENT_CONTEXT;
  4552. LOG_TRY(TGenKey(hProv, AT_SIGNATURE, CRYPT_USER_PROTECTED, &hKey, ptc));
  4553. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  4554. break;
  4555. }
  4556. }
  4557. fSuccess = TRUE;
  4558. Cleanup:
  4559. if (hKey)
  4560. {
  4561. TDestroyKey(hKey, ptc);
  4562. }
  4563. if (hProv)
  4564. {
  4565. TRelease(hProv, 0, ptc);
  4566. }
  4567. return fSuccess;
  4568. }
  4569. //
  4570. // Function: PositiveGetKeyParamTests
  4571. // Purpose: Run the test cases for CryptGetKeyParam
  4572. //
  4573. BOOL PositiveGetKeyParamTests(PCSPINFO pCSPInfo)
  4574. {
  4575. BOOL fSuccess = FALSE;
  4576. HCRYPTPROV hProv = 0;
  4577. HCRYPTKEY hKey = 0;
  4578. DWORD dw = 0;
  4579. DWORD cb = 0;
  4580. PBYTE pb = NULL;
  4581. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4582. DWORD dwSavedErrorLevel = 0;
  4583. //
  4584. // Group 4G
  4585. //
  4586. //
  4587. // Do CryptGetKeyParam positive test cases
  4588. //
  4589. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  4590. //
  4591. // Test CryptGetKeyParam for a stream cipher key
  4592. //
  4593. LOG_TRY(CreateNewKey(
  4594. hProv,
  4595. CALG_RC4,
  4596. CRYPT_CREATE_SALT | CRYPT_EXPORTABLE | (40 << 16),
  4597. &hKey,
  4598. ptc));
  4599. // KP_ALGID
  4600. cb = sizeof(dw);
  4601. LOG_TRY(TGetKey(
  4602. hKey,
  4603. KP_ALGID,
  4604. (PBYTE) &dw,
  4605. &cb,
  4606. 0,
  4607. ptc));
  4608. if (CALG_RC4 != dw)
  4609. {
  4610. LOG_TRY(LogBadParam(
  4611. API_CRYPTGETKEYPARAM,
  4612. L"CryptGetKeyParam KP_ALGID doesn't match",
  4613. ptc));
  4614. }
  4615. // KP_BLOCKLEN
  4616. cb = sizeof(dw);
  4617. LOG_TRY(TGetKey(
  4618. hKey,
  4619. KP_BLOCKLEN,
  4620. (PBYTE) &dw,
  4621. &cb,
  4622. 0,
  4623. ptc));
  4624. if (0 != dw)
  4625. {
  4626. LOG_TRY(LogBadParam(
  4627. API_CRYPTGETKEYPARAM,
  4628. L"CryptGetKeyParam KP_BLOCKLEN should be zero",
  4629. ptc));
  4630. }
  4631. // KP_KEYLEN
  4632. cb = sizeof(dw);
  4633. LOG_TRY(TGetKey(
  4634. hKey,
  4635. KP_KEYLEN,
  4636. (PBYTE) &dw,
  4637. &cb,
  4638. 0,
  4639. ptc));
  4640. // TODO: Determine the best way to verify KP_KEYLEN. CSP's will return
  4641. // the effective KEYLEN, including parity bits.
  4642. // KP_SALT
  4643. cb = 0;
  4644. LOG_TRY(TGetKey(
  4645. hKey,
  4646. KP_SALT,
  4647. NULL,
  4648. &cb,
  4649. 0,
  4650. ptc));
  4651. //
  4652. // The MS_ENHANCED_PROV will use salt length zero for any key size even
  4653. // when CRYPT_CREATE_SALT has been specified.
  4654. //
  4655. // The MS_BASE_PROV will exhibit one of the following behaviors:
  4656. // 1) Default - use 11 bytes of zeroed salt
  4657. // 2) CRYPT_CREATE_SALT - use 11 bytes of random salt
  4658. // 3) CRYPT_NO_SALT - use no salt
  4659. //
  4660. // For this reason, various valid-looking salting behaviors
  4661. // should not be considered errors.
  4662. //
  4663. dwSavedErrorLevel = ptc->dwErrorLevel;
  4664. ptc->dwErrorLevel = CSP_ERROR_WARNING;
  4665. if (0 == cb)
  4666. {
  4667. LOG_TRY(LogBadParam(
  4668. API_CRYPTGETKEYPARAM,
  4669. L"CryptGetKeyParam KP_SALT has zero length after CryptGenKey CRYPT_CREATE_SALT",
  4670. ptc));
  4671. }
  4672. LOG_TRY(TestAlloc(&pb, cb, ptc));
  4673. LOG_TRY(TGetKey(
  4674. hKey,
  4675. KP_SALT,
  4676. pb,
  4677. &cb,
  4678. 0,
  4679. ptc));
  4680. // Verify that salt is not completely zero
  4681. while (cb && (0 == pb[cb - 1]))
  4682. cb--;
  4683. if (0 == cb)
  4684. {
  4685. LOG_TRY(LogBadParam(
  4686. API_CRYPTGETKEYPARAM,
  4687. L"CryptGetKeyParam KP_SALT should not be zeroized after CryptGenKey CRYPT_CREATE_SALT",
  4688. ptc));
  4689. }
  4690. free(pb);
  4691. pb = NULL;
  4692. ptc->dwErrorLevel = dwSavedErrorLevel;
  4693. // KP_PERMISSIONS
  4694. cb = sizeof(dw);
  4695. LOG_TRY(TGetKey(
  4696. hKey,
  4697. KP_PERMISSIONS,
  4698. (PBYTE) &dw,
  4699. &cb,
  4700. 0,
  4701. ptc));
  4702. if (! (CRYPT_EXPORT & dw))
  4703. {
  4704. LOG_TRY(LogBadParam(
  4705. API_CRYPTGETKEYPARAM,
  4706. L"CryptGetKeyParam KP_PERMISSIONS, CRYPT_EXPORT should be set",
  4707. ptc));
  4708. }
  4709. LOG_TRY(TDestroyKey(hKey, ptc));
  4710. hKey = 0;
  4711. //
  4712. // Test CryptGetKeyParam with a block cipher key
  4713. //
  4714. LOG_TRY(CreateNewKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hKey, ptc));
  4715. // KP_BLOCKLEN
  4716. cb = sizeof(dw);
  4717. LOG_TRY(TGetKey(
  4718. hKey,
  4719. KP_BLOCKLEN,
  4720. (PBYTE) &dw,
  4721. &cb,
  4722. 0,
  4723. ptc));
  4724. if (0 == dw)
  4725. {
  4726. LOG_TRY(LogBadParam(
  4727. API_CRYPTGETKEYPARAM,
  4728. L"CryptGetKeyParam KP_BLOCKLEN should not be zero for CALG_RC2 key",
  4729. ptc));
  4730. }
  4731. // KP_EFFECTIVE_KEYLEN
  4732. cb = sizeof(dw);
  4733. LOG_TRY(TGetKey(
  4734. hKey,
  4735. KP_EFFECTIVE_KEYLEN,
  4736. (PBYTE) &dw,
  4737. &cb,
  4738. 0,
  4739. ptc));
  4740. // TODO: In general, how should the effective key length
  4741. // be determined?
  4742. // KP_IV
  4743. cb = 0;
  4744. LOG_TRY(TGetKey(
  4745. hKey,
  4746. KP_IV,
  4747. NULL,
  4748. &cb,
  4749. 0,
  4750. ptc));
  4751. LOG_TRY(TestAlloc(&pb, cb, ptc));
  4752. LOG_TRY(TGetKey(
  4753. hKey,
  4754. KP_IV,
  4755. pb,
  4756. &cb,
  4757. 0,
  4758. ptc));
  4759. // Verify that IV is zero
  4760. while (cb && (! pb[cb - 1]))
  4761. cb--;
  4762. if (0 != cb)
  4763. {
  4764. LOG_TRY(LogBadParam(
  4765. API_CRYPTGETKEYPARAM,
  4766. L"CryptGetKeyParam KP_IV should be zero",
  4767. ptc));
  4768. }
  4769. free(pb);
  4770. pb = NULL;
  4771. // KP_PADDING
  4772. cb = sizeof(dw);
  4773. LOG_TRY(TGetKey(
  4774. hKey,
  4775. KP_PADDING,
  4776. (PBYTE) &dw,
  4777. &cb,
  4778. 0,
  4779. ptc));
  4780. if (PKCS5_PADDING != dw)
  4781. {
  4782. LOG_TRY(LogBadParam(
  4783. API_CRYPTGETKEYPARAM,
  4784. L"CryptGetKeyParam KP_PADDING should be PKCS5_PADDING",
  4785. ptc));
  4786. }
  4787. // KP_MODE
  4788. cb = sizeof(dw);
  4789. LOG_TRY(TGetKey(
  4790. hKey,
  4791. KP_MODE,
  4792. (PBYTE) &dw,
  4793. &cb,
  4794. 0,
  4795. ptc));
  4796. if (CRYPT_MODE_CBC != dw)
  4797. {
  4798. LOG_TRY(LogBadParam(
  4799. API_CRYPTGETKEYPARAM,
  4800. L"CryptGetKeyParam KP_MODE should be CRYPT_MODE_CBC",
  4801. ptc));
  4802. }
  4803. // KP_MODE_BITS
  4804. cb = sizeof(dw);
  4805. LOG_TRY(TGetKey(
  4806. hKey,
  4807. KP_MODE_BITS,
  4808. (PBYTE) &dw,
  4809. &cb,
  4810. 0,
  4811. ptc));
  4812. // TODO: Looks like this should always be initialized to zero. Is that true?
  4813. if (0 != dw)
  4814. {
  4815. LOG_TRY(LogBadParam(
  4816. API_CRYPTGETKEYPARAM,
  4817. L"CryptGetKeyParam KP_MODE_BITS should be zero",
  4818. ptc));
  4819. }
  4820. fSuccess = TRUE;
  4821. Cleanup:
  4822. if (pb)
  4823. {
  4824. free(pb);
  4825. }
  4826. if (hKey)
  4827. {
  4828. TDestroyKey(hKey, ptc);
  4829. }
  4830. if (hProv)
  4831. {
  4832. TRelease(hProv, 0, ptc);
  4833. }
  4834. return fSuccess;
  4835. }
  4836. //
  4837. // Function: NegativeGetKeyParamTests
  4838. // Purpose: Run the negative test cases for CryptGetKeyParam
  4839. //
  4840. BOOL NegativeGetKeyParamTests(PCSPINFO pCSPInfo)
  4841. {
  4842. BOOL fSuccess = FALSE;
  4843. //LPWSTR pwszContainer = TEST_CONTAINER;
  4844. HCRYPTPROV hProv = 0;
  4845. HCRYPTKEY hKey = 0;
  4846. DWORD dw = 0;
  4847. DWORD cb = 0;
  4848. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4849. //
  4850. // Group 4G
  4851. //
  4852. //
  4853. // Do CryptGetKeyParam negative test cases
  4854. //
  4855. cb = sizeof(dw);
  4856. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  4857. LOG_TRY(TGetKey(0, KP_KEYLEN, (PBYTE) &dw, &cb, 0, ptc));
  4858. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  4859. LOG_TRY(TGetKey(TEST_INVALID_HANDLE, KP_KEYLEN, (PBYTE) &dw, &cb, 0, ptc));
  4860. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  4861. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  4862. /*
  4863. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  4864. LOG_TRY(TGetKey(hKey, KP_KEYLEN, NULL, &cb, 0, ptc));
  4865. */
  4866. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  4867. LOG_TRY(TGetKey(hKey, KP_KEYLEN, (PBYTE) TEST_INVALID_POINTER, NULL, 0, ptc));
  4868. cb = 1;
  4869. ptc->dwErrorCode = ERROR_MORE_DATA;
  4870. LOG_TRY(TGetKey(hKey, KP_KEYLEN, (PBYTE) &dw, &cb, 0, ptc));
  4871. ptc->dwErrorCode = NTE_BAD_FLAGS;
  4872. LOG_TRY(TGetKey(hKey, KP_KEYLEN, (PBYTE) &dw, &cb, TEST_INVALID_FLAG, ptc));
  4873. ptc->dwErrorCode = NTE_BAD_TYPE;
  4874. LOG_TRY(TGetKey(hKey, TEST_INVALID_FLAG, (PBYTE) &dw, &cb, 0, ptc));
  4875. /*
  4876. LOG_TRY(TRelease(hProv, 0, ptc));
  4877. hProv = 0;
  4878. // Provider handle used to create hKey is now invalid
  4879. ptc->dwErrorCode = NTE_BAD_UID;
  4880. LOG_TRY(TGetKey(hKey, KP_KEYLEN, (PBYTE) &dw, &cb, 0, ptc));
  4881. */
  4882. fSuccess = TRUE;
  4883. Cleanup:
  4884. if (hKey)
  4885. {
  4886. TDestroyKey(hKey, ptc);
  4887. }
  4888. if (hProv)
  4889. {
  4890. TRelease(hProv, 0, ptc);
  4891. }
  4892. return fSuccess;
  4893. }
  4894. //
  4895. // Function: TestHashSessionKeyProc
  4896. // Purpose: Callback function for testing CryptHashSessionKey
  4897. // using AlgListIterate. For each session key algorithm
  4898. // supported by the target CSP, this function will be called.
  4899. //
  4900. BOOL TestHashSessionKeyProc(
  4901. PALGNODE pAlgNode,
  4902. PTESTCASE ptc,
  4903. PVOID pvTestHashSessionKey)
  4904. {
  4905. BOOL fSuccess = FALSE;
  4906. DWORD dwFlags = 0;
  4907. HASH_SESSION_INFO HashSessionInfo;
  4908. PTEST_HASH_SESSION_KEY pTestHashSessionKey = (PTEST_HASH_SESSION_KEY) pvTestHashSessionKey;
  4909. //
  4910. // Run the HashSessionKey scenario twice:
  4911. // 1) dwFlags = 0 --> hash is Big Endian
  4912. // 2) dwFlags = CRYPT_LITTLE_ENDIAN
  4913. //
  4914. while (TEST_INVALID_FLAG != dwFlags)
  4915. {
  4916. memset(&HashSessionInfo, 0, sizeof(HashSessionInfo));
  4917. HashSessionInfo.aiHash = pTestHashSessionKey->aiHash;
  4918. HashSessionInfo.aiKey = pAlgNode->ProvEnumalgsEx.aiAlgid;
  4919. HashSessionInfo.dwKeySize = pAlgNode->ProvEnumalgsEx.dwMaxLen;
  4920. HashSessionInfo.dwFlags = dwFlags;
  4921. LOG_TRY(CreateHashedSessionKey(
  4922. pTestHashSessionKey->hProv,
  4923. &HashSessionInfo,
  4924. ptc));
  4925. LOG_TRY(VerifyHashedSessionKey(
  4926. pTestHashSessionKey->hInteropProv,
  4927. &HashSessionInfo,
  4928. ptc));
  4929. if (CRYPT_LITTLE_ENDIAN == dwFlags)
  4930. {
  4931. dwFlags = TEST_INVALID_FLAG;
  4932. }
  4933. else
  4934. {
  4935. dwFlags = CRYPT_LITTLE_ENDIAN;
  4936. }
  4937. }
  4938. fSuccess = TRUE;
  4939. Cleanup:
  4940. return fSuccess;
  4941. }
  4942. //
  4943. // Function: InteropHashSessionKeyTests
  4944. // Purpose: Run the interoperability test cases for CryptHashSessionKey
  4945. // between the CSP under test and a second CSP.
  4946. //
  4947. BOOL InteropHashSessionKeyTests(PCSPINFO pCSPInfo)
  4948. {
  4949. BOOL fSuccess = FALSE;
  4950. //LPWSTR pwszContainer = TEST_CONTAINER;
  4951. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4952. TEST_HASH_SESSION_KEY TestHashSessionKey;
  4953. memset(&TestHashSessionKey, 0, sizeof(TestHashSessionKey));
  4954. TestHashSessionKey.aiHash = CALG_SHA1;
  4955. LOG_TRY(CreateNewContext(
  4956. &(TestHashSessionKey.hProv),
  4957. NULL,
  4958. CRYPT_VERIFYCONTEXT,
  4959. ptc));
  4960. LOG_TRY(CreateNewInteropContext(
  4961. &(TestHashSessionKey.hInteropProv),
  4962. NULL,
  4963. CRYPT_VERIFYCONTEXT,
  4964. ptc));
  4965. LOG_TRY(AlgListIterate(
  4966. pCSPInfo->pAlgList,
  4967. DataEncryptFilter,
  4968. TestHashSessionKeyProc,
  4969. (PVOID) &TestHashSessionKey,
  4970. ptc));
  4971. fSuccess = TRUE;
  4972. Cleanup:
  4973. if (TestHashSessionKey.hProv)
  4974. {
  4975. TRelease(TestHashSessionKey.hProv, 0, ptc);
  4976. }
  4977. if (TestHashSessionKey.hInteropProv)
  4978. {
  4979. TRelease(TestHashSessionKey.hInteropProv, 0, ptc);
  4980. }
  4981. return fSuccess;
  4982. }
  4983. //
  4984. // Function: PositiveHashSessionKeyTests
  4985. // Purpose: Run the test cases for CryptHashSessionKey
  4986. //
  4987. BOOL PositiveHashSessionKeyTests(PCSPINFO pCSPInfo)
  4988. {
  4989. BOOL fSuccess = FALSE;
  4990. //LPWSTR pwszContainer = TEST_CONTAINER;
  4991. HCRYPTPROV hProv = 0;
  4992. HCRYPTKEY hKey = 0;
  4993. HCRYPTHASH hHash = 0;
  4994. PTESTCASE ptc = &(pCSPInfo->TestCase);
  4995. LOG_TRY(CreateNewContext(
  4996. &hProv,
  4997. NULL,
  4998. CRYPT_VERIFYCONTEXT,
  4999. ptc));
  5000. //
  5001. // Group 4H
  5002. //
  5003. //
  5004. // Do CryptHashSessionKey test cases
  5005. //
  5006. //
  5007. // Hash a stream cipher key
  5008. //
  5009. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  5010. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  5011. LOG_TRY(THashSession(hHash, hKey, 0, ptc));
  5012. //
  5013. // Hash the key again with the CRYPT_LITTLE_ENDIAN flag
  5014. //
  5015. LOG_TRY(THashSession(hHash, hKey, CRYPT_LITTLE_ENDIAN, ptc));
  5016. fSuccess = TRUE;
  5017. Cleanup:
  5018. if (hKey)
  5019. {
  5020. TDestroyKey(hKey, ptc);
  5021. }
  5022. if (hHash)
  5023. {
  5024. TDestroyHash(hHash, ptc);
  5025. }
  5026. if (hProv)
  5027. {
  5028. TRelease(hProv, 0, ptc);
  5029. }
  5030. return fSuccess;
  5031. }
  5032. //
  5033. // Function: NegativeHashSessionKeyTests
  5034. // Purpose: Run the negative test cases for CryptHashSessionKey
  5035. //
  5036. BOOL NegativeHashSessionKeyTests(PCSPINFO pCSPInfo)
  5037. {
  5038. BOOL fSuccess = FALSE;
  5039. //LPWSTR pwszContainer = TEST_CONTAINER;
  5040. HCRYPTPROV hProv = 0;
  5041. HCRYPTKEY hKey = 0;
  5042. HCRYPTKEY hHash = 0;
  5043. DWORD cb = 0;
  5044. BYTE rgHashVal[HASH_LENGTH_SHA1];
  5045. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5046. //
  5047. // Group 4H
  5048. //
  5049. //
  5050. // Do CryptHashSessionKey negative test cases
  5051. //
  5052. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  5053. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  5054. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5055. LOG_TRY(THashSession(0, hKey, 0, ptc));
  5056. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5057. LOG_TRY(THashSession(TEST_INVALID_HANDLE, hKey, 0, ptc));
  5058. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  5059. ptc->dwErrorCode = NTE_BAD_FLAGS;
  5060. LOG_TRY(THashSession(hHash, hKey, TEST_INVALID_FLAG, ptc));
  5061. ptc->dwErrorCode = NTE_BAD_KEY;
  5062. LOG_TRY(THashSession(hHash, TEST_INVALID_HANDLE, 0, ptc));
  5063. cb = sizeof(rgHashVal);
  5064. LOG_TRY(TGetHash(hHash, HP_HASHVAL, rgHashVal, &cb, 0, ptc));
  5065. // Hash is now finished, so any attempt to hash data should fail
  5066. ptc->dwErrorCode = NTE_BAD_HASH_STATE;
  5067. LOG_TRY(THashSession(hHash, hKey, 0, ptc));
  5068. /*
  5069. LOG_TRY(TRelease(hProv, 0, ptc));
  5070. hProv = 0;
  5071. // Provider handle used to create hHash is now invalid
  5072. ptc->dwErrorCode = NTE_BAD_UID;
  5073. LOG_TRY(THashSession(hHash, hKey, 0, ptc));
  5074. */
  5075. fSuccess = TRUE;
  5076. Cleanup:
  5077. if (hKey)
  5078. {
  5079. TDestroyKey(hKey, ptc);
  5080. }
  5081. if (hHash)
  5082. {
  5083. TDestroyHash(hHash, ptc);
  5084. }
  5085. if (hProv)
  5086. {
  5087. TRelease(hProv, 0, ptc);
  5088. }
  5089. return fSuccess;
  5090. }
  5091. //
  5092. // Function: PositiveSetKeyParamTests
  5093. // Purpose: Run the test cases for CryptSetKeyParam
  5094. //
  5095. BOOL PositiveSetKeyParamTests(PCSPINFO pCSPInfo)
  5096. {
  5097. BOOL fSuccess = FALSE;
  5098. //LPWSTR pwszContainer = TEST_CONTAINER;
  5099. HCRYPTPROV hProv = 0;
  5100. HCRYPTKEY hKey = 0;
  5101. PBYTE pbData = NULL;
  5102. DWORD cbData = 0;
  5103. DWORD dw = 0;
  5104. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5105. DATA_BLOB db;
  5106. memset(&db, 0, sizeof(db));
  5107. LOG_TRY(CreateNewContext(
  5108. &hProv,
  5109. NULL,
  5110. CRYPT_VERIFYCONTEXT,
  5111. ptc));
  5112. //
  5113. // Create a block cipher key for testing SetKeyParam
  5114. //
  5115. LOG_TRY(CreateNewKey(hProv, CALG_RC2, (40 << 16) | CRYPT_CREATE_SALT, &hKey, ptc));
  5116. //
  5117. // Group 4I
  5118. //
  5119. //
  5120. // Do CryptSetKeyParam test cases
  5121. //
  5122. //
  5123. // Test KP_SALT
  5124. //
  5125. LOG_TRY(TGetKey(hKey, KP_SALT, NULL, &cbData, 0, ptc));
  5126. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  5127. memset(pbData, TEST_SALT_BYTE, cbData);
  5128. // Set key's salt to a known value
  5129. LOG_TRY(TSetKey(hKey, KP_SALT, pbData, 0, ptc));
  5130. // Retrieve the salt value from the CSP for verification
  5131. LOG_TRY(TGetKey(hKey, KP_SALT, pbData, &cbData, 0, ptc));
  5132. while (cbData && (pbData[cbData - 1] == TEST_SALT_BYTE))
  5133. {
  5134. cbData--;
  5135. }
  5136. if (0 != cbData)
  5137. {
  5138. LOG_TRY(LogBadParam(
  5139. API_CRYPTSETKEYPARAM,
  5140. L"CryptSetKeyParam KP_SALT bytes have incorrect value",
  5141. ptc));
  5142. }
  5143. free(pbData);
  5144. pbData = NULL;
  5145. //
  5146. // Test KP_SALT_EX
  5147. //
  5148. db.cbData = TEST_SALT_LEN;
  5149. LOG_TRY(TestAlloc(&(db.pbData), TEST_SALT_LEN, ptc));
  5150. memset(db.pbData, TEST_SALT_BYTE, TEST_SALT_LEN);
  5151. LOG_TRY(TSetKey(hKey, KP_SALT_EX, (PBYTE) &db, 0, ptc));
  5152. // TODO: Not sure how to verify KP_SALT_EX values
  5153. //
  5154. // Test KP_PERMISSIONS
  5155. //
  5156. dw = CRYPT_EXPORT;
  5157. //
  5158. // The Microsoft CSP's do not allow the exportability of a key
  5159. // to be changed.
  5160. //
  5161. ptc->KnownErrorID = KNOWN_CRYPTSETKEYPARAM_EXPORT;
  5162. ptc->pwszErrorHelp = L"Attempt to change key to exportable";
  5163. LOG_TRY(TSetKey(hKey, KP_PERMISSIONS, (PBYTE) &dw, 0, ptc));
  5164. ptc->pwszErrorHelp = NULL;
  5165. dw = 0;
  5166. cbData = sizeof(dw);
  5167. LOG_TRY(TGetKey(hKey, KP_PERMISSIONS, (PBYTE) &dw, &cbData, 0, ptc));
  5168. if (! (CRYPT_EXPORT & dw))
  5169. {
  5170. LOG_TRY(LogBadParam(
  5171. API_CRYPTSETKEYPARAM,
  5172. L"CryptGetKeyParam KP_PERMISSIONS should now include CRYPT_EXPORT",
  5173. ptc));
  5174. }
  5175. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  5176. //
  5177. // Test KP_EFFECTIVE_KEYLEN
  5178. //
  5179. dw = TEST_EFFECTIVE_KEYLEN;
  5180. LOG_TRY(TSetKey(hKey, KP_EFFECTIVE_KEYLEN, (PBYTE) &dw, 0, ptc));
  5181. dw = 0;
  5182. cbData = sizeof(dw);
  5183. LOG_TRY(TGetKey(hKey, KP_EFFECTIVE_KEYLEN, (PBYTE) &dw, &cbData, 0, ptc));
  5184. if (TEST_EFFECTIVE_KEYLEN != dw)
  5185. {
  5186. LOG_TRY(LogBadParam(
  5187. API_CRYPTSETKEYPARAM,
  5188. L"CryptSetKeyParam KP_EFFECTIVE_KEYLEN failed",
  5189. ptc));
  5190. }
  5191. //
  5192. // KP_IV
  5193. //
  5194. LOG_TRY(TGetKey(hKey, KP_IV, NULL, &cbData, 0, ptc));
  5195. LOG_TRY(TestAlloc(&pbData, cbData, ptc));
  5196. memset(pbData, TEST_IV_BYTE, cbData);
  5197. LOG_TRY(TSetKey(hKey, KP_IV, pbData, 0, ptc));
  5198. memset(pbData, 0x00, cbData);
  5199. LOG_TRY(TGetKey(hKey, KP_IV, pbData, &cbData, 0, ptc));
  5200. while (cbData && (TEST_IV_BYTE == pbData[cbData - 1]))
  5201. {
  5202. cbData--;
  5203. }
  5204. if (0 != cbData)
  5205. {
  5206. LOG_TRY(LogBadParam(
  5207. API_CRYPTSETKEYPARAM,
  5208. L"CryptSetKeyParam TEST_IV_BYTE contains incorrect data",
  5209. ptc));
  5210. }
  5211. free(pbData);
  5212. pbData = NULL;
  5213. //
  5214. // KP_PADDING
  5215. //
  5216. dw = PKCS5_PADDING;
  5217. LOG_TRY(TSetKey(hKey, KP_PADDING, (PBYTE) &dw, 0, ptc));
  5218. dw = 0;
  5219. cbData = sizeof(dw);
  5220. LOG_TRY(TGetKey(hKey, KP_PADDING, (PBYTE) &dw, &cbData, 0, ptc));
  5221. if (PKCS5_PADDING != dw)
  5222. {
  5223. LOG_TRY(LogBadParam(
  5224. API_CRYPTSETKEYPARAM,
  5225. L"CryptSetKeyParam KP_PADDING has incorrect value",
  5226. ptc));
  5227. }
  5228. //
  5229. // KP_MODE
  5230. //
  5231. dw = CRYPT_MODE_ECB;
  5232. LOG_TRY(TSetKey(hKey, KP_MODE, (PBYTE) &dw, 0, ptc));
  5233. dw = 0;
  5234. cbData = sizeof(dw);
  5235. LOG_TRY(TGetKey(hKey, KP_MODE, (PBYTE) &dw, &cbData, 0, ptc));
  5236. if (CRYPT_MODE_ECB != dw)
  5237. {
  5238. LOG_TRY(LogBadParam(
  5239. API_CRYPTSETKEYPARAM,
  5240. L"CryptSetKeyParam KP_MODE has incorrect value",
  5241. ptc));
  5242. }
  5243. //
  5244. // KP_MODE_BITS
  5245. //
  5246. dw = TEST_MODE_BITS;
  5247. LOG_TRY(TSetKey(hKey, KP_MODE_BITS, (PBYTE) &dw, 0, ptc));
  5248. dw = 0;
  5249. cbData = sizeof(dw);
  5250. LOG_TRY(TGetKey(hKey, KP_MODE_BITS, (PBYTE) &dw, &cbData, 0, ptc));
  5251. if (TEST_MODE_BITS != dw)
  5252. {
  5253. LOG_TRY(LogBadParam(
  5254. API_CRYPTSETKEYPARAM,
  5255. L"CryptSetKeyParam KP_MODE_BITS contains incorrect value",
  5256. ptc));
  5257. }
  5258. fSuccess = TRUE;
  5259. Cleanup:
  5260. if (hKey)
  5261. {
  5262. TDestroyKey(hKey, ptc);
  5263. }
  5264. if (hProv)
  5265. {
  5266. TRelease(hProv, 0, ptc);
  5267. }
  5268. return fSuccess;
  5269. }
  5270. //
  5271. // Function: NegativeSetKeyParamTests
  5272. // Purpose: Run the negative test cases for CryptSetKeyParam
  5273. //
  5274. BOOL NegativeSetKeyParamTests(PCSPINFO pCSPInfo)
  5275. {
  5276. BOOL fSuccess = FALSE;
  5277. //LPWSTR pwszContainer = TEST_CONTAINER;
  5278. HCRYPTPROV hProv = 0;
  5279. HCRYPTKEY hKey = 0;
  5280. DWORD dw = 0;
  5281. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5282. //
  5283. // Group 4I
  5284. //
  5285. //
  5286. // Do CryptSetKeyParam negative test cases
  5287. //
  5288. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5289. LOG_TRY(TSetKey(0, KP_PERMISSIONS, (PBYTE) &dw, 0, ptc));
  5290. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5291. LOG_TRY(TSetKey(TEST_INVALID_HANDLE, KP_PERMISSIONS, (PBYTE) &dw, 0, ptc));
  5292. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  5293. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hKey, ptc));
  5294. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  5295. LOG_TRY(TSetKey(hKey, KP_PERMISSIONS, NULL, 0, ptc));
  5296. ptc->dwErrorCode = NTE_BAD_FLAGS;
  5297. LOG_TRY(TSetKey(hKey, KP_PERMISSIONS, (PBYTE) &dw, TEST_INVALID_FLAG, ptc));
  5298. ptc->dwErrorCode = NTE_BAD_TYPE;
  5299. LOG_TRY(TSetKey(hKey, TEST_INVALID_FLAG, (PBYTE) &dw, 0, ptc));
  5300. fSuccess = TRUE;
  5301. Cleanup:
  5302. if (hKey)
  5303. {
  5304. TDestroyKey(hKey, ptc);
  5305. }
  5306. if (hProv)
  5307. {
  5308. TRelease(hProv, 0, ptc);
  5309. }
  5310. return fSuccess;
  5311. }
  5312. //
  5313. // Function: PositiveExportKeyTests
  5314. // Purpose: Run the test cases for CryptExportKey. The set of test cases depends on the current
  5315. // CSP class being tested, as specified in the dwCSPClass parameter.
  5316. //
  5317. BOOL PositiveExportKeyTests(PCSPINFO pCSPInfo)
  5318. {
  5319. BOOL fSuccess = FALSE;
  5320. LPWSTR pwszContainer = TEST_CONTAINER;
  5321. HCRYPTPROV hProv = 0;
  5322. HCRYPTKEY hKey = 0;
  5323. HCRYPTKEY hEncryptKey = 0;
  5324. PBYTE pbKey = NULL;
  5325. DWORD cbKey = 0;
  5326. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5327. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  5328. //
  5329. // Group 5C
  5330. //
  5331. //
  5332. // Do CryptExportKey test cases
  5333. //
  5334. switch (pCSPInfo->TestCase.dwCSPClass)
  5335. {
  5336. case CLASS_SIG_ONLY:
  5337. {
  5338. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey, ptc));
  5339. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hEncryptKey, ptc));
  5340. //
  5341. // Export a PRIVATEKEYBLOB
  5342. //
  5343. // Private key export is not permitted on Smart Cards
  5344. if (! pCSPInfo->fSmartCardCSP)
  5345. {
  5346. LOG_TRY(TExportKey(hKey, hEncryptKey, PRIVATEKEYBLOB, 0, NULL, &cbKey, ptc));
  5347. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  5348. LOG_TRY(TExportKey(hKey, hEncryptKey, PRIVATEKEYBLOB, 0, pbKey, &cbKey, ptc));
  5349. free(pbKey);
  5350. pbKey = NULL;
  5351. }
  5352. //
  5353. // Export a PUBLICKEYBLOB
  5354. //
  5355. cbKey = 0;
  5356. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &cbKey, ptc));
  5357. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  5358. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, 0, pbKey, &cbKey, ptc));
  5359. free(pbKey);
  5360. pbKey = NULL;
  5361. LOG_TRY(TDestroyKey(hKey, ptc));
  5362. hKey = 0;
  5363. //
  5364. // Export a SYMMETRICWRAPKEYBLOB
  5365. //
  5366. LOG_TRY(CreateNewKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey, ptc));
  5367. cbKey = 0;
  5368. LOG_TRY(TExportKey(hKey, hEncryptKey, SYMMETRICWRAPKEYBLOB, 0, NULL, &cbKey, ptc));
  5369. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  5370. LOG_TRY(TExportKey(hKey, hEncryptKey, SYMMETRICWRAPKEYBLOB, 0, pbKey, &cbKey, ptc));
  5371. break;
  5372. }
  5373. case CLASS_SIG_KEYX:
  5374. {
  5375. //
  5376. // Export a SIMPLEBLOB
  5377. //
  5378. LOG_TRY(CreateNewKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey, ptc));
  5379. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hEncryptKey, ptc));
  5380. cbKey = 0;
  5381. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, 0, NULL, &cbKey, ptc));
  5382. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  5383. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, 0, pbKey, &cbKey, ptc));
  5384. free(pbKey);
  5385. pbKey = NULL;
  5386. //
  5387. // Export a SIMPLEBLOB with the CRYPT_OAEP flag
  5388. //
  5389. cbKey = 0;
  5390. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, CRYPT_OAEP, NULL, &cbKey, ptc));
  5391. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  5392. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, CRYPT_OAEP, pbKey, &cbKey, ptc));
  5393. break;
  5394. }
  5395. default:
  5396. {
  5397. goto Cleanup;
  5398. }
  5399. }
  5400. fSuccess = TRUE;
  5401. Cleanup:
  5402. if (pbKey)
  5403. {
  5404. free(pbKey);
  5405. }
  5406. if (hKey)
  5407. {
  5408. TDestroyKey(hKey, ptc);
  5409. }
  5410. if (hEncryptKey)
  5411. {
  5412. TDestroyKey(hEncryptKey, ptc);
  5413. }
  5414. if (hProv)
  5415. {
  5416. TRelease(hProv, 0, ptc);
  5417. }
  5418. return fSuccess;
  5419. }
  5420. //
  5421. // Function: NegativeExportKeyTests
  5422. // Purpose: Run the negative test cases for CryptExportKey. The set of test cases depends on the current
  5423. // CSP class being tested, as specified in the dwCSPClass parameter.
  5424. //
  5425. BOOL NegativeExportKeyTests(PCSPINFO pCSPInfo)
  5426. {
  5427. BOOL fSuccess = FALSE;
  5428. LPWSTR pwszContainer = TEST_CONTAINER;
  5429. LPWSTR pwszContainer2 = TEST_CONTAINER_2;
  5430. HCRYPTPROV hProv = 0;
  5431. HCRYPTPROV hProv2 = 0;
  5432. HCRYPTKEY hKey = 0;
  5433. HCRYPTKEY hKeyExch = 0;
  5434. HCRYPTKEY hEncryptKey = 0;
  5435. DWORD dw = 0;
  5436. DWORD cb = 0;
  5437. PBYTE pb = NULL;
  5438. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5439. //
  5440. // Group 5C
  5441. //
  5442. //
  5443. // Run only the negative test cases appropriate for the current CSP class
  5444. //
  5445. switch (ptc->dwCSPClass)
  5446. {
  5447. case CLASS_SIG_ONLY:
  5448. {
  5449. //
  5450. // Do CryptExportKey CLASS_SIG_ONLY negative test cases
  5451. //
  5452. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5453. LOG_TRY(TExportKey(0, 0, PUBLICKEYBLOB, 0, (PBYTE) &dw, &cb, ptc));
  5454. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5455. LOG_TRY(TExportKey(TEST_INVALID_HANDLE, 0, PUBLICKEYBLOB, 0, (PBYTE) &dw, &cb, ptc));
  5456. // The TEST_LEVEL_CONTAINER CryptAcquireContext tests should be run before
  5457. // other Container level tests to ensure that this works.
  5458. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  5459. // Create an exportable signature key pair
  5460. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey, ptc));
  5461. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  5462. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, 0, (PBYTE) TEST_INVALID_POINTER, NULL, ptc));
  5463. // Indicate a buffer length that is too small
  5464. cb = 1;
  5465. ptc->dwErrorCode = ERROR_MORE_DATA;
  5466. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, 0, (PBYTE) &dw, &cb, ptc));
  5467. // cb should contain the actual required buffer size to export
  5468. // try to export to buffer that's too small, will AV
  5469. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  5470. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, 0, (PBYTE) TEST_INVALID_POINTER, &cb, ptc));
  5471. // invalid flags
  5472. ptc->dwErrorCode = NTE_BAD_FLAGS;
  5473. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, TEST_INVALID_FLAG, (PBYTE) &dw, &cb, ptc));
  5474. // invalid blob type
  5475. ptc->dwErrorCode = NTE_BAD_TYPE;
  5476. LOG_TRY(TExportKey(hKey, 0, TEST_INVALID_FLAG, 0, NULL, &cb, ptc));
  5477. // Private key export is not permitted on Smart Cards
  5478. if (pCSPInfo->fSmartCardCSP)
  5479. {
  5480. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hEncryptKey, ptc));
  5481. ptc->dwErrorCode = NTE_BAD_TYPE;
  5482. LOG_TRY(TExportKey(hKey, hEncryptKey, PRIVATEKEYBLOB, 0, NULL, &cb, ptc));
  5483. }
  5484. else
  5485. {
  5486. LOG_TRY(TDestroyKey(hKey, ptc));
  5487. hKey = 0;
  5488. // Create a new non-exportable signature key pair
  5489. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  5490. // Try to export non-exportable key
  5491. ptc->dwErrorCode = NTE_BAD_KEY_STATE;
  5492. LOG_TRY(TExportKey(hKey, 0, PRIVATEKEYBLOB, 0, (PBYTE) &dw, &cb, ptc));
  5493. }
  5494. break;
  5495. }
  5496. case CLASS_SIG_KEYX:
  5497. {
  5498. //
  5499. // Do CryptExportKey CLASS_SIG_KEYX negative test cases
  5500. //
  5501. // Create context and key handle for signature pair
  5502. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  5503. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey, ptc));
  5504. // Create key handle for exchange pair
  5505. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hKeyExch, ptc));
  5506. // Should not be able to export PUBLICKEYBLOB with exchange key specified
  5507. ptc->dwErrorCode = NTE_BAD_PUBLIC_KEY;
  5508. LOG_TRY(TExportKey(hKey, hKeyExch, PUBLICKEYBLOB, 0, (PBYTE) &dw, &cb, ptc));
  5509. // Destroy signature key
  5510. LOG_TRY(TDestroyKey(hKey, ptc));
  5511. hKey = 0;
  5512. // Create symmetric key
  5513. LOG_TRY(CreateNewKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey, ptc));
  5514. ptc->dwErrorCode = NTE_BAD_KEY;
  5515. LOG_TRY(TExportKey(hKey, TEST_INVALID_HANDLE, SIMPLEBLOB, 0, (PBYTE) &dw, &cb, ptc));
  5516. // Destroy the key exchange pair handle
  5517. LOG_TRY(TDestroyKey(hKeyExch, ptc));
  5518. hKeyExch = 0;
  5519. // Create separate cryptographic context
  5520. LOG_TRY(CreateNewContext(&hProv2, pwszContainer2, CRYPT_NEWKEYSET, ptc));
  5521. // Create new key exchange pair in new context
  5522. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hKeyExch, ptc));
  5523. // Should not be able to export using keys from separate contexts
  5524. ptc->dwErrorCode = NTE_BAD_KEY;
  5525. LOG_TRY(TExportKey(hKey, hKeyExch, PRIVATEKEYBLOB, 0, (PBYTE) &dw, &cb, ptc));
  5526. break;
  5527. }
  5528. }
  5529. fSuccess = TRUE;
  5530. Cleanup:
  5531. if (hKey)
  5532. {
  5533. TDestroyKey(hKey, ptc);
  5534. }
  5535. if (hKeyExch)
  5536. {
  5537. TDestroyKey(hKeyExch, ptc);
  5538. }
  5539. if (hEncryptKey)
  5540. {
  5541. TDestroyKey(hKey, ptc);
  5542. }
  5543. if (hProv)
  5544. {
  5545. TRelease(hProv, 0, ptc);
  5546. }
  5547. if (hProv2)
  5548. {
  5549. TRelease(hProv2, 0, ptc);
  5550. }
  5551. return fSuccess;
  5552. }
  5553. //
  5554. // Function: PositiveGetUserKeyTests
  5555. // Purpose: Run the test cases for CryptGetUserKey
  5556. //
  5557. BOOL PositiveGetUserKeyTests(PCSPINFO pCSPInfo)
  5558. {
  5559. BOOL fSuccess = FALSE;
  5560. LPWSTR pwszContainer = TEST_CONTAINER;
  5561. HCRYPTPROV hProv = 0;
  5562. HCRYPTKEY hKey = 0;
  5563. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5564. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  5565. //
  5566. // Group 5E
  5567. //
  5568. //
  5569. // Do CryptGetUserKey test cases
  5570. //
  5571. switch(ptc->dwCSPClass)
  5572. {
  5573. case CLASS_SIG_ONLY:
  5574. {
  5575. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  5576. LOG_TRY(TDestroyKey(hKey, ptc));
  5577. LOG_TRY(TGetUser(hProv, AT_SIGNATURE, &hKey, ptc));
  5578. break;
  5579. }
  5580. case CLASS_SIG_KEYX:
  5581. {
  5582. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hKey, ptc));
  5583. LOG_TRY(TDestroyKey(hKey, ptc));
  5584. LOG_TRY(TGetUser(hProv, AT_KEYEXCHANGE, &hKey, ptc));
  5585. break;
  5586. }
  5587. default:
  5588. {
  5589. goto Cleanup;
  5590. }
  5591. }
  5592. fSuccess = TRUE;
  5593. Cleanup:
  5594. if (hKey)
  5595. {
  5596. TDestroyKey(hKey, ptc);
  5597. }
  5598. if (hProv)
  5599. {
  5600. TRelease(hProv, 0, ptc);
  5601. }
  5602. return fSuccess;
  5603. }
  5604. //
  5605. // Function: NegativeGetUserKeyTests
  5606. // Purpose: Run the negative test cases for CryptGetUserKey
  5607. //
  5608. BOOL NegativeGetUserKeyTests(PCSPINFO pCSPInfo)
  5609. {
  5610. BOOL fSuccess = FALSE;
  5611. LPWSTR pwszContainer = TEST_CONTAINER;
  5612. HCRYPTPROV hProv = 0;
  5613. HCRYPTKEY hKey = 0;
  5614. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5615. //
  5616. // Group 5E
  5617. //
  5618. switch (ptc->dwCSPClass)
  5619. {
  5620. case CLASS_SIG_ONLY:
  5621. {
  5622. //
  5623. // Do CryptGetUserKey negative test cases
  5624. //
  5625. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5626. LOG_TRY(TGetUser(0, AT_SIGNATURE, &hKey, ptc));
  5627. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  5628. LOG_TRY(TGetUser(TEST_INVALID_HANDLE, AT_SIGNATURE, &hKey, ptc));
  5629. //
  5630. // Use context with no container access
  5631. //
  5632. LOG_TRY(CreateNewContext(&hProv, NULL, CRYPT_VERIFYCONTEXT, ptc));
  5633. //
  5634. // Create a non-persisted key pair.
  5635. //
  5636. /*
  5637. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  5638. LOG_TRY(TDestroyKey(hKey, ptc));
  5639. */
  5640. // Not sure what expected error code should be here
  5641. ptc->dwErrorCode = NTE_NO_KEY;
  5642. LOG_TRY(TGetUser(hProv, AT_SIGNATURE, &hKey, ptc));
  5643. LOG_TRY(TRelease(hProv, 0, ptc));
  5644. hProv = 0;
  5645. // Create new context but no key
  5646. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  5647. ptc->dwErrorCode = NTE_BAD_KEY;
  5648. LOG_TRY(TGetUser(hProv, TEST_INVALID_FLAG, &hKey, ptc));
  5649. ptc->dwErrorCode = NTE_NO_KEY;
  5650. LOG_TRY(TGetUser(hProv, AT_SIGNATURE, &hKey, ptc));
  5651. break;
  5652. }
  5653. case CLASS_SIG_KEYX:
  5654. {
  5655. // Create new context and signature key pair
  5656. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  5657. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  5658. // Request key exchange key pair, should fail since it hasn't been created
  5659. ptc->dwErrorCode = NTE_NO_KEY;
  5660. LOG_TRY(TGetUser(hProv, AT_KEYEXCHANGE, &hKey, ptc));
  5661. break;
  5662. }
  5663. }
  5664. fSuccess = TRUE;
  5665. Cleanup:
  5666. if (hKey)
  5667. {
  5668. TDestroyKey(hKey, ptc);
  5669. }
  5670. if (hProv)
  5671. {
  5672. TRelease(hProv, 0, ptc);
  5673. }
  5674. return fSuccess;
  5675. }
  5676. //
  5677. // Function: TestPrivateKeyBlobProc
  5678. //
  5679. BOOL TestPrivateKeyBlobProc(
  5680. PALGNODE pAlgNode,
  5681. PTESTCASE ptc,
  5682. PVOID pvKeyExportInfo)
  5683. {
  5684. BOOL fSuccess = FALSE;
  5685. HCRYPTKEY hKey = 0;
  5686. HCRYPTKEY hEncryptKey = 0;
  5687. PBYTE pbKey = NULL;
  5688. DWORD cbKey = 0;
  5689. PKEY_EXPORT_INFO pKeyExportInfo = (PKEY_EXPORT_INFO) pvKeyExportInfo;
  5690. LOG_TRY(CreateNewKey(
  5691. pKeyExportInfo->hProv,
  5692. pKeyExportInfo->aiKey,
  5693. CRYPT_EXPORTABLE | (pKeyExportInfo->dwKeySize << 16),
  5694. &hKey,
  5695. ptc));
  5696. if (pKeyExportInfo->fUseEncryptKey)
  5697. {
  5698. LOG_TRY(CreateNewKey(
  5699. pKeyExportInfo->hProv,
  5700. pAlgNode->ProvEnumalgsEx.aiAlgid,
  5701. pKeyExportInfo->dwEncryptKeySize << 16,
  5702. &hEncryptKey,
  5703. ptc));
  5704. }
  5705. LOG_TRY(TExportKey(
  5706. hKey,
  5707. hEncryptKey,
  5708. PRIVATEKEYBLOB,
  5709. pKeyExportInfo->dwExportFlags,
  5710. NULL,
  5711. &cbKey,
  5712. ptc));
  5713. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  5714. LOG_TRY(TExportKey(
  5715. hKey,
  5716. hEncryptKey,
  5717. PRIVATEKEYBLOB,
  5718. pKeyExportInfo->dwExportFlags,
  5719. pbKey,
  5720. &cbKey,
  5721. ptc));
  5722. LOG_TRY(TDestroyKey(hKey, ptc));
  5723. hKey = 0;
  5724. LOG_TRY(TImportKey(
  5725. pKeyExportInfo->hProv,
  5726. pbKey,
  5727. cbKey,
  5728. hEncryptKey,
  5729. pKeyExportInfo->dwExportFlags,
  5730. &hKey,
  5731. ptc));
  5732. fSuccess = TRUE;
  5733. Cleanup:
  5734. if (pbKey)
  5735. {
  5736. free(pbKey);
  5737. }
  5738. if (hKey)
  5739. {
  5740. TDestroyKey(hKey, ptc);
  5741. }
  5742. if (hEncryptKey)
  5743. {
  5744. TDestroyKey(hEncryptKey, ptc);
  5745. }
  5746. return fSuccess;
  5747. }
  5748. //
  5749. // Function: TestSymmetricWrapKeyBlobProc
  5750. //
  5751. BOOL TestSymmetricWrapKeyBlobProc(
  5752. PALGNODE pAlgNode,
  5753. PTESTCASE ptc,
  5754. PVOID pvKeyExportInfo)
  5755. {
  5756. BOOL fSuccess = FALSE;
  5757. HCRYPTKEY hKey = 0;
  5758. HCRYPTKEY hEncryptKey = 0;
  5759. PBYTE pbKey = NULL;
  5760. DWORD cbKey = 0;
  5761. PKEY_EXPORT_INFO pKeyExportInfo = (PKEY_EXPORT_INFO) pvKeyExportInfo;
  5762. //
  5763. // Create the key to be exported
  5764. //
  5765. LOG_TRY(CreateNewKey(
  5766. pKeyExportInfo->hProv,
  5767. pAlgNode->ProvEnumalgsEx.aiAlgid,
  5768. CRYPT_EXPORTABLE | (pKeyExportInfo->dwKeySize << 16),
  5769. &hKey,
  5770. ptc));
  5771. if (! pKeyExportInfo->fUseEncryptKey)
  5772. {
  5773. return FALSE;
  5774. }
  5775. //
  5776. // Create the encryption key
  5777. //
  5778. LOG_TRY(CreateNewKey(
  5779. pKeyExportInfo->hProv,
  5780. pKeyExportInfo->aiEncryptKey,
  5781. pKeyExportInfo->dwEncryptKeySize << 16,
  5782. &hEncryptKey,
  5783. ptc));
  5784. LOG_TRY(TExportKey(
  5785. hKey,
  5786. hEncryptKey,
  5787. SYMMETRICWRAPKEYBLOB,
  5788. pKeyExportInfo->dwExportFlags,
  5789. NULL,
  5790. &cbKey,
  5791. ptc));
  5792. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  5793. LOG_TRY(TExportKey(
  5794. hKey,
  5795. hEncryptKey,
  5796. SYMMETRICWRAPKEYBLOB,
  5797. pKeyExportInfo->dwExportFlags,
  5798. pbKey,
  5799. &cbKey,
  5800. ptc));
  5801. LOG_TRY(TDestroyKey(hKey, ptc));
  5802. hKey = 0;
  5803. LOG_TRY(TImportKey(
  5804. pKeyExportInfo->hProv,
  5805. pbKey,
  5806. cbKey,
  5807. hEncryptKey,
  5808. pKeyExportInfo->dwExportFlags,
  5809. &hKey,
  5810. ptc));
  5811. fSuccess = TRUE;
  5812. Cleanup:
  5813. if (pbKey)
  5814. {
  5815. free(pbKey);
  5816. }
  5817. if (hKey)
  5818. {
  5819. TDestroyKey(hKey, ptc);
  5820. }
  5821. if (hEncryptKey)
  5822. {
  5823. TDestroyKey(hEncryptKey, ptc);
  5824. }
  5825. return fSuccess;
  5826. }
  5827. //
  5828. // Function: TestSymmetricWrapperProc
  5829. // Purpose: Test all possible combinations of wrapping one symmetric
  5830. // key algorithm with another. This function will be called once for
  5831. // each encryption key alg, and this function will use AlgListIterate
  5832. // to call TestSymmetricWrapKeyBlobProc once for each encryption
  5833. // key alg.
  5834. //
  5835. BOOL TestSymmetricWrapperProc(
  5836. PALGNODE pAlgNode,
  5837. PTESTCASE ptc,
  5838. PVOID pvKeyExportInfo)
  5839. {
  5840. BOOL fSuccess = FALSE;
  5841. ((PKEY_EXPORT_INFO) pvKeyExportInfo)->aiEncryptKey = pAlgNode->ProvEnumalgsEx.aiAlgid;
  5842. LOG_TRY(AlgListIterate(
  5843. ((PKEY_EXPORT_INFO) pvKeyExportInfo)->pAlgList,
  5844. DataEncryptFilter,
  5845. TestSymmetricWrapKeyBlobProc,
  5846. pvKeyExportInfo,
  5847. ptc));
  5848. fSuccess = TRUE;
  5849. Cleanup:
  5850. return fSuccess;
  5851. }
  5852. //
  5853. // Function: ScenarioImportKeyTests
  5854. // Purpose: Test CryptImportKey and CryptExportKey for PRIVATEKEYBLOB and
  5855. // SYMMETRICWRAPKEYBLOB scenarios. Repeat for all supported encryption
  5856. // algorithms.
  5857. //
  5858. BOOL ScenarioImportKeyTests(PCSPINFO pCSPInfo)
  5859. {
  5860. BOOL fSuccess = FALSE;
  5861. LPWSTR pwszContainer = TEST_CONTAINER;
  5862. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5863. PALGNODE pAlgList = pCSPInfo->pAlgList;
  5864. KEY_EXPORT_INFO KeyExportInfo;
  5865. memset(&KeyExportInfo, 0, sizeof(KeyExportInfo));
  5866. LOG_TRY(CreateNewContext(
  5867. &(KeyExportInfo.hProv),
  5868. pwszContainer,
  5869. CRYPT_NEWKEYSET,
  5870. ptc));
  5871. //
  5872. // Run the PRIVATEKEYBLOB variations
  5873. //
  5874. KeyExportInfo.aiKey = AT_KEYEXCHANGE;
  5875. KeyExportInfo.fUseEncryptKey = TRUE;
  5876. LOG_TRY(AlgListIterate(
  5877. pAlgList,
  5878. DataEncryptFilter,
  5879. TestPrivateKeyBlobProc,
  5880. (PVOID) &KeyExportInfo,
  5881. ptc));
  5882. //
  5883. // Run the SYMMETRICWRAPKEYBLOB variations
  5884. //
  5885. KeyExportInfo.aiKey = 0;
  5886. KeyExportInfo.pAlgList = pAlgList;
  5887. LOG_TRY(AlgListIterate(
  5888. pAlgList,
  5889. DataEncryptFilter,
  5890. TestSymmetricWrapperProc,
  5891. (PVOID) &KeyExportInfo,
  5892. ptc));
  5893. fSuccess = TRUE;
  5894. Cleanup:
  5895. if (KeyExportInfo.hProv)
  5896. {
  5897. TRelease(KeyExportInfo.hProv, 0, ptc);
  5898. }
  5899. return fSuccess;
  5900. }
  5901. //
  5902. // RSA Signature PRIVATEKEYBLOB
  5903. //
  5904. BYTE rgbPrivateKeyBlob [] =
  5905. {
  5906. 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
  5907. 0x52, 0x53, 0x41, 0x32, 0x00, 0x02, 0x00, 0x00,
  5908. 0x01, 0x00, 0x01, 0x00, 0xf3, 0xd8, 0x26, 0xb9,
  5909. 0xbc, 0x43, 0xe4, 0x7c, 0x73, 0x36, 0xf6, 0xc3,
  5910. 0x92, 0x1e, 0x2d, 0x69, 0x8d, 0x17, 0x78, 0xdf,
  5911. 0x49, 0x9d, 0x1c, 0x5d, 0xbd, 0x9d, 0xf9, 0x66,
  5912. 0xd8, 0x27, 0xa2, 0x5f, 0x40, 0x95, 0x20, 0xe1,
  5913. 0xbf, 0xd4, 0x0b, 0x0d, 0xd7, 0xb6, 0x2d, 0x8b,
  5914. 0x05, 0x06, 0x9d, 0x9f, 0x4d, 0x17, 0x9e, 0x82,
  5915. 0x5e, 0x48, 0x74, 0xcf, 0x73, 0x1d, 0x60, 0xea,
  5916. 0x62, 0x7f, 0xfe, 0xeb, 0x37, 0x3e, 0x03, 0x3b,
  5917. 0x2b, 0x50, 0xc6, 0x28, 0x4a, 0x7d, 0xd9, 0x08,
  5918. 0xb3, 0x2e, 0x3c, 0x61, 0x61, 0x78, 0xf7, 0xd8,
  5919. 0xfd, 0x50, 0x05, 0x87, 0xfe, 0x6a, 0x68, 0x6e,
  5920. 0x15, 0xa8, 0x99, 0xfd, 0x25, 0x7d, 0x22, 0xef,
  5921. 0x9f, 0x70, 0x1c, 0xa7, 0x38, 0xa5, 0x18, 0x31,
  5922. 0x82, 0x72, 0x71, 0x72, 0x95, 0x01, 0x70, 0x12,
  5923. 0x04, 0xc8, 0xb9, 0xa0, 0xa1, 0xde, 0x8f, 0xef,
  5924. 0xc3, 0x30, 0x3a, 0xee, 0xc1, 0x57, 0xf3, 0x63,
  5925. 0xef, 0xb5, 0x78, 0x12, 0xb7, 0x69, 0x55, 0x45,
  5926. 0x57, 0x45, 0x51, 0x65, 0x01, 0x6e, 0x77, 0xad,
  5927. 0xe1, 0x0c, 0xa0, 0x02, 0x20, 0x91, 0x2c, 0x36,
  5928. 0x42, 0xad, 0x81, 0xdf, 0x21, 0x60, 0x5c, 0x06,
  5929. 0x0f, 0x4b, 0x26, 0xb4, 0x58, 0x1a, 0xda, 0x19,
  5930. 0x6c, 0x5b, 0x7c, 0x9a, 0x80, 0xcb, 0x15, 0x2d,
  5931. 0xb3, 0xde, 0x2b, 0xb2, 0xf8, 0xb8, 0x9d, 0xc8,
  5932. 0x38, 0x41, 0x93, 0xa3, 0xb1, 0x8d, 0x3e, 0x7e,
  5933. 0x3c, 0x78, 0xd7, 0x6f, 0xfd, 0xea, 0xc4, 0xf8,
  5934. 0xbb, 0x44, 0xb8, 0x1e, 0x3f, 0x70, 0x98, 0x38,
  5935. 0x4e, 0x4c, 0x2f, 0x95, 0xb8, 0xef, 0x21, 0x2e,
  5936. 0x12, 0x95, 0x0e, 0x3f, 0xb9, 0xdd, 0xa1, 0x97,
  5937. 0xdb, 0xcf, 0xdb, 0xcc, 0x86, 0xfe, 0x54, 0xae,
  5938. 0x59, 0xe6, 0xa7, 0x83, 0xd3, 0x7d, 0x5f, 0x5c,
  5939. 0xd1, 0xf6, 0x5a, 0xf0, 0xc1, 0xe2, 0xf8, 0xb8,
  5940. 0xc0, 0x7c, 0xd8, 0x2a, 0xcd, 0xc4, 0x31, 0xd5,
  5941. 0xe5, 0xc2, 0xa9, 0xa3, 0xe9, 0x70, 0x64, 0x28,
  5942. 0xf0, 0xb8, 0x31, 0x52, 0x6c, 0x8a, 0x3c, 0xae,
  5943. 0x43, 0xc4, 0xa5, 0x93, 0x1b, 0x86, 0x0f, 0x71,
  5944. 0xd1, 0x27, 0xb4, 0xe2
  5945. };
  5946. //
  5947. // RSA Signature PUBLICKEYBLOB
  5948. //
  5949. BYTE rgbPublicKeyBlob [] =
  5950. {
  5951. 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
  5952. 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
  5953. 0x01, 0x00, 0x01, 0x00, 0xd7, 0x90, 0x56, 0x7a,
  5954. 0x9e, 0x87, 0x53, 0x90, 0x94, 0x37, 0x46, 0x4e,
  5955. 0x99, 0xe7, 0xee, 0xc5, 0xa8, 0x24, 0x10, 0x5c,
  5956. 0xd3, 0xc9, 0x22, 0x15, 0xab, 0xfa, 0xa5, 0x2f,
  5957. 0x4e, 0x51, 0x73, 0x83, 0xef, 0x4c, 0x87, 0xe7,
  5958. 0x79, 0x83, 0xd0, 0xf0, 0xb7, 0x34, 0xf1, 0xe8,
  5959. 0x76, 0xb2, 0x6a, 0x0b, 0x13, 0x82, 0x9c, 0x89,
  5960. 0xeb, 0x57, 0xf1, 0x6b, 0x9c, 0x47, 0x99, 0xd2,
  5961. 0x26, 0x9d, 0x75, 0xc4
  5962. };
  5963. //
  5964. // Function: PositiveImportKeyTests
  5965. // Purpose: Run the test cases for CryptImportKey. The set of test cases to be run
  5966. // depends on the current CSP class being tested, as specified in the dwCSPClass
  5967. // parameter.
  5968. //
  5969. BOOL PositiveImportKeyTests(PCSPINFO pCSPInfo)
  5970. {
  5971. BOOL fSuccess = FALSE;
  5972. LPWSTR pwszContainer = TEST_CONTAINER;
  5973. HCRYPTKEY hKey = 0;
  5974. HCRYPTKEY hEncryptKey = 0;
  5975. HCRYPTPROV hProv = 0;
  5976. PBYTE pbKey = NULL;
  5977. DWORD cbKey = 0;
  5978. PTESTCASE ptc = &(pCSPInfo->TestCase);
  5979. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  5980. //
  5981. // Group 5F
  5982. //
  5983. //
  5984. // Do CryptImportKey positive test cases
  5985. //
  5986. switch (pCSPInfo->TestCase.dwCSPClass)
  5987. {
  5988. case CLASS_SIG_ONLY:
  5989. {
  5990. //
  5991. // Import a previously generated unencrypted PRIVATEKEYBLOB
  5992. //
  5993. LOG_TRY(TImportKey(
  5994. hProv,
  5995. rgbPrivateKeyBlob,
  5996. sizeof(rgbPrivateKeyBlob),
  5997. 0,
  5998. 0,
  5999. &hKey,
  6000. ptc));
  6001. LOG_TRY(TDestroyKey(hKey, ptc));
  6002. hKey = 0;
  6003. //
  6004. // Import a encrypted PRIVATEKEYBLOB generated from this CSP
  6005. //
  6006. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey, ptc));
  6007. LOG_TRY(CreateNewKey(hProv, CALG_RC4, 0, &hEncryptKey, ptc));
  6008. LOG_TRY(TExportKey(hKey, hEncryptKey, PRIVATEKEYBLOB, 0, NULL, &cbKey, ptc));
  6009. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  6010. LOG_TRY(TExportKey(hKey, hEncryptKey, PRIVATEKEYBLOB, 0, pbKey, &cbKey, ptc));
  6011. LOG_TRY(TDestroyKey(hKey, ptc));
  6012. hKey = 0;
  6013. LOG_TRY(TImportKey(hProv, pbKey, cbKey, hEncryptKey, 0, &hKey, ptc));
  6014. LOG_TRY(TDestroyKey(hKey, ptc));
  6015. hKey = 0;
  6016. free(pbKey);
  6017. pbKey = NULL;
  6018. //
  6019. // Import a previously generated PUBLICKEYBLOB
  6020. //
  6021. LOG_TRY(TImportKey(
  6022. hProv,
  6023. rgbPublicKeyBlob,
  6024. sizeof(rgbPublicKeyBlob),
  6025. 0,
  6026. 0,
  6027. &hKey,
  6028. ptc));
  6029. LOG_TRY(TDestroyKey(hKey, ptc));
  6030. hKey = 0;
  6031. //
  6032. // Import a SYMMETRICWRAPKEYBLOB
  6033. //
  6034. LOG_TRY(CreateNewKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey, ptc));
  6035. cbKey = 0;
  6036. LOG_TRY(TExportKey(hKey, hEncryptKey, SYMMETRICWRAPKEYBLOB, 0, NULL, &cbKey, ptc));
  6037. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  6038. LOG_TRY(TExportKey(hKey, hEncryptKey, SYMMETRICWRAPKEYBLOB, 0, pbKey, &cbKey, ptc));
  6039. LOG_TRY(TDestroyKey(hKey, ptc));
  6040. hKey = 0;
  6041. LOG_TRY(TImportKey(hProv, pbKey, cbKey, hEncryptKey, 0, &hKey, ptc));
  6042. break;
  6043. }
  6044. case CLASS_SIG_KEYX:
  6045. {
  6046. //
  6047. // Import a SIMPLEBLOB
  6048. //
  6049. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hEncryptKey, ptc));
  6050. LOG_TRY(CreateNewKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey, ptc));
  6051. cbKey = 0;
  6052. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, 0, NULL, &cbKey, ptc));
  6053. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  6054. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, 0, pbKey, &cbKey, ptc));
  6055. LOG_TRY(TDestroyKey(hKey, ptc));
  6056. hKey = 0;
  6057. LOG_TRY(TImportKey(hProv, pbKey, cbKey, hEncryptKey, 0, &hKey, ptc));
  6058. LOG_TRY(TDestroyKey(hKey, ptc));
  6059. hKey = 0;
  6060. free(pbKey);
  6061. pbKey = NULL;
  6062. //
  6063. // Import a SIMPLEBLOB with the CRYPT_OAEP flag
  6064. //
  6065. LOG_TRY(CreateNewKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey, ptc));
  6066. cbKey = 0;
  6067. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, CRYPT_OAEP, NULL, &cbKey, ptc));
  6068. LOG_TRY(TestAlloc(&pbKey, cbKey, ptc));
  6069. LOG_TRY(TExportKey(hKey, hEncryptKey, SIMPLEBLOB, CRYPT_OAEP, pbKey, &cbKey, ptc));
  6070. LOG_TRY(TDestroyKey(hKey, ptc));
  6071. hKey = 0;
  6072. LOG_TRY(TImportKey(hProv, pbKey, cbKey, hEncryptKey, CRYPT_OAEP, &hKey, ptc));
  6073. break;
  6074. }
  6075. default:
  6076. {
  6077. goto Cleanup;
  6078. }
  6079. }
  6080. fSuccess = TRUE;
  6081. Cleanup:
  6082. if (pbKey)
  6083. {
  6084. free(pbKey);
  6085. }
  6086. if (hKey)
  6087. {
  6088. TDestroyKey(hKey, ptc);
  6089. }
  6090. if (hEncryptKey)
  6091. {
  6092. TDestroyKey(hEncryptKey, ptc);
  6093. }
  6094. if (hProv)
  6095. {
  6096. TRelease(hProv, 0, ptc);
  6097. }
  6098. return fSuccess;
  6099. }
  6100. //
  6101. // Function: NegativeImportKeyTests
  6102. // Purpose: Run the negative test cases for CryptImportKey. The set of test cases to be run
  6103. // depends on the current CSP class being tested, as specified in the dwCSPClass
  6104. // parameter.
  6105. //
  6106. BOOL NegativeImportKeyTests(PCSPINFO pCSPInfo)
  6107. {
  6108. BOOL fSuccess = FALSE;
  6109. LPWSTR pwszContainer = TEST_CONTAINER;
  6110. HCRYPTPROV hProv = 0;
  6111. HCRYPTKEY hKey = 0;
  6112. HCRYPTKEY hKeyExch = 0;
  6113. HCRYPTKEY hKeySig = 0;
  6114. HCRYPTKEY hKeyEncr = 0;
  6115. DWORD dw = 0;
  6116. DWORD cb = 0;
  6117. PBYTE pbKey = NULL;
  6118. BLOBHEADER *pBlobHeader = NULL;
  6119. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6120. // Acquire context with key container access
  6121. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  6122. //
  6123. // Group 5F
  6124. //
  6125. switch (ptc->dwCSPClass)
  6126. {
  6127. case CLASS_SIG_ONLY:
  6128. {
  6129. //
  6130. // Do CryptImportKey negative test cases for CSP CLASS_SIG_ONLY
  6131. //
  6132. cb = sizeof(dw);
  6133. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  6134. LOG_TRY(TImportKey(0, (PBYTE) &dw, cb, 0, PUBLICKEYBLOB, &hKey, ptc));
  6135. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  6136. LOG_TRY(TImportKey(TEST_INVALID_HANDLE, (PBYTE) &dw, cb, 0, PUBLICKEYBLOB, &hKey, ptc));
  6137. // Create a key signature key pair
  6138. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKey, ptc));
  6139. // Get correct blob size for signature key public blob
  6140. ptc->fExpectSuccess = TRUE;
  6141. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &cb, ptc));
  6142. LOG_TRY(TestAlloc(&pbKey, cb, ptc));
  6143. // Export the key
  6144. LOG_TRY(TExportKey(hKey, 0, PUBLICKEYBLOB, 0, pbKey, &cb, ptc));
  6145. // Destroy the key handle
  6146. LOG_TRY(TDestroyKey(hKey, ptc));
  6147. hKey = 0;
  6148. ptc->fExpectSuccess = FALSE;
  6149. // Invalid flag value
  6150. ptc->KnownErrorID = KNOWN_CRYPTIMPORTKEY_BADFLAGS;
  6151. ptc->dwErrorCode = NTE_BAD_FLAGS;
  6152. LOG_TRY(TImportKey(hProv, pbKey, cb, 0, TEST_INVALID_FLAG, &hKey, ptc));
  6153. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  6154. // Pass in too short buffer
  6155. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  6156. LOG_TRY(TImportKey(hProv, (PBYTE) TEST_INVALID_POINTER, cb, 0, 0, &hKey, ptc));
  6157. break;
  6158. }
  6159. case CLASS_SIG_KEYX:
  6160. {
  6161. //
  6162. // Do CryptImportKey negative test cases for CSP CLASS_SIG_KEYX
  6163. //
  6164. // Create a key signature key pair
  6165. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hKeySig, ptc));
  6166. // Create a key exchange key pair
  6167. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hKeyExch, ptc));
  6168. // Get correct blob size for signature key public blob
  6169. ptc->fExpectSuccess = TRUE;
  6170. LOG_TRY(TExportKey(hKeySig, 0, PUBLICKEYBLOB, 0, NULL, &cb, ptc));
  6171. ptc->fExpectSuccess = FALSE;
  6172. // Attempt to import an unencrypted key blob using a key-exchange key
  6173. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  6174. LOG_TRY(TImportKey(hProv, (PBYTE) TEST_INVALID_POINTER, cb, hKeyExch, 0, &hKey, ptc));
  6175. // Get correct blob size for encrypted signature key blob
  6176. /*
  6177. ptc->fExpectSuccess = TRUE;
  6178. LOG_TRY(TExportKey(hKeySig, hKeyExch, PRIVATEKEYBLOB, 0, NULL, &cb, ptc));
  6179. LOG_TRY(TestAlloc(&pbKey, cb, ptc));
  6180. // Export the encrypted signature key
  6181. LOG_TRY(TExportKey(hKeySig, hKeyExch, PRIVATEKEYBLOB, 0, pbKey, &cb, ptc));
  6182. ptc->fExpectSuccess = FALSE;
  6183. // Attempt to import encrypted key blob with invalid key-exchange handle
  6184. ptc->dwErrorCode = NTE_BAD_KEY;
  6185. LOG_TRY(TImportKey(hProv, pbKey, cb, TEST_INVALID_HANDLE, 0, &hKey, ptc));
  6186. // Free the key blob memory
  6187. free(pbKey);
  6188. */
  6189. // Create a new encryption key
  6190. LOG_TRY(CreateNewKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKeyEncr, ptc));
  6191. // Get blob size for exporting encrypted symmetric key
  6192. ptc->fExpectSuccess = TRUE;
  6193. LOG_TRY(TExportKey(hKeyEncr, hKeyExch, SIMPLEBLOB, 0, NULL, &cb, ptc));
  6194. LOG_TRY(TestAlloc(&pbKey, cb, ptc));
  6195. // Export encrypted symmetric key
  6196. LOG_TRY(TExportKey(hKeyEncr, hKeyExch, SIMPLEBLOB, 0, pbKey, &cb, ptc));
  6197. ptc->fExpectSuccess = FALSE;
  6198. // Attempt to import encrypted key blob with invalid key-exchange handle
  6199. ptc->dwErrorCode = NTE_BAD_KEY;
  6200. LOG_TRY(TImportKey(hProv, pbKey, cb, TEST_INVALID_HANDLE, 0, &hKey, ptc));
  6201. pBlobHeader = (BLOBHEADER *) pbKey;
  6202. // Save header encryption alg
  6203. dw = pBlobHeader->aiKeyAlg;
  6204. // Clear header encryption alg field
  6205. pBlobHeader->aiKeyAlg = 0;
  6206. ptc->pwszErrorHelp =
  6207. L"The blob header encryption algorithm is missing";
  6208. ptc->KnownErrorID = KNOWN_CRYPTIMPORTKEY_BADALGID;
  6209. ptc->dwErrorCode = NTE_BAD_ALGID;
  6210. LOG_TRY(TImportKey(hProv, pbKey, cb, hKeyExch, 0, &hKey, ptc));
  6211. ptc->pwszErrorHelp = NULL;
  6212. ptc->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  6213. // Restore header encryption alg
  6214. pBlobHeader->aiKeyAlg = dw;
  6215. // Save blob type header field
  6216. dw = pBlobHeader->bType;
  6217. // Clear blob type header field
  6218. pBlobHeader->bType = 0;
  6219. ptc->dwErrorCode = NTE_BAD_TYPE;
  6220. LOG_TRY(TImportKey(hProv, pbKey, cb, hKeyExch, 0, &hKey, ptc));
  6221. // Restore blob type header field
  6222. pBlobHeader->bType = (BYTE) dw;
  6223. // Save blob version header field
  6224. dw = pBlobHeader->bVersion;
  6225. // Clear blob version header field
  6226. pBlobHeader->bVersion = 0;
  6227. ptc->dwErrorCode = NTE_BAD_VER;
  6228. LOG_TRY(TImportKey(hProv, pbKey, cb, hKeyExch, 0, &hKey, ptc));
  6229. break;
  6230. }
  6231. }
  6232. fSuccess = TRUE;
  6233. Cleanup:
  6234. if (pbKey)
  6235. {
  6236. free(pbKey);
  6237. }
  6238. if (hKey)
  6239. {
  6240. TDestroyKey(hKey, ptc);
  6241. }
  6242. if (hKeySig)
  6243. {
  6244. TDestroyKey(hKeySig, ptc);
  6245. }
  6246. if (hKeyExch)
  6247. {
  6248. TDestroyKey(hKeyExch, ptc);
  6249. }
  6250. if (hKeyEncr)
  6251. {
  6252. TDestroyKey(hKeyEncr, ptc);
  6253. }
  6254. if (hProv)
  6255. {
  6256. TRelease(hProv, 0, ptc);
  6257. }
  6258. return fSuccess;
  6259. }
  6260. //
  6261. // Function: PositiveSignHashTests
  6262. // Purpose: Run the test cases for CryptSignHash. The set of positive test cases to be run depends on the
  6263. // current CSP class being tested, as specified in the dwCSPClass parameter.
  6264. //
  6265. BOOL PositiveSignHashTests(PCSPINFO pCSPInfo)
  6266. {
  6267. BOOL fSuccess = FALSE;
  6268. LPWSTR pwszContainer = TEST_CONTAINER;
  6269. HCRYPTPROV hProv = 0;
  6270. HCRYPTKEY hKey = 0;
  6271. HCRYPTHASH hHash = 0;
  6272. PBYTE pbSignature = NULL;
  6273. DWORD cbSignature = 0;
  6274. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6275. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  6276. //
  6277. // Group 5G
  6278. //
  6279. //
  6280. // Do CryptSignHash positive test cases
  6281. //
  6282. switch(ptc->dwCSPClass)
  6283. {
  6284. case CLASS_SIG_ONLY:
  6285. {
  6286. //
  6287. // Sign a hash with a signature key pair
  6288. //
  6289. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  6290. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  6291. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &cbSignature, ptc));
  6292. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6293. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &cbSignature, ptc));
  6294. free(pbSignature);
  6295. pbSignature = NULL;
  6296. //
  6297. // Sign with the CRYPT_NOHASHOID flag
  6298. //
  6299. LOG_TRY(TSignHash(
  6300. hHash,
  6301. AT_SIGNATURE,
  6302. NULL,
  6303. CRYPT_NOHASHOID,
  6304. NULL,
  6305. &cbSignature,
  6306. ptc));
  6307. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6308. LOG_TRY(TSignHash(
  6309. hHash,
  6310. AT_SIGNATURE,
  6311. NULL,
  6312. CRYPT_NOHASHOID,
  6313. pbSignature,
  6314. &cbSignature,
  6315. ptc));
  6316. break;
  6317. }
  6318. case CLASS_SIG_KEYX:
  6319. {
  6320. //
  6321. // Sign a hash with a key exchange key pair
  6322. //
  6323. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hKey, ptc));
  6324. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  6325. LOG_TRY(TSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &cbSignature, ptc));
  6326. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6327. LOG_TRY(TSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, pbSignature, &cbSignature, ptc));
  6328. free(pbSignature);
  6329. pbSignature = NULL;
  6330. //
  6331. // Sign with the CRYPT_NOHASHOID flag
  6332. //
  6333. LOG_TRY(TSignHash(
  6334. hHash,
  6335. AT_KEYEXCHANGE,
  6336. NULL,
  6337. CRYPT_NOHASHOID,
  6338. NULL,
  6339. &cbSignature,
  6340. ptc));
  6341. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6342. LOG_TRY(TSignHash(
  6343. hHash,
  6344. AT_KEYEXCHANGE,
  6345. NULL,
  6346. CRYPT_NOHASHOID,
  6347. pbSignature,
  6348. &cbSignature,
  6349. ptc));
  6350. break;
  6351. }
  6352. default:
  6353. {
  6354. goto Cleanup;
  6355. }
  6356. }
  6357. fSuccess = TRUE;
  6358. Cleanup:
  6359. if (pbSignature)
  6360. {
  6361. free(pbSignature);
  6362. }
  6363. if (hKey)
  6364. {
  6365. TDestroyKey(hKey, ptc);
  6366. }
  6367. if (hProv)
  6368. {
  6369. TRelease(hProv, 0, ptc);
  6370. }
  6371. return fSuccess;
  6372. }
  6373. //
  6374. // Function: NegativeSignHashTests
  6375. // Purpose: Run the negative test cases for CryptSignHash.
  6376. //
  6377. BOOL NegativeSignHashTests(PCSPINFO pCSPInfo)
  6378. {
  6379. BOOL fSuccess = FALSE;
  6380. LPWSTR pwszContainer = TEST_CONTAINER;
  6381. HCRYPTPROV hProv = 0;
  6382. HCRYPTKEY hKey = 0;
  6383. HCRYPTHASH hHash = 0;
  6384. DWORD dw = 0;
  6385. DWORD cb = 0;
  6386. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6387. //
  6388. // Group 5G
  6389. //
  6390. //
  6391. // Do CryptSignHash negative test cases
  6392. //
  6393. // Create provider handle with key container access
  6394. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  6395. // Create hash
  6396. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  6397. // Attempt to sign with a keyset that doesn't exist
  6398. ptc->dwErrorCode = NTE_BAD_KEYSET;
  6399. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, (PBYTE) &dw, &cb, ptc));
  6400. // Create signature key pair
  6401. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  6402. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  6403. LOG_TRY(TSignHash(0, AT_SIGNATURE, NULL, 0, (PBYTE) &dw, &cb, ptc));
  6404. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  6405. LOG_TRY(TSignHash(TEST_INVALID_HANDLE, AT_SIGNATURE, NULL, 0, (PBYTE) &dw, &cb, ptc));
  6406. cb = 1;
  6407. ptc->dwErrorCode = ERROR_MORE_DATA;
  6408. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, (PBYTE) &dw, &cb, ptc));
  6409. ptc->dwErrorCode = NTE_BAD_ALGID;
  6410. LOG_TRY(TSignHash(hHash, TEST_INVALID_FLAG, NULL, 0, (PBYTE) &dw, &cb, ptc));
  6411. ptc->dwErrorCode = NTE_BAD_FLAGS;
  6412. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, TEST_INVALID_FLAG, (PBYTE) &dw, &cb, ptc));
  6413. // Release the provider handle
  6414. /*
  6415. LOG_TRY(TRelease(hProv, 0, ptc));
  6416. hProv = 0;
  6417. // Provider handle used to create hHash is now invalid
  6418. ptc->dwErrorCode = NTE_BAD_UID;
  6419. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, (PBYTE) &dw, &cb, ptc));
  6420. */
  6421. fSuccess = TRUE;
  6422. Cleanup:
  6423. if (hKey)
  6424. {
  6425. TDestroyKey(hKey, ptc);
  6426. }
  6427. if (hHash)
  6428. {
  6429. TDestroyHash(hHash, ptc);
  6430. }
  6431. if (hProv)
  6432. {
  6433. TRelease(hProv, 0, ptc);
  6434. }
  6435. return fSuccess;
  6436. }
  6437. //
  6438. // Function: SignAndVerifySignatureProc
  6439. //
  6440. BOOL SignAndVerifySignatureProc(
  6441. PALGNODE pAlgNode,
  6442. PTESTCASE ptc,
  6443. PVOID pvSignHashInfo)
  6444. {
  6445. BOOL fSuccess = FALSE;
  6446. HCRYPTHASH hHash = 0;
  6447. PBYTE pbSignature = NULL;
  6448. DWORD cbSignature = 0;
  6449. PSIGN_HASH_INFO pSignHashInfo = (PSIGN_HASH_INFO) pvSignHashInfo;
  6450. LOG_TRY(CreateNewHash(
  6451. pSignHashInfo->hProv,
  6452. pAlgNode->ProvEnumalgsEx.aiAlgid,
  6453. &hHash,
  6454. ptc));
  6455. LOG_TRY(THashData(
  6456. hHash,
  6457. pSignHashInfo->dbBaseData.pbData,
  6458. pSignHashInfo->dbBaseData.cbData,
  6459. 0,
  6460. ptc));
  6461. //
  6462. // Sign the hash with the Signature key pair and verify
  6463. // the signature.
  6464. //
  6465. LOG_TRY(TSignHash(
  6466. hHash,
  6467. AT_SIGNATURE,
  6468. NULL,
  6469. 0,
  6470. NULL,
  6471. &cbSignature,
  6472. ptc));
  6473. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6474. LOG_TRY(TSignHash(
  6475. hHash,
  6476. AT_SIGNATURE,
  6477. NULL,
  6478. 0,
  6479. pbSignature,
  6480. &cbSignature,
  6481. ptc));
  6482. LOG_TRY(TVerifySign(
  6483. hHash,
  6484. pbSignature,
  6485. cbSignature,
  6486. pSignHashInfo->hSigKey,
  6487. NULL,
  6488. 0,
  6489. ptc));
  6490. free(pbSignature);
  6491. pbSignature = NULL;
  6492. //
  6493. // Sign the hash with the Key Exchange key pair and
  6494. // verify the signature.
  6495. //
  6496. LOG_TRY(TSignHash(
  6497. hHash,
  6498. AT_KEYEXCHANGE,
  6499. NULL,
  6500. 0,
  6501. NULL,
  6502. &cbSignature,
  6503. ptc));
  6504. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6505. LOG_TRY(TSignHash(
  6506. hHash,
  6507. AT_KEYEXCHANGE,
  6508. NULL,
  6509. 0,
  6510. pbSignature,
  6511. &cbSignature,
  6512. ptc));
  6513. LOG_TRY(TVerifySign(
  6514. hHash,
  6515. pbSignature,
  6516. cbSignature,
  6517. pSignHashInfo->hExchKey,
  6518. NULL,
  6519. 0,
  6520. ptc));
  6521. fSuccess = TRUE;
  6522. Cleanup:
  6523. if (pbSignature)
  6524. {
  6525. free(pbSignature);
  6526. }
  6527. if (hHash)
  6528. {
  6529. TDestroyHash(hHash, ptc);
  6530. }
  6531. return fSuccess;
  6532. }
  6533. //
  6534. // Function: ScenarioVerifySignatureTests
  6535. // Purpose: For each supported hash algorithm, call
  6536. // SignAndVerifySignatureProc.
  6537. //
  6538. BOOL ScenarioVerifySignatureTests(PCSPINFO pCSPInfo)
  6539. {
  6540. BOOL fSuccess = FALSE;
  6541. LPWSTR pwszContainer = TEST_CONTAINER;
  6542. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6543. PALGNODE pAlgList = pCSPInfo->pAlgList;
  6544. SIGN_HASH_INFO SignHashInfo;
  6545. memset(&SignHashInfo, 0, sizeof(SignHashInfo));
  6546. LOG_TRY(CreateNewContext(
  6547. &(SignHashInfo.hProv),
  6548. pwszContainer,
  6549. CRYPT_NEWKEYSET,
  6550. ptc));
  6551. LOG_TRY(CreateNewKey(
  6552. SignHashInfo.hProv,
  6553. AT_SIGNATURE,
  6554. 0,
  6555. &(SignHashInfo.hSigKey),
  6556. ptc));
  6557. LOG_TRY(CreateNewKey(
  6558. SignHashInfo.hProv,
  6559. AT_KEYEXCHANGE,
  6560. 0,
  6561. &(SignHashInfo.hExchKey),
  6562. ptc));
  6563. SignHashInfo.dbBaseData.cbData = wcslen(TEST_HASH_DATA) * sizeof(WCHAR);
  6564. LOG_TRY(TestAlloc(
  6565. &(SignHashInfo.dbBaseData.pbData),
  6566. SignHashInfo.dbBaseData.cbData,
  6567. ptc));
  6568. memcpy(
  6569. SignHashInfo.dbBaseData.pbData,
  6570. TEST_HASH_DATA,
  6571. SignHashInfo.dbBaseData.cbData);
  6572. //
  6573. // The SignAndVerifySignatureProc isn't meant to work with
  6574. // MAC algorithms, so filter those out.
  6575. //
  6576. LOG_TRY(AlgListIterate(
  6577. pAlgList,
  6578. HashAlgFilter,
  6579. SignAndVerifySignatureProc,
  6580. (PVOID) &SignHashInfo,
  6581. ptc));
  6582. fSuccess = TRUE;
  6583. Cleanup:
  6584. if (SignHashInfo.dbBaseData.pbData)
  6585. {
  6586. free(SignHashInfo.dbBaseData.pbData);
  6587. }
  6588. if (SignHashInfo.hExchKey)
  6589. {
  6590. TDestroyKey(SignHashInfo.hExchKey, ptc);
  6591. }
  6592. if (SignHashInfo.hSigKey)
  6593. {
  6594. TDestroyKey(SignHashInfo.hSigKey, ptc);
  6595. }
  6596. if (SignHashInfo.hProv)
  6597. {
  6598. TRelease(SignHashInfo.hProv, 0, ptc);
  6599. }
  6600. return fSuccess;
  6601. }
  6602. //
  6603. // Function: PositiveVerifySignatureTests
  6604. // Purpose: Run the test cases for CryptVerifySignature
  6605. //
  6606. BOOL PositiveVerifySignatureTests(PCSPINFO pCSPInfo)
  6607. {
  6608. BOOL fSuccess = FALSE;
  6609. LPWSTR pwszContainer = TEST_CONTAINER;
  6610. HCRYPTPROV hProv = 0;
  6611. HCRYPTKEY hKey = 0;
  6612. HCRYPTHASH hHash = 0;
  6613. PBYTE pbSignature = NULL;
  6614. DWORD cbSignature = 0;
  6615. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6616. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  6617. //
  6618. // Group 5H
  6619. //
  6620. //
  6621. // Do CryptVerifySignature positive test cases
  6622. //
  6623. switch(ptc->dwCSPClass)
  6624. {
  6625. case CLASS_SIG_ONLY:
  6626. {
  6627. //
  6628. // Sign and verify a hash using a signature key pair
  6629. //
  6630. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  6631. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  6632. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &cbSignature, ptc));
  6633. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6634. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &cbSignature, ptc));
  6635. LOG_TRY(TVerifySign(
  6636. hHash,
  6637. pbSignature,
  6638. cbSignature,
  6639. hKey,
  6640. NULL,
  6641. 0,
  6642. ptc));
  6643. free(pbSignature);
  6644. pbSignature = NULL;
  6645. //
  6646. // Sign and verify using the CRYPT_NOHASHOID flag
  6647. //
  6648. LOG_TRY(TSignHash(
  6649. hHash,
  6650. AT_SIGNATURE,
  6651. NULL,
  6652. CRYPT_NOHASHOID,
  6653. NULL,
  6654. &cbSignature,
  6655. ptc));
  6656. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6657. LOG_TRY(TSignHash(
  6658. hHash,
  6659. AT_SIGNATURE,
  6660. NULL,
  6661. CRYPT_NOHASHOID,
  6662. pbSignature,
  6663. &cbSignature,
  6664. ptc));
  6665. LOG_TRY(TVerifySign(
  6666. hHash,
  6667. pbSignature,
  6668. cbSignature,
  6669. hKey,
  6670. NULL,
  6671. CRYPT_NOHASHOID,
  6672. ptc));
  6673. break;
  6674. }
  6675. case CLASS_SIG_KEYX:
  6676. {
  6677. //
  6678. // Sign and verify a hash with a key exchange key pair
  6679. //
  6680. LOG_TRY(CreateNewKey(hProv, AT_KEYEXCHANGE, 0, &hKey, ptc));
  6681. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  6682. LOG_TRY(TSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &cbSignature, ptc));
  6683. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6684. LOG_TRY(TSignHash(hHash, AT_KEYEXCHANGE, NULL, 0, pbSignature, &cbSignature, ptc));
  6685. LOG_TRY(TVerifySign(
  6686. hHash,
  6687. pbSignature,
  6688. cbSignature,
  6689. hKey,
  6690. NULL,
  6691. 0,
  6692. ptc));
  6693. free(pbSignature);
  6694. pbSignature = NULL;
  6695. //
  6696. // Sign and verify using the CRYPT_NOHASHOID flag
  6697. //
  6698. LOG_TRY(TSignHash(
  6699. hHash,
  6700. AT_KEYEXCHANGE,
  6701. NULL,
  6702. CRYPT_NOHASHOID,
  6703. NULL,
  6704. &cbSignature,
  6705. ptc));
  6706. LOG_TRY(TestAlloc(&pbSignature, cbSignature, ptc));
  6707. LOG_TRY(TSignHash(
  6708. hHash,
  6709. AT_KEYEXCHANGE,
  6710. NULL,
  6711. CRYPT_NOHASHOID,
  6712. pbSignature,
  6713. &cbSignature,
  6714. ptc));
  6715. LOG_TRY(TVerifySign(
  6716. hHash,
  6717. pbSignature,
  6718. cbSignature,
  6719. hKey,
  6720. NULL,
  6721. CRYPT_NOHASHOID,
  6722. ptc));
  6723. break;
  6724. }
  6725. default:
  6726. {
  6727. goto Cleanup;
  6728. }
  6729. }
  6730. fSuccess = TRUE;
  6731. Cleanup:
  6732. if (pbSignature)
  6733. {
  6734. free(pbSignature);
  6735. }
  6736. if (hKey)
  6737. {
  6738. TDestroyKey(hKey, ptc);
  6739. }
  6740. if (hProv)
  6741. {
  6742. TRelease(hProv, 0, ptc);
  6743. }
  6744. return fSuccess;
  6745. }
  6746. //
  6747. // Function: NegativeVerifySignatureTests
  6748. // Purpose: Run the negative test cases for CryptVerifySignature
  6749. //
  6750. BOOL NegativeVerifySignatureTests(PCSPINFO pCSPInfo)
  6751. {
  6752. BOOL fSuccess = FALSE;
  6753. LPWSTR pwszContainer = TEST_CONTAINER;
  6754. HCRYPTPROV hProv = 0;
  6755. HCRYPTKEY hKey = 0;
  6756. HCRYPTHASH hHash = 0;
  6757. //DWORD dw = 0;
  6758. DWORD cb = 0;
  6759. PBYTE pb = NULL;
  6760. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6761. //
  6762. // Group 5H
  6763. //
  6764. //
  6765. // Do CryptVerifySignature negative test cases
  6766. //
  6767. // Create new context with key container access
  6768. LOG_TRY(CreateNewContext(&hProv, pwszContainer, CRYPT_NEWKEYSET, ptc));
  6769. // Create new signature key pair
  6770. LOG_TRY(CreateNewKey(hProv, AT_SIGNATURE, 0, &hKey, ptc));
  6771. // Create new hash
  6772. LOG_TRY(CreateNewHash(hProv, CALG_SHA1, &hHash, ptc));
  6773. // Sign the hash
  6774. ptc->fExpectSuccess = TRUE;
  6775. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &cb, ptc));
  6776. LOG_TRY(TestAlloc(&pb, cb, ptc));
  6777. LOG_TRY(TSignHash(hHash, AT_SIGNATURE, NULL, 0, pb, &cb, ptc));
  6778. ptc->fExpectSuccess = FALSE;
  6779. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  6780. LOG_TRY(TVerifySign(0, pb, cb, hKey, NULL, 0, ptc));
  6781. ptc->dwErrorCode = ERROR_INVALID_HANDLE;
  6782. LOG_TRY(TVerifySign(TEST_INVALID_HANDLE, pb, cb, hKey, NULL, 0, ptc));
  6783. ptc->dwErrorCode = ERROR_INVALID_PARAMETER;
  6784. LOG_TRY(TVerifySign(hHash, NULL, cb, hKey, NULL, 0, ptc));
  6785. ptc->dwErrorCode = NTE_BAD_FLAGS;
  6786. LOG_TRY(TVerifySign(hHash, pb, cb, hKey, NULL, TEST_INVALID_FLAG, ptc));
  6787. // Use invalid signature key handle
  6788. ptc->dwErrorCode = NTE_BAD_KEY;
  6789. LOG_TRY(TVerifySign(hHash, pb, cb, TEST_INVALID_HANDLE, NULL, 0, ptc));
  6790. // Indicate a too-short buffer length
  6791. ptc->dwErrorCode = NTE_BAD_SIGNATURE;
  6792. LOG_TRY(TVerifySign(hHash, pb, cb - 1, hKey, NULL, 0, ptc));
  6793. // Flip the bits in the last byte of the signature blob
  6794. pb[cb - 1] = ~(pb[cb - 1]);
  6795. ptc->dwErrorCode = NTE_BAD_SIGNATURE;
  6796. LOG_TRY(TVerifySign(hHash, pb, cb, hKey, NULL, 0, ptc));
  6797. /*
  6798. // Release the context used to create hHash
  6799. LOG_TRY(TRelease(hProv, 0, ptc));
  6800. hProv = 0;
  6801. // Provider handle used to create hHash is now invalid
  6802. ptc->dwErrorCode = NTE_BAD_UID;
  6803. LOG_TRY(TVerifySign(hHash, pb, cb, hKey, NULL, 0, ptc));
  6804. */
  6805. fSuccess = TRUE;
  6806. Cleanup:
  6807. if (hHash)
  6808. {
  6809. TDestroyHash(hHash, ptc);
  6810. }
  6811. if (hKey)
  6812. {
  6813. TDestroyKey(hKey, ptc);
  6814. }
  6815. if (hProv)
  6816. {
  6817. TRelease(hProv, 0, ptc);
  6818. }
  6819. if (pb)
  6820. {
  6821. free(pb);
  6822. }
  6823. return fSuccess;
  6824. }
  6825. //
  6826. // Function: TestKeyExchangeProc
  6827. // Purpose: Simulate a key/data exchange scenario for the specified
  6828. // encryption alg.
  6829. //
  6830. BOOL TestKeyExchangeProc(
  6831. PALGNODE pAlgNode,
  6832. PTESTCASE ptc,
  6833. PVOID pvExchangeProcInfo)
  6834. {
  6835. BOOL fSuccess = FALSE;
  6836. PEXCHANGE_PROC_INFO pExchangeProcInfo = (PEXCHANGE_PROC_INFO) pvExchangeProcInfo;
  6837. KEYEXCHANGE_INFO KeyExchangeInfo;
  6838. KEYEXCHANGE_STATE KeyExchangeState;
  6839. memset(&KeyExchangeInfo, 0, sizeof(KeyExchangeInfo));
  6840. memset(&KeyExchangeState, 0, sizeof(KeyExchangeState));
  6841. KeyExchangeInfo.aiHash = pExchangeProcInfo->aiHashAlg;
  6842. KeyExchangeInfo.aiSessionKey = pAlgNode->ProvEnumalgsEx.aiAlgid;
  6843. KeyExchangeInfo.dbPlainText.pbData = pExchangeProcInfo->dbPlainText.pbData;
  6844. KeyExchangeInfo.dbPlainText.cbData = pExchangeProcInfo->dbPlainText.cbData;
  6845. KeyExchangeInfo.dwPubKeySize = pExchangeProcInfo->dwPublicKeySize;
  6846. LOG_TRY(RSA1_CreateKeyPair(
  6847. pExchangeProcInfo->hProv,
  6848. &KeyExchangeInfo,
  6849. &KeyExchangeState,
  6850. ptc));
  6851. LOG_TRY(RSA2_EncryptPlainText(
  6852. pExchangeProcInfo->hInteropProv,
  6853. &KeyExchangeInfo,
  6854. &KeyExchangeState,
  6855. ptc));
  6856. LOG_TRY(RSA3_DecryptAndCheck(
  6857. pExchangeProcInfo->hProv,
  6858. &KeyExchangeInfo,
  6859. &KeyExchangeState,
  6860. ptc));
  6861. fSuccess = TRUE;
  6862. Cleanup:
  6863. return fSuccess;
  6864. }
  6865. //
  6866. // Function: InteropKeyExchangeTests
  6867. // Purpose: Run the TestKeyExchangeProc for each encryption algorithm
  6868. // supported by this CSP. Cryptographic context A will be from the CSP
  6869. // under test. Context B will be from the interop context specified
  6870. // by the user.
  6871. //
  6872. BOOL InteropKeyExchangeTests(PCSPINFO pCSPInfo)
  6873. {
  6874. BOOL fSuccess = FALSE;
  6875. LPWSTR pwszContainer = TEST_CONTAINER;
  6876. LPWSTR pwszInteropContainer = TEST_CONTAINER_2;
  6877. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6878. PALGNODE pAlgList = pCSPInfo->pAlgList;
  6879. EXCHANGE_PROC_INFO ExchangeProcInfo;
  6880. memset(&ExchangeProcInfo, 0, sizeof(ExchangeProcInfo));
  6881. LOG_TRY(CreateNewContext(
  6882. &(ExchangeProcInfo.hProv),
  6883. pwszContainer,
  6884. CRYPT_NEWKEYSET,
  6885. ptc));
  6886. LOG_TRY(CreateNewInteropContext(
  6887. &(ExchangeProcInfo.hInteropProv),
  6888. pwszInteropContainer,
  6889. CRYPT_NEWKEYSET,
  6890. ptc));
  6891. //
  6892. // Note: Using the following hard-coded information for this
  6893. // test.
  6894. //
  6895. ExchangeProcInfo.aiHashAlg = CALG_SHA1;
  6896. ExchangeProcInfo.dbPlainText.cbData = wcslen(TEST_HASH_DATA) * sizeof(WCHAR);
  6897. LOG_TRY(TestAlloc(
  6898. &(ExchangeProcInfo.dbPlainText.pbData),
  6899. ExchangeProcInfo.dbPlainText.cbData,
  6900. ptc));
  6901. memcpy(
  6902. ExchangeProcInfo.dbPlainText.pbData,
  6903. TEST_DECRYPT_DATA,
  6904. ExchangeProcInfo.dbPlainText.cbData);
  6905. LOG_TRY(AlgListIterate(
  6906. pAlgList,
  6907. DataEncryptFilter,
  6908. TestKeyExchangeProc,
  6909. (PVOID) &ExchangeProcInfo,
  6910. ptc));
  6911. fSuccess = TRUE;
  6912. Cleanup:
  6913. if (ExchangeProcInfo.dbPlainText.pbData)
  6914. {
  6915. free(ExchangeProcInfo.dbPlainText.pbData);
  6916. }
  6917. if (ExchangeProcInfo.hProv)
  6918. {
  6919. TRelease(ExchangeProcInfo.hProv, 0, ptc);
  6920. }
  6921. if (ExchangeProcInfo.hInteropProv)
  6922. {
  6923. TRelease(ExchangeProcInfo.hInteropProv, 0, ptc);
  6924. }
  6925. return fSuccess;
  6926. }
  6927. //
  6928. // Function: ScenarioKeyExchangeTests
  6929. // Purpose: Run the TestKeyExchangeProc for each encryption algorithm
  6930. // supported by this CSP. Both of the cryptographic contexts in the
  6931. // scenario will be from the CSP under test.
  6932. //
  6933. BOOL ScenarioKeyExchangeTests(PCSPINFO pCSPInfo)
  6934. {
  6935. BOOL fSuccess = FALSE;
  6936. LPWSTR pwszContainer = TEST_CONTAINER;
  6937. LPWSTR pwszContainer2 = TEST_CONTAINER_2;
  6938. PTESTCASE ptc = &(pCSPInfo->TestCase);
  6939. PALGNODE pAlgList = pCSPInfo->pAlgList;
  6940. EXCHANGE_PROC_INFO ExchangeProcInfo;
  6941. memset(&ExchangeProcInfo, 0, sizeof(ExchangeProcInfo));
  6942. LOG_TRY(CreateNewContext(
  6943. &(ExchangeProcInfo.hProv),
  6944. pwszContainer,
  6945. CRYPT_NEWKEYSET,
  6946. ptc));
  6947. LOG_TRY(CreateNewContext(
  6948. &(ExchangeProcInfo.hInteropProv),
  6949. pwszContainer2,
  6950. CRYPT_NEWKEYSET,
  6951. ptc));
  6952. //
  6953. // Note: Using the following hard-coded information for this
  6954. // test.
  6955. //
  6956. ExchangeProcInfo.aiHashAlg = CALG_SHA1;
  6957. ExchangeProcInfo.dbPlainText.cbData = wcslen(TEST_HASH_DATA) * sizeof(WCHAR);
  6958. LOG_TRY(TestAlloc(
  6959. &(ExchangeProcInfo.dbPlainText.pbData),
  6960. ExchangeProcInfo.dbPlainText.cbData,
  6961. ptc));
  6962. memcpy(
  6963. ExchangeProcInfo.dbPlainText.pbData,
  6964. (PVOID) TEST_DECRYPT_DATA,
  6965. ExchangeProcInfo.dbPlainText.cbData);
  6966. LOG_TRY(AlgListIterate(
  6967. pAlgList,
  6968. DataEncryptFilter,
  6969. TestKeyExchangeProc,
  6970. (PVOID) &ExchangeProcInfo,
  6971. ptc));
  6972. fSuccess = TRUE;
  6973. Cleanup:
  6974. if (ExchangeProcInfo.dbPlainText.pbData)
  6975. {
  6976. free(ExchangeProcInfo.dbPlainText.pbData);
  6977. }
  6978. if (ExchangeProcInfo.hProv)
  6979. {
  6980. TRelease(ExchangeProcInfo.hProv, 0, ptc);
  6981. }
  6982. if (ExchangeProcInfo.hInteropProv)
  6983. {
  6984. TRelease(ExchangeProcInfo.hInteropProv, 0, ptc);
  6985. }
  6986. return fSuccess;
  6987. }
  6988. //
  6989. // Function: GetKnownErrorValue
  6990. //
  6991. DWORD GetKnownErrorValue(
  6992. IN KNOWN_ERROR_ID KnownErrorID,
  6993. IN DWORD dwCurrentErrorLevel)
  6994. {
  6995. DWORD dwActualErrorLevel = dwCurrentErrorLevel;
  6996. int iErrorTable = 0;
  6997. //
  6998. // Search the g_KnownErrorTable for KnownErrorID
  6999. //
  7000. for (
  7001. iErrorTable = 0;
  7002. iErrorTable < (sizeof(g_KnownErrorTable) / sizeof(KNOWN_ERROR_INFO));
  7003. iErrorTable++)
  7004. {
  7005. if (KnownErrorID == g_KnownErrorTable[iErrorTable].KnownErrorID)
  7006. {
  7007. //
  7008. // This is a known error. Get the error level that should be
  7009. // applied.
  7010. //
  7011. dwActualErrorLevel = g_KnownErrorTable[iErrorTable].dwErrorLevel;
  7012. //
  7013. // Check the version information for this error
  7014. //
  7015. if (! IsVersionCorrect(
  7016. g_KnownErrorTable[iErrorTable].dwMajorVersion,
  7017. g_KnownErrorTable[iErrorTable].dwMinorVersion,
  7018. g_KnownErrorTable[iErrorTable].dwServicePackMajor,
  7019. g_KnownErrorTable[iErrorTable].dwServicePackMinor))
  7020. {
  7021. //
  7022. // This error is old. Increase the error level.
  7023. //
  7024. dwActualErrorLevel = IncrementErrorLevel(dwActualErrorLevel);
  7025. }
  7026. }
  7027. }
  7028. return dwActualErrorLevel;
  7029. }
  7030. //
  7031. // Function: IsAPIRelevant
  7032. // Purpose: Determine if the test case supplied in the pTableEntry parameter
  7033. // is appropriate for the supplied dwCSPClass and dwTestLevel.
  7034. //
  7035. BOOL IsAPIRelevant(
  7036. IN DWORD dwCSPClass,
  7037. IN DWORD dwTestLevel,
  7038. IN DWORD dwTestType,
  7039. IN PTESTTABLEENTRY pTableEntry)
  7040. {
  7041. DWORD dwAPITestLevels = 0;
  7042. switch (dwCSPClass)
  7043. {
  7044. case CLASS_SIG_ONLY:
  7045. {
  7046. dwAPITestLevels = pTableEntry->dwClassSigOnly;
  7047. break;
  7048. }
  7049. case CLASS_SIG_KEYX:
  7050. {
  7051. dwAPITestLevels = pTableEntry->dwClassSigKeyX;
  7052. break;
  7053. }
  7054. case CLASS_FULL:
  7055. {
  7056. dwAPITestLevels = pTableEntry->dwClassFull;
  7057. break;
  7058. }
  7059. case CLASS_OPTIONAL:
  7060. {
  7061. dwAPITestLevels = pTableEntry->dwClassOptional;
  7062. break;
  7063. }
  7064. default:
  7065. {
  7066. return FALSE;
  7067. }
  7068. }
  7069. if ((dwTestType == pTableEntry->dwTestType) &&
  7070. (dwAPITestLevels & dwTestLevel))
  7071. {
  7072. return TRUE;
  7073. }
  7074. return FALSE;
  7075. }
  7076. //
  7077. // Function: InitTestCase
  7078. // Purpose: Initialize a TESTCASE structure with the most typical default
  7079. // values.
  7080. //
  7081. void InitTestCase(PTESTCASE pTestCase)
  7082. {
  7083. //
  7084. // Initialize the TESTCASE structure for this API test
  7085. //
  7086. memset(pTestCase, 0, sizeof(TESTCASE));
  7087. //
  7088. // For now, set a low-enough error level so that the test will
  7089. // continue after most failed test cases.
  7090. //
  7091. // The pTestCase->dwErrorLevel is where most of the control of the flow of the
  7092. // test (with respect to error handling) is afforded. The flags used here should
  7093. // be a function of the environment in which the test is being run, and should
  7094. // be optionally controllable by command-line.
  7095. //
  7096. pTestCase->dwErrorLevel = CSP_ERROR_CONTINUE;
  7097. pTestCase->KnownErrorID = KNOWN_ERROR_UNKNOWN;
  7098. }
  7099. //
  7100. // Function: RunTestsByClassAndLevel
  7101. // Purpose: For a given CSP Class and Test Level, run the appropriate set
  7102. // of API tests, per the test mappings in the
  7103. // g_TestFunctionMappings table.
  7104. //
  7105. BOOL RunTestsByClassAndLevel(
  7106. IN DWORD dwCSPClass,
  7107. IN DWORD dwTestLevel,
  7108. IN DWORD dwTestType,
  7109. PCSPINFO pCspInfo)
  7110. {
  7111. BOOL fErrorOccurred = FALSE;
  7112. int iAPI = 0;
  7113. //
  7114. // For each (CSP_CLASS, TEST_LEVEL) combination, run through
  7115. // each of the entries in the test table above.
  7116. //
  7117. for (
  7118. iAPI = 0;
  7119. iAPI < (sizeof(g_TestFunctionMappings) / sizeof(TESTTABLEENTRY));
  7120. ++iAPI)
  7121. {
  7122. //
  7123. // Determine if the current TESTTABLEENTRY in TestFunctionMappings is
  7124. // applicable for the current (dwCSPClass, dwTestLevel) combination.
  7125. //
  7126. if (IsAPIRelevant(
  7127. dwCSPClass,
  7128. dwTestLevel,
  7129. dwTestType,
  7130. &(g_TestFunctionMappings[iAPI])))
  7131. {
  7132. if (LogBeginAPI(
  7133. g_TestFunctionMappings[iAPI].ApiName,
  7134. dwTestType))
  7135. {
  7136. //
  7137. // Initialize the test TESTCASE member of the CSPINFO struct
  7138. // to typical values.
  7139. //
  7140. InitTestCase(&(pCspInfo->TestCase));
  7141. pCspInfo->TestCase.dwTestLevel = dwTestLevel;
  7142. pCspInfo->TestCase.dwCSPClass = dwCSPClass;
  7143. pCspInfo->TestCase.fSmartCardCSP = pCspInfo->fSmartCardCSP;
  7144. if (TEST_CASES_POSITIVE == dwTestType)
  7145. {
  7146. pCspInfo->TestCase.fExpectSuccess = TRUE;
  7147. }
  7148. //
  7149. // Run the current test case
  7150. //
  7151. if (! (*(g_TestFunctionMappings[iAPI].pTestFunc))(pCspInfo))
  7152. {
  7153. fErrorOccurred = TRUE;
  7154. }
  7155. LogEndAPI(
  7156. g_TestFunctionMappings[iAPI].ApiName,
  7157. dwTestType);
  7158. }
  7159. }
  7160. }
  7161. return ! fErrorOccurred;
  7162. }
  7163. //
  7164. // Function: RunStandardTests
  7165. // Purpose: Iterate through the [CSP_CLASS, TEST_LEVEL] combinations for each
  7166. // test listed in the g_TestFunctionMappings table.
  7167. //
  7168. BOOL RunStandardTests(
  7169. IN DWORD dwTargetCSPClass,
  7170. IN DWORD dwTestType,
  7171. PCSPINFO pCspInfo)
  7172. {
  7173. BOOL fErrorOccurred = FALSE;
  7174. DWORD dwCSPClass = 0;
  7175. DWORD dwTestLevel = 0;
  7176. int iCSPClass = 0;
  7177. int iTestLevel = 0;
  7178. dwCSPClass = g_rgCspClasses[iCSPClass];
  7179. //
  7180. // Run through each possible CSP_CLASS but stop after the CSP_CLASS
  7181. // specified by the dwTargetCSPClass parameter.
  7182. //
  7183. while ( LogBeginCSPClass(dwCSPClass))
  7184. {
  7185. //
  7186. // Run through each TEST_LEVEL for the current CSP_CLASS
  7187. //
  7188. for ( iTestLevel = 0;
  7189. iTestLevel < (sizeof(g_rgTestLevels) / sizeof(dwTestLevel));
  7190. ++iTestLevel)
  7191. {
  7192. dwTestLevel = g_rgTestLevels[iTestLevel];
  7193. if (LogBeginTestLevel(dwTestLevel))
  7194. {
  7195. if (! RunTestsByClassAndLevel(
  7196. dwCSPClass,
  7197. dwTestLevel,
  7198. dwTestType,
  7199. pCspInfo))
  7200. {
  7201. fErrorOccurred = TRUE;
  7202. }
  7203. LogEndTestLevel(dwTestLevel);
  7204. }
  7205. }
  7206. LogEndCSPClass(dwCSPClass);
  7207. if (dwCSPClass == dwTargetCSPClass)
  7208. {
  7209. break;
  7210. }
  7211. else
  7212. {
  7213. iCSPClass++;
  7214. dwCSPClass = g_rgCspClasses[iCSPClass];
  7215. }
  7216. }
  7217. return ! fErrorOccurred;
  7218. }
  7219. //
  7220. // Function: RunPositiveTests
  7221. // Purpose: Run all of the positive test cases for a CSP of the
  7222. // specified class.
  7223. //
  7224. BOOL RunPositiveTests(DWORD dwTargetCSPClass, PCSPINFO pCSPInfo)
  7225. {
  7226. return RunStandardTests(dwTargetCSPClass, TEST_CASES_POSITIVE, pCSPInfo);
  7227. }
  7228. //
  7229. // Function: RunNegativeTests
  7230. // Purpose: Run all of the negative test cases for a CSP of the
  7231. // specified class.
  7232. //
  7233. BOOL RunNegativeTests(DWORD dwTargetCSPClass, PCSPINFO pCSPInfo)
  7234. {
  7235. return RunStandardTests(dwTargetCSPClass, TEST_CASES_NEGATIVE, pCSPInfo);
  7236. }
  7237. //
  7238. // Function: RunScenarioTests
  7239. // Purpose: Run all of the CSP Test Suite Scenario tests.
  7240. //
  7241. BOOL RunScenarioTests(PCSPINFO pCSPInfo)
  7242. {
  7243. BOOL fErrorOccurred = FALSE;
  7244. int iScenarioTable = 0;
  7245. for (
  7246. iScenarioTable = 0;
  7247. iScenarioTable < (sizeof(g_ScenarioTestTable) / sizeof(BASIC_TEST_TABLE));
  7248. iScenarioTable++)
  7249. {
  7250. InitTestCase(&(pCSPInfo->TestCase));
  7251. pCSPInfo->TestCase.fExpectSuccess = TRUE;
  7252. pCSPInfo->TestCase.dwErrorLevel = CSP_ERROR_API;
  7253. LogBeginScenarioTest(g_ScenarioTestTable[iScenarioTable].pwszDescription);
  7254. //
  7255. // Run the current test case
  7256. //
  7257. if (! (*(g_ScenarioTestTable[iScenarioTable].pTestFunc))(pCSPInfo))
  7258. {
  7259. fErrorOccurred = TRUE;
  7260. }
  7261. LogEndScenarioTest();
  7262. }
  7263. return ! fErrorOccurred;
  7264. }
  7265. //
  7266. // Function: RunInteropTests
  7267. // Purpose: Run all of the CSP Test Suite Interoperability tests.
  7268. //
  7269. BOOL RunInteropTests(PCSPINFO pCSPInfo)
  7270. {
  7271. BOOL fErrorOccurred = FALSE;
  7272. int iInteropTable = 0;
  7273. for (
  7274. iInteropTable = 0;
  7275. iInteropTable < (sizeof(g_InteropTestTable) / sizeof(BASIC_TEST_TABLE));
  7276. iInteropTable++)
  7277. {
  7278. InitTestCase(&(pCSPInfo->TestCase));
  7279. pCSPInfo->TestCase.fExpectSuccess = TRUE;
  7280. pCSPInfo->TestCase.dwErrorLevel = CSP_ERROR_API;
  7281. LogBeginInteropTest(g_InteropTestTable[iInteropTable].pwszDescription);
  7282. //
  7283. // Run the current test case
  7284. //
  7285. if (! (*(g_InteropTestTable[iInteropTable].pTestFunc))(pCSPInfo))
  7286. {
  7287. fErrorOccurred = TRUE;
  7288. }
  7289. LogEndInteropTest();
  7290. }
  7291. return ! fErrorOccurred;
  7292. }
  7293. //
  7294. // Function: CleanupCspInfo
  7295. // Purpose: Perform any cleanup or memory-freeing necessary for the
  7296. // CSPINFO struct.
  7297. //
  7298. void CleanupCspInfo(PCSPINFO pCSPInfo)
  7299. {
  7300. PALGNODE pAlgNode = NULL;
  7301. if (pCSPInfo->pwszCSPName)
  7302. {
  7303. free(pCSPInfo->pwszCSPName);
  7304. }
  7305. //
  7306. // Free the linked ALGNODE list
  7307. //
  7308. while (pCSPInfo->pAlgList)
  7309. {
  7310. pAlgNode = pCSPInfo->pAlgList->pAlgNodeNext;
  7311. free(pCSPInfo->pAlgList);
  7312. pCSPInfo->pAlgList = pAlgNode;
  7313. }
  7314. }
  7315. //
  7316. // Function: GetProviderType
  7317. // Purpose: Given the name of the CSP under test, call CryptEnumProviders
  7318. // until that CSP is found. Return the type for that CSP to the caller.
  7319. //
  7320. BOOL GetProviderType(
  7321. IN LPWSTR pwszProvName,
  7322. OUT PDWORD pdwProvType)
  7323. {
  7324. WCHAR rgProvName [MAX_PATH * sizeof(WCHAR)];
  7325. DWORD cb = sizeof(rgProvName);
  7326. DWORD dwIndex = 0;
  7327. memset(rgProvName, 0, sizeof(rgProvName));
  7328. while (CryptEnumProviders(
  7329. dwIndex,
  7330. NULL,
  7331. 0,
  7332. pdwProvType,
  7333. rgProvName,
  7334. &cb))
  7335. {
  7336. if (0 == wcscmp(rgProvName, pwszProvName))
  7337. {
  7338. return TRUE;
  7339. }
  7340. else
  7341. {
  7342. dwIndex++;
  7343. cb = sizeof(rgProvName);
  7344. }
  7345. }
  7346. return FALSE;
  7347. }
  7348. //
  7349. // Function: DeleteDefaultContainer
  7350. // Purpose: Delete the default key container for the CSP
  7351. // under test.
  7352. //
  7353. BOOL DeleteDefaultContainer(PCSPINFO pCSPInfo)
  7354. {
  7355. HCRYPTPROV hProv = 0;
  7356. return CryptAcquireContext(
  7357. &hProv,
  7358. NULL,
  7359. pCSPInfo->pwszCSPName,
  7360. pCSPInfo->dwExternalProvType,
  7361. CRYPT_DELETEKEYSET);
  7362. }
  7363. //
  7364. // Function: DeleteAllContainers
  7365. // Purpose: Delete all key containers for the CSP
  7366. // under test.
  7367. //
  7368. BOOL DeleteAllContainers(PCSPINFO pCSPInfo)
  7369. {
  7370. HCRYPTPROV hDefProv = 0;
  7371. HCRYPTPROV hProv = 0;
  7372. CHAR rgszContainer[MAX_PATH];
  7373. LPWSTR pwszContainer = NULL;
  7374. DWORD cbContainer = MAX_PATH;
  7375. BOOL fCreatedDefaultKeyset = FALSE;
  7376. DWORD dwFlags = CRYPT_FIRST;
  7377. if (! CryptAcquireContext(
  7378. &hDefProv, NULL, pCSPInfo->pwszCSPName,
  7379. pCSPInfo->dwExternalProvType, 0))
  7380. {
  7381. return FALSE;
  7382. }
  7383. while (CryptGetProvParam(
  7384. hDefProv, PP_ENUMCONTAINERS, (PBYTE) rgszContainer,
  7385. &cbContainer, dwFlags))
  7386. {
  7387. if (dwFlags)
  7388. {
  7389. dwFlags = 0;
  7390. }
  7391. pwszContainer = MkWStr(rgszContainer);
  7392. if (! CryptAcquireContext(
  7393. &hProv, pwszContainer, pCSPInfo->pwszCSPName,
  7394. pCSPInfo->dwExternalProvType, CRYPT_DELETEKEYSET))
  7395. {
  7396. return FALSE;
  7397. }
  7398. cbContainer = sizeof(rgszContainer);
  7399. free(pwszContainer);
  7400. }
  7401. if (! CryptReleaseContext(hDefProv, 0))
  7402. {
  7403. return FALSE;
  7404. }
  7405. return TRUE;
  7406. }
  7407. //
  7408. // Function: main
  7409. // Purpose: Test entry function
  7410. //
  7411. int __cdecl wmain(int argc, WCHAR *wargv[])
  7412. {
  7413. BOOL fInvalidArgs = FALSE;
  7414. int iCspTypeTable = 0;
  7415. DWORD dwTestsToRun = TEST_CASES_POSITIVE;
  7416. BOOL fDeleteDefaultContainer = FALSE;
  7417. int iCsp = 0;
  7418. DWORD dwProvType = 0;
  7419. DWORD cbCspName = 0;
  7420. DWORD dwError = 0;
  7421. WCHAR rgwszCsp[ MAX_PATH ];
  7422. WCHAR rgwszOption[ MAX_PATH ];
  7423. WCHAR rgwsz[BUFFER_SIZE];
  7424. CSPINFO CspInfo;
  7425. LOGINIT_INFO LogInitInfo;
  7426. BOOL fDeleteAllContainers = FALSE;
  7427. memset(&CspInfo, 0, sizeof(CspInfo));
  7428. memset(&LogInitInfo, 0, sizeof(LogInitInfo));
  7429. if (argc < MINIMUM_ARGC)
  7430. {
  7431. fInvalidArgs = TRUE;
  7432. goto Ret;
  7433. }
  7434. argc--;
  7435. wargv++;
  7436. while (argc)
  7437. {
  7438. if (L'-' != wargv[0][0])
  7439. {
  7440. fInvalidArgs = TRUE;
  7441. goto Ret;
  7442. }
  7443. switch (wargv[0][1])
  7444. {
  7445. case L't':
  7446. {
  7447. // Assign which test to run
  7448. --argc;
  7449. ++wargv;
  7450. dwTestsToRun = _wtoi(*wargv);
  7451. break;
  7452. }
  7453. case L'c':
  7454. {
  7455. // Assign CSP Name
  7456. --argc;
  7457. ++wargv;
  7458. cbCspName = 0;
  7459. GetNextRegisteredCSP(
  7460. NULL,
  7461. &cbCspName,
  7462. &(CspInfo.dwExternalProvType),
  7463. _wtoi(*wargv));
  7464. if (NULL == (CspInfo.pwszCSPName = (LPWSTR) malloc(cbCspName)))
  7465. {
  7466. wprintf(L"Insufficient memory\n");
  7467. goto Ret;
  7468. }
  7469. dwError = GetNextRegisteredCSP(
  7470. CspInfo.pwszCSPName,
  7471. &cbCspName,
  7472. &(CspInfo.dwExternalProvType),
  7473. _wtoi(*wargv));
  7474. if (ERROR_SUCCESS != dwError)
  7475. {
  7476. fInvalidArgs = TRUE;
  7477. goto Ret;
  7478. }
  7479. break;
  7480. }
  7481. case L'i':
  7482. {
  7483. // Assign interop CSP name
  7484. --argc;
  7485. ++wargv;
  7486. cbCspName = 0;
  7487. GetNextRegisteredCSP(
  7488. NULL,
  7489. &cbCspName,
  7490. &(LogInitInfo.dwInteropCSPExternalType),
  7491. _wtoi(*wargv));
  7492. if (NULL == (LogInitInfo.pwszInteropCSPName = (LPWSTR) malloc(cbCspName)))
  7493. {
  7494. wprintf(L"Insufficient memory\n");
  7495. goto Ret;
  7496. }
  7497. dwError = GetNextRegisteredCSP(
  7498. LogInitInfo.pwszInteropCSPName,
  7499. &cbCspName,
  7500. &(LogInitInfo.dwInteropCSPExternalType),
  7501. _wtoi(*wargv));
  7502. if (ERROR_SUCCESS != dwError)
  7503. {
  7504. fInvalidArgs = TRUE;
  7505. goto Ret;
  7506. }
  7507. break;
  7508. }
  7509. case L'd':
  7510. {
  7511. // Option to delete the default container
  7512. fDeleteDefaultContainer = TRUE;
  7513. break;
  7514. }
  7515. case L'a':
  7516. {
  7517. // Option to delete all containers
  7518. fDeleteAllContainers = TRUE;
  7519. break;
  7520. }
  7521. default:
  7522. {
  7523. fInvalidArgs = TRUE;
  7524. goto Ret;
  7525. }
  7526. }
  7527. argc--;
  7528. wargv++;
  7529. }
  7530. if ( (0 != argc) ||
  7531. (NULL == CspInfo.pwszCSPName))
  7532. {
  7533. // Bad combination of args
  7534. fInvalidArgs = TRUE;
  7535. goto Ret;
  7536. }
  7537. //
  7538. // If no interop CSP was specified, look for a default
  7539. //
  7540. if ( TEST_CASES_INTEROP == dwTestsToRun &&
  7541. NULL == LogInitInfo.pwszInteropCSPName)
  7542. {
  7543. if (! CryptGetDefaultProvider(
  7544. CspInfo.dwExternalProvType,
  7545. NULL,
  7546. CRYPT_MACHINE_DEFAULT,
  7547. NULL,
  7548. &cbCspName))
  7549. {
  7550. printf("No default interop provider found for this CSP type\n");
  7551. fInvalidArgs = TRUE;
  7552. goto Ret;
  7553. }
  7554. if (NULL == (LogInitInfo.pwszInteropCSPName = (LPWSTR) malloc(cbCspName)))
  7555. {
  7556. wprintf(L"Insufficient memory\n");
  7557. goto Ret;
  7558. }
  7559. if (! CryptGetDefaultProvider(
  7560. CspInfo.dwExternalProvType,
  7561. NULL,
  7562. CRYPT_MACHINE_DEFAULT,
  7563. LogInitInfo.pwszInteropCSPName,
  7564. &cbCspName))
  7565. {
  7566. printf("No default interop provider found for this CSP type\n");
  7567. fInvalidArgs = TRUE;
  7568. goto Ret;
  7569. }
  7570. LogInitInfo.dwInteropCSPExternalType = CspInfo.dwExternalProvType;
  7571. }
  7572. //
  7573. // Search for an entry for the external CSP type in the test suite
  7574. // CspTypeTable. The table provides mappings from external types to
  7575. // internal types used by the test.
  7576. //
  7577. while ( iCspTypeTable < (sizeof(g_CspTypeTable) / sizeof(CSPTYPEMAP)) &&
  7578. g_CspTypeTable[iCspTypeTable].dwExternalProvType != CspInfo.dwExternalProvType)
  7579. {
  7580. iCspTypeTable++;
  7581. }
  7582. //
  7583. // Check that the CSP type was found in the g_CspTypeTable
  7584. //
  7585. if (iCspTypeTable == (sizeof(g_CspTypeTable) / sizeof(CSPTYPEMAP)))
  7586. {
  7587. fInvalidArgs = TRUE;
  7588. goto Ret;
  7589. }
  7590. CspInfo.dwInternalProvType = g_CspTypeTable[iCspTypeTable].dwProvType;
  7591. CspInfo.dwCSPInternalClass = g_CspTypeTable[iCspTypeTable].dwCSPClass;
  7592. LogInitInfo.dwCSPExternalType = CspInfo.dwExternalProvType;
  7593. LogInitInfo.dwCSPInternalClass = g_CspTypeTable[iCspTypeTable].dwCSPClass;
  7594. LogInitInfo.dwCSPInternalType = g_CspTypeTable[iCspTypeTable].dwProvType;
  7595. LogInitInfo.pwszCSPName = CspInfo.pwszCSPName;
  7596. // Initialize logging routines
  7597. LogInit(&LogInitInfo);
  7598. //
  7599. // Log the settings being used (including command-line
  7600. // options that were specified).
  7601. //
  7602. swprintf(
  7603. rgwszOption,
  7604. L"CSP under test: %s",
  7605. CspInfo.pwszCSPName);
  7606. LogUserOption(rgwszOption);
  7607. swprintf(
  7608. rgwszOption,
  7609. L"CSP type: %s",
  7610. g_CspTypeTable[iCspTypeTable].pwszExternalProvType);
  7611. LogUserOption(rgwszOption);
  7612. if (TEST_CASES_INTEROP == dwTestsToRun)
  7613. {
  7614. swprintf(
  7615. rgwszOption,
  7616. L"Interop CSP: %s",
  7617. LogInitInfo.pwszInteropCSPName);
  7618. LogUserOption(rgwszOption);
  7619. }
  7620. TestCaseTypeToString(dwTestsToRun, rgwsz);
  7621. swprintf(
  7622. rgwszOption,
  7623. L"Test case set: %s",
  7624. rgwsz);
  7625. LogUserOption(rgwszOption);
  7626. //
  7627. // Delete default container, if requested
  7628. //
  7629. if (fDeleteDefaultContainer)
  7630. {
  7631. LogInfo(L"Deleting default container...");
  7632. if (DeleteDefaultContainer(&CspInfo))
  7633. {
  7634. LogInfo(L"...Success");
  7635. }
  7636. else
  7637. {
  7638. swprintf(
  7639. rgwszOption,
  7640. L"...Failed 0x%x",
  7641. GetLastError());
  7642. LogInfo(rgwszOption);
  7643. }
  7644. LogClose();
  7645. goto Ret;
  7646. }
  7647. //
  7648. // Delete all containers, if requested
  7649. //
  7650. if (fDeleteAllContainers)
  7651. {
  7652. LogInfo(L"Deleting all containers...");
  7653. if (DeleteAllContainers(&CspInfo))
  7654. {
  7655. LogInfo(L"...Success");
  7656. }
  7657. else
  7658. {
  7659. swprintf(
  7660. rgwszOption,
  7661. L"...Failed 0x%x",
  7662. GetLastError());
  7663. LogInfo(rgwszOption);
  7664. }
  7665. LogClose();
  7666. goto Ret;
  7667. }
  7668. //
  7669. // Run the set of tests requested by the user
  7670. //
  7671. switch (dwTestsToRun)
  7672. {
  7673. case TEST_CASES_POSITIVE:
  7674. {
  7675. RunPositiveTests(
  7676. g_CspTypeTable[iCspTypeTable].dwCSPClass,
  7677. &CspInfo);
  7678. break;
  7679. }
  7680. case TEST_CASES_NEGATIVE:
  7681. {
  7682. RunNegativeTests(
  7683. g_CspTypeTable[iCspTypeTable].dwCSPClass,
  7684. &CspInfo);
  7685. break;
  7686. }
  7687. case TEST_CASES_SCENARIO:
  7688. {
  7689. RunScenarioTests(&CspInfo);
  7690. break;
  7691. }
  7692. case TEST_CASES_INTEROP:
  7693. {
  7694. RunInteropTests(&CspInfo);
  7695. break;
  7696. }
  7697. }
  7698. LogClose();
  7699. Ret:
  7700. CleanupCspInfo(&CspInfo);
  7701. if (LogInitInfo.pwszInteropCSPName)
  7702. {
  7703. free(LogInitInfo.pwszInteropCSPName);
  7704. }
  7705. if (fInvalidArgs)
  7706. {
  7707. Usage();
  7708. wprintf(L"\nRegistered CSP's:\n");
  7709. cbCspName = MAX_PATH;
  7710. for ( iCsp = 0;
  7711. ERROR_SUCCESS == GetNextRegisteredCSP(
  7712. rgwszCsp,
  7713. &cbCspName,
  7714. &dwProvType,
  7715. ENUMERATE_REGISTERED_CSP);
  7716. iCsp++)
  7717. {
  7718. wprintf(L" %d: %s, Type %d\n", iCsp, rgwszCsp, dwProvType);
  7719. }
  7720. exit(1);
  7721. }
  7722. return 0;
  7723. }