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.

532 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1997
  6. //
  7. // File: tfindctl.cpp
  8. //
  9. // Contents: Find CTL in Cert Store API Tests
  10. //
  11. // See Usage() for list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 06-May-96 philh created
  17. //--------------------------------------------------------------------------
  18. #include <windows.h>
  19. #include <assert.h>
  20. #include "wincrypt.h"
  21. #include "certtest.h"
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <memory.h>
  26. #include <time.h>
  27. static void Usage(void)
  28. {
  29. printf("Usage: tfindctl [options] <StoreName>\n");
  30. printf("Options are:\n");
  31. printf(" -h - This message\n");
  32. printf(" -D<digest> - Find CTL matching Digest (Hash)\n");
  33. printf(" -S<filename> - Subject certificate file\n");
  34. printf(" -I<filename> - CTL issuer certificate file\n");
  35. printf(" -U<ObjectID> - Usage Identifiers\n");
  36. printf(" -L<text> - List Identifier\n");
  37. printf(" -A - Test via AnySubjectType\n");
  38. printf(" -e<number> - Cert encoding type\n");
  39. printf(" -s - Open the \"StoreName\" System store\n");
  40. printf(" -p<filename> - Put encoded CTL to file\n");
  41. printf(" -d - Delete CTL\n");
  42. printf(" -b - Brief\n");
  43. printf(" -v - Verbose\n");
  44. printf(" -c - Verify checks enabled\n");
  45. printf(" -q - Quiet. Don't display CTLs\n");
  46. printf(" -fTimeValid - Only Time Valid CTLs\n");
  47. printf(" -fTimeInvalid - Only Time Invalid CTLs\n");
  48. printf(" -fSameUsage - Only CTLs with same -U<ObjectID>'s\n");
  49. printf("\n");
  50. printf("Default: find all CTLs in the store\n");
  51. }
  52. static PCCERT_CONTEXT GetCertFromFile(
  53. LPSTR pszCertFilename
  54. )
  55. {
  56. BYTE *pbEncodedCert = NULL;
  57. DWORD cbEncodedCert;
  58. PCCERT_CONTEXT pCert = NULL;
  59. if (!ReadDERFromFile(pszCertFilename, &pbEncodedCert, &cbEncodedCert)) {
  60. PrintLastError("GetCertFromFile::ReadDERFromFile");
  61. goto ErrorReturn;
  62. }
  63. if (NULL == (pCert = CertCreateCertificateContext(
  64. dwCertEncodingType,
  65. pbEncodedCert,
  66. cbEncodedCert
  67. ))) {
  68. PrintLastError("GetCertFromFile::CertCreateCertificateContext");
  69. goto ErrorReturn;
  70. }
  71. ErrorReturn:
  72. if (pbEncodedCert)
  73. TestFree(pbEncodedCert);
  74. return pCert;
  75. }
  76. // Attempt to read as a file containing an encoded CTL.
  77. static HCERTSTORE OpenCtlStoreFile(
  78. LPSTR pszStoreFilename)
  79. {
  80. HCERTSTORE hStore;
  81. BYTE *pbEncoded;
  82. DWORD cbEncoded;
  83. if (!ReadDERFromFile(pszStoreFilename, &pbEncoded, &cbEncoded))
  84. return NULL;
  85. if (NULL == (hStore = CertOpenStore(
  86. CERT_STORE_PROV_MEMORY,
  87. 0, // dwEncodingType
  88. 0, // hCryptProv
  89. 0, // dwFlags
  90. NULL // pvPara
  91. )))
  92. goto CommonReturn;
  93. if (!CertAddEncodedCTLToStore(
  94. hStore,
  95. dwMsgAndCertEncodingType,
  96. pbEncoded,
  97. cbEncoded,
  98. CERT_STORE_ADD_ALWAYS,
  99. NULL // ppCtlContext
  100. )) {
  101. CertCloseStore(hStore, 0);
  102. hStore = NULL;
  103. }
  104. CommonReturn:
  105. TestFree(pbEncoded);
  106. return hStore;
  107. }
  108. int _cdecl main(int argc, char * argv[])
  109. {
  110. int ReturnStatus;
  111. DWORD dwFindType = CTL_FIND_ANY;
  112. DWORD dwFindFlags = 0;
  113. void *pvFindPara = NULL;
  114. DWORD cbHash = 0;
  115. BYTE rgbHash[MAX_HASH_LEN];
  116. CRYPT_HASH_BLOB HashBlob;
  117. LPSTR pszSubjectFilename = NULL; // not allocated
  118. PCCERT_CONTEXT pSubjectCert = NULL;
  119. LPSTR pszIssuerFilename = NULL; // not allocated
  120. PCCERT_CONTEXT pIssuerCert = NULL;
  121. #define MAX_USAGE_ID 20
  122. LPSTR rgpszUsageId[MAX_USAGE_ID];
  123. CTL_FIND_USAGE_PARA FindUsagePara;
  124. CTL_FIND_SUBJECT_PARA FindSubjectPara;
  125. CTL_ANY_SUBJECT_INFO AnySubjectInfo;
  126. BOOL fFindUsagePara = FALSE;
  127. BOOL fFindSubjectPara = FALSE;
  128. BOOL fAnySubjectType = FALSE;
  129. BOOL fSystemStore = FALSE;
  130. BOOL fDelete = FALSE;
  131. BOOL fTimeValid = FALSE;
  132. BOOL fTimeInvalid = FALSE;
  133. LPSTR pszStoreFilename = NULL; // not allocated
  134. LPSTR pszPutFilename = NULL; // not allocated
  135. DWORD dwDisplayFlags = 0;
  136. BOOL fQuiet = FALSE;
  137. HCERTSTORE hStore = NULL;
  138. memset(&FindUsagePara, 0, sizeof(FindUsagePara));
  139. FindUsagePara.cbSize = sizeof(FindUsagePara);
  140. memset(&FindSubjectPara, 0, sizeof(FindSubjectPara));
  141. FindSubjectPara.cbSize = sizeof(FindSubjectPara);
  142. while (--argc>0)
  143. {
  144. if (**++argv == '-')
  145. {
  146. switch(argv[0][1])
  147. {
  148. case 'D':
  149. {
  150. char *pszHash = argv[0]+2;
  151. int cchHash = strlen(pszHash);
  152. char rgch[3];
  153. if (!(cchHash == 32 || cchHash == 40)) {
  154. printf("Need 32 digits (MD5) or 40 digits (SHA) ");
  155. printf("for hash , not %d digits\n", cchHash);
  156. goto BadUsage;
  157. }
  158. if (32 == cchHash)
  159. dwFindType = CTL_FIND_MD5_HASH;
  160. else
  161. dwFindType = CTL_FIND_SHA1_HASH;
  162. cbHash = 0;
  163. while (cchHash > 0) {
  164. rgch[0] = *pszHash++;
  165. rgch[1] = *pszHash++;
  166. rgch[2] = '\0';
  167. rgbHash[cbHash++] = (BYTE) strtoul(rgch, NULL, 16);
  168. cchHash -= 2;
  169. }
  170. }
  171. break;
  172. case 'U':
  173. if (FindUsagePara.SubjectUsage.cUsageIdentifier >=
  174. MAX_USAGE_ID) {
  175. printf("Maximum number of Usage Identifiers: %d\n",
  176. MAX_USAGE_ID);
  177. goto BadUsage;
  178. }
  179. FindUsagePara.SubjectUsage.rgpszUsageIdentifier = rgpszUsageId;
  180. rgpszUsageId[FindUsagePara.SubjectUsage.cUsageIdentifier++] =
  181. argv[0] + 2;
  182. fFindUsagePara = TRUE;
  183. break;
  184. case 'L':
  185. if (0 == strlen(argv[0] + 2))
  186. FindUsagePara.ListIdentifier.cbData =
  187. CTL_FIND_NO_LIST_ID_CBDATA;
  188. else {
  189. FindUsagePara.ListIdentifier.cbData = strlen(argv[0] + 2);
  190. FindUsagePara.ListIdentifier.pbData = (BYTE *) argv[0] + 2;
  191. }
  192. fFindUsagePara = TRUE;
  193. break;
  194. case 'I':
  195. if (0 == strlen(argv[0] + 2))
  196. FindUsagePara.pSigner = CTL_FIND_NO_SIGNER_PTR;
  197. else
  198. pszIssuerFilename = argv[0]+2;
  199. fFindUsagePara = TRUE;
  200. break;
  201. case 'S':
  202. pszSubjectFilename = argv[0]+2;
  203. if (*pszSubjectFilename == '\0') {
  204. printf("Need to specify SubjectFilename\n");
  205. goto BadUsage;
  206. }
  207. fFindSubjectPara = TRUE;
  208. break;
  209. case 'p':
  210. pszPutFilename = argv[0]+2;
  211. if (*pszPutFilename == '\0') {
  212. printf("Need to specify filename\n");
  213. goto BadUsage;
  214. }
  215. break;
  216. case 'A':
  217. fAnySubjectType = TRUE;
  218. break;
  219. case 'd':
  220. fDelete = TRUE;
  221. break;
  222. case 'f':
  223. if (argv[0][2]) {
  224. if (0 == _stricmp(argv[0]+2, "TimeValid"))
  225. fTimeValid = TRUE;
  226. else if (0 == _stricmp(argv[0]+2, "TimeInvalid"))
  227. fTimeInvalid = TRUE;
  228. else if (0 == _stricmp(argv[0]+2, "SameUsage"))
  229. dwFindFlags |= CTL_FIND_SAME_USAGE_FLAG;
  230. else {
  231. printf("Need to specify -fTimeValid | -fTimeInvalid | -fSameUsage\n");
  232. goto BadUsage;
  233. }
  234. } else {
  235. printf("Need to specify -fTimeValid | -fTimeInvalid | -fSameUsage\n");
  236. goto BadUsage;
  237. }
  238. break;
  239. case 'b':
  240. dwDisplayFlags |= DISPLAY_BRIEF_FLAG;
  241. break;
  242. case 'v':
  243. dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
  244. break;
  245. case 'c':
  246. dwDisplayFlags |= DISPLAY_CHECK_FLAG;
  247. break;
  248. case 'q':
  249. fQuiet = TRUE;
  250. break;
  251. case 's':
  252. fSystemStore = TRUE;
  253. break;
  254. case 'e':
  255. dwCertEncodingType = (DWORD) strtoul(argv[0]+2, NULL, 0);
  256. break;
  257. case 'h':
  258. default:
  259. goto BadUsage;
  260. }
  261. } else {
  262. if (pszStoreFilename == NULL)
  263. pszStoreFilename = argv[0];
  264. else {
  265. printf("Too many arguments\n");
  266. goto BadUsage;
  267. }
  268. }
  269. }
  270. printf("command line: %s\n", GetCommandLine());
  271. if (dwDisplayFlags & DISPLAY_VERBOSE_FLAG)
  272. dwDisplayFlags &= ~DISPLAY_BRIEF_FLAG;
  273. if (pszStoreFilename == NULL) {
  274. printf("missing store filename\n");
  275. goto BadUsage;
  276. }
  277. if (pszIssuerFilename) {
  278. if (NULL == (pIssuerCert = GetCertFromFile(pszIssuerFilename))) {
  279. printf("Unable to read/decode IssuerFilename\n");
  280. goto ErrorReturn;
  281. }
  282. FindUsagePara.pSigner = pIssuerCert->pCertInfo;
  283. }
  284. if (pszSubjectFilename) {
  285. if (NULL == (pSubjectCert = GetCertFromFile(pszSubjectFilename))) {
  286. printf("Unable to read/decode SubjectFilename\n");
  287. goto ErrorReturn;
  288. }
  289. if (fAnySubjectType) {
  290. memset(&AnySubjectInfo, 0, sizeof(AnySubjectInfo));
  291. AnySubjectInfo.SubjectAlgorithm.pszObjId = szOID_OIWSEC_sha1;
  292. AnySubjectInfo.SubjectIdentifier.cbData = MAX_HASH_LEN;
  293. if (!CertGetCertificateContextProperty(
  294. pSubjectCert,
  295. CERT_SHA1_HASH_PROP_ID,
  296. rgbHash,
  297. &AnySubjectInfo.SubjectIdentifier.cbData) ||
  298. 0 == AnySubjectInfo.SubjectIdentifier.cbData) {
  299. printf("failed => unable to get SHA1 hash for Subject Cert\n");
  300. goto ErrorReturn;;
  301. }
  302. AnySubjectInfo.SubjectIdentifier.pbData = rgbHash;
  303. FindSubjectPara.dwSubjectType = CTL_ANY_SUBJECT_TYPE;
  304. FindSubjectPara.pvSubject = &AnySubjectInfo;
  305. } else {
  306. FindSubjectPara.dwSubjectType = CTL_CERT_SUBJECT_TYPE;
  307. FindSubjectPara.pvSubject = (void *) pSubjectCert;
  308. }
  309. }
  310. if (fFindSubjectPara) {
  311. if (fFindUsagePara)
  312. FindSubjectPara.pUsagePara = &FindUsagePara;
  313. dwFindType = CTL_FIND_SUBJECT;
  314. } else if (fFindUsagePara)
  315. dwFindType = CTL_FIND_USAGE;
  316. switch (dwFindType) {
  317. case CTL_FIND_ANY:
  318. printf("Finding all CTLs\n");
  319. break;
  320. case CTL_FIND_MD5_HASH:
  321. case CTL_FIND_SHA1_HASH:
  322. {
  323. if (CTL_FIND_MD5_HASH == dwFindType)
  324. printf("Finding MD5 hash:: ");
  325. else
  326. printf("Finding SHA1 hash:: ");
  327. DWORD cb = cbHash;
  328. BYTE *pb = rgbHash;
  329. for (; cb > 0; cb--, pb++)
  330. printf("%02X", *pb);
  331. printf("\n");
  332. }
  333. HashBlob.pbData = rgbHash;
  334. HashBlob.cbData = cbHash;
  335. pvFindPara = &HashBlob;
  336. break;
  337. case CTL_FIND_USAGE:
  338. printf("Finding by Usage\n");
  339. pvFindPara = &FindUsagePara;
  340. break;
  341. case CTL_FIND_SUBJECT:
  342. if (FindSubjectPara.pUsagePara)
  343. printf("Finding by Usage and Subject\n");
  344. else
  345. printf("Finding by Subject\n");
  346. pvFindPara = &FindSubjectPara;
  347. break;
  348. default:
  349. printf("Bad dwFindType: %x\n", dwFindType);
  350. goto BadUsage;
  351. }
  352. if (fFindUsagePara) {
  353. DWORD cUsageId = FindUsagePara.SubjectUsage.cUsageIdentifier;
  354. if (0 == cUsageId)
  355. printf("No Usage Identifiers\n");
  356. else {
  357. LPSTR *ppszId = FindUsagePara.SubjectUsage.rgpszUsageIdentifier;
  358. DWORD i;
  359. printf("Usage Identifiers::\n");
  360. for (i = 0; i < cUsageId; i++, ppszId++)
  361. printf(" [%d] %s\n", i, *ppszId);
  362. }
  363. if (CTL_FIND_NO_LIST_ID_CBDATA == FindUsagePara.ListIdentifier.cbData)
  364. printf("Enabled:: CTL_FIND_NO_LIST_ID_CBDATA\n");
  365. else if (0 == FindUsagePara.ListIdentifier.cbData)
  366. printf("Matching any ListIdentifier\n");
  367. else
  368. printf("Matching ListIdentifier: %s\n",
  369. FindUsagePara.ListIdentifier.pbData);
  370. if (CTL_FIND_NO_SIGNER_PTR == FindUsagePara.pSigner)
  371. printf("Enabled:: CTL_FIND_NO_SIGNER_PTR\n");
  372. else if (NULL == FindUsagePara.pSigner)
  373. printf("Matching any Signer\n");
  374. else
  375. printf("Matching signer with certificate from %s\n",
  376. pszIssuerFilename);
  377. }
  378. if (fFindSubjectPara) {
  379. printf("Matching subject with certificate from %s", pszSubjectFilename);
  380. if (FindSubjectPara.dwSubjectType == CTL_ANY_SUBJECT_TYPE)
  381. printf("Using CTL_ANY_SUBJECT_TYPE\n");
  382. else
  383. printf("\n");
  384. }
  385. if (!fSystemStore)
  386. // Attempt to open as encoded CTL file
  387. hStore = OpenCtlStoreFile(pszStoreFilename);
  388. else
  389. hStore = NULL;
  390. if (NULL == hStore) {
  391. // Attempt to open the store
  392. hStore = OpenStore(fSystemStore, pszStoreFilename);
  393. if (hStore == NULL)
  394. goto ErrorReturn;
  395. }
  396. {
  397. PCCTL_CONTEXT pCtl = NULL;
  398. DWORD i = 0;
  399. while (pCtl = CertFindCTLInStore(
  400. hStore,
  401. dwMsgAndCertEncodingType,
  402. dwFindFlags,
  403. dwFindType,
  404. pvFindPara,
  405. pCtl
  406. )) {
  407. if (fTimeValid && !IsTimeValidCtl(pCtl))
  408. continue;
  409. if (fTimeInvalid && IsTimeValidCtl(pCtl))
  410. continue;
  411. if (!fQuiet) {
  412. printf("===== %d =====\n", i);
  413. DisplayCtl(pCtl, dwDisplayFlags, hStore);
  414. if (fFindSubjectPara) {
  415. PCTL_ENTRY pEntry;
  416. pEntry = CertFindSubjectInCTL(
  417. dwMsgAndCertEncodingType,
  418. FindSubjectPara.dwSubjectType,
  419. FindSubjectPara.pvSubject,
  420. pCtl,
  421. 0 // dwFlags
  422. );
  423. printf("\n");
  424. if (pEntry)
  425. printf("Subject Index:: %d\n",
  426. pEntry - pCtl->pCtlInfo->rgCTLEntry);
  427. else
  428. PrintLastError("CertFindSubjectInCTL");
  429. }
  430. }
  431. i++;
  432. if (pszPutFilename) {
  433. printf("Putting\n");
  434. if (!WriteDERToFile(
  435. pszPutFilename,
  436. pCtl->pbCtlEncoded,
  437. pCtl->cbCtlEncoded
  438. ))
  439. PrintLastError("Put Ctl::WriteDERToFile");
  440. }
  441. if (fDelete) {
  442. PCCTL_CONTEXT pDeleteCtl;
  443. printf("Deleting\n");
  444. pDeleteCtl = CertDuplicateCTLContext(pCtl);
  445. if (!CertDeleteCTLFromStore(pDeleteCtl))
  446. PrintLastError("CertDeleteCTLFromStore");
  447. }
  448. }
  449. if (i == 0) {
  450. if (GetLastError() == CRYPT_E_NOT_FOUND)
  451. printf("CertFindCTLsInStore warning => CTL not found\n");
  452. else
  453. PrintLastError("CertFindCTLsInStore");
  454. } else if (fDelete && !fSystemStore)
  455. SaveStore(hStore, pszStoreFilename);
  456. }
  457. if (!CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
  458. PrintLastError("CertCloseStore");
  459. ReturnStatus = 0;
  460. goto CommonReturn;
  461. BadUsage:
  462. Usage();
  463. ErrorReturn:
  464. ReturnStatus = -1;
  465. CommonReturn:
  466. if (pSubjectCert)
  467. CertFreeCertificateContext(pSubjectCert);
  468. if (pIssuerCert)
  469. CertFreeCertificateContext(pIssuerCert);
  470. if (!ReturnStatus)
  471. printf("Passed\n");
  472. else
  473. printf("Failed\n");
  474. return ReturnStatus;
  475. }