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.

736 lines
25 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: tfindcer.cpp
  8. //
  9. // Contents: Cert Store Find API Tests
  10. //
  11. // See Usage() for list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 11-Apr-96 philh created
  17. // 07-Jun-96 HelleS Added printing the command line
  18. // and Failed or Passed at the end.
  19. // 20-Aug-96 jeffspel name changes
  20. //--------------------------------------------------------------------------
  21. #include <windows.h>
  22. #include <assert.h>
  23. #include "wincrypt.h"
  24. #include "certtest.h"
  25. #include "cryptuiapi.h"
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30. #include <memory.h>
  31. #include <time.h>
  32. #include <stddef.h>
  33. static CRYPT_ENCODE_PARA TestEncodePara = {
  34. offsetof(CRYPT_ENCODE_PARA, pfnFree) + sizeof(TestEncodePara.pfnFree),
  35. TestAlloc,
  36. TestFree
  37. };
  38. static BOOL AllocAndEncodeObject(
  39. IN LPCSTR lpszStructType,
  40. IN const void *pvStructInfo,
  41. OUT BYTE **ppbEncoded,
  42. OUT DWORD *pcbEncoded
  43. )
  44. {
  45. BOOL fResult;
  46. fResult = CryptEncodeObjectEx(
  47. dwCertEncodingType,
  48. lpszStructType,
  49. pvStructInfo,
  50. CRYPT_ENCODE_ALLOC_FLAG,
  51. &TestEncodePara,
  52. (void *) ppbEncoded,
  53. pcbEncoded
  54. );
  55. if (!fResult) {
  56. if ((DWORD_PTR) lpszStructType <= 0xFFFF)
  57. printf("CryptEncodeObject(StructType: %d)",
  58. (DWORD)(DWORD_PTR) lpszStructType);
  59. else
  60. printf("CryptEncodeObject(StructType: %s)",
  61. lpszStructType);
  62. PrintLastError("");
  63. }
  64. return fResult;
  65. }
  66. static void Usage(void)
  67. {
  68. printf("Usage: tfindcer [options] <StoreName> [<Name String>]\n");
  69. printf("Options are:\n");
  70. printf(" -h - This message\n");
  71. printf(" -D<digest> - Find cert matching Digest (Hash)\n");
  72. printf(" -S - Find cert matching Subject\n");
  73. printf(" -I - Find cert matching Issuer\n");
  74. printf(" -U<ObjectID> - Find cert matching Usage Identifiers\n");
  75. printf(" -F<number> - Find Flags\n");
  76. printf(" -f<filename> - Get matching Name from cert file\n");
  77. printf(" -o<ObjectID> - Object Identifier (1.2.3.4)\n");
  78. printf(" -t<ValueType> - Attribute value type (printableString - %d)\n", CERT_RDN_PRINTABLE_STRING);
  79. printf(" -a[<attributeString>] - Attribute value match\n");
  80. printf(" -A[<attributeString>] - Attribute value match (test unicode)\n");
  81. printf(" -C - Case Insensitive Attribute value match\n");
  82. printf(" -e<number> - Cert encoding type\n");
  83. printf(" -s - Open the \"StoreName\" System store\n");
  84. printf(" -p<filename> - Put encoded cert to file\n");
  85. printf(" -d - Delete cert\n");
  86. printf(" -7[<SaveFilename>] - PKCS# 7 formated save for delete\n");
  87. printf(" -b - Brief\n");
  88. printf(" -v - Verbose\n");
  89. printf(" -u - UI Dialog Viewer//Selection\n");
  90. printf(" -c - Verify checks enabled\n");
  91. printf(" -q - Quiet. Don't display certs\n");
  92. printf(" -xDelete - Delete CrossCertDistPoint property\n");
  93. printf(" -x<number> - CrossCertDistPoint sync delta seconds\n");
  94. printf(" -x<Url> - CrossCertDistPoint Url\n");
  95. printf(" -X<Url> - CrossCertDistPoint Alternate Url\n");
  96. printf("\n");
  97. printf("Default: find all certs in the store\n");
  98. }
  99. static BOOL AllocAndGetEncodedName(
  100. LPSTR pszCertFilename,
  101. DWORD dwFindInfo,
  102. BYTE **ppbEncodedName,
  103. DWORD *pcbEncodedName)
  104. {
  105. BOOL fResult;
  106. BYTE *pbEncodedCert = NULL;
  107. DWORD cbEncodedCert;
  108. PCCERT_CONTEXT pCert = NULL;
  109. BYTE *pbAllocEncodedName = NULL;
  110. BYTE *pbEncodedName;
  111. DWORD cbEncodedName;
  112. if (!ReadDERFromFile(pszCertFilename, &pbEncodedCert, &cbEncodedCert)) {
  113. PrintLastError("AllocAndGetEncodedName::ReadDERFromFile");
  114. goto ErrorReturn;
  115. }
  116. if (NULL == (pCert = CertCreateCertificateContext(
  117. dwCertEncodingType,
  118. pbEncodedCert,
  119. cbEncodedCert
  120. ))) {
  121. PrintLastError("AllocAndGetEncodedName::CertCreateCertificateContext");
  122. goto ErrorReturn;
  123. }
  124. if (dwFindInfo == CERT_INFO_SUBJECT_FLAG) {
  125. cbEncodedName = pCert->pCertInfo->Subject.cbData;
  126. pbEncodedName = pCert->pCertInfo->Subject.pbData;
  127. } else {
  128. cbEncodedName = pCert->pCertInfo->Issuer.cbData;
  129. pbEncodedName = pCert->pCertInfo->Issuer.pbData;
  130. }
  131. pbAllocEncodedName = (BYTE *) TestAlloc(cbEncodedName);
  132. if (pbAllocEncodedName == NULL) goto ErrorReturn;
  133. memcpy(pbAllocEncodedName, pbEncodedName, cbEncodedName);
  134. fResult = TRUE;
  135. goto CommonReturn;
  136. ErrorReturn:
  137. if (pbAllocEncodedName) {
  138. TestFree(pbAllocEncodedName);
  139. pbAllocEncodedName = NULL;
  140. }
  141. cbEncodedName = 0;
  142. fResult = FALSE;
  143. CommonReturn:
  144. if (pbEncodedCert)
  145. TestFree(pbEncodedCert);
  146. if (pCert)
  147. CertFreeCertificateContext(pCert);
  148. *ppbEncodedName = pbAllocEncodedName;
  149. *pcbEncodedName = cbEncodedName;
  150. return fResult;
  151. }
  152. static void DisplayFindAttr(DWORD cRDNAttr, CERT_RDN_ATTR rgRDNAttr[])
  153. {
  154. DWORD i;
  155. for (i = 0; i < cRDNAttr; i++) {
  156. LPSTR pszObjId = rgRDNAttr[i].pszObjId;
  157. LPSTR pszValue = (LPSTR) rgRDNAttr[i].Value.pbData;
  158. printf(" [%d] ", i);
  159. if (pszObjId)
  160. printf("%s ", pszObjId);
  161. if (rgRDNAttr[i].dwValueType)
  162. printf("ValueType: %d ", rgRDNAttr[i].dwValueType);
  163. if (pszValue == NULL)
  164. pszValue = "<NONE>";
  165. else {
  166. if (rgRDNAttr[i].Value.cbData)
  167. printf("Value: %s\n", pszValue);
  168. else
  169. // For UNICODE, cbData is 0.
  170. printf("Value: %S\n", (LPCSTR) pszValue);
  171. }
  172. }
  173. }
  174. typedef PCCERT_CONTEXT (WINAPI *PFN_CRYPT_UI_DLG_SELECT_CERTIFICATE_FROM_STORE)(
  175. IN HCERTSTORE hCertStore,
  176. IN OPTIONAL HWND hwnd, // Defaults to the desktop window
  177. IN OPTIONAL LPCWSTR pwszTitle,
  178. IN OPTIONAL LPCWSTR pwszDisplaystring,
  179. IN DWORD dwDontUseColumn,
  180. IN DWORD dwFlags,
  181. IN void *pvReserved
  182. );
  183. void SelectCertficateFromStoreUI(
  184. IN HCERTSTORE hStore,
  185. IN DWORD dwDisplayFlags
  186. )
  187. {
  188. HMODULE hDll = NULL;
  189. PCCERT_CONTEXT pCert = NULL;
  190. PFN_CRYPT_UI_DLG_SELECT_CERTIFICATE_FROM_STORE
  191. pfnCryptUIDlgSelectCertificateFromStore;
  192. if (NULL == (hDll = LoadLibraryA("cryptui.dll"))) {
  193. PrintLastError("LoadLibraryA(cryptui.dll)");
  194. goto CommonReturn;
  195. }
  196. if (NULL == (pfnCryptUIDlgSelectCertificateFromStore =
  197. (PFN_CRYPT_UI_DLG_SELECT_CERTIFICATE_FROM_STORE)
  198. GetProcAddress(hDll, "CryptUIDlgSelectCertificateFromStore"))) {
  199. PrintLastError("GetProcAddress(CryptUIDlgSelectCertificateFromStore)");
  200. goto CommonReturn;
  201. }
  202. pCert = pfnCryptUIDlgSelectCertificateFromStore(
  203. hStore,
  204. NULL, // hwnd
  205. NULL, // pwszTitle
  206. NULL, // pwszDisplaystring
  207. CRYPTUI_SELECT_INTENDEDUSE_COLUMN |
  208. CRYPTUI_SELECT_FRIENDLYNAME_COLUMN |
  209. CRYPTUI_SELECT_LOCATION_COLUMN,
  210. 0, // dwFlags
  211. NULL // pvReserved
  212. );
  213. if (NULL == pCert)
  214. PrintLastError("CryptUIDlgSelectCertificateFromStore");
  215. else {
  216. printf("===== Selected Certificate =====\n");
  217. DisplayCert(pCert, dwDisplayFlags & ~DISPLAY_UI_FLAG);
  218. }
  219. CommonReturn:
  220. if (pCert)
  221. CertFreeCertificateContext(pCert);
  222. if (hDll)
  223. FreeLibrary(hDll);
  224. }
  225. int _cdecl main(int argc, char * argv[])
  226. {
  227. int ReturnStatus;
  228. DWORD dwFindCmp = CERT_COMPARE_ANY;
  229. DWORD dwFindInfo = 0;
  230. LPSTR pszFindInfo = NULL;
  231. DWORD dwFindType;
  232. DWORD dwFindFlags = 0;
  233. void *pvFindPara = NULL;
  234. DWORD cbHash = 0;
  235. BYTE rgbHash[MAX_HASH_LEN];
  236. CRYPT_HASH_BLOB HashBlob;
  237. CERT_NAME_BLOB NameBlob;
  238. BYTE *pbEncodedName = NULL;
  239. DWORD cbEncodedName;
  240. #define MAX_RDN_ATTR 20
  241. DWORD cRDNAttr = 0;
  242. CERT_RDN_ATTR rgRDNAttr[MAX_RDN_ATTR + 1];
  243. memset (rgRDNAttr, 0, sizeof(rgRDNAttr));
  244. CERT_RDN NameRDN;
  245. #define MAX_USAGE_ID 20
  246. LPSTR rgpszUsageId[MAX_USAGE_ID];
  247. CTL_USAGE CtlUsage = {0, rgpszUsageId};
  248. BOOL fSystemStore = FALSE;
  249. BOOL fDelete = FALSE;
  250. LPSTR pszCertFilename = NULL;
  251. LPSTR pszStoreFilename = NULL;
  252. LPSTR pszPutFilename = NULL;
  253. LPSTR pszFindStr = NULL;
  254. DWORD dwDisplayFlags = 0;
  255. BOOL fQuiet = FALSE;
  256. BOOL fPKCS7Save = FALSE;
  257. LPSTR pszSaveFilename = NULL;
  258. #define MAX_DIST_POINT 10
  259. #define MAX_DIST_POINT_ALT_NAME_ENTRY 20
  260. CERT_ALT_NAME_INFO rgDistPoint[MAX_DIST_POINT];
  261. CERT_ALT_NAME_ENTRY rgDistPointAltNameEntry[MAX_DIST_POINT_ALT_NAME_ENTRY];
  262. CROSS_CERT_DIST_POINTS_INFO XCertInfo = {0, 0, rgDistPoint};
  263. DWORD cDistPointAltNameEntry = 0;
  264. BOOL fAddXCertProp = FALSE;
  265. BOOL fDeleteXCertProp = FALSE;
  266. BYTE *pbEncodedXCert = NULL;
  267. DWORD cbEncodedXCert;
  268. HANDLE hStore;
  269. while (--argc>0)
  270. {
  271. if (**++argv == '-')
  272. {
  273. switch(argv[0][1])
  274. {
  275. case 'D':
  276. {
  277. char *pszHash = argv[0]+2;
  278. int cchHash = strlen(pszHash);
  279. char rgch[3];
  280. if (!(cchHash == 32 || cchHash == 40)) {
  281. printf("Need 32 digits (MD5) or 40 digits (SHA) ");
  282. printf("for hash , not %d digits\n", cchHash);
  283. goto BadUsage;
  284. }
  285. if (32 == cchHash)
  286. dwFindCmp = CERT_COMPARE_MD5_HASH;
  287. else
  288. dwFindCmp = CERT_COMPARE_SHA1_HASH;
  289. cbHash = 0;
  290. while (cchHash > 0) {
  291. rgch[0] = *pszHash++;
  292. rgch[1] = *pszHash++;
  293. rgch[2] = '\0';
  294. rgbHash[cbHash++] = (BYTE) strtoul(rgch, NULL, 16);
  295. cchHash -= 2;
  296. }
  297. }
  298. break;
  299. case 'S':
  300. dwFindInfo = CERT_INFO_SUBJECT_FLAG;
  301. pszFindInfo = "subject";
  302. break;
  303. case 'I':
  304. dwFindInfo = CERT_INFO_ISSUER_FLAG;
  305. pszFindInfo = "issuer";
  306. break;
  307. case 'f':
  308. pszCertFilename = argv[0]+2;
  309. if (*pszCertFilename == '\0') {
  310. printf("Need to specify filename\n");
  311. goto BadUsage;
  312. }
  313. dwFindCmp = CERT_COMPARE_NAME;
  314. break;
  315. case 'o':
  316. rgRDNAttr[cRDNAttr].pszObjId = argv[0] + 2;
  317. break;
  318. case 't':
  319. rgRDNAttr[cRDNAttr].dwValueType =
  320. (DWORD) strtoul(argv[0]+2, NULL, 0);
  321. break;
  322. case 'a':
  323. if (cRDNAttr >= MAX_RDN_ATTR) {
  324. printf("Maximum number of attributes: %d\n", MAX_RDN_ATTR);
  325. goto BadUsage;
  326. }
  327. rgRDNAttr[cRDNAttr].Value.cbData = strlen(argv[0] + 2);
  328. if (rgRDNAttr[cRDNAttr].Value.cbData == 0)
  329. rgRDNAttr[cRDNAttr].Value.pbData = NULL;
  330. else
  331. rgRDNAttr[cRDNAttr].Value.pbData = (BYTE *) (argv[0] + 2);
  332. cRDNAttr++;
  333. dwFindCmp = CERT_COMPARE_ATTR;
  334. break;
  335. case 'A':
  336. if (cRDNAttr >= MAX_RDN_ATTR) {
  337. printf("Maximum number of attributes: %d\n", MAX_RDN_ATTR);
  338. goto BadUsage;
  339. }
  340. rgRDNAttr[cRDNAttr].Value.pbData =
  341. (BYTE *) AllocAndSzToWsz(argv[0]+2);
  342. rgRDNAttr[cRDNAttr].Value.cbData = 0;
  343. cRDNAttr++;
  344. dwFindFlags |= CERT_UNICODE_IS_RDN_ATTRS_FLAG;
  345. dwFindCmp = CERT_COMPARE_ATTR;
  346. break;
  347. case 'C':
  348. dwFindFlags |= CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG;
  349. break;
  350. case 'U':
  351. if (CtlUsage.cUsageIdentifier >= MAX_USAGE_ID) {
  352. printf("Maximum number of Usage Identifiers: %d\n",
  353. MAX_USAGE_ID);
  354. goto BadUsage;
  355. }
  356. if (0 < strlen(argv[0] + 2))
  357. rgpszUsageId[CtlUsage.cUsageIdentifier++] = argv[0] + 2;
  358. dwFindCmp = CERT_COMPARE_CTL_USAGE;
  359. break;
  360. case 'F':
  361. dwFindFlags = (DWORD) strtoul(argv[0]+2, NULL, 0);
  362. break;
  363. case 'p':
  364. pszPutFilename = argv[0]+2;
  365. if (*pszPutFilename == '\0') {
  366. printf("Need to specify filename\n");
  367. goto BadUsage;
  368. }
  369. break;
  370. case 'd':
  371. fDelete = TRUE;
  372. break;
  373. case '7':
  374. fPKCS7Save = TRUE;
  375. if (argv[0][2])
  376. pszSaveFilename = argv[0]+2;
  377. break;
  378. case 'b':
  379. dwDisplayFlags |= DISPLAY_BRIEF_FLAG;
  380. break;
  381. case 'v':
  382. dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
  383. break;
  384. case 'u':
  385. dwDisplayFlags |= DISPLAY_UI_FLAG;
  386. break;
  387. case 'c':
  388. dwDisplayFlags |= DISPLAY_CHECK_FLAG;
  389. break;
  390. case 'q':
  391. fQuiet = TRUE;
  392. break;
  393. case 's':
  394. fSystemStore = TRUE;
  395. break;
  396. case 'e':
  397. dwCertEncodingType = (DWORD) strtoul(argv[0]+2, NULL, 0);
  398. break;
  399. case 'x':
  400. case 'X':
  401. fAddXCertProp = TRUE;
  402. if (argv[0][2] == 0)
  403. ;
  404. else if (0 == _stricmp(argv[0]+2, "Delete"))
  405. fDeleteXCertProp = TRUE;
  406. else if (isdigit(argv[0][2]))
  407. XCertInfo.dwSyncDeltaTime =
  408. (DWORD) strtoul(argv[0]+2, NULL, 0);
  409. else {
  410. if (cDistPointAltNameEntry >=
  411. MAX_DIST_POINT_ALT_NAME_ENTRY) {
  412. printf("Exceeded DistPointAltNameEntry MaxCount(%d)\n",
  413. MAX_DIST_POINT_ALT_NAME_ENTRY);
  414. goto BadUsage;
  415. }
  416. if (XCertInfo.cDistPoint == 0 ||
  417. argv[0][1] == 'x') {
  418. if (XCertInfo.cDistPoint >= MAX_DIST_POINT) {
  419. printf("Exceeded DistPoint MaxCount(%d)\n",
  420. MAX_DIST_POINT);
  421. goto BadUsage;
  422. }
  423. XCertInfo.rgDistPoint[XCertInfo.cDistPoint].cAltEntry =
  424. 0;
  425. XCertInfo.rgDistPoint[XCertInfo.cDistPoint].rgAltEntry =
  426. &rgDistPointAltNameEntry[cDistPointAltNameEntry];
  427. XCertInfo.cDistPoint++;
  428. }
  429. rgDistPointAltNameEntry[cDistPointAltNameEntry].dwAltNameChoice =
  430. CERT_ALT_NAME_URL;
  431. rgDistPointAltNameEntry[cDistPointAltNameEntry].pwszURL =
  432. AllocAndSzToWsz(argv[0]+2);
  433. cDistPointAltNameEntry++;
  434. XCertInfo.rgDistPoint[XCertInfo.cDistPoint - 1].cAltEntry++;
  435. }
  436. break;
  437. case 'h':
  438. default:
  439. goto BadUsage;
  440. }
  441. } else {
  442. if (pszStoreFilename == NULL)
  443. pszStoreFilename = argv[0];
  444. else if (pszFindStr == NULL) {
  445. if (dwFindCmp != CERT_COMPARE_ANY) {
  446. printf("Invalid options for <Name String>\n");
  447. goto BadUsage;
  448. }
  449. dwFindCmp = CERT_COMPARE_NAME_STR_A;
  450. if (dwFindInfo == 0) {
  451. dwFindInfo = CERT_INFO_SUBJECT_FLAG;
  452. pszFindInfo = "subject";
  453. }
  454. pszFindStr = argv[0];
  455. } else {
  456. printf("Too many arguments\n");
  457. goto BadUsage;
  458. }
  459. }
  460. }
  461. printf("command line: %s\n", GetCommandLine());
  462. if (dwDisplayFlags & DISPLAY_VERBOSE_FLAG)
  463. dwDisplayFlags &= ~DISPLAY_BRIEF_FLAG;
  464. if (pszStoreFilename == NULL) {
  465. printf("missing store filename\n");
  466. goto BadUsage;
  467. }
  468. if (pszSaveFilename == NULL) {
  469. if (!fSystemStore)
  470. pszSaveFilename = pszStoreFilename;
  471. }
  472. dwFindType = dwFindCmp << CERT_COMPARE_SHIFT | dwFindInfo;
  473. switch (dwFindType) {
  474. case CERT_FIND_ANY:
  475. if (dwDisplayFlags & DISPLAY_UI_FLAG)
  476. printf("UI certificate selection\n");
  477. else
  478. printf("Finding all certificates\n");
  479. break;
  480. case CERT_FIND_MD5_HASH:
  481. case CERT_FIND_SHA1_HASH:
  482. {
  483. if (CERT_FIND_MD5_HASH == dwFindType)
  484. printf("Finding MD5 hash:: ");
  485. else
  486. printf("Finding SHA1 hash:: ");
  487. DWORD cb = cbHash;
  488. BYTE *pb = rgbHash;
  489. for (; cb > 0; cb--, pb++)
  490. printf("%02X", *pb);
  491. printf("\n");
  492. }
  493. HashBlob.pbData = rgbHash;
  494. HashBlob.cbData = cbHash;
  495. pvFindPara = &HashBlob;
  496. break;
  497. case CERT_FIND_SUBJECT_NAME:
  498. case CERT_FIND_ISSUER_NAME:
  499. printf("Finding %s name using CertFile %s\n",
  500. pszFindInfo, pszCertFilename);
  501. if (!AllocAndGetEncodedName(pszCertFilename, dwFindInfo,
  502. &pbEncodedName, &cbEncodedName))
  503. goto ErrorReturn;
  504. NameBlob.pbData = pbEncodedName;
  505. NameBlob.cbData = cbEncodedName;
  506. pvFindPara = &NameBlob;
  507. break;
  508. case CERT_FIND_SUBJECT_ATTR:
  509. case CERT_FIND_ISSUER_ATTR:
  510. printf("Finding %s name using attributes::\n", pszFindInfo);
  511. DisplayFindAttr(cRDNAttr, rgRDNAttr);
  512. NameRDN.cRDNAttr = cRDNAttr;
  513. NameRDN.rgRDNAttr = rgRDNAttr;
  514. pvFindPara = &NameRDN;
  515. break;
  516. case CERT_FIND_SUBJECT_STR_A:
  517. case CERT_FIND_ISSUER_STR_A:
  518. printf("Finding %s name matching:: %s\n", pszFindInfo, pszFindStr);
  519. pvFindPara = pszFindStr;
  520. break;
  521. case CERT_FIND_CTL_USAGE:
  522. if (dwFindFlags & CERT_FIND_OPTIONAL_CTL_USAGE_FLAG)
  523. printf("Enabled:: CERT_FIND_OPTIONAL_CTL_USAGE_FLAG\n");
  524. if (dwFindFlags & CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG)
  525. printf("Enabled:: CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG\n");
  526. if (dwFindFlags & CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG)
  527. printf("Enabled:: CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG\n");
  528. if (dwFindFlags & CERT_FIND_NO_CTL_USAGE_FLAG)
  529. printf("Enabled:: CERT_FIND_NO_CTL_USAGE_FLAG\n");
  530. if (0 == CtlUsage.cUsageIdentifier) {
  531. printf("No Usage Identifiers\n");
  532. pvFindPara = NULL;
  533. } else {
  534. LPSTR *ppszId = CtlUsage.rgpszUsageIdentifier;
  535. DWORD i;
  536. printf("Usage Identifiers::\n");
  537. for (i = 0; i < CtlUsage.cUsageIdentifier; i++, ppszId++)
  538. printf(" [%d] %s\n", i, *ppszId);
  539. pvFindPara = &CtlUsage;
  540. }
  541. break;
  542. default:
  543. printf("Bad dwFindType: %x\n", dwFindType);
  544. goto BadUsage;
  545. }
  546. if (fAddXCertProp && !fDeleteXCertProp) {
  547. printf("Encoding Cross Certificate Property\n");
  548. if (!AllocAndEncodeObject(
  549. X509_CROSS_CERT_DIST_POINTS,
  550. &XCertInfo,
  551. &pbEncodedXCert,
  552. &cbEncodedXCert))
  553. goto ErrorReturn;
  554. }
  555. // Attempt to open the store
  556. hStore = OpenStore(fSystemStore, pszStoreFilename);
  557. if (hStore == NULL)
  558. return -1;
  559. if (CERT_FIND_ANY == dwFindType && (dwDisplayFlags & DISPLAY_UI_FLAG)) {
  560. SelectCertficateFromStoreUI(hStore, dwDisplayFlags);
  561. } else {
  562. int i;
  563. PCCERT_CONTEXT pCert = NULL;
  564. PCCERT_CONTEXT pDeleteCert = NULL;
  565. for (i = 0;; i++) {
  566. pCert = CertFindCertificateInStore(
  567. hStore,
  568. dwCertEncodingType,
  569. dwFindFlags,
  570. dwFindType,
  571. pvFindPara,
  572. pCert
  573. );
  574. if (pCert == NULL) {
  575. if (i == 0) {
  576. if (GetLastError() == CRYPT_E_NOT_FOUND)
  577. printf(
  578. "CertFindCertificateInStore warning => cert not found\n");
  579. else
  580. PrintLastError("CertFindCertificateInStore");
  581. }
  582. break;
  583. }
  584. if (fDeleteXCertProp) {
  585. printf("Deleting Cross Certificate Property from following =>\n");
  586. if (!CertSetCertificateContextProperty(
  587. pCert,
  588. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  589. 0, // dwFlags
  590. NULL
  591. ))
  592. PrintLastError("CertSetCertificateContextProperty(Delete)");
  593. } else if (fAddXCertProp) {
  594. CRYPT_DATA_BLOB Data;
  595. printf("Adding Cross Certificate Property to following =>\n");
  596. Data.pbData = pbEncodedXCert;
  597. Data.cbData = cbEncodedXCert;
  598. if (!CertSetCertificateContextProperty(
  599. pCert,
  600. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  601. 0, // dwFlags
  602. &Data
  603. ))
  604. PrintLastError("CertSetCertificateContextProperty");
  605. }
  606. if (!fQuiet) {
  607. printf("===== %d =====\n", i);
  608. DisplayCert(pCert, dwDisplayFlags);
  609. }
  610. if (pszPutFilename) {
  611. printf("Putting\n");
  612. if (!WriteDERToFile(
  613. pszPutFilename,
  614. pCert->pbCertEncoded,
  615. pCert->cbCertEncoded
  616. ))
  617. PrintLastError("Put Cert::WriteDERToFile");
  618. }
  619. if (fDelete) {
  620. printf("Deleting\n");
  621. if (pDeleteCert) {
  622. if (!CertDeleteCertificateFromStore(pDeleteCert))
  623. PrintLastError("CertDeleteCertificateFromStore");
  624. }
  625. pDeleteCert = CertDuplicateCertificateContext(pCert);
  626. }
  627. }
  628. if (pDeleteCert) {
  629. if (!CertDeleteCertificateFromStore(pDeleteCert))
  630. PrintLastError("CertDeleteCertificateFromStore");
  631. if (!fSystemStore)
  632. SaveStoreEx(hStore, fPKCS7Save, pszSaveFilename);
  633. } else if (fAddXCertProp || fDeleteXCertProp) {
  634. if (!fSystemStore)
  635. SaveStoreEx(hStore, fPKCS7Save, pszSaveFilename);
  636. }
  637. }
  638. if (!CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
  639. PrintLastError("CertCloseStore");
  640. if (pbEncodedName)
  641. TestFree(pbEncodedName);
  642. ReturnStatus = 0;
  643. goto CommonReturn;
  644. BadUsage:
  645. Usage();
  646. ErrorReturn:
  647. ReturnStatus = -1;
  648. CommonReturn:
  649. while (cRDNAttr--) {
  650. if (0 == rgRDNAttr[cRDNAttr].Value.cbData &&
  651. rgRDNAttr[cRDNAttr].Value.pbData)
  652. // Allocated for unicode
  653. TestFree(rgRDNAttr[cRDNAttr].Value.pbData);
  654. }
  655. while (cDistPointAltNameEntry--)
  656. TestFree(rgDistPointAltNameEntry[cDistPointAltNameEntry].pwszURL);
  657. TestFree(pbEncodedXCert);
  658. if (!ReturnStatus)
  659. printf("Passed\n");
  660. else
  661. printf("Failed\n");
  662. return ReturnStatus;
  663. }