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.

654 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1997
  6. //
  7. // File: tminver.cpp
  8. //
  9. // Contents: Minimal ASN.1 Parsing and Cryptographic API Tests
  10. //
  11. // See Usage() for a list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 29-Jan-01 philh created
  17. //--------------------------------------------------------------------------
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include "testutil.h"
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <memory.h>
  25. #include <time.h>
  26. #define MAX_FILENAME_CNT 100
  27. #define DEFAULT_ATTR_LEN 1000
  28. #define MAX_ATTR_CNT 20
  29. //+-------------------------------------------------------------------------
  30. // Global Test Parameters
  31. //--------------------------------------------------------------------------
  32. BOOL fVerbose = FALSE;
  33. BOOL fContent = FALSE;
  34. BOOL fQuiet = FALSE;
  35. LONG lQuietErr = 0;
  36. DWORD cbFirstAttrLen = DEFAULT_ATTR_LEN;
  37. ALG_ID HashAlgId = CALG_SHA1;
  38. static void Usage(void)
  39. {
  40. printf("Usage: ttrust [options] <TestName> <Filename>\n");
  41. printf("TestNames are:\n");
  42. printf(" Data - PKCS #7 SignedData\n");
  43. printf(" Cert - X.509 encoded certifcate\n");
  44. printf(" Certs - Certs in PKCS #7 SignedData\n");
  45. printf(" File - Authenticode Signed File\n");
  46. printf(" Cat - File(s) in System Catalogs\n");
  47. printf("\n");
  48. printf("Options are:\n");
  49. printf(" -Content - Display content\n");
  50. printf(" -MD5 - MD5 File hash default of SHA1\n");
  51. printf("\n");
  52. printf(" -h - This message\n");
  53. printf(" -v - Verbose\n");
  54. printf(" -q[<Number>] - Quiet, expected error\n");
  55. printf(" -a<OID String> - Attribute OID string\n");
  56. printf(" -A<Number> - Attribute length, default of %d\n",
  57. DEFAULT_ATTR_LEN);
  58. printf("\n");
  59. }
  60. BOOL
  61. TestData(
  62. IN LPCSTR pszFilename
  63. )
  64. {
  65. BOOL fResult;
  66. LONG lErr;
  67. DWORD cbEncoded;
  68. PBYTE pbEncoded = NULL;
  69. CRYPT_DER_BLOB rgVerSignedDataBlob[MINCRYPT_VER_SIGNED_DATA_BLOB_CNT];
  70. BOOL fCTL = FALSE;
  71. if (!ReadDERFromFile(pszFilename, &pbEncoded, &cbEncoded))
  72. goto ErrorReturn;
  73. lErr = MinCryptVerifySignedData(
  74. pbEncoded,
  75. cbEncoded,
  76. rgVerSignedDataBlob
  77. );
  78. if (fQuiet) {
  79. if (lErr != lQuietErr) {
  80. printf("Expected => 0x%x, ", lQuietErr);
  81. PrintErr("MinCryptVerifySignedData", lErr);
  82. goto ErrorReturn;
  83. } else
  84. goto SuccessReturn;
  85. }
  86. if (ERROR_SUCCESS != lErr)
  87. PrintErr("MinCryptVerifySignedData", lErr);
  88. if (0 == rgVerSignedDataBlob[
  89. MINCRYPT_VER_SIGNED_DATA_SIGNER_CERT_IDX].cbData)
  90. printf("No Signer\n");
  91. else {
  92. LONG lSkipped;
  93. CRYPT_DER_BLOB rgCertBlob[MINASN1_CERT_BLOB_CNT];
  94. printf("==== Signer ====\n");
  95. lSkipped = MinAsn1ParseCertificate(
  96. rgVerSignedDataBlob[
  97. MINCRYPT_VER_SIGNED_DATA_SIGNER_CERT_IDX].pbData,
  98. rgVerSignedDataBlob[
  99. MINCRYPT_VER_SIGNED_DATA_SIGNER_CERT_IDX].cbData,
  100. rgCertBlob
  101. );
  102. if (0 > lSkipped)
  103. printf("MinAsn1ParseCertificate failed at offset: %d\n",
  104. -lSkipped - 1);
  105. else
  106. DisplayCert(rgCertBlob, fVerbose);
  107. if (fVerbose) {
  108. DisplayAttrs("Authenticated",
  109. &rgVerSignedDataBlob[MINCRYPT_VER_SIGNED_DATA_AUTH_ATTRS_IDX]);
  110. DisplayAttrs("Unauthenticated",
  111. &rgVerSignedDataBlob[MINCRYPT_VER_SIGNED_DATA_UNAUTH_ATTRS_IDX]);
  112. }
  113. printf("\n");
  114. }
  115. if (0 == rgVerSignedDataBlob[
  116. MINCRYPT_VER_SIGNED_DATA_CONTENT_OID_IDX].cbData)
  117. printf("No Content OID\n");
  118. else {
  119. CHAR rgszOID[MAX_OID_STRING_LEN];
  120. EncodedOIDToDot(&rgVerSignedDataBlob[
  121. MINCRYPT_VER_SIGNED_DATA_CONTENT_OID_IDX],
  122. rgszOID
  123. );
  124. if (0 == strcmp(rgszOID, szOID_CTL))
  125. fCTL = TRUE;
  126. printf("Content OID:: %s\n", rgszOID);
  127. }
  128. if (0 == rgVerSignedDataBlob[
  129. MINCRYPT_VER_SIGNED_DATA_CONTENT_DATA_IDX].cbData)
  130. printf("No Content Data\n");
  131. else {
  132. if (fCTL)
  133. printf("CTL ");
  134. printf("Content Data:: %d bytes\n",
  135. rgVerSignedDataBlob[
  136. MINCRYPT_VER_SIGNED_DATA_CONTENT_DATA_IDX].cbData);
  137. if (fContent) {
  138. if (fCTL) {
  139. printf("\n==== CTL ====\n");
  140. DisplayCTL(&rgVerSignedDataBlob[
  141. MINCRYPT_VER_SIGNED_DATA_CONTENT_DATA_IDX], fVerbose);
  142. } else
  143. PrintMultiLineBytes(" ", &rgVerSignedDataBlob[
  144. MINCRYPT_VER_SIGNED_DATA_CONTENT_DATA_IDX]);
  145. }
  146. }
  147. SuccessReturn:
  148. fResult = TRUE;
  149. CommonReturn:
  150. TestFree(pbEncoded);
  151. return fResult;
  152. ErrorReturn:
  153. fResult = FALSE;
  154. goto CommonReturn;
  155. }
  156. BOOL
  157. TestCert(
  158. IN LPCSTR pszFilename
  159. )
  160. {
  161. BOOL fResult;
  162. DWORD cbEncoded;
  163. PBYTE pbEncoded = NULL;
  164. LONG lSkipped;
  165. CRYPT_DER_BLOB rgCertBlob[MINASN1_CERT_BLOB_CNT];
  166. if (!ReadDERFromFile(pszFilename, &pbEncoded, &cbEncoded))
  167. goto ErrorReturn;
  168. printf("==== Cert ====\n");
  169. lSkipped = MinAsn1ParseCertificate(
  170. pbEncoded,
  171. cbEncoded,
  172. rgCertBlob
  173. );
  174. if (0 > lSkipped) {
  175. printf("MinAsn1ParseCertificate failed at offset: %d\n",
  176. -lSkipped - 1);
  177. fResult = FALSE;
  178. } else {
  179. DisplayCert(rgCertBlob, fVerbose);
  180. fResult = TRUE;
  181. }
  182. printf("\n");
  183. fResult = TRUE;
  184. CommonReturn:
  185. TestFree(pbEncoded);
  186. return fResult;
  187. ErrorReturn:
  188. fResult = FALSE;
  189. goto CommonReturn;
  190. }
  191. #define MAX_CERTS_CNT 256
  192. BOOL
  193. TestCerts(
  194. IN LPCSTR pszFilename
  195. )
  196. {
  197. BOOL fResult;
  198. LONG lSkipped;
  199. DWORD cbEncoded;
  200. PBYTE pbEncoded = NULL;
  201. CRYPT_DER_BLOB rgrgCertBlob[MAX_CERTS_CNT][MINASN1_CERT_BLOB_CNT];
  202. DWORD cCert = MAX_CERTS_CNT;
  203. if (!ReadDERFromFile(pszFilename, &pbEncoded, &cbEncoded))
  204. goto ErrorReturn;
  205. lSkipped = MinAsn1ExtractParsedCertificatesFromSignedData(
  206. pbEncoded,
  207. cbEncoded,
  208. &cCert,
  209. rgrgCertBlob
  210. );
  211. if (0 > lSkipped) {
  212. printf("MinAsn1ExtractParsedCertificatesFromSignedData failed at offset: %d\n",
  213. -lSkipped - 1);
  214. goto ErrorReturn;
  215. }
  216. if (0 == cCert)
  217. printf("No Certs\n");
  218. else {
  219. DWORD i;
  220. LONG lErr;
  221. for (i = 0; i < cCert; i++) {
  222. printf("==== Cert[%d] ====\n", i);
  223. lErr = MinCryptVerifyCertificate(
  224. rgrgCertBlob[i],
  225. cCert,
  226. rgrgCertBlob
  227. );
  228. printf("Verify: ");
  229. if (ERROR_SUCCESS == lErr)
  230. printf("Success\n");
  231. else
  232. printf("0x%x (%d) \n", lErr, lErr);
  233. DisplayCert(rgrgCertBlob[i], fVerbose);
  234. printf("\n");
  235. }
  236. }
  237. fResult = TRUE;
  238. CommonReturn:
  239. TestFree(pbEncoded);
  240. return fResult;
  241. ErrorReturn:
  242. fResult = FALSE;
  243. goto CommonReturn;
  244. }
  245. BOOL
  246. TestFile(
  247. IN LPCSTR pszFilename,
  248. IN OPTIONAL DWORD cAttrOID,
  249. IN OPTIONAL LPCSTR rgpszAttrOID[MAX_ATTR_CNT],
  250. IN OPTIONAL CRYPT_DER_BLOB rgAttrEncodedOIDBlob[MAX_ATTR_CNT]
  251. )
  252. {
  253. BOOL fResult;
  254. LONG lErr;
  255. DWORD cbAttr = 0;
  256. LPWSTR pwszFilename = NULL;
  257. PCRYPT_DER_BLOB pAttrValueBlob = NULL;
  258. pwszFilename = AllocAndSzToWsz(pszFilename);
  259. if (0 != cAttrOID && 0 != cbFirstAttrLen) {
  260. if (NULL == (pAttrValueBlob =
  261. (PCRYPT_DER_BLOB) TestAlloc(cbFirstAttrLen)))
  262. goto ErrorReturn;
  263. cbAttr = cbFirstAttrLen;
  264. }
  265. lErr = MinCryptVerifySignedFile(
  266. MINCRYPT_FILE_NAME,
  267. (const VOID *) pwszFilename,
  268. cAttrOID,
  269. rgAttrEncodedOIDBlob,
  270. pAttrValueBlob,
  271. &cbAttr
  272. );
  273. if (fQuiet) {
  274. if (lErr != lQuietErr) {
  275. printf("Expected => 0x%x, ", lQuietErr);
  276. PrintErr("MinCryptVerifySignedFile", lErr);
  277. goto ErrorReturn;
  278. } else
  279. goto SuccessReturn;
  280. }
  281. if (ERROR_INSUFFICIENT_BUFFER == lErr) {
  282. printf("Insufficient Buffer, require: %d input: %d\n",
  283. cbAttr, cbFirstAttrLen);
  284. TestFree(pAttrValueBlob);
  285. if (NULL == (pAttrValueBlob =
  286. (PCRYPT_DER_BLOB) TestAlloc(cbAttr)))
  287. goto ErrorReturn;
  288. lErr = MinCryptVerifySignedFile(
  289. MINCRYPT_FILE_NAME,
  290. (const VOID *) pwszFilename,
  291. cAttrOID,
  292. rgAttrEncodedOIDBlob,
  293. pAttrValueBlob,
  294. &cbAttr
  295. );
  296. }
  297. if (ERROR_SUCCESS != lErr)
  298. PrintErr("MinVerifySignedFile", lErr);
  299. else {
  300. DWORD i;
  301. printf("MinVerifySignedFile succeeded\n");
  302. for (i = 0; i < cAttrOID; i++) {
  303. printf("==== Attr[%d] ====\n", i);
  304. printf("OID: %s ", rgpszAttrOID[i]);
  305. PrintBytes(&rgAttrEncodedOIDBlob[i]);
  306. printf("Value:\n");
  307. PrintMultiLineBytes(" ", &pAttrValueBlob[i]);
  308. }
  309. }
  310. SuccessReturn:
  311. fResult = TRUE;
  312. CommonReturn:
  313. TestFree(pwszFilename);
  314. TestFree(pAttrValueBlob);
  315. return fResult;
  316. ErrorReturn:
  317. fResult = FALSE;
  318. goto CommonReturn;
  319. }
  320. BOOL
  321. TestCat(
  322. IN DWORD cFilename,
  323. IN LPCSTR rgpszFilename[MAX_FILENAME_CNT],
  324. IN OPTIONAL DWORD cAttrOID,
  325. IN OPTIONAL LPCSTR rgpszAttrOID[MAX_ATTR_CNT],
  326. IN OPTIONAL CRYPT_DER_BLOB rgAttrEncodedOIDBlob[MAX_ATTR_CNT]
  327. )
  328. {
  329. BOOL fResult;
  330. LONG lErr;
  331. DWORD cbAttr = 0;
  332. LPWSTR rgpwszFilename[MAX_FILENAME_CNT];
  333. CRYPT_HASH_BLOB rgHashBlob[MAX_FILENAME_CNT];
  334. BYTE rgrgbHash[MAX_FILENAME_CNT][MINCRYPT_MAX_HASH_LEN];
  335. LONG rglErr[MAX_FILENAME_CNT];
  336. PCRYPT_DER_BLOB pAttrValueBlob = NULL;
  337. DWORD i;
  338. for (i = 0; i < cFilename; i++)
  339. rgpwszFilename[i] = AllocAndSzToWsz(rgpszFilename[i]);
  340. fResult = TRUE;
  341. for (i = 0; i < cFilename; i++) {
  342. rgHashBlob[i].pbData = rgrgbHash[i];
  343. rgHashBlob[i].cbData = 0;
  344. lErr = MinCryptHashFile(
  345. MINCRYPT_FILE_NAME,
  346. (const VOID *) rgpwszFilename[i],
  347. HashAlgId,
  348. rgHashBlob[i].pbData,
  349. &rgHashBlob[i].cbData
  350. );
  351. if (ERROR_SUCCESS != lErr) {
  352. printf("<%S> ", rgpwszFilename[i]);
  353. PrintErr("MinCryptHashFile", lErr);
  354. fResult = FALSE;
  355. }
  356. }
  357. if (!fResult)
  358. goto ErrorReturn;
  359. if (0 != cAttrOID && 0 != cbFirstAttrLen) {
  360. if (NULL == (pAttrValueBlob =
  361. (PCRYPT_DER_BLOB) TestAlloc(cbFirstAttrLen)))
  362. goto ErrorReturn;
  363. cbAttr = cbFirstAttrLen;
  364. }
  365. lErr = MinCryptVerifyHashInSystemCatalogs(
  366. HashAlgId,
  367. cFilename,
  368. rgHashBlob,
  369. rglErr,
  370. cAttrOID,
  371. rgAttrEncodedOIDBlob,
  372. pAttrValueBlob,
  373. &cbAttr
  374. );
  375. if (ERROR_INSUFFICIENT_BUFFER == lErr) {
  376. printf("Insufficient Buffer, require: %d input: %d\n",
  377. cbAttr, cbFirstAttrLen);
  378. TestFree(pAttrValueBlob);
  379. if (NULL == (pAttrValueBlob =
  380. (PCRYPT_DER_BLOB) TestAlloc(cbAttr)))
  381. goto ErrorReturn;
  382. lErr = MinCryptVerifyHashInSystemCatalogs(
  383. HashAlgId,
  384. cFilename,
  385. rgHashBlob,
  386. rglErr,
  387. cAttrOID,
  388. rgAttrEncodedOIDBlob,
  389. pAttrValueBlob,
  390. &cbAttr
  391. );
  392. }
  393. if (ERROR_SUCCESS != lErr) {
  394. PrintErr("MinCryptVerifyHashInSystemCatalogs", lErr);
  395. goto ErrorReturn;
  396. }
  397. if (fQuiet) {
  398. fResult = TRUE;
  399. for (i = 0; i < cFilename; i++) {
  400. if (rglErr[i] != lQuietErr) {
  401. printf("<%S> ", rgpwszFilename[i]);
  402. printf("Expected => 0x%x, ", lQuietErr);
  403. PrintErr("MinCryptVerifyHashInSystemCatalogs", rglErr[i]);
  404. fResult = FALSE;
  405. }
  406. }
  407. if (fResult)
  408. goto SuccessReturn;
  409. else
  410. goto ErrorReturn;
  411. }
  412. printf("MinCryptVerifyHashInSystemCatalogs succeeded\n");
  413. for (i = 0; i < cFilename; i++) {
  414. DWORD j;
  415. printf("##### [%d] <%S> #####\n", i, rgpwszFilename[i]);
  416. if (ERROR_SUCCESS == rglErr[i])
  417. printf("Verify: SUCCESS\n");
  418. else {
  419. printf("%S ", rgpwszFilename[i]);
  420. PrintErr("Verify", rglErr[i]);
  421. }
  422. printf("Hash:");
  423. PrintBytes(&rgHashBlob[i]);
  424. for (j = 0; j < cAttrOID; j++) {
  425. printf("==== Attr[%d] ====\n", j);
  426. printf("OID: %s ", rgpszAttrOID[j]);
  427. PrintBytes(&rgAttrEncodedOIDBlob[j]);
  428. printf("Value:\n");
  429. PrintMultiLineBytes(" ", &pAttrValueBlob[i*cAttrOID + j]);
  430. }
  431. printf("\n");
  432. }
  433. SuccessReturn:
  434. fResult = TRUE;
  435. CommonReturn:
  436. for (i = 0; i < cFilename; i++)
  437. TestFree(rgpwszFilename[i]);
  438. TestFree(pAttrValueBlob);
  439. return fResult;
  440. ErrorReturn:
  441. fResult = FALSE;
  442. goto CommonReturn;
  443. }
  444. int _cdecl main(int argc, char * argv[])
  445. {
  446. BOOL fResult;
  447. DWORD cFilename = 0;
  448. LPCSTR rgpszFilename[MAX_FILENAME_CNT];
  449. LPCSTR pszTestName = NULL;
  450. DWORD cAttrOID = 0;
  451. LPCSTR rgpszAttrOID[MAX_ATTR_CNT];
  452. CRYPT_DER_BLOB rgAttrEncodedOIDBlob[MAX_ATTR_CNT];
  453. BYTE rgbEncodedOID[MAX_ATTR_CNT][MAX_ENCODED_OID_LEN];
  454. int iStatus = 0;
  455. while (--argc>0) {
  456. if (**++argv == '-')
  457. {
  458. if (0 == _stricmp(argv[0]+1, "Content")) {
  459. fContent = TRUE;
  460. } else if (0 == _stricmp(argv[0]+1, "MD5")) {
  461. HashAlgId = CALG_MD5;
  462. } else {
  463. switch(argv[0][1])
  464. {
  465. case 'v':
  466. fVerbose = TRUE;
  467. break;
  468. case 'q':
  469. fQuiet = TRUE;
  470. if (argv[0][2])
  471. lQuietErr = (LONG) strtoul(argv[0]+2, NULL, 0);
  472. break;
  473. case 'a':
  474. if (MAX_ATTR_CNT <= cAttrOID) {
  475. printf("Too many Attribute OIDs\n");
  476. goto BadUsage;
  477. }
  478. rgpszAttrOID[cAttrOID] = argv[0]+2;
  479. rgAttrEncodedOIDBlob[cAttrOID].cbData = MAX_ENCODED_OID_LEN;
  480. rgAttrEncodedOIDBlob[cAttrOID].pbData =
  481. rgbEncodedOID[cAttrOID];
  482. if (!DotToEncodedOID(
  483. rgpszAttrOID[cAttrOID],
  484. rgAttrEncodedOIDBlob[cAttrOID].pbData,
  485. &rgAttrEncodedOIDBlob[cAttrOID].cbData
  486. )) {
  487. printf("Invalid OID: %s\n", rgpszAttrOID[cAttrOID]);
  488. goto BadUsage;
  489. }
  490. cAttrOID++;
  491. break;
  492. case 'A':
  493. cbFirstAttrLen = strtoul(argv[0]+2, NULL, 0);
  494. break;
  495. case 'h':
  496. default:
  497. goto BadUsage;
  498. }
  499. }
  500. } else {
  501. if (pszTestName == NULL)
  502. pszTestName = argv[0];
  503. else if (cFilename < MAX_FILENAME_CNT)
  504. rgpszFilename[cFilename++] = argv[0];
  505. else {
  506. printf("Too many Filenames\n");
  507. goto BadUsage;
  508. }
  509. }
  510. }
  511. if (NULL == pszTestName) {
  512. printf("Missing TestName\n");
  513. goto BadUsage;
  514. }
  515. if (0 == cFilename) {
  516. printf("Missing Filename\n");
  517. goto BadUsage;
  518. }
  519. printf("command line: %s\n", GetCommandLine());
  520. if (0 == _stricmp(pszTestName, "Data"))
  521. fResult = TestData(rgpszFilename[0]);
  522. else if (0 == _stricmp(pszTestName, "Cert"))
  523. fResult = TestCert(rgpszFilename[0]);
  524. else if (0 == _stricmp(pszTestName, "Certs"))
  525. fResult = TestCerts(rgpszFilename[0]);
  526. else if (0 == _stricmp(pszTestName, "File"))
  527. fResult = TestFile(
  528. rgpszFilename[0],
  529. cAttrOID,
  530. rgpszAttrOID,
  531. rgAttrEncodedOIDBlob
  532. );
  533. else if (0 == _stricmp(pszTestName, "Cat"))
  534. fResult = TestCat(
  535. cFilename,
  536. rgpszFilename,
  537. cAttrOID,
  538. rgpszAttrOID,
  539. rgAttrEncodedOIDBlob
  540. );
  541. else {
  542. printf("Invalid TestName\n");
  543. goto BadUsage;
  544. }
  545. if (!fResult)
  546. goto ErrorReturn;
  547. printf("Passed\n");
  548. iStatus = 0;
  549. CommonReturn:
  550. return iStatus;
  551. ErrorReturn:
  552. iStatus = -1;
  553. printf("Failed\n");
  554. goto CommonReturn;
  555. BadUsage:
  556. Usage();
  557. goto ErrorReturn;
  558. }