Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1196 lines
42 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: tcertper.cpp
  8. //
  9. // Contents: Cert Performance Tests
  10. //
  11. // See Usage() for a list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 30-Nov-97 philh created
  17. //--------------------------------------------------------------------------
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include "wincrypt.h"
  21. #include "wintrust.h"
  22. #include "softpub.h"
  23. #include "mscat.h"
  24. #include "certtest.h"
  25. #include "unicode.h"
  26. #include "certprot.h"
  27. #include "certtest.h"
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <memory.h>
  32. #include <time.h>
  33. static void Usage(void)
  34. {
  35. printf("Usage: tcertper [options] <TestName> [<Para1> <Para2>]\n");
  36. printf("\n");
  37. printf(" -UseIE4Trust\n");
  38. printf(" -NoIE4Chain\n");
  39. printf(" -CacheEndCert\n");
  40. printf("\n");
  41. printf(" -NoEntry\n");
  42. printf(" -NoMsg\n");
  43. printf("\n");
  44. printf(" -AuthPolicy\n");
  45. printf(" -TSPolicy\n");
  46. printf("\n");
  47. printf(" -Pause\n");
  48. printf("\n");
  49. printf("Options are:\n");
  50. printf(" -u<OID String> - Usage OID string -u1.3.6.1.5.5.7.3.3\n");
  51. printf(" -h - This message\n");
  52. printf(" -i<number> - Iterations (default to 1000)\n");
  53. printf("TestNames (case insensitive):\n");
  54. printf(" NULL\n");
  55. printf(" CreateCertContext <cert filename>\n");
  56. printf(" VerifyCertSignature <cert filename> [<issuer filename>]\n");
  57. printf(" CreateCRLContext <CRL filename>\n");
  58. printf(" CreateCTLContext <CTL filename>\n");
  59. printf(" CreateSortedCTLContext <CTL filename>\n");
  60. printf(" CreateFastCTLContext <CTL filename>\n");
  61. printf(" DecodePKCS7 <CTL filename>\n");
  62. printf(" StreamDecodePKCS7 <CTL filename>\n");
  63. printf(" GetCertProperty <cert filename>\n");
  64. printf(" DecodeOID <OID>\n");
  65. printf(" FindExtension <cert filename> <OID>\n");
  66. printf(" DecodeExtension <cert filename> <OID>\n");
  67. printf(" WVTCert <cert filename> [<AdditionalFileStore>]\n");
  68. printf(" WVTFile <filename>\n");
  69. printf(" WVTCat <cat filename> <member filename>\n");
  70. printf(" CertChain <cert filename> [<AdditionalFileStore>]\n");
  71. printf("\n");
  72. }
  73. #define NULL_TEST_ID 1
  74. #define CREATE_CERT_CONTEXT_TEST_ID 2
  75. #define VERIFY_CERT_SIGNATURE_TEST_ID 3
  76. #define CREATE_CTL_CONTEXT_TEST_ID 4
  77. #define GET_CERT_PROPERTY_TEST_ID 5
  78. #define DECODE_OID_TEST_ID 6
  79. #define FIND_EXTENSION_TEST_ID 7
  80. #define DECODE_EXTENSION_TEST_ID 8
  81. #define CREATE_SORTED_CTL_CONTEXT_TEST_ID 9
  82. #define DECODE_PKCS7_TEST_ID 10
  83. #define STREAM_DECODE_PKCS7_TEST_ID 11
  84. #define WVT_CERT_TEST_ID 12
  85. #define WVT_FILE_TEST_ID 13
  86. #define CERT_CHAIN_TEST_ID 14
  87. #define CREATE_CRL_CONTEXT_TEST_ID 15
  88. #define WVT_CAT_TEST_ID 16
  89. #define CREATE_FAST_CTL_CONTEXT_TEST_ID 17
  90. static struct
  91. {
  92. LPCSTR pszName;
  93. DWORD dwID;
  94. } Tests[] = {
  95. "NULL", NULL_TEST_ID,
  96. "CreateCertContext", CREATE_CERT_CONTEXT_TEST_ID,
  97. "VerifyCertSignature", VERIFY_CERT_SIGNATURE_TEST_ID,
  98. "CreateCRLContext", CREATE_CRL_CONTEXT_TEST_ID,
  99. "CreateCTLContext", CREATE_CTL_CONTEXT_TEST_ID,
  100. "GetCertProperty", GET_CERT_PROPERTY_TEST_ID,
  101. "DecodeOID", DECODE_OID_TEST_ID,
  102. "FindExtension", FIND_EXTENSION_TEST_ID,
  103. "DecodeExtension", DECODE_EXTENSION_TEST_ID,
  104. "CreateSortedCTLContext", CREATE_SORTED_CTL_CONTEXT_TEST_ID,
  105. "CreateFastCTLContext", CREATE_FAST_CTL_CONTEXT_TEST_ID,
  106. "DecodePKCS7", DECODE_PKCS7_TEST_ID,
  107. "StreamDecodePKCS7", STREAM_DECODE_PKCS7_TEST_ID,
  108. "WVTCert", WVT_CERT_TEST_ID,
  109. "WVTFile", WVT_FILE_TEST_ID,
  110. "WVTCat", WVT_CAT_TEST_ID,
  111. "CertChain", CERT_CHAIN_TEST_ID,
  112. };
  113. #define NTESTS (sizeof(Tests)/sizeof(Tests[0]))
  114. static BOOL WINAPI StreamOutputCallback(
  115. IN const void *pvArg,
  116. IN BYTE *pbData,
  117. IN DWORD cbData,
  118. IN BOOL fFinal
  119. )
  120. {
  121. #if 0
  122. printf("StreamOutputCallback:: pbData: 0x%x cbData: 0x%x fFinal: 0x%x\n",
  123. pbData, cbData, fFinal);
  124. #endif
  125. return TRUE;
  126. }
  127. static PCCERT_CONTEXT ReadCert(
  128. IN LPCSTR pszCert
  129. )
  130. {
  131. BOOL fResult;
  132. BYTE *pbEncoded;
  133. DWORD cbEncoded;
  134. PCCERT_CONTEXT pCert;
  135. if (!ReadDERFromFile(pszCert, &pbEncoded, &cbEncoded)) {
  136. PrintLastError("ReadCert");
  137. return NULL;
  138. }
  139. pCert = CertCreateCertificateContext(
  140. dwCertEncodingType,
  141. pbEncoded,
  142. cbEncoded
  143. );
  144. if (pCert == NULL)
  145. PrintLastError("CertCreateCertificateContext");
  146. TestFree(pbEncoded);
  147. return pCert;
  148. }
  149. int _cdecl main(int argc, char * argv[])
  150. {
  151. int status;
  152. #define TEST_NAME_INDEX 0
  153. #define CERT_FILENAME_INDEX 1
  154. #define CTL_FILENAME_INDEX 1
  155. #define CRL_FILENAME_INDEX 1
  156. #define PKCS7_FILENAME_INDEX 1
  157. #define OID_INDEX 1
  158. #define WVT_FILENAME_INDEX 1
  159. #define ISSUER_FILENAME_INDEX 2
  160. #define CERT_OID_INDEX 2
  161. #define STORE_FILENAME_INDEX 2
  162. #define WVT_CAT_FILENAME_INDEX 1
  163. #define WVT_MEMBER_FILENAME_INDEX 2
  164. #define MAX_NAME_CNT 3
  165. DWORD dwNameCnt = 0;
  166. LPCSTR rgpszName[MAX_NAME_CNT];
  167. LPCSTR pszTestName; // not allocated
  168. DWORD dwIterations = 1000;
  169. DWORD i;
  170. DWORD dwTestID;
  171. BOOL fPause = FALSE;
  172. BYTE *pbEncoded = NULL;
  173. DWORD cbEncoded;
  174. BYTE *pbEncodedCert = NULL;
  175. DWORD cbEncodedCert;
  176. PCCERT_CONTEXT pCert = NULL;
  177. PCCERT_CONTEXT pIssuer = NULL;
  178. PCCTL_CONTEXT pCtl = NULL;
  179. PCCRL_CONTEXT pCrl = NULL;
  180. HCRYPTMSG hMsg = NULL;
  181. CMSG_STREAM_INFO StreamInfo;
  182. LPCSTR pszOID;
  183. BYTE rgbEncodedAttr[512];
  184. DWORD cbEncodedAttr;
  185. BYTE rgbAttr[512];
  186. DWORD cbAttr;
  187. PCRYPT_ATTRIBUTE pAttr = (PCRYPT_ATTRIBUTE) rgbAttr;
  188. DWORD dwProp;
  189. DWORD cbData;
  190. PCERT_EXTENSION pExt;
  191. DWORD cbExt;
  192. BYTE rgbExt[8192];
  193. SYSTEMTIME stFirst, stStart, stEnd;
  194. FILETIME ftFirst, ftStart, ftEnd;
  195. _int64 DeltaTime;
  196. int Microseconds;
  197. int Milliseconds;
  198. int Seconds;
  199. DWORD dwCreateChainFlags = 0;
  200. DWORD dwError;
  201. DWORD dwFirstError;
  202. LONG lStatus;
  203. LONG lFirstStatus;
  204. LPSTR pszUsageOID = NULL; // not allocated
  205. LPSTR pszSignerUsage = szOID_KP_CTL_USAGE_SIGNING;
  206. GUID wvtFileActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  207. GUID wvtCertActionID = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
  208. GUID wvtDriverActionID = DRIVER_ACTION_VERIFY;
  209. GUID *pwvtActionID;
  210. WINTRUST_FILE_INFO wvtFileInfo;
  211. memset(&wvtFileInfo, 0, sizeof(wvtFileInfo));
  212. wvtFileInfo.cbStruct = sizeof(wvtFileInfo);
  213. wvtFileInfo.pcwszFilePath = NULL;
  214. HCERTSTORE hAdditionalStore = NULL;
  215. PCCERT_CHAIN_CONTEXT pChainContext = NULL;
  216. WINTRUST_CERT_INFO wvtCertInfo;
  217. memset(&wvtCertInfo, 0, sizeof(wvtCertInfo));
  218. wvtCertInfo.cbStruct = sizeof(wvtCertInfo);
  219. wvtCertInfo.psCertContext = NULL;
  220. wvtCertInfo.chStores = 0;
  221. wvtCertInfo.pahStores = &hAdditionalStore;
  222. wvtCertInfo.dwFlags = 0;
  223. wvtCertInfo.pcwszDisplayName = L"Cert Display Name";
  224. WINTRUST_DATA wvtData;
  225. memset(&wvtData, 0, sizeof(wvtData));
  226. wvtData.cbStruct = sizeof(wvtData);
  227. wvtData.pPolicyCallbackData = NULL;
  228. wvtData.dwUIChoice = WTD_UI_NONE;
  229. wvtData.fdwRevocationChecks = WTD_REVOKE_NONE;
  230. wvtData.dwUnionChoice = WTD_CHOICE_CERT;
  231. wvtData.pCert = &wvtCertInfo;
  232. wvtData.dwStateAction = WTD_STATEACTION_IGNORE;
  233. wvtData.hWVTStateData = NULL;
  234. wvtData.dwProvFlags = 0;
  235. WINTRUST_CATALOG_INFO wvtCat;
  236. memset(&wvtCat, 0, sizeof(wvtCat));
  237. wvtCat.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
  238. DWORD cbCatHash;
  239. BYTE rgbCatHash[40];
  240. CERT_CHAIN_PARA ChainPara;
  241. memset(&ChainPara, 0, sizeof(ChainPara));
  242. ChainPara.cbSize = sizeof(ChainPara);
  243. CERT_CHAIN_POLICY_PARA ChainPolicyPara;
  244. memset(&ChainPolicyPara, 0, sizeof(ChainPolicyPara));
  245. ChainPolicyPara.cbSize = sizeof(ChainPolicyPara);
  246. CERT_CHAIN_POLICY_STATUS ChainPolicyStatus;
  247. memset(&ChainPolicyStatus, 0, sizeof(ChainPolicyStatus));
  248. ChainPolicyStatus.cbSize = sizeof(ChainPolicyStatus);
  249. LPCSTR pszChainPolicyOID = CERT_CHAIN_POLICY_BASE;
  250. DWORD dwFastCtlFlags = 0;
  251. while (--argc>0) {
  252. if (**++argv == '-')
  253. {
  254. if (0 == _stricmp(argv[0]+1, "UseIE4Trust")) {
  255. wvtData.dwProvFlags |= WTD_USE_IE4_TRUST_FLAG;
  256. } else if (0 == _stricmp(argv[0]+1, "NoIE4Chain")) {
  257. wvtData.dwProvFlags |= WTD_NO_IE4_CHAIN_FLAG;
  258. } else if (0 == _stricmp(argv[0]+1, "CacheEndCert")) {
  259. dwCreateChainFlags |= CERT_CHAIN_CACHE_END_CERT;
  260. } else if (0 == _stricmp(argv[0]+1, "AuthPolicy")) {
  261. pszChainPolicyOID = CERT_CHAIN_POLICY_AUTHENTICODE;
  262. } else if (0 == _stricmp(argv[0]+1, "TSPolicy")) {
  263. pszChainPolicyOID = CERT_CHAIN_POLICY_AUTHENTICODE_TS;
  264. } else if (0 == _stricmp(argv[0]+1, "NoMsg")) {
  265. dwFastCtlFlags |= CERT_CREATE_CONTEXT_NO_HCRYPTMSG_FLAG;
  266. } else if (0 == _stricmp(argv[0]+1, "NoEntry")) {
  267. dwFastCtlFlags |= CERT_CREATE_CONTEXT_NO_ENTRY_FLAG;
  268. } else if (0 == _stricmp(argv[0]+1, "Pause")) {
  269. fPause = TRUE;
  270. } else {
  271. switch(argv[0][1])
  272. {
  273. case 'u':
  274. pszUsageOID = argv[0]+2;
  275. break;
  276. case 'i':
  277. dwIterations = strtoul(argv[0]+2, NULL, 0);
  278. break;
  279. case 'h':
  280. default:
  281. goto BadUsage;
  282. }
  283. }
  284. } else {
  285. if (MAX_NAME_CNT <= dwNameCnt) {
  286. printf("Too many names starting with:: %s\n", argv[0]);
  287. goto BadUsage;
  288. }
  289. rgpszName[dwNameCnt++] = argv[0];
  290. }
  291. }
  292. printf("command line: %s\n", GetCommandLine());
  293. if (0 == dwNameCnt) {
  294. printf("Missing <TestName>\n");
  295. goto BadUsage;
  296. } else
  297. pszTestName = rgpszName[TEST_NAME_INDEX];
  298. dwTestID = 0;
  299. for (i = 0; i < NTESTS; i++) {
  300. if (_stricmp(pszTestName, Tests[i].pszName) == 0) {
  301. dwTestID = Tests[i].dwID;
  302. break;
  303. }
  304. }
  305. if (0 == dwTestID) {
  306. printf("Bad TestName: %s\n", pszTestName);
  307. Usage();
  308. goto BadUsage;
  309. }
  310. if (0 == dwIterations) {
  311. printf("0 iterations\n");
  312. goto BadUsage;
  313. } else
  314. printf("%d iterations\n", dwIterations);
  315. if (fPause) {
  316. int c;
  317. fputs("Waiting to start ->", stdout);
  318. fflush(stdin);
  319. fflush(stdout);
  320. c = getchar();
  321. }
  322. GetSystemTime(&stFirst);
  323. for (i = 0; i <= dwIterations; i++) {
  324. if (1 == i)
  325. GetSystemTime(&stStart);
  326. switch (dwTestID) {
  327. case NULL_TEST_ID:
  328. break;
  329. case CREATE_CERT_CONTEXT_TEST_ID:
  330. if (0 == i) {
  331. if (CERT_FILENAME_INDEX >= dwNameCnt) {
  332. printf("missing cert filename\n");
  333. goto BadUsage;
  334. }
  335. if (!ReadDERFromFile(
  336. rgpszName[CERT_FILENAME_INDEX],
  337. &pbEncodedCert,
  338. &cbEncodedCert
  339. )) {
  340. printf("Unable to read cert file\n");
  341. goto ErrorReturn;
  342. }
  343. }
  344. if (NULL == (pCert = CertCreateCertificateContext(
  345. X509_ASN_ENCODING,
  346. pbEncodedCert,
  347. cbEncodedCert
  348. ))) {
  349. PrintLastError("CertCreateCertificateContext");
  350. goto ErrorReturn;
  351. }
  352. CertFreeCertificateContext(pCert);
  353. pCert = NULL;
  354. break;
  355. case VERIFY_CERT_SIGNATURE_TEST_ID:
  356. if (0 == i) {
  357. if (CERT_FILENAME_INDEX >= dwNameCnt) {
  358. printf("missing cert filename\n");
  359. goto BadUsage;
  360. }
  361. if (!ReadDERFromFile(
  362. rgpszName[CERT_FILENAME_INDEX],
  363. &pbEncodedCert,
  364. &cbEncodedCert
  365. )) {
  366. printf("Unable to read cert file\n");
  367. goto ErrorReturn;
  368. }
  369. if (NULL == (pCert = CertCreateCertificateContext(
  370. X509_ASN_ENCODING,
  371. pbEncodedCert,
  372. cbEncodedCert
  373. ))) {
  374. PrintLastError("CertCreateCertificateContext(cert)");
  375. goto ErrorReturn;
  376. }
  377. TestFree(pbEncodedCert);
  378. pbEncodedCert = NULL;
  379. if (ISSUER_FILENAME_INDEX >= dwNameCnt)
  380. pIssuer = CertDuplicateCertificateContext(pCert);
  381. else {
  382. if (!ReadDERFromFile(
  383. rgpszName[ISSUER_FILENAME_INDEX],
  384. &pbEncodedCert,
  385. &cbEncodedCert
  386. )) {
  387. printf("Unable to read issuer file\n");
  388. goto ErrorReturn;
  389. }
  390. if (NULL == (pIssuer = CertCreateCertificateContext(
  391. X509_ASN_ENCODING,
  392. pbEncodedCert,
  393. cbEncodedCert
  394. ))) {
  395. PrintLastError(
  396. "CertCreateCertificateContext(issuer)");
  397. goto ErrorReturn;
  398. }
  399. }
  400. }
  401. if (!CryptVerifyCertificateSignature(
  402. 0, // hCryptProv
  403. pCert->dwCertEncodingType,
  404. pCert->pbCertEncoded,
  405. pCert->cbCertEncoded,
  406. &pIssuer->pCertInfo->SubjectPublicKeyInfo
  407. )) {
  408. PrintLastError("CryptVerifyCertificateSignature");
  409. goto ErrorReturn;
  410. }
  411. break;
  412. case CREATE_CRL_CONTEXT_TEST_ID:
  413. if (0 == i) {
  414. if (CRL_FILENAME_INDEX >= dwNameCnt) {
  415. printf("missing CRL filename\n");
  416. goto BadUsage;
  417. }
  418. if (!ReadDERFromFile(
  419. rgpszName[CRL_FILENAME_INDEX],
  420. &pbEncoded,
  421. &cbEncoded
  422. )) {
  423. printf("Unable to read CRL file\n");
  424. goto ErrorReturn;
  425. }
  426. }
  427. if (NULL == (pCrl = CertCreateCRLContext(
  428. X509_ASN_ENCODING,
  429. pbEncoded,
  430. cbEncoded
  431. ))) {
  432. PrintLastError("CertCreateCRLContext");
  433. goto ErrorReturn;
  434. }
  435. CertFreeCRLContext(pCrl);
  436. pCrl = NULL;
  437. break;
  438. case CREATE_CTL_CONTEXT_TEST_ID:
  439. if (0 == i) {
  440. if (CTL_FILENAME_INDEX >= dwNameCnt) {
  441. printf("missing CTL filename\n");
  442. goto BadUsage;
  443. }
  444. if (!ReadDERFromFile(
  445. rgpszName[CTL_FILENAME_INDEX],
  446. &pbEncoded,
  447. &cbEncoded
  448. )) {
  449. printf("Unable to read CTL file\n");
  450. goto ErrorReturn;
  451. }
  452. }
  453. if (NULL == (pCtl = CertCreateCTLContext(
  454. X509_ASN_ENCODING,
  455. pbEncoded,
  456. cbEncoded
  457. ))) {
  458. PrintLastError("CertCreateCTLContext");
  459. goto ErrorReturn;
  460. }
  461. CertFreeCTLContext(pCtl);
  462. pCtl = NULL;
  463. break;
  464. case CREATE_SORTED_CTL_CONTEXT_TEST_ID:
  465. if (0 == i) {
  466. if (CTL_FILENAME_INDEX >= dwNameCnt) {
  467. printf("missing CTL filename\n");
  468. goto BadUsage;
  469. }
  470. if (!ReadDERFromFile(
  471. rgpszName[CTL_FILENAME_INDEX],
  472. &pbEncoded,
  473. &cbEncoded
  474. )) {
  475. printf("Unable to read CTL file\n");
  476. goto ErrorReturn;
  477. }
  478. }
  479. if (NULL == (pCtl = (PCCTL_CONTEXT) CertCreateContext(
  480. CERT_STORE_CTL_CONTEXT,
  481. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  482. pbEncoded,
  483. cbEncoded,
  484. CERT_CREATE_CONTEXT_NOCOPY_FLAG |
  485. CERT_CREATE_CONTEXT_SORTED_FLAG,
  486. NULL // pCreatePara
  487. ))) {
  488. PrintLastError("CertCreateContext(Sorted CTL)");
  489. goto ErrorReturn;
  490. }
  491. CertFreeCTLContext(pCtl);
  492. pCtl = NULL;
  493. break;
  494. case CREATE_FAST_CTL_CONTEXT_TEST_ID:
  495. if (0 == i) {
  496. dwFastCtlFlags |= CERT_CREATE_CONTEXT_NOCOPY_FLAG;
  497. if (CTL_FILENAME_INDEX >= dwNameCnt) {
  498. printf("missing CTL filename\n");
  499. goto BadUsage;
  500. }
  501. if (!ReadDERFromFile(
  502. rgpszName[CTL_FILENAME_INDEX],
  503. &pbEncoded,
  504. &cbEncoded
  505. )) {
  506. printf("Unable to read CTL file\n");
  507. goto ErrorReturn;
  508. }
  509. }
  510. if (NULL == (pCtl = (PCCTL_CONTEXT) CertCreateContext(
  511. CERT_STORE_CTL_CONTEXT,
  512. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  513. pbEncoded,
  514. cbEncoded,
  515. dwFastCtlFlags,
  516. NULL // pCreatePara
  517. ))) {
  518. PrintLastError("CertCreateContext(Fast CTL)");
  519. goto ErrorReturn;
  520. }
  521. CertFreeCTLContext(pCtl);
  522. pCtl = NULL;
  523. break;
  524. case DECODE_PKCS7_TEST_ID:
  525. if (0 == i) {
  526. if (PKCS7_FILENAME_INDEX >= dwNameCnt) {
  527. printf("missing PKCS7 filename\n");
  528. goto BadUsage;
  529. }
  530. if (!ReadDERFromFile(
  531. rgpszName[PKCS7_FILENAME_INDEX],
  532. &pbEncoded,
  533. &cbEncoded
  534. )) {
  535. printf("Unable to read PKCS7 file\n");
  536. goto ErrorReturn;
  537. }
  538. }
  539. if (NULL == (hMsg = CryptMsgOpenToDecode(
  540. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  541. 0, // dwFlags
  542. 0, // dwMsgType
  543. NULL, // hProv
  544. NULL, // pRecipientInfo
  545. NULL // pStreamInfo
  546. ))) {
  547. PrintLastError("CryptMsgOpenToDecode");
  548. goto ErrorReturn;
  549. }
  550. if (!CryptMsgUpdate(
  551. hMsg,
  552. pbEncoded,
  553. cbEncoded,
  554. TRUE // fFinal
  555. )) {
  556. PrintLastError("CryptMsgUpdate");
  557. goto ErrorReturn;
  558. }
  559. CryptMsgClose(hMsg);
  560. hMsg = NULL;
  561. break;
  562. case STREAM_DECODE_PKCS7_TEST_ID:
  563. if (0 == i) {
  564. if (PKCS7_FILENAME_INDEX >= dwNameCnt) {
  565. printf("missing PKCS7 filename\n");
  566. goto BadUsage;
  567. }
  568. if (!ReadDERFromFile(
  569. rgpszName[PKCS7_FILENAME_INDEX],
  570. &pbEncoded,
  571. &cbEncoded
  572. )) {
  573. printf("Unable to read PKCS7 file\n");
  574. goto ErrorReturn;
  575. }
  576. }
  577. memset(&StreamInfo, 0, sizeof(StreamInfo));
  578. StreamInfo.pfnStreamOutput = StreamOutputCallback;
  579. if (NULL == (hMsg = CryptMsgOpenToDecode(
  580. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  581. 0, // dwFlags
  582. 0, // dwMsgType
  583. NULL, // hProv
  584. NULL, // pRecipientInfo
  585. &StreamInfo
  586. ))) {
  587. PrintLastError("CryptMsgOpenToDecode(STREAM)");
  588. goto ErrorReturn;
  589. }
  590. if (!CryptMsgUpdate(
  591. hMsg,
  592. pbEncoded,
  593. cbEncoded,
  594. TRUE // fFinal
  595. )) {
  596. PrintLastError("CryptMsgUpdate");
  597. goto ErrorReturn;
  598. }
  599. CryptMsgClose(hMsg);
  600. hMsg = NULL;
  601. break;
  602. case GET_CERT_PROPERTY_TEST_ID:
  603. if (0 == i) {
  604. CRYPT_DATA_BLOB DataBlob;
  605. if (CERT_FILENAME_INDEX >= dwNameCnt) {
  606. printf("missing cert filename\n");
  607. goto BadUsage;
  608. }
  609. if (!ReadDERFromFile(
  610. rgpszName[CERT_FILENAME_INDEX],
  611. &pbEncodedCert,
  612. &cbEncodedCert
  613. )) {
  614. printf("Unable to read cert file\n");
  615. goto ErrorReturn;
  616. }
  617. if (NULL == (pCert = CertCreateCertificateContext(
  618. X509_ASN_ENCODING,
  619. pbEncodedCert,
  620. cbEncodedCert
  621. ))) {
  622. PrintLastError("CertCreateCertificateContext");
  623. goto ErrorReturn;
  624. }
  625. DataBlob.pbData = (BYTE *) &dwProp;
  626. DataBlob.cbData = sizeof(dwProp);
  627. dwProp = 0x12345678;
  628. if (!CertSetCertificateContextProperty(
  629. pCert,
  630. CERT_FIRST_USER_PROP_ID,
  631. 0, // dwFlags
  632. &DataBlob
  633. )) {
  634. PrintLastError("CertSetCertificateContextProperty");
  635. goto ErrorReturn;
  636. }
  637. }
  638. dwProp = 0;
  639. cbData = sizeof(dwProp);
  640. if (!CertGetCertificateContextProperty(
  641. pCert,
  642. CERT_FIRST_USER_PROP_ID,
  643. &dwProp,
  644. &cbData
  645. )) {
  646. PrintLastError("CertGetCertificateContextProperty");
  647. goto ErrorReturn;
  648. }
  649. if (0x12345678 != dwProp || sizeof(dwProp) != cbData) {
  650. printf("failed => invalid get property\n");
  651. goto ErrorReturn;
  652. }
  653. break;
  654. case DECODE_OID_TEST_ID:
  655. if (0 == i) {
  656. CRYPT_ATTRIBUTE Attribute;
  657. if (OID_INDEX >= dwNameCnt) {
  658. printf("missing OID\n");
  659. goto BadUsage;
  660. } else
  661. pszOID = rgpszName[OID_INDEX];
  662. Attribute.pszObjId = (LPSTR) pszOID;
  663. Attribute.cValue = 0;
  664. Attribute.rgValue = NULL;
  665. cbEncodedAttr = sizeof(rgbEncodedAttr);
  666. if (!CryptEncodeObject(
  667. X509_ASN_ENCODING,
  668. PKCS_ATTRIBUTE,
  669. &Attribute,
  670. rgbEncodedAttr,
  671. &cbEncodedAttr
  672. )) {
  673. PrintLastError("CryptEncodeObject(PKCS_ATTRIBUTE)");
  674. goto ErrorReturn;
  675. }
  676. }
  677. pAttr->pszObjId = NULL;
  678. cbAttr = sizeof(rgbAttr);
  679. if (!CryptDecodeObject(
  680. X509_ASN_ENCODING,
  681. PKCS_ATTRIBUTE,
  682. rgbEncodedAttr,
  683. cbEncodedAttr,
  684. CRYPT_DECODE_NOCOPY_FLAG,
  685. pAttr,
  686. &cbAttr
  687. )) {
  688. PrintLastError("CryptDecodeObject(PKCS_ATTRIBUTE)");
  689. goto ErrorReturn;
  690. }
  691. if (0 != strcmp(pszOID, pAttr->pszObjId)) {
  692. printf("failed => invalid decoded OID\n");
  693. goto ErrorReturn;
  694. }
  695. break;
  696. case FIND_EXTENSION_TEST_ID:
  697. if (0 == i) {
  698. CRYPT_DATA_BLOB DataBlob;
  699. if (CERT_FILENAME_INDEX >= dwNameCnt) {
  700. printf("missing cert filename\n");
  701. goto BadUsage;
  702. }
  703. if (!ReadDERFromFile(
  704. rgpszName[CERT_FILENAME_INDEX],
  705. &pbEncodedCert,
  706. &cbEncodedCert
  707. )) {
  708. printf("Unable to read cert file\n");
  709. goto ErrorReturn;
  710. }
  711. if (NULL == (pCert = CertCreateCertificateContext(
  712. X509_ASN_ENCODING,
  713. pbEncodedCert,
  714. cbEncodedCert
  715. ))) {
  716. PrintLastError("CertCreateCertificateContext");
  717. goto ErrorReturn;
  718. }
  719. if (CERT_OID_INDEX >= dwNameCnt) {
  720. printf("missing OID\n");
  721. goto BadUsage;
  722. } else
  723. pszOID = rgpszName[CERT_OID_INDEX];
  724. }
  725. if (NULL == (pExt = CertFindExtension(
  726. pszOID,
  727. pCert->pCertInfo->cExtension,
  728. pCert->pCertInfo->rgExtension
  729. ))) {
  730. PrintLastError("CertFindExtension");
  731. goto ErrorReturn;
  732. }
  733. break;
  734. case DECODE_EXTENSION_TEST_ID:
  735. if (0 == i) {
  736. CRYPT_DATA_BLOB DataBlob;
  737. if (CERT_FILENAME_INDEX >= dwNameCnt) {
  738. printf("missing cert filename\n");
  739. goto BadUsage;
  740. }
  741. if (!ReadDERFromFile(
  742. rgpszName[CERT_FILENAME_INDEX],
  743. &pbEncodedCert,
  744. &cbEncodedCert
  745. )) {
  746. printf("Unable to read cert file\n");
  747. goto ErrorReturn;
  748. }
  749. if (NULL == (pCert = CertCreateCertificateContext(
  750. X509_ASN_ENCODING,
  751. pbEncodedCert,
  752. cbEncodedCert
  753. ))) {
  754. PrintLastError("CertCreateCertificateContext");
  755. goto ErrorReturn;
  756. }
  757. if (CERT_OID_INDEX >= dwNameCnt) {
  758. printf("missing OID\n");
  759. goto BadUsage;
  760. } else
  761. pszOID = rgpszName[CERT_OID_INDEX];
  762. if (NULL == (pExt = CertFindExtension(
  763. pszOID,
  764. pCert->pCertInfo->cExtension,
  765. pCert->pCertInfo->rgExtension
  766. ))) {
  767. PrintLastError("CertFindExtension");
  768. goto ErrorReturn;
  769. }
  770. }
  771. #if 0
  772. cbExt = sizeof(rgbExt);
  773. if (!CryptDecodeObject(
  774. X509_ASN_ENCODING,
  775. pExt->pszObjId,
  776. pExt->Value.pbData,
  777. pExt->Value.cbData,
  778. CRYPT_DECODE_NOCOPY_FLAG,
  779. rgbExt,
  780. &cbExt
  781. )) {
  782. PrintLastError("CryptDecodeObject(Extension)");
  783. goto ErrorReturn;
  784. }
  785. #else
  786. {
  787. void *pvExt;
  788. if (!CryptDecodeObjectEx(
  789. X509_ASN_ENCODING,
  790. pExt->pszObjId,
  791. pExt->Value.pbData,
  792. pExt->Value.cbData,
  793. CRYPT_DECODE_ALLOC_FLAG |
  794. CRYPT_DECODE_NOCOPY_FLAG |
  795. CRYPT_DECODE_SHARE_OID_STRING_FLAG,
  796. NULL,
  797. (void *) &pvExt,
  798. &cbExt
  799. )) {
  800. PrintLastError("CryptDecodeObjectEx(Extension)");
  801. goto ErrorReturn;
  802. } else
  803. LocalFree(pvExt);
  804. }
  805. #endif
  806. break;
  807. case WVT_CERT_TEST_ID:
  808. if (0 == i) {
  809. if (CERT_FILENAME_INDEX >= dwNameCnt) {
  810. printf("missing cert filename\n");
  811. goto BadUsage;
  812. }
  813. pwvtActionID = &wvtCertActionID;
  814. wvtData.dwUnionChoice = WTD_CHOICE_CERT;
  815. wvtData.pCert = &wvtCertInfo;
  816. wvtData.pPolicyCallbackData = (void *) pszUsageOID;
  817. if (NULL == (wvtCertInfo.psCertContext = (CERT_CONTEXT *)
  818. ReadCert(rgpszName[CERT_FILENAME_INDEX])))
  819. goto ErrorReturn;
  820. if (STORE_FILENAME_INDEX < dwNameCnt) {
  821. if (NULL == (hAdditionalStore =
  822. OpenSystemStoreOrFile(
  823. FALSE, // fSystemStore
  824. rgpszName[STORE_FILENAME_INDEX],
  825. 0 // dwFlags
  826. )))
  827. goto BadUsage;
  828. wvtCertInfo.chStores = 1;
  829. }
  830. }
  831. lStatus = WinVerifyTrust(
  832. NULL, // hwnd
  833. pwvtActionID,
  834. &wvtData
  835. );
  836. if (0 == i) {
  837. lFirstStatus = lStatus;
  838. printf("WinVerifyTrust returned => 0x%x\n", lStatus);
  839. } else {
  840. if (lStatus != lFirstStatus) {
  841. printf("WinVerifyTrust failed => 0x%x\n", lStatus);
  842. goto ErrorReturn;
  843. }
  844. }
  845. break;
  846. case WVT_FILE_TEST_ID:
  847. if (0 == i) {
  848. if (WVT_FILENAME_INDEX >= dwNameCnt) {
  849. printf("missing WVT filename\n");
  850. goto BadUsage;
  851. }
  852. pwvtActionID = &wvtFileActionID;
  853. wvtData.dwUnionChoice = WTD_CHOICE_FILE;
  854. wvtData.pFile = &wvtFileInfo;
  855. wvtFileInfo.pcwszFilePath = AllocAndSzToWsz(
  856. rgpszName[WVT_FILENAME_INDEX]);
  857. }
  858. lStatus = WinVerifyTrust(
  859. NULL, // hwnd
  860. pwvtActionID,
  861. &wvtData
  862. );
  863. if (0 == i) {
  864. lFirstStatus = lStatus;
  865. printf("WinVerifyTrust returned => 0x%x\n", lStatus);
  866. } else {
  867. if (lStatus != lFirstStatus) {
  868. printf("WinVerifyTrust failed => 0x%x\n", lStatus);
  869. goto ErrorReturn;
  870. }
  871. }
  872. break;
  873. case WVT_CAT_TEST_ID:
  874. if (0 == i) {
  875. if (WVT_MEMBER_FILENAME_INDEX >= dwNameCnt) {
  876. printf("missing WVT member filename\n");
  877. goto BadUsage;
  878. }
  879. pwvtActionID = &wvtDriverActionID;
  880. wvtData.dwUnionChoice = WTD_CHOICE_CATALOG;
  881. wvtData.pCatalog = &wvtCat;
  882. wvtCat.pcwszCatalogFilePath = AllocAndSzToWsz(
  883. rgpszName[WVT_CAT_FILENAME_INDEX]);
  884. wvtCat.pcwszMemberTag = L"foo";
  885. wvtCat.pcwszMemberFilePath = AllocAndSzToWsz(
  886. rgpszName[WVT_MEMBER_FILENAME_INDEX]);
  887. wvtCat.hMemberFile = CreateFileU(
  888. wvtCat.pcwszMemberFilePath,
  889. GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  890. FILE_ATTRIBUTE_NORMAL, NULL);
  891. cbCatHash = sizeof(rgbCatHash);
  892. if (!(CryptCATAdminCalcHashFromFileHandle(
  893. wvtCat.hMemberFile, &cbCatHash, rgbCatHash, 0))) {
  894. PrintLastError("CryptCATAdminCalcHashFromFileHandle");
  895. goto ErrorReturn;
  896. }
  897. wvtCat.pbCalculatedFileHash = rgbCatHash;
  898. wvtCat.cbCalculatedFileHash = cbCatHash;
  899. }
  900. lStatus = WinVerifyTrust(
  901. NULL, // hwnd
  902. pwvtActionID,
  903. &wvtData
  904. );
  905. if (0 == i) {
  906. lFirstStatus = lStatus;
  907. printf("WinVerifyTrust returned => 0x%x\n", lStatus);
  908. } else {
  909. if (lStatus != lFirstStatus) {
  910. printf("WinVerifyTrust failed => 0x%x\n", lStatus);
  911. goto ErrorReturn;
  912. }
  913. }
  914. break;
  915. case CERT_CHAIN_TEST_ID:
  916. if (0 == i) {
  917. if (CERT_FILENAME_INDEX >= dwNameCnt) {
  918. printf("missing cert filename\n");
  919. goto BadUsage;
  920. }
  921. if (NULL == (pCert =
  922. ReadCert(rgpszName[CERT_FILENAME_INDEX])))
  923. goto ErrorReturn;
  924. if (STORE_FILENAME_INDEX < dwNameCnt) {
  925. if (NULL == (hAdditionalStore =
  926. OpenSystemStoreOrFile(
  927. FALSE, // fSystemStore
  928. rgpszName[STORE_FILENAME_INDEX],
  929. 0 // dwFlags
  930. )))
  931. goto BadUsage;
  932. }
  933. if (pszUsageOID) {
  934. ChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
  935. ChainPara.RequestedUsage.Usage.cUsageIdentifier = 1;
  936. ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier =
  937. &pszUsageOID;
  938. }
  939. }
  940. if (!CertGetCertificateChain(
  941. NULL, // hChainEngine
  942. pCert,
  943. NULL, // pTime
  944. hAdditionalStore,
  945. &ChainPara,
  946. dwCreateChainFlags,
  947. NULL, // pvReserved
  948. &pChainContext
  949. )) {
  950. PrintLastError("CertGetCertificateChain");
  951. goto ErrorReturn;
  952. }
  953. if (!CertVerifyCertificateChainPolicy(
  954. pszChainPolicyOID,
  955. pChainContext,
  956. &ChainPolicyPara,
  957. &ChainPolicyStatus
  958. )) {
  959. PrintLastError("CertVerifyCertificateChainPolicy");
  960. goto ErrorReturn;
  961. }
  962. if (0 == i) {
  963. dwFirstError = ChainPolicyStatus.dwError;
  964. printf("Chain Policy returned => 0x%x\n", dwFirstError);
  965. if (dwFirstError)
  966. printf("Chain Index: %d Element Index: %d\n",
  967. ChainPolicyStatus.lChainIndex,
  968. ChainPolicyStatus.lElementIndex
  969. );
  970. } else {
  971. dwError = ChainPolicyStatus.dwError;
  972. if (dwError != dwFirstError) {
  973. printf("Chain Policy failed => 0x%x\n", dwError);
  974. goto ErrorReturn;
  975. }
  976. }
  977. if (pChainContext) {
  978. CertFreeCertificateChain(pChainContext);
  979. pChainContext = NULL;
  980. }
  981. break;
  982. default:
  983. printf("unknown test name\n");
  984. goto BadUsage;
  985. }
  986. }
  987. GetSystemTime(&stEnd);
  988. SystemTimeToFileTime(&stFirst, &ftFirst);
  989. SystemTimeToFileTime(&stStart, &ftStart);
  990. SystemTimeToFileTime(&stEnd, &ftEnd);
  991. DeltaTime = *((_int64 *) &ftStart) - *((_int64 *) &ftFirst);
  992. Microseconds = (int) (DeltaTime / 10);
  993. Milliseconds = (int) (DeltaTime / 10000);
  994. Seconds = (int) (DeltaTime / 10000000);
  995. printf("First Micro: %d Milli: %d Seconds: %d\n",
  996. Microseconds, Milliseconds, Seconds);
  997. DeltaTime = *((_int64 *) &ftEnd) - *((_int64 *) &ftStart);
  998. Microseconds = (int) (DeltaTime / 10);
  999. Milliseconds = (int) (DeltaTime / 10000);
  1000. Seconds = (int) (DeltaTime / 10000000);
  1001. printf("Total Micro: %d Milli: %d Seconds: %d\n",
  1002. Microseconds, Milliseconds, Seconds);
  1003. DeltaTime = DeltaTime / dwIterations;
  1004. Microseconds = (int) (DeltaTime / 10);
  1005. Milliseconds = (int) (DeltaTime / 10000);
  1006. Seconds = (int) (DeltaTime / 10000000);
  1007. printf("Average Micro: %d Milli: %d Seconds: %d\n",
  1008. Microseconds, Milliseconds, Seconds);
  1009. status = 0;
  1010. CommonReturn:
  1011. CertFreeCertificateContext(pCert);
  1012. CertFreeCertificateContext(pIssuer);
  1013. CertFreeCTLContext(pCtl);
  1014. CertFreeCRLContext(pCrl);
  1015. CryptMsgClose(hMsg);
  1016. TestFree(pbEncodedCert);
  1017. TestFree(pbEncoded);
  1018. CertFreeCertificateContext(wvtCertInfo.psCertContext);
  1019. TestFree((LPWSTR) wvtFileInfo.pcwszFilePath);
  1020. if (hAdditionalStore) {
  1021. if (!CertCloseStore(hAdditionalStore, CERT_CLOSE_STORE_CHECK_FLAG))
  1022. PrintLastError("CertCloseStore(AdditionalStore)");
  1023. }
  1024. if (pChainContext)
  1025. CertFreeCertificateChain(pChainContext);
  1026. TestFree(const_cast<LPWSTR>(wvtCat.pcwszCatalogFilePath));
  1027. TestFree(const_cast<LPWSTR>(wvtCat.pcwszMemberFilePath));
  1028. if (!(NULL == wvtCat.hMemberFile ||
  1029. INVALID_HANDLE_VALUE == wvtCat.hMemberFile))
  1030. CloseHandle(wvtCat.hMemberFile);
  1031. if (fPause) {
  1032. int c;
  1033. fputs("Waiting to exit ->", stdout);
  1034. fflush(stdin);
  1035. fflush(stdout);
  1036. c = getchar();
  1037. }
  1038. return status;
  1039. ErrorReturn:
  1040. status = -1;
  1041. goto CommonReturn;
  1042. BadUsage:
  1043. Usage();
  1044. status = -1;
  1045. goto CommonReturn;
  1046. }