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.

2900 lines
63 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1999
  6. //
  7. // File: misc.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <pch.cpp>
  11. #pragma hdrstop
  12. #include <setupapi.h>
  13. #include <ocmanage.h>
  14. #include "certsrvd.h"
  15. #include "cscsp.h"
  16. #include "initcert.h"
  17. #include "csprop.h"
  18. #define __dwFILE__ __dwFILE_CERTUTIL_MISC_CPP__
  19. DWORD
  20. cuFileSize(
  21. IN WCHAR const *pwszfn)
  22. {
  23. WIN32_FILE_ATTRIBUTE_DATA fad;
  24. if (!GetFileAttributesEx(pwszfn, GetFileExInfoStandard, &fad))
  25. {
  26. fad.nFileSizeLow = 0;
  27. }
  28. return(fad.nFileSizeLow);
  29. }
  30. HRESULT
  31. verbHexTranslate(
  32. IN WCHAR const *pwszOption,
  33. IN WCHAR const *pwszfnIn,
  34. IN WCHAR const *pwszfnOut,
  35. IN OPTIONAL IN WCHAR const *pwszType,
  36. IN WCHAR const *pwszArg4)
  37. {
  38. BYTE *pbIn = NULL;
  39. DWORD cbIn;
  40. HRESULT hr;
  41. BOOL fEncode = g_wszEncodeHex == pwszOption;
  42. DWORD dwEncodeFlags;
  43. // Read in and decode the file.
  44. hr = DecodeFileW(
  45. pwszfnIn,
  46. &pbIn,
  47. &cbIn,
  48. fEncode? CRYPT_STRING_BINARY : CRYPT_STRING_HEX_ANY);
  49. if (S_OK != hr)
  50. {
  51. cuPrintError(IDS_ERR_FORMAT_DECODEFILE, hr);
  52. goto error;
  53. }
  54. CSASSERT(NULL != pbIn && 0 != cbIn);
  55. wprintf(
  56. myLoadResourceString(IDS_FORMAT_INPUT_LENGTH), // "Input Length = %d"
  57. cuFileSize(pwszfnIn));
  58. wprintf(wszNewLine);
  59. // Write encoded certificate to file
  60. dwEncodeFlags = CRYPT_STRING_BINARY;
  61. if (fEncode)
  62. {
  63. dwEncodeFlags = CRYPT_STRING_HEXASCIIADDR;
  64. if (NULL != pwszType)
  65. {
  66. BOOL fValid;
  67. dwEncodeFlags = myWtoI(pwszType, &fValid);
  68. if (!fValid)
  69. {
  70. hr = E_INVALIDARG;
  71. _JumpError(hr, error, "bad encoding type");
  72. }
  73. }
  74. dwEncodeFlags |= g_CryptEncodeFlags;
  75. }
  76. hr = EncodeToFileW(pwszfnOut, pbIn, cbIn, dwEncodeFlags | g_EncodeFlags);
  77. if (S_OK != hr)
  78. {
  79. cuPrintError(IDS_ERR_FORMAT_ENCODETOFILE, hr);
  80. goto error;
  81. }
  82. wprintf(
  83. myLoadResourceString(IDS_FORMAT_OUTPUT_LENGTH), // "Output Length = %d"
  84. cuFileSize(pwszfnOut));
  85. wprintf(wszNewLine);
  86. error:
  87. if (NULL != pbIn)
  88. {
  89. LocalFree(pbIn);
  90. }
  91. return(hr);
  92. }
  93. // If a CRL, return CRYPT_STRING_BASE64X509CRLHEADER.
  94. // If a cert or an empty PKCS7 with at least one cert, return
  95. // CRYPT_STRING_BASE64HEADER.
  96. // Otherwise, return CRYPT_STRING_BASE64REQUESTHEADER
  97. HRESULT
  98. GetBase64EncodeFlags(
  99. IN BYTE const *pbIn,
  100. IN DWORD cbIn,
  101. OUT DWORD *pdwEncodeFlags)
  102. {
  103. HRESULT hr;
  104. *pdwEncodeFlags = CRYPT_STRING_BASE64HEADER;
  105. // Try as a Cert:
  106. {
  107. CERT_CONTEXT const *pCertContext;
  108. pCertContext = CertCreateCertificateContext(
  109. X509_ASN_ENCODING,
  110. pbIn,
  111. cbIn);
  112. if (NULL != pCertContext)
  113. {
  114. CertFreeCertificateContext(pCertContext);
  115. goto error;
  116. }
  117. }
  118. // Try as a CRL:
  119. {
  120. CRL_CONTEXT const *pCRLContext;
  121. pCRLContext = CertCreateCRLContext(X509_ASN_ENCODING, pbIn, cbIn);
  122. if (NULL != pCRLContext)
  123. {
  124. CertFreeCRLContext(pCRLContext);
  125. *pdwEncodeFlags = CRYPT_STRING_BASE64X509CRLHEADER;
  126. goto error;
  127. }
  128. }
  129. // Try as a PKCS10, KeyGen or CMC request
  130. {
  131. BYTE *pbDecoded;
  132. DWORD cbDecoded;
  133. DWORD i;
  134. char const *rgpszStructType[] = {
  135. X509_CERT_REQUEST_TO_BE_SIGNED,
  136. X509_KEYGEN_REQUEST_TO_BE_SIGNED,
  137. CMC_DATA,
  138. };
  139. for (i = 0; i < ARRAYSIZE(rgpszStructType); i++)
  140. {
  141. if (myDecodeObject(
  142. X509_ASN_ENCODING,
  143. rgpszStructType[i],
  144. pbIn,
  145. cbIn,
  146. CERTLIB_USE_LOCALALLOC,
  147. (VOID **) &pbDecoded,
  148. &cbDecoded))
  149. {
  150. LocalFree(pbDecoded);
  151. *pdwEncodeFlags = CRYPT_STRING_BASE64REQUESTHEADER;
  152. goto error;
  153. }
  154. }
  155. }
  156. // Recurse on the PKCS7 to examine the innermost content
  157. {
  158. BYTE *pbContents;
  159. DWORD cbContents;
  160. DWORD dwMsgType;
  161. DWORD cRecipient;
  162. hr = myDecodePKCS7(
  163. pbIn,
  164. cbIn,
  165. &pbContents,
  166. &cbContents,
  167. &dwMsgType,
  168. NULL,
  169. NULL,
  170. &cRecipient,
  171. NULL,
  172. NULL);
  173. if (S_OK == hr)
  174. {
  175. if (CMSG_SIGNED == dwMsgType &&
  176. NULL != pbContents &&
  177. 0 != cbContents &&
  178. 0 == cRecipient)
  179. {
  180. DWORD dwEncodeFlags;
  181. hr = GetBase64EncodeFlags(
  182. pbContents,
  183. cbContents,
  184. pdwEncodeFlags);
  185. _JumpIfError(hr, error, "GetBase64EncodeFlags");
  186. }
  187. }
  188. }
  189. error:
  190. hr = S_OK;
  191. return(hr);
  192. }
  193. HRESULT
  194. verbBase64Translate(
  195. IN WCHAR const *pwszOption,
  196. IN WCHAR const *pwszfnIn,
  197. IN WCHAR const *pwszfnOut,
  198. IN WCHAR const *pwszArg3,
  199. IN WCHAR const *pwszArg4)
  200. {
  201. BYTE *pbIn = NULL;
  202. DWORD cbIn;
  203. HRESULT hr;
  204. BOOL fEncode = g_wszEncode == pwszOption;
  205. DWORD dwEncodeFlags;
  206. // Read in and decode the file.
  207. hr = DecodeFileW(
  208. pwszfnIn,
  209. &pbIn,
  210. &cbIn,
  211. fEncode? CRYPT_STRING_BINARY : CRYPT_STRING_BASE64_ANY);
  212. if (S_OK != hr)
  213. {
  214. cuPrintError(IDS_ERR_FORMAT_DECODEFILE, hr);
  215. goto error;
  216. }
  217. CSASSERT(NULL != pbIn && 0 != cbIn);
  218. dwEncodeFlags = CRYPT_STRING_BINARY;
  219. if (fEncode)
  220. {
  221. hr = GetBase64EncodeFlags(pbIn, cbIn, &dwEncodeFlags);
  222. _JumpIfError(hr, error, "GetBase64EncodeFlags");
  223. dwEncodeFlags |= g_CryptEncodeFlags;
  224. }
  225. wprintf(
  226. myLoadResourceString(IDS_FORMAT_INPUT_LENGTH), // "Input Length = %d"
  227. cuFileSize(pwszfnIn));
  228. wprintf(wszNewLine);
  229. // Write encoded certificate to file
  230. hr = EncodeToFileW(
  231. pwszfnOut,
  232. pbIn,
  233. cbIn,
  234. dwEncodeFlags | g_EncodeFlags);
  235. if (S_OK != hr)
  236. {
  237. cuPrintError(IDS_ERR_FORMAT_ENCODETOFILE, hr);
  238. goto error;
  239. }
  240. wprintf(
  241. myLoadResourceString(IDS_FORMAT_OUTPUT_LENGTH), // "Output Length = %d"
  242. cuFileSize(pwszfnOut));
  243. wprintf(wszNewLine);
  244. error:
  245. if (NULL != pbIn)
  246. {
  247. LocalFree(pbIn);
  248. }
  249. return(hr);
  250. }
  251. HRESULT
  252. TestCSP(
  253. IN WCHAR const *pwszProvName,
  254. IN DWORD const dwProvType,
  255. OPTIONAL WCHAR const *pwszKeyContainer)
  256. {
  257. HRESULT hr;
  258. HCRYPTPROV hProv = NULL;
  259. DWORD dwFlags = 0;
  260. if (NULL == pwszKeyContainer)
  261. {
  262. dwFlags |= CRYPT_VERIFYCONTEXT;
  263. }
  264. if (g_fCryptSilent)
  265. {
  266. dwFlags |= CRYPT_SILENT;
  267. }
  268. wprintf(
  269. L"CryptAcquireContext(%ws, %ws, %d, 0x%x)\n",
  270. NULL == pwszKeyContainer? L"Verify" : pwszKeyContainer,
  271. pwszProvName,
  272. dwProvType,
  273. dwFlags);
  274. if (!myCertSrvCryptAcquireContext(
  275. &hProv,
  276. pwszKeyContainer,
  277. pwszProvName,
  278. dwProvType,
  279. dwFlags,
  280. !g_fUserRegistry)) // fMachineKeyset
  281. {
  282. hr = myHLastError();
  283. cuPrintError(0, hr);
  284. _JumpErrorStr(hr, error, "myCertSrvCryptAcquireContext", pwszProvName);
  285. }
  286. wprintf(L"%ws\n", myLoadResourceString(IDS_PASS)); // "Pass"
  287. hr = S_OK;
  288. error:
  289. if (NULL != hProv)
  290. {
  291. CryptReleaseContext(hProv, 0);
  292. }
  293. return hr;
  294. }
  295. HRESULT
  296. EnumAndTestCSP(
  297. IN BOOL const fTest)
  298. {
  299. HRESULT hr;
  300. DWORD i;
  301. DWORD dwProvType;
  302. WCHAR *pwszProvName = NULL;
  303. BOOL fFirst = TRUE;
  304. for (i = 0; ; i++)
  305. {
  306. hr = myEnumProviders(i, NULL, 0, &dwProvType, &pwszProvName);
  307. if (S_OK != hr)
  308. {
  309. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr ||
  310. NTE_FAIL == hr)
  311. {
  312. // no more providers under type, terminate loop
  313. break;
  314. }
  315. // invalid csp entry, skip it
  316. wprintf(myLoadResourceString(IDS_FORMAT_SKIP_CSP_ENUM), i);
  317. wprintf(wszNewLine);
  318. }
  319. else
  320. {
  321. if (!fFirst)
  322. {
  323. wprintf(wszNewLine);
  324. }
  325. fFirst = FALSE;
  326. wprintf(myLoadResourceString(IDS_PROVIDER_NAME_COLON));
  327. wprintf(L" %ws\n", pwszProvName);
  328. wprintf(myLoadResourceString(IDS_PROVIDER_TYPE_COLON));
  329. wprintf(L" %d\n", dwProvType);
  330. if (fTest)
  331. {
  332. hr = TestCSP(pwszProvName, dwProvType, NULL);
  333. }
  334. LocalFree(pwszProvName);
  335. pwszProvName = NULL;
  336. }
  337. }
  338. hr = S_OK;
  339. //error:
  340. if (NULL != pwszProvName)
  341. {
  342. LocalFree(pwszProvName);
  343. }
  344. return(hr);
  345. }
  346. HRESULT
  347. verbCSPList(
  348. IN WCHAR const *pwszOption,
  349. IN WCHAR const *pwszArg1,
  350. IN WCHAR const *pwszArg2,
  351. IN WCHAR const *pwszArg3,
  352. IN WCHAR const *pwszArg4)
  353. {
  354. return EnumAndTestCSP(FALSE);
  355. }
  356. HRESULT
  357. verbCSPTest(
  358. IN WCHAR const *pwszOption,
  359. IN WCHAR const *pwszKeyContainer,
  360. IN WCHAR const *pwszArg2,
  361. IN WCHAR const *pwszArg3,
  362. IN WCHAR const *pwszArg4)
  363. {
  364. HRESULT hr;
  365. DWORD dwProvType;
  366. if (NULL != g_pwszCSP)
  367. {
  368. // get prov type
  369. hr = csiGetProviderTypeFromProviderName(g_pwszCSP, &dwProvType);
  370. _JumpIfError(hr, error, "GetProviderTypeFromProviderName");
  371. hr = TestCSP(g_pwszCSP, dwProvType, pwszKeyContainer);
  372. _JumpIfError(hr, error, "TestCSP");
  373. }
  374. else
  375. {
  376. hr = EnumAndTestCSP(TRUE);
  377. _JumpIfError(hr, error, "EnumAndTestCSP");
  378. }
  379. error:
  380. return(hr);
  381. }
  382. UINT enumCATypeRscMap[] =
  383. {
  384. IDS_ENTERPRISE_ROOT, // ENUM_ENTERPRISE_ROOT = 0
  385. IDS_ENTERPRISE_SUB, // ENUM_ENTERPRISE_SUBCA = 1
  386. IDS_CATYPE_UNKNOWN, // ENUM_UNUSED2 = 2
  387. IDS_STANDALONE_ROOT, // ENUM_STANDALONE_ROOTCA = 3
  388. IDS_STANDALONE_SUB, // ENUM_STANDALONE_SUBCA = 4
  389. // ENUM_UNKNOWN_CA = 5
  390. };
  391. typedef struct _CAINFOTABLE
  392. {
  393. WCHAR const *pwszCmdLineName;
  394. LONG lPropId;
  395. LONG lPropType;
  396. UINT ids;
  397. DWORD dwGetCert;
  398. DWORD Flags;
  399. WCHAR const *pwszRegName;
  400. } CAINFOTABLE;
  401. #define CAITF_FLAGSARG 0x00000001
  402. #define CAITF_INDEXARGMAXDWORD 0x00000002 // default index is MAXDWORD
  403. #define CAITF_INDEXARGZERO 0x00000004 // default index is 0
  404. #define CAITF_INDEXARGREQUIRED 0x00000008 // index required
  405. #define CAITF_SIGCERTCOUNT 0x00000010 // cCASigCert elements
  406. #define CAITF_XCHGCERTCOUNT 0x00000020 // cCAXchgCert elements
  407. #define CAITF_KRACERTCOUNT 0x00000040 // cCAXchgCert elements
  408. #define CAITF_EXITCOUNT 0x00000080 // exit mod count elements
  409. #define CAITF_ASN 0x00000100 // contains dumpable ASN object
  410. #define CAITF_DEFAULT 0x00000200 // default (unnamed) set
  411. #define CAITF_SKIPINVALIDARG 0x00000400 // skip if multiple & E_INVALIDARG
  412. #define CAITF_SKIP 0x00000800 // skip when enumerating all
  413. #define CAITF_OPTIONAL 0x00001000 // not always available
  414. #define CAITF_CRLSTATE 0x00002000 // depends on CRL state
  415. #define CAITF_FORWARDCROSSCERTSTATE 0x00004000 // depends on fwd cross state
  416. #define CAITF_BACKWARDCROSSCERTSTATE 0x00008000 // depends on rev cross state
  417. #define CAITF_INDEXARG (CAITF_INDEXARGMAXDWORD | \
  418. CAITF_INDEXARGZERO | \
  419. CAITF_INDEXARGREQUIRED)
  420. WCHAR const g_wszCAInfoCRL[] = L"crl";
  421. WCHAR const g_wszCAInfoCert[] = L"cert";
  422. WCHAR const g_wszCAInfoCertChain[] = L"certchain";
  423. WCHAR const g_wszCAInfoName[] = L"name";
  424. WCHAR const g_wszCAInfoSanitizedName[] = L"sanitizedname";
  425. WCHAR const g_wszCAInfoDSName[] = L"dsname";
  426. #define GETCERT_UNSUPPORTED MAXDWORD // not supported by old ICertRequest
  427. CAINFOTABLE g_aCAInfoTable[] =
  428. {
  429. {
  430. L"file",
  431. CR_PROP_FILEVERSION,
  432. PROPTYPE_STRING,
  433. IDS_PROP_FILEVERSION,
  434. GETCERT_FILEVERSION,
  435. 0,
  436. NULL,
  437. },
  438. {
  439. L"product",
  440. CR_PROP_PRODUCTVERSION,
  441. PROPTYPE_STRING,
  442. IDS_PROP_PRODUCTVERSION,
  443. GETCERT_PRODUCTVERSION,
  444. 0,
  445. NULL,
  446. },
  447. {
  448. L"exitcount",
  449. CR_PROP_EXITCOUNT,
  450. PROPTYPE_LONG,
  451. IDS_PROP_EXITCOUNT,
  452. GETCERT_UNSUPPORTED,
  453. CAITF_DEFAULT,
  454. NULL,
  455. },
  456. {
  457. L"exit",
  458. CR_PROP_EXITDESCRIPTION,
  459. PROPTYPE_STRING,
  460. IDS_PROP_EXITDESCRIPTION,
  461. GETCERT_EXITVERSIONBYINDEX,
  462. CAITF_INDEXARGZERO | CAITF_EXITCOUNT,
  463. NULL,
  464. },
  465. {
  466. L"policy",
  467. CR_PROP_POLICYDESCRIPTION,
  468. PROPTYPE_STRING,
  469. IDS_PROP_POLICYDESCRIPTION,
  470. GETCERT_POLICYVERSION,
  471. 0,
  472. NULL,
  473. },
  474. {
  475. g_wszCAInfoName,
  476. CR_PROP_CANAME,
  477. PROPTYPE_STRING,
  478. IDS_PROP_CANAME,
  479. GETCERT_CANAME,
  480. CAITF_DEFAULT,
  481. NULL,
  482. },
  483. {
  484. g_wszCAInfoSanitizedName,
  485. CR_PROP_SANITIZEDCANAME,
  486. PROPTYPE_STRING,
  487. IDS_PROP_SANITIZEDCANAME,
  488. GETCERT_SANITIZEDCANAME,
  489. 0,
  490. NULL,
  491. },
  492. {
  493. g_wszCAInfoDSName,
  494. CR_PROP_SANITIZEDCASHORTNAME,
  495. PROPTYPE_STRING,
  496. IDS_PROP_SANITIZEDCASHORTNAME,
  497. GETCERT_UNSUPPORTED,
  498. CAITF_DEFAULT | CAITF_OPTIONAL,
  499. NULL,
  500. },
  501. {
  502. L"sharedfolder",
  503. CR_PROP_SHAREDFOLDER,
  504. PROPTYPE_STRING,
  505. IDS_PROP_SHAREDFOLDER,
  506. GETCERT_SHAREDFOLDER,
  507. CAITF_OPTIONAL,
  508. NULL,
  509. },
  510. {
  511. L"error1",
  512. CR_PROP_NONE, // separate method call in ICertRequest2
  513. PROPTYPE_STRING,
  514. IDS_PROP_ERROR1,
  515. GETCERT_ERRORTEXT1,
  516. CAITF_FLAGSARG | CAITF_SKIP,
  517. NULL,
  518. },
  519. {
  520. L"error2",
  521. CR_PROP_NONE, // separate method call in ICertRequest2
  522. PROPTYPE_STRING,
  523. IDS_PROP_ERROR2,
  524. GETCERT_ERRORTEXT2,
  525. CAITF_FLAGSARG | CAITF_SKIP,
  526. NULL,
  527. },
  528. {
  529. L"type",
  530. CR_PROP_CATYPE,
  531. PROPTYPE_LONG,
  532. IDS_PROP_CATYPE,
  533. GETCERT_CATYPE,
  534. CAITF_DEFAULT,
  535. wszPROPCATYPE,
  536. },
  537. {
  538. L"info",
  539. CR_PROP_NONE, // not supported by ICertRequest2
  540. PROPTYPE_BINARY,
  541. IDS_PROP_CAINFO,
  542. GETCERT_CAINFO,
  543. 0,
  544. NULL,
  545. },
  546. {
  547. L"parent",
  548. CR_PROP_PARENTCA,
  549. PROPTYPE_STRING,
  550. IDS_PROP_PARENTCA,
  551. GETCERT_PARENTCONFIG,
  552. CAITF_OPTIONAL,
  553. NULL,
  554. },
  555. {
  556. L"certcount",
  557. CR_PROP_CASIGCERTCOUNT,
  558. PROPTYPE_LONG,
  559. IDS_PROP_CASIGCERTCOUNT,
  560. GETCERT_UNSUPPORTED,
  561. CAITF_DEFAULT,
  562. NULL,
  563. },
  564. {
  565. L"xchgcount",
  566. CR_PROP_CAXCHGCERTCOUNT,
  567. PROPTYPE_LONG,
  568. IDS_PROP_CAXCHGCERTCOUNT,
  569. GETCERT_UNSUPPORTED,
  570. 0,
  571. NULL,
  572. },
  573. {
  574. L"kracount",
  575. CR_PROP_KRACERTCOUNT,
  576. PROPTYPE_LONG,
  577. IDS_PROP_KRACERTCOUNT,
  578. GETCERT_UNSUPPORTED,
  579. CAITF_DEFAULT,
  580. NULL,
  581. },
  582. {
  583. L"kraused",
  584. CR_PROP_KRACERTUSEDCOUNT,
  585. PROPTYPE_LONG,
  586. IDS_PROP_KRACERTUSEDCOUNT,
  587. GETCERT_UNSUPPORTED,
  588. CAITF_DEFAULT,
  589. NULL,
  590. },
  591. {
  592. L"propidmax",
  593. CR_PROP_CAPROPIDMAX,
  594. PROPTYPE_LONG,
  595. IDS_PROP_CAPROPIDMAX,
  596. GETCERT_UNSUPPORTED,
  597. 0,
  598. NULL,
  599. },
  600. // Cert and CRL state:
  601. {
  602. L"certstate",
  603. CR_PROP_CACERTSTATE,
  604. PROPTYPE_LONG,
  605. IDS_PROP_CACERTSTATE,
  606. GETCERT_CACERTSTATEBYINDEX,
  607. CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
  608. NULL,
  609. },
  610. {
  611. L"certversion",
  612. CR_PROP_CACERTVERSION,
  613. PROPTYPE_LONG,
  614. IDS_PROP_CACERTVERSION,
  615. GETCERT_UNSUPPORTED,
  616. CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
  617. NULL,
  618. },
  619. {
  620. L"certstatuscode",
  621. CR_PROP_CACERTSTATUSCODE,
  622. PROPTYPE_LONG,
  623. IDS_PROP_CACERSTATUSCODE,
  624. GETCERT_UNSUPPORTED,
  625. CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
  626. NULL,
  627. },
  628. {
  629. L"crlstate",
  630. CR_PROP_CRLSTATE,
  631. PROPTYPE_LONG,
  632. IDS_PROP_CRLSTATE,
  633. GETCERT_CRLSTATEBYINDEX,
  634. CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT,
  635. NULL,
  636. },
  637. {
  638. L"krastate",
  639. CR_PROP_KRACERTSTATE,
  640. PROPTYPE_LONG,
  641. IDS_PROP_KRACERTSTATE,
  642. GETCERT_UNSUPPORTED,
  643. CAITF_INDEXARGZERO | CAITF_KRACERTCOUNT | CAITF_DEFAULT,
  644. NULL,
  645. },
  646. {
  647. L"crossstate+",
  648. CR_PROP_CAFORWARDCROSSCERTSTATE,
  649. PROPTYPE_LONG,
  650. IDS_PROP_CAFORWARDCROSSCERTSTATE,
  651. GETCERT_UNSUPPORTED,
  652. CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT,
  653. NULL,
  654. },
  655. {
  656. L"crossstate-",
  657. CR_PROP_CABACKWARDCROSSCERTSTATE,
  658. PROPTYPE_LONG,
  659. IDS_PROP_CABACKWARDCROSSCERTSTATE,
  660. GETCERT_UNSUPPORTED,
  661. CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT,
  662. NULL,
  663. },
  664. // Signature certs:
  665. {
  666. g_wszCAInfoCert, // L"cert"
  667. CR_PROP_CASIGCERT,
  668. PROPTYPE_BINARY,
  669. IDS_PROP_CASIGCERT,
  670. GETCERT_CACERTBYINDEX, // GETCERT_CASIGCERT handled by code hack
  671. CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
  672. NULL,
  673. },
  674. {
  675. g_wszCAInfoCertChain, // L"certchain"
  676. CR_PROP_CASIGCERTCHAIN,
  677. PROPTYPE_BINARY,
  678. IDS_PROP_CASIGCERTCHAIN,
  679. GETCERT_CACERTBYINDEX | GETCERT_CHAIN, // GETCERT_CASIGCERT | GETCERT_CHAIN handled by code hack
  680. CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
  681. NULL,
  682. },
  683. {
  684. L"certcrlchain",
  685. CR_PROP_CASIGCERTCRLCHAIN,
  686. PROPTYPE_BINARY,
  687. IDS_PROP_CASIGCERTCRLCHAIN,
  688. GETCERT_CACERTBYINDEX | GETCERT_CHAIN | GETCERT_CRLS,
  689. CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
  690. NULL,
  691. },
  692. // Exchange certs:
  693. {
  694. L"xchg",
  695. CR_PROP_CAXCHGCERT,
  696. PROPTYPE_BINARY,
  697. IDS_PROP_CAXCHGCERT,
  698. GETCERT_UNSUPPORTED,
  699. CAITF_INDEXARGMAXDWORD | CAITF_XCHGCERTCOUNT | CAITF_ASN,
  700. NULL,
  701. },
  702. {
  703. L"xchgchain",
  704. CR_PROP_CAXCHGCERTCHAIN,
  705. PROPTYPE_BINARY,
  706. IDS_PROP_CAXCHGCERTCHAIN,
  707. GETCERT_UNSUPPORTED,
  708. CAITF_INDEXARGMAXDWORD | CAITF_XCHGCERTCOUNT | CAITF_ASN,
  709. NULL,
  710. },
  711. {
  712. L"xchgcrlchain",
  713. CR_PROP_CAXCHGCERTCRLCHAIN,
  714. PROPTYPE_BINARY,
  715. IDS_PROP_CAXCHGCERTCRLCHAIN,
  716. GETCERT_UNSUPPORTED,
  717. CAITF_INDEXARGMAXDWORD | CAITF_XCHGCERTCOUNT | CAITF_ASN,
  718. NULL,
  719. },
  720. // KRA certs:
  721. {
  722. L"kra",
  723. CR_PROP_KRACERT,
  724. PROPTYPE_BINARY,
  725. IDS_PROP_KRACERT,
  726. GETCERT_UNSUPPORTED,
  727. CAITF_INDEXARGMAXDWORD | CAITF_KRACERTCOUNT | CAITF_ASN,
  728. NULL,
  729. },
  730. // Cross certs:
  731. {
  732. L"cross+",
  733. CR_PROP_CAFORWARDCROSSCERT,
  734. PROPTYPE_BINARY,
  735. IDS_PROP_CAFORWARDCROSSCERT,
  736. GETCERT_UNSUPPORTED,
  737. CAITF_FORWARDCROSSCERTSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
  738. NULL,
  739. },
  740. {
  741. L"cross-",
  742. CR_PROP_CABACKWARDCROSSCERT,
  743. PROPTYPE_BINARY,
  744. IDS_PROP_CABACKWARDCROSSCERT,
  745. GETCERT_UNSUPPORTED,
  746. CAITF_BACKWARDCROSSCERTSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
  747. NULL,
  748. },
  749. // CRLs:
  750. {
  751. g_wszCAInfoCRL, // L"CRL"
  752. CR_PROP_BASECRL,
  753. PROPTYPE_BINARY,
  754. IDS_PROP_BASECRL,
  755. GETCERT_CRLBYINDEX, // GETCERT_CURRENTCRL handled by code hack
  756. CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
  757. NULL,
  758. },
  759. {
  760. L"deltacrl",
  761. CR_PROP_DELTACRL,
  762. PROPTYPE_BINARY,
  763. IDS_PROP_DELTACRL,
  764. GETCERT_UNSUPPORTED,
  765. CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGMAXDWORD | CAITF_SIGCERTCOUNT | CAITF_ASN,
  766. NULL,
  767. },
  768. {
  769. L"crlstatus",
  770. CR_PROP_BASECRLPUBLISHSTATUS,
  771. PROPTYPE_LONG,
  772. IDS_PROP_BASECRLPUBLISHSTATUS,
  773. GETCERT_UNSUPPORTED,
  774. CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT | CAITF_OPTIONAL,
  775. wszPROPCRLPUBLISHFLAGS,
  776. },
  777. {
  778. L"deltacrlstatus",
  779. CR_PROP_DELTACRLPUBLISHSTATUS,
  780. PROPTYPE_LONG,
  781. IDS_PROP_DELTACRLPUBLISHSTATUS,
  782. GETCERT_UNSUPPORTED,
  783. CAITF_CRLSTATE | CAITF_SKIPINVALIDARG | CAITF_INDEXARGZERO | CAITF_SIGCERTCOUNT | CAITF_DEFAULT | CAITF_OPTIONAL,
  784. wszPROPCRLPUBLISHFLAGS,
  785. },
  786. {
  787. L"dns",
  788. CR_PROP_DNSNAME,
  789. PROPTYPE_STRING,
  790. IDS_PROP_DNSNAME,
  791. GETCERT_UNSUPPORTED,
  792. CAITF_DEFAULT | CAITF_OPTIONAL,
  793. NULL,
  794. },
  795. {
  796. L"role",
  797. CR_PROP_ROLESEPARATIONENABLED,
  798. PROPTYPE_LONG,
  799. IDS_PROP_ROLESEPARATIONENABLED,
  800. GETCERT_UNSUPPORTED,
  801. CAITF_OPTIONAL | CAITF_SKIP,
  802. NULL,
  803. },
  804. {
  805. L"ads",
  806. CR_PROP_ADVANCEDSERVER,
  807. PROPTYPE_LONG,
  808. IDS_PROP_ADVANCEDSERVER,
  809. GETCERT_UNSUPPORTED,
  810. CAITF_DEFAULT | CAITF_OPTIONAL,
  811. NULL,
  812. },
  813. {
  814. L"templates",
  815. CR_PROP_TEMPLATES,
  816. PROPTYPE_STRING,
  817. IDS_PROP_TEMPLATES,
  818. GETCERT_UNSUPPORTED,
  819. CAITF_SKIPINVALIDARG | CAITF_OPTIONAL,
  820. NULL,
  821. },
  822. {
  823. NULL,
  824. },
  825. };
  826. typedef HRESULT (FNPROP_INIT)(
  827. IN DWORD Flags,
  828. IN OUT DISPATCHINTERFACE *pdiProp);
  829. typedef VOID (FNPROP_RELEASE)(
  830. IN OUT DISPATCHINTERFACE *pdiProp);
  831. typedef HRESULT (FNPROP2_GETCAPROPERTY)(
  832. IN DISPATCHINTERFACE *pdiRequest,
  833. IN WCHAR const *pwszConfig,
  834. IN LONG PropId,
  835. IN LONG PropIndex,
  836. IN LONG PropType,
  837. IN LONG Flags,
  838. OUT VOID *pPropertyValue);
  839. typedef HRESULT (FNPROP2_GETCAPROPERTYFLAGS)(
  840. IN DISPATCHINTERFACE *pdiProp,
  841. IN WCHAR const *pwszConfig,
  842. IN LONG PropId,
  843. OUT LONG *pPropFlags);
  844. typedef HRESULT (FNPROP2_GETCAPROPERTYDISPLAYNAME)(
  845. IN DISPATCHINTERFACE *pdiProp,
  846. IN WCHAR const *pwszConfig,
  847. IN LONG PropId,
  848. OUT BSTR *pstrDisplayName);
  849. FNPROP_INIT *g_pfnProp_Init;
  850. FNPROP_RELEASE *g_pfnProp_Release;
  851. FNPROP2_GETCAPROPERTY *g_pfnProp2_GetCAProperty;
  852. FNPROP2_GETCAPROPERTYFLAGS *g_pfnProp2_GetCAPropertyFlags;
  853. FNPROP2_GETCAPROPERTYDISPLAYNAME *g_pfnProp2_GetCAPropertyDisplayName;
  854. VOID
  855. InitPropFunctionPointers(VOID)
  856. {
  857. if (g_fAdminInterface)
  858. {
  859. g_pfnProp_Init = Admin_Init;
  860. g_pfnProp_Release = Admin_Release;
  861. g_pfnProp2_GetCAProperty = Admin2_GetCAProperty;
  862. g_pfnProp2_GetCAPropertyFlags = Admin2_GetCAPropertyFlags;
  863. g_pfnProp2_GetCAPropertyDisplayName = Admin2_GetCAPropertyDisplayName;
  864. }
  865. else
  866. {
  867. g_pfnProp_Init = Request_Init;
  868. g_pfnProp_Release = Request_Release;
  869. g_pfnProp2_GetCAProperty = Request2_GetCAProperty;
  870. g_pfnProp2_GetCAPropertyFlags = Request2_GetCAPropertyFlags;
  871. g_pfnProp2_GetCAPropertyDisplayName = Request2_GetCAPropertyDisplayName;
  872. }
  873. }
  874. VOID
  875. cuCAInfoUsage(VOID)
  876. {
  877. CAINFOTABLE const *pcait;
  878. UINT id;
  879. wprintf(wszNewLine);
  880. wprintf(L" %ws\n", myLoadResourceString(IDS_CAINFO_USAGEHEADERCOLON)); // "InfoName argument values:"
  881. for (pcait = g_aCAInfoTable; NULL != pcait->pwszCmdLineName; pcait++)
  882. {
  883. id = 0;
  884. wprintf(L"\t%ws", pcait->pwszCmdLineName);
  885. if (CAITF_FLAGSARG & pcait->Flags)
  886. {
  887. id = IDS_CAINFO_USAGEERROR;
  888. }
  889. if (CAITF_INDEXARG & pcait->Flags)
  890. {
  891. id = IDS_CAINFO_USAGEINDEX;
  892. }
  893. if (0 != id)
  894. {
  895. wprintf(L" %ws", myLoadResourceString(id));
  896. }
  897. wprintf(L" -- %ws", myLoadResourceString(pcait->ids));
  898. wprintf(wszNewLine);
  899. }
  900. }
  901. BOOL
  902. cuParseDecimal(
  903. IN OUT WCHAR const **ppwc,
  904. IN OUT DWORD *pcwc,
  905. OUT DWORD *pdw)
  906. {
  907. BOOL fFound = FALSE;
  908. WCHAR const *pwc = *ppwc;
  909. DWORD cwc = *pcwc;
  910. DWORD dw = 0;
  911. while (0 != cwc && iswdigit(*pwc))
  912. {
  913. dw = (10 * dw) + *pwc++ - L'0';
  914. cwc--;
  915. fFound = TRUE;
  916. }
  917. if (fFound && 0 != cwc && L',' == *pwc)
  918. {
  919. pwc++;
  920. cwc--;
  921. }
  922. *ppwc = pwc;
  923. *pcwc = cwc;
  924. *pdw = dw;
  925. return(fFound);
  926. }
  927. UINT enumDispositionResourceMap[] =
  928. {
  929. IDS_CADISP_INCOMPLETE, // CA_DISP_INCOMPLETE = 0
  930. IDS_CADISP_ERROR, // CA_DISP_ERROR = 1
  931. //IDS_CADISP_ERROR_CRL, // CA_DISP_ERROR = 1
  932. IDS_CADISP_REVOKED, // CA_DISP_REVOKED = 2
  933. IDS_CADISP_VALID, // CA_DISP_VALID = 3
  934. IDS_CADISP_EXPIRED, // CA_DISP_INVALID = 4
  935. IDS_CADISP_UNDERSUBMISSION, // CA_DISP_UNDER_SUBMISSION = 5
  936. //IDS_CADISP_UNKNOWN, // ???
  937. };
  938. VOID
  939. DisplayCAState(
  940. IN LONG lPropId,
  941. IN DWORD State)
  942. {
  943. UINT id;
  944. CSASSERT(
  945. CR_PROP_CACERTSTATE == lPropId ||
  946. CR_PROP_CRLSTATE == lPropId ||
  947. CR_PROP_CAFORWARDCROSSCERTSTATE == lPropId ||
  948. CR_PROP_CABACKWARDCROSSCERTSTATE == lPropId);
  949. id = IDS_CADISP_UNKNOWN;
  950. if (ARRAYSIZE(enumDispositionResourceMap) > State)
  951. {
  952. id = enumDispositionResourceMap[State];
  953. if (IDS_CADISP_ERROR == id && CR_PROP_CRLSTATE == lPropId)
  954. {
  955. id = IDS_CADISP_ERROR_CRL; // "Error: No CRL for this Cert"
  956. }
  957. }
  958. wprintf(L" -- %ws", myLoadResourceString(id)); // "Valid", etc.
  959. wprintf(wszNewLine);
  960. }
  961. VOID
  962. DisplayCAVersion(
  963. IN LONG longValue)
  964. {
  965. wprintf(
  966. L" -- V%u.%u\n",
  967. CANAMEIDTOICERT(longValue),
  968. CANAMEIDTOIKEY(longValue));
  969. }
  970. UINT enumKRADispositionResourceMap[] =
  971. {
  972. IDS_CADISP_EXPIRED, // KRA_DISP_EXPIRED = 0
  973. IDS_KRADISP_NOTFOUND, // KRA_DISP_NOTFOUND = 1
  974. IDS_CADISP_REVOKED, // KRA_DISP_REVOKED = 2
  975. IDS_CADISP_VALID, // KRA_DISP_VALID = 3
  976. IDS_KRADISP_INVALID, // KRA_DISP_INVALID = 4
  977. IDS_KRADISP_UNTRUSTED, // KRA_DISP_UNTRUSTED = 5
  978. IDS_KRADISP_NOTLOADED, // KRA_DISP_NOTLOADED = 6
  979. //IDS_CADISP_UNKNOWN, // ???
  980. };
  981. VOID
  982. DisplayKRAState(
  983. IN DWORD State)
  984. {
  985. UINT id;
  986. id = IDS_CADISP_UNKNOWN;
  987. if (ARRAYSIZE(enumKRADispositionResourceMap) > State)
  988. {
  989. id = enumKRADispositionResourceMap[State];
  990. }
  991. wprintf(L" -- %ws", myLoadResourceString(id)); // "Valid", etc.
  992. wprintf(wszNewLine);
  993. }
  994. VOID
  995. cuDisplayCAType(
  996. IN LONG CAType)
  997. {
  998. UINT uid;
  999. if (CAType >= ARRAYSIZE(enumCATypeRscMap))
  1000. {
  1001. uid = IDS_CATYPE_UNKNOWN;
  1002. }
  1003. else
  1004. {
  1005. uid = enumCATypeRscMap[CAType];
  1006. }
  1007. wprintf(myLoadResourceString(uid), CAType);
  1008. wprintf(wszNewLine);
  1009. }
  1010. //+-------------------------------------------------------------------------
  1011. // cuGetCAInfoPropertyByIndex -- display one CA Property for one index value.
  1012. //
  1013. //--------------------------------------------------------------------------
  1014. HRESULT
  1015. cuGetCAInfoPropertyByIndex(
  1016. OPTIONAL IN WCHAR const *pwszOption,
  1017. OPTIONAL IN WCHAR const *pwszfnOut,
  1018. OPTIONAL IN WCHAR const *pwszInfoName,
  1019. OPTIONAL IN LONG const *pPropIndex,
  1020. IN CAINFOTABLE const *pcait,
  1021. IN OUT DISPATCHINTERFACE *pdiProp,
  1022. IN BOOL fV1,
  1023. IN BOOL fDisplayResult,
  1024. OPTIONAL OUT DWORD *pdwValue)
  1025. {
  1026. HRESULT hr;
  1027. BYTE *pbBinary = NULL;
  1028. DWORD cbBinary;
  1029. DWORD dwGetCertType;
  1030. DWORD Format;
  1031. DWORD Index = 0;
  1032. DWORD IndexV1 = 0;
  1033. LONG longValue;
  1034. BSTR strValue = NULL;
  1035. BOOL fVerbose = FALSE;
  1036. BOOL fVerboseOld = g_fVerbose;
  1037. BOOL fDisplayed = FALSE;
  1038. if (NULL != pdwValue)
  1039. {
  1040. *pdwValue = MAXDWORD;
  1041. }
  1042. if (g_fVerbose)
  1043. {
  1044. g_fVerbose--;
  1045. fVerbose = TRUE;
  1046. }
  1047. dwGetCertType = pcait->dwGetCert;
  1048. if ((CAITF_INDEXARG | CAITF_FLAGSARG) & pcait->Flags)
  1049. {
  1050. if (NULL == pPropIndex)
  1051. {
  1052. if ((CAITF_INDEXARGREQUIRED | CAITF_FLAGSARG) & pcait->Flags)
  1053. {
  1054. hr = E_INVALIDARG;
  1055. _JumpError(hr, error, "missing numeric arg");
  1056. }
  1057. if (CAITF_INDEXARGMAXDWORD & pcait->Flags)
  1058. {
  1059. Index = MAXDWORD;
  1060. }
  1061. switch (pcait->lPropId)
  1062. {
  1063. case CR_PROP_BASECRL:
  1064. dwGetCertType = GETCERT_CURRENTCRL;
  1065. break;
  1066. case CR_PROP_CASIGCERT:
  1067. dwGetCertType = GETCERT_CASIGCERT;
  1068. break;
  1069. case CR_PROP_CASIGCERTCHAIN:
  1070. dwGetCertType = GETCERT_CASIGCERT | GETCERT_CHAIN;
  1071. break;
  1072. }
  1073. }
  1074. else
  1075. {
  1076. Index = *pPropIndex;
  1077. IndexV1 = Index;
  1078. }
  1079. if (0 == (CAITF_FLAGSARG & pcait->Flags))
  1080. {
  1081. if (GETCERT_INDEXVALUEMASK < IndexV1)
  1082. {
  1083. hr = E_INVALIDARG;
  1084. _JumpError(hr, error, "index too large");
  1085. }
  1086. CSASSERT(
  1087. 0 == IndexV1 ||
  1088. GETCERT_UNSUPPORTED == dwGetCertType ||
  1089. 0 == (GETCERT_INDEXVALUEMASK & dwGetCertType));
  1090. }
  1091. }
  1092. else
  1093. {
  1094. if (NULL != pPropIndex)
  1095. {
  1096. hr = E_INVALIDARG;
  1097. _JumpError(hr, error, "too many args");
  1098. }
  1099. }
  1100. if (!fV1)
  1101. {
  1102. if (CR_PROP_NONE != pcait->lPropId)
  1103. {
  1104. hr = (*g_pfnProp2_GetCAProperty)(
  1105. pdiProp,
  1106. g_pwszConfig,
  1107. pcait->lPropId,
  1108. Index,
  1109. pcait->lPropType,
  1110. PROPTYPE_BINARY == pcait->lPropType?
  1111. CV_OUT_BASE64HEADER : CV_OUT_BINARY,
  1112. PROPTYPE_LONG == pcait->lPropType?
  1113. (VOID *) &longValue : (VOID *) &strValue);
  1114. if (E_NOTIMPL != hr && RPC_E_VERSION_MISMATCH != hr)
  1115. {
  1116. _JumpIfError2(hr, error, "g_pfnProp2_GetCAProperty", hr);
  1117. }
  1118. else
  1119. {
  1120. fV1 = TRUE;
  1121. }
  1122. }
  1123. else
  1124. {
  1125. fV1 = TRUE;
  1126. }
  1127. }
  1128. if (fV1)
  1129. {
  1130. DWORD FlagsV1;
  1131. if (g_fAdminInterface || GETCERT_UNSUPPORTED == dwGetCertType)
  1132. {
  1133. hr = E_NOTIMPL;
  1134. _JumpIfError(hr, error, "ICertRequest2 required");
  1135. }
  1136. if (CAITF_FLAGSARG & pcait->Flags)
  1137. {
  1138. FlagsV1 = IndexV1;
  1139. IndexV1 = 0;
  1140. }
  1141. else
  1142. {
  1143. FlagsV1 = (CAITF_ASN & pcait->Flags)?
  1144. CR_OUT_BASE64HEADER : CR_OUT_BINARY;
  1145. if (g_wszCAChain == pwszOption)
  1146. {
  1147. FlagsV1 |= CR_OUT_CHAIN;
  1148. }
  1149. }
  1150. hr = Request_GetCACertificate(
  1151. pdiProp,
  1152. dwGetCertType | IndexV1, // fExchangeCertificate
  1153. g_pwszConfig,
  1154. FlagsV1,
  1155. &strValue);
  1156. _JumpIfError2(
  1157. hr,
  1158. error,
  1159. "Request_GetCACertificate",
  1160. (CAITF_OPTIONAL & pcait->Flags)?
  1161. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) : S_OK);
  1162. // Build up a nice debug print:
  1163. if (fVerbose)
  1164. {
  1165. WCHAR wszArg[5 + cwcDWORDSPRINTF];
  1166. switch (dwGetCertType)
  1167. {
  1168. case GETCERT_CASIGCERT:
  1169. wcscpy(wszArg, L"SignatureCert");
  1170. break;
  1171. case GETCERT_CAXCHGCERT:
  1172. wcscpy(wszArg, L"ExchangeCert");
  1173. break;
  1174. case GETCERT_CACERTBYINDEX:
  1175. case GETCERT_CRLBYINDEX:
  1176. case GETCERT_CACERTSTATEBYINDEX:
  1177. case GETCERT_CRLSTATEBYINDEX:
  1178. case GETCERT_EXITVERSIONBYINDEX:
  1179. swprintf(
  1180. wszArg,
  1181. L"\"%c%c.%d\"",
  1182. ((char *) &dwGetCertType)[3],
  1183. ((char *) &dwGetCertType)[2],
  1184. Index);
  1185. break;
  1186. default:
  1187. swprintf(
  1188. wszArg,
  1189. L"\"%c%c%c%c\"",
  1190. ((char *) &dwGetCertType)[3],
  1191. ((char *) &dwGetCertType)[2],
  1192. ((char *) &dwGetCertType)[1],
  1193. ((char *) &dwGetCertType)[0]);
  1194. break;
  1195. }
  1196. wprintf(L"GetCACertificate(%ws):\n%ws\n", wszArg, strValue);
  1197. }
  1198. if (PROPTYPE_LONG == pcait->lPropType)
  1199. {
  1200. DWORD cwc = wcslen(strValue);
  1201. WCHAR const *pwc = strValue;
  1202. if (!cuParseDecimal(&pwc, &cwc, (DWORD *) &longValue))
  1203. {
  1204. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1205. _JumpErrorStr(hr, error, "bad decimal number", strValue);
  1206. }
  1207. }
  1208. }
  1209. // At this point:
  1210. // if PROPTYPE_LONG, the value is in longValue,
  1211. // if PROPTYPE_STRING, the value is in strValue
  1212. // if PROPTYPE_BINARY, the base64-encoded string is in strValue
  1213. if (PROPTYPE_LONG == pcait->lPropType && NULL != pdwValue)
  1214. {
  1215. *pdwValue = longValue;
  1216. }
  1217. if ((CAITF_ASN & pcait->Flags))
  1218. {
  1219. hr = myCryptStringToBinary(
  1220. strValue,
  1221. 0,
  1222. CRYPT_STRING_BASE64HEADER,
  1223. &pbBinary,
  1224. &cbBinary,
  1225. NULL,
  1226. NULL);
  1227. _JumpIfError(hr, error, "myCryptStringToBinary");
  1228. if (fVerbose)
  1229. {
  1230. hr = cuDumpAsnBinary(pbBinary, cbBinary, MAXDWORD);
  1231. _JumpIfError(hr, error, "cuDumpAsnBinary");
  1232. }
  1233. }
  1234. switch (pcait->lPropId)
  1235. {
  1236. case CR_PROP_NONE:
  1237. {
  1238. switch (dwGetCertType)
  1239. {
  1240. case GETCERT_ERRORTEXT1:
  1241. case GETCERT_ERRORTEXT2:
  1242. wprintf(
  1243. myLoadResourceString(IDS_FORMAT_MESSAGE_TEXT), // "Error message text: %ws"
  1244. L"");
  1245. wprintf(L"%ws\n", strValue);
  1246. fDisplayed = TRUE;
  1247. break;
  1248. // prettyprint CA Type/CA Info
  1249. case GETCERT_CAINFO:
  1250. {
  1251. DWORD cwc = wcslen(strValue);
  1252. WCHAR const *pwc = strValue;
  1253. CAINFO CAInfo;
  1254. if (cuParseDecimal(&pwc, &cwc, (DWORD *) &CAInfo.CAType))
  1255. {
  1256. if (NULL != pwszInfoName &&
  1257. 0 != lstrcmp(L"*", pwszInfoName))
  1258. {
  1259. cuDisplayCAType(CAInfo.CAType);
  1260. }
  1261. if (cuParseDecimal(&pwc, &cwc, &CAInfo.cCASignatureCerts))
  1262. {
  1263. wprintf(
  1264. myLoadResourceString(IDS_FORMAT_CCACERTS),
  1265. CAInfo.cCASignatureCerts);
  1266. wprintf(wszNewLine);
  1267. }
  1268. }
  1269. fDisplayed = TRUE;
  1270. break;
  1271. }
  1272. }
  1273. break;
  1274. }
  1275. }
  1276. if (!fDisplayed && fDisplayResult)
  1277. {
  1278. wprintf(L"%ws", myLoadResourceString(pcait->ids));
  1279. if (NULL != pPropIndex)
  1280. {
  1281. wprintf(L"[%d]", *pPropIndex);
  1282. }
  1283. if (PROPTYPE_LONG == pcait->lPropType)
  1284. {
  1285. if (0 > longValue || 9 < longValue)
  1286. {
  1287. wprintf(L": 0x%x (%d)", longValue, longValue);
  1288. }
  1289. else
  1290. {
  1291. wprintf(L": %x", longValue);
  1292. }
  1293. switch (pcait->lPropId)
  1294. {
  1295. // prettyprint Cert/CRL State
  1296. case CR_PROP_CACERTSTATE:
  1297. case CR_PROP_CRLSTATE:
  1298. case CR_PROP_CAFORWARDCROSSCERTSTATE:
  1299. case CR_PROP_CABACKWARDCROSSCERTSTATE:
  1300. DisplayCAState(pcait->lPropId, longValue);
  1301. break;
  1302. case CR_PROP_CACERTVERSION:
  1303. DisplayCAVersion(longValue);
  1304. break;
  1305. case CR_PROP_KRACERTSTATE:
  1306. DisplayKRAState(longValue);
  1307. break;
  1308. case CR_PROP_CATYPE:
  1309. wprintf(L" -- ");
  1310. cuDisplayCAType(longValue);
  1311. break;
  1312. default:
  1313. wprintf(wszNewLine);
  1314. break;
  1315. }
  1316. if (NULL != pcait->pwszRegName)
  1317. {
  1318. cuRegPrintDwordValue(
  1319. FALSE,
  1320. pcait->pwszRegName,
  1321. pcait->pwszRegName,
  1322. longValue);
  1323. }
  1324. }
  1325. else
  1326. {
  1327. wprintf(L":%ws", (CAITF_ASN & pcait->Flags)? L"\n" : L" ");
  1328. cuPrintCRLFString(NULL, strValue);
  1329. wprintf(wszNewLine);
  1330. }
  1331. }
  1332. if (NULL != pwszfnOut && NULL != pbBinary)
  1333. {
  1334. hr = EncodeToFileW(
  1335. pwszfnOut,
  1336. pbBinary,
  1337. cbBinary,
  1338. CRYPT_STRING_BINARY | g_EncodeFlags);
  1339. if (S_OK != hr)
  1340. {
  1341. _PrintError(hr, "EncodeToFileW");
  1342. cuPrintError(IDS_ERR_FORMAT_ENCODETOFILE, hr);
  1343. goto error;
  1344. }
  1345. }
  1346. error:
  1347. g_fVerbose = fVerboseOld;
  1348. if (NULL != pbBinary)
  1349. {
  1350. LocalFree(pbBinary);
  1351. }
  1352. if (NULL != strValue)
  1353. {
  1354. SysFreeString(strValue);
  1355. }
  1356. return(hr);
  1357. }
  1358. HRESULT
  1359. GetCACounts(
  1360. IN OUT DISPATCHINTERFACE *pdiProp,
  1361. IN OUT BOOL *pfV1,
  1362. OUT LONG *pcCASigCerts,
  1363. OUT LONG *pcCAXchgCerts,
  1364. OUT LONG *pcKRACerts,
  1365. OUT LONG *pcExitMods,
  1366. OUT LONG *plPropIdMax)
  1367. {
  1368. HRESULT hr;
  1369. BSTR strValue = NULL;
  1370. if (!*pfV1)
  1371. {
  1372. hr = (*g_pfnProp2_GetCAProperty)(
  1373. pdiProp,
  1374. g_pwszConfig,
  1375. CR_PROP_CASIGCERTCOUNT,
  1376. 0,
  1377. PROPTYPE_LONG,
  1378. CV_OUT_BINARY,
  1379. pcCASigCerts);
  1380. if (RPC_E_VERSION_MISMATCH != hr)
  1381. {
  1382. _JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
  1383. hr = (*g_pfnProp2_GetCAProperty)(
  1384. pdiProp,
  1385. g_pwszConfig,
  1386. CR_PROP_CAXCHGCERTCOUNT,
  1387. 0,
  1388. PROPTYPE_LONG,
  1389. CV_OUT_BINARY,
  1390. pcCAXchgCerts);
  1391. _JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
  1392. hr = (*g_pfnProp2_GetCAProperty)(
  1393. pdiProp,
  1394. g_pwszConfig,
  1395. CR_PROP_KRACERTCOUNT,
  1396. 0,
  1397. PROPTYPE_LONG,
  1398. CV_OUT_BINARY,
  1399. pcKRACerts);
  1400. _JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
  1401. hr = (*g_pfnProp2_GetCAProperty)(
  1402. pdiProp,
  1403. g_pwszConfig,
  1404. CR_PROP_EXITCOUNT,
  1405. 0,
  1406. PROPTYPE_LONG,
  1407. CV_OUT_BINARY,
  1408. pcExitMods);
  1409. _JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
  1410. hr = (*g_pfnProp2_GetCAProperty)(
  1411. pdiProp,
  1412. g_pwszConfig,
  1413. CR_PROP_CAPROPIDMAX,
  1414. 0,
  1415. PROPTYPE_LONG,
  1416. CV_OUT_BINARY,
  1417. plPropIdMax);
  1418. _JumpIfError(hr, error, "g_pfnProp2_GetCAProperty");
  1419. }
  1420. else
  1421. {
  1422. *pfV1 = TRUE;
  1423. }
  1424. }
  1425. if (*pfV1)
  1426. {
  1427. WCHAR const *pwc;
  1428. DWORD cwc;
  1429. if (g_fAdminInterface)
  1430. {
  1431. hr = E_NOTIMPL;
  1432. _JumpIfError(hr, error, "ICertRequest required");
  1433. }
  1434. hr = Request_GetCACertificate(
  1435. pdiProp,
  1436. GETCERT_CAINFO, // fExchangeCertificate
  1437. g_pwszConfig,
  1438. CR_OUT_BINARY,
  1439. &strValue);
  1440. _JumpIfError(hr, error, "Request_GetCACertificate");
  1441. pwc = wcschr(strValue, L',');
  1442. if (NULL == pwc)
  1443. {
  1444. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1445. _JumpErrorStr(hr, error, "bad CAInfo string", strValue);
  1446. }
  1447. pwc++;
  1448. cwc = wcslen(pwc);
  1449. if (!cuParseDecimal(&pwc, &cwc, (DWORD *) pcCASigCerts))
  1450. {
  1451. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1452. _JumpErrorStr(hr, error, "bad CAInfo cert count", strValue);
  1453. }
  1454. *pcCAXchgCerts = 0;
  1455. *pcExitMods = 1;
  1456. *plPropIdMax = 0;
  1457. }
  1458. if (1 < g_fVerbose)
  1459. {
  1460. wprintf(
  1461. L"GetCACounts(): cCASigCerts = %d, cCAXchgCerts = %d, cKRACerts = %d\n",
  1462. *pcCASigCerts,
  1463. *pcCAXchgCerts,
  1464. *pcKRACerts);
  1465. }
  1466. error:
  1467. if (NULL != strValue)
  1468. {
  1469. SysFreeString(strValue);
  1470. }
  1471. return(hr);
  1472. }
  1473. //+-------------------------------------------------------------------------
  1474. // cuGetCAInfoProperty -- display one CA Property.
  1475. //
  1476. // If an index is specifed, display the property only for that index.
  1477. // Otherwse, display the property for all valid indexes.
  1478. //
  1479. //--------------------------------------------------------------------------
  1480. HRESULT
  1481. cuGetCAInfoProperty(
  1482. IN WCHAR const *pwszOption,
  1483. OPTIONAL IN WCHAR const *pwszfnOut,
  1484. OPTIONAL IN WCHAR const *pwszInfoName,
  1485. OPTIONAL IN WCHAR const *pwszNumber,
  1486. IN BOOL fMultiple,
  1487. IN CAINFOTABLE const *pcait,
  1488. IN LONG cCASigCerts,
  1489. IN LONG cCAXchgCerts,
  1490. IN LONG cKRACerts,
  1491. IN LONG cExitMods,
  1492. IN OUT DISPATCHINTERFACE *pdiProp,
  1493. IN BOOL fV1)
  1494. {
  1495. HRESULT hr;
  1496. HRESULT hr2 = S_OK;
  1497. LONG CmdLineIndex;
  1498. LONG PropIndex;
  1499. LONG *pPropIndex = NULL;
  1500. LONG Count = 1;
  1501. // Determine indexed property Count.
  1502. // Non-indexed property Count is always 1.
  1503. switch (
  1504. (CAITF_EXITCOUNT | CAITF_SIGCERTCOUNT | CAITF_XCHGCERTCOUNT | CAITF_KRACERTCOUNT) &
  1505. pcait->Flags)
  1506. {
  1507. case CAITF_EXITCOUNT:
  1508. Count = cExitMods;
  1509. pPropIndex = &PropIndex;
  1510. break;
  1511. case CAITF_SIGCERTCOUNT:
  1512. Count = cCASigCerts;
  1513. pPropIndex = &PropIndex;
  1514. break;
  1515. case CAITF_XCHGCERTCOUNT:
  1516. Count = cCAXchgCerts;
  1517. pPropIndex = &PropIndex;
  1518. break;
  1519. case CAITF_KRACERTCOUNT:
  1520. Count = cKRACerts;
  1521. pPropIndex = &PropIndex;
  1522. break;
  1523. }
  1524. if (NULL != pwszNumber)
  1525. {
  1526. hr = myGetSignedLong(pwszNumber, &CmdLineIndex);
  1527. _JumpIfErrorStr(hr, error, "Value not a number", pwszNumber);
  1528. if (MAXDWORD == CmdLineIndex)
  1529. {
  1530. CmdLineIndex = Count - 1;
  1531. }
  1532. Count = 1;
  1533. pPropIndex = &CmdLineIndex;
  1534. }
  1535. for (PropIndex = 0; PropIndex < Count; PropIndex++)
  1536. {
  1537. DWORD lPropIdState = MAXDWORD;
  1538. BOOL fSkip;
  1539. switch (
  1540. (CAITF_CRLSTATE | CAITF_FORWARDCROSSCERTSTATE | CAITF_BACKWARDCROSSCERTSTATE) &
  1541. pcait->Flags)
  1542. {
  1543. case CAITF_CRLSTATE:
  1544. lPropIdState = CR_PROP_CRLSTATE;
  1545. break;
  1546. case CAITF_FORWARDCROSSCERTSTATE:
  1547. lPropIdState = CR_PROP_CAFORWARDCROSSCERTSTATE;
  1548. break;
  1549. case CAITF_BACKWARDCROSSCERTSTATE:
  1550. lPropIdState = CR_PROP_CABACKWARDCROSSCERTSTATE;
  1551. break;
  1552. }
  1553. if (MAXDWORD != lPropIdState)
  1554. {
  1555. CAINFOTABLE const *pcaitT;
  1556. fSkip = FALSE;
  1557. for (pcaitT = g_aCAInfoTable; NULL != pcaitT->pwszCmdLineName; pcaitT++)
  1558. {
  1559. if (lPropIdState == pcaitT->lPropId)
  1560. {
  1561. LONG PropIndexState = *pPropIndex;
  1562. DWORD dwState;
  1563. hr = cuGetCAInfoPropertyByIndex(
  1564. NULL, // pwszOption
  1565. NULL, // pwszfnOut
  1566. NULL, // pwszInfoName
  1567. &PropIndexState,
  1568. pcaitT,
  1569. pdiProp,
  1570. fV1,
  1571. (CAITF_ASN & pcait->Flags)?
  1572. TRUE : FALSE, // fDisplayResult
  1573. &dwState); // pdwValue
  1574. _PrintIfError2(hr, "cuGetCAInfoPropertyByIndex", hr);
  1575. if (S_OK == hr && CA_DISP_ERROR == dwState)
  1576. {
  1577. fSkip = TRUE;
  1578. }
  1579. break;
  1580. }
  1581. }
  1582. if (fSkip)
  1583. {
  1584. continue;
  1585. }
  1586. }
  1587. if (1 < g_fVerbose)
  1588. {
  1589. wprintf(
  1590. NULL == pPropIndex?
  1591. L"cuGetCAInfoProperty(%ws): %ws:\n" :
  1592. L"cuGetCAInfoProperty(%ws): %ws[%u]:\n",
  1593. pcait->pwszCmdLineName,
  1594. pcait->pwszCmdLineName,
  1595. NULL == pPropIndex? -1 : *pPropIndex);
  1596. }
  1597. hr = cuGetCAInfoPropertyByIndex(
  1598. pwszOption,
  1599. pwszfnOut,
  1600. pwszInfoName,
  1601. pPropIndex,
  1602. pcait,
  1603. pdiProp,
  1604. fV1,
  1605. TRUE, // fDisplayResult
  1606. NULL); // pdwValue
  1607. if (E_INVALIDARG == hr &&
  1608. (fMultiple || 1 < Count) &&
  1609. (CAITF_SKIPINVALIDARG & pcait->Flags))
  1610. {
  1611. _PrintIfError2(hr, "cuGetCAInfoPropertyByIndex", hr);
  1612. hr = S_OK;
  1613. }
  1614. _PrintIfErrorStr3(
  1615. hr,
  1616. "cuGetCAInfoPropertyByIndex",
  1617. pcait->pwszCmdLineName,
  1618. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
  1619. E_INVALIDARG);
  1620. if (S_OK == hr2)
  1621. {
  1622. hr2 = hr; // Save first error
  1623. }
  1624. }
  1625. hr = hr2;
  1626. error:
  1627. return(hr);
  1628. }
  1629. //+-------------------------------------------------------------------------
  1630. // cuGetCAInfo -- display one or more CA Properties.
  1631. //
  1632. // If indexed property counts will be needed, fetch them first, so we know
  1633. // how many of each indexed property to fetch.
  1634. //
  1635. // If pwszInfoName is NULL, display the default set of properties.
  1636. // If pwszInfoName is L"*", display all properties.
  1637. // Otherwise, display only the specified property.
  1638. //
  1639. //--------------------------------------------------------------------------
  1640. HRESULT
  1641. cuGetCAInfo(
  1642. IN WCHAR const *pwszOption,
  1643. OPTIONAL IN WCHAR const *pwszfnOut,
  1644. OPTIONAL IN WCHAR const *pwszInfoName,
  1645. OPTIONAL IN WCHAR const *pwszNumber)
  1646. {
  1647. HRESULT hr;
  1648. HRESULT hr2 = S_OK;
  1649. DISPATCHINTERFACE diProp;
  1650. BOOL fV1 = g_fV1Interface;
  1651. BOOL fMustRelease = FALSE;
  1652. BOOL fMultiple = FALSE;
  1653. LONG cCASigCerts = 0;
  1654. LONG cCAXchgCerts = 0;
  1655. LONG cKRACerts = 0;
  1656. LONG cExitMods = 0;
  1657. LONG lPropIdMax;
  1658. CAINFOTABLE const *pcait;
  1659. InitPropFunctionPointers();
  1660. hr = (*g_pfnProp_Init)(g_DispatchFlags, &diProp);
  1661. _JumpIfError(hr, error, "g_pfnProp_Init");
  1662. fMustRelease = TRUE;
  1663. if (NULL == pwszInfoName ||
  1664. (0 != LSTRCMPIS(pwszInfoName, g_wszCAInfoName) &&
  1665. 0 != LSTRCMPIS(pwszInfoName, g_wszCAInfoSanitizedName) &&
  1666. 0 != LSTRCMPIS(pwszInfoName, g_wszCAInfoDSName)))
  1667. {
  1668. hr = GetCACounts(
  1669. &diProp,
  1670. &fV1,
  1671. &cCASigCerts,
  1672. &cCAXchgCerts,
  1673. &cKRACerts,
  1674. &cExitMods,
  1675. &lPropIdMax);
  1676. _JumpIfError(hr, error, "GetCACounts");
  1677. }
  1678. if (NULL == pwszInfoName || 0 == lstrcmp(L"*", pwszInfoName))
  1679. {
  1680. CSASSERT(NULL == pwszfnOut);
  1681. if (NULL != pwszNumber)
  1682. {
  1683. hr = E_INVALIDARG;
  1684. _JumpError(hr, error, "too many args");
  1685. }
  1686. fMultiple = TRUE; // loop displaying default or all entries
  1687. }
  1688. for (pcait = g_aCAInfoTable; ; pcait++)
  1689. {
  1690. if (NULL == pcait->pwszCmdLineName)
  1691. {
  1692. if (!fMultiple)
  1693. {
  1694. hr = E_INVALIDARG;
  1695. _JumpErrorStr(hr, error, "bad command line name", pwszInfoName);
  1696. }
  1697. break;
  1698. }
  1699. if (fMultiple)
  1700. {
  1701. if (NULL == pwszInfoName)
  1702. {
  1703. if (0 == (CAITF_DEFAULT & pcait->Flags))
  1704. {
  1705. continue;
  1706. }
  1707. }
  1708. else
  1709. {
  1710. if (CAITF_SKIP & pcait->Flags)
  1711. {
  1712. continue;
  1713. }
  1714. }
  1715. if (fV1)
  1716. {
  1717. if (GETCERT_UNSUPPORTED == pcait->dwGetCert)
  1718. {
  1719. continue;
  1720. }
  1721. }
  1722. else
  1723. {
  1724. if (CR_PROP_NONE == pcait->lPropId)
  1725. {
  1726. continue;
  1727. }
  1728. }
  1729. }
  1730. else
  1731. {
  1732. if (0 != mylstrcmpiS(pwszInfoName, pcait->pwszCmdLineName))
  1733. {
  1734. continue;
  1735. }
  1736. }
  1737. hr = cuGetCAInfoProperty(
  1738. pwszOption,
  1739. pwszfnOut,
  1740. pwszInfoName,
  1741. pwszNumber,
  1742. fMultiple,
  1743. pcait,
  1744. cCASigCerts,
  1745. cCAXchgCerts,
  1746. cKRACerts,
  1747. cExitMods,
  1748. &diProp,
  1749. fV1);
  1750. if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr ||
  1751. HRESULT_FROM_WIN32(ERROR_NOT_FOUND) == hr ||
  1752. E_INVALIDARG == hr) &&
  1753. (CAITF_OPTIONAL & pcait->Flags) &&
  1754. fMultiple)
  1755. {
  1756. _PrintError2(hr, "cuGetCAInfoProperty", hr);
  1757. hr = S_OK;
  1758. }
  1759. _PrintIfError2(hr, "cuGetCAInfoProperty", E_INVALIDARG);
  1760. if (S_OK == hr2)
  1761. {
  1762. hr2 = hr; // Save first error
  1763. }
  1764. if (!fMultiple)
  1765. {
  1766. break;
  1767. }
  1768. }
  1769. hr = hr2;
  1770. error:
  1771. if (fMustRelease)
  1772. {
  1773. (*g_pfnProp_Release)(&diProp);
  1774. }
  1775. return(hr);
  1776. }
  1777. HRESULT
  1778. verbGetCACertificate(
  1779. IN WCHAR const *pwszOption,
  1780. IN WCHAR const *pwszfnCert,
  1781. OPTIONAL IN WCHAR const *pwszIndex,
  1782. IN WCHAR const *pwszArg3,
  1783. IN WCHAR const *pwszArg4)
  1784. {
  1785. HRESULT hr;
  1786. if (NULL == pwszIndex)
  1787. {
  1788. pwszIndex = L"-1";
  1789. }
  1790. hr = cuGetCAInfo(
  1791. pwszOption,
  1792. pwszfnCert,
  1793. g_wszCACert == pwszOption?
  1794. g_wszCAInfoCert : g_wszCAInfoCertChain,
  1795. pwszIndex);
  1796. _JumpIfError(hr, error, "cuGetCAInfo");
  1797. error:
  1798. return(hr);
  1799. }
  1800. HRESULT
  1801. verbGetCAInfo(
  1802. IN WCHAR const *pwszOption,
  1803. OPTIONAL IN WCHAR const *pwszInfoName,
  1804. OPTIONAL IN WCHAR const *pwszNumber,
  1805. IN WCHAR const *pwszArg3,
  1806. IN WCHAR const *pwszArg4)
  1807. {
  1808. HRESULT hr;
  1809. hr = cuGetCAInfo(pwszOption, NULL, pwszInfoName, pwszNumber);
  1810. _JumpIfError(hr, error, "cuGetCAInfo");
  1811. error:
  1812. return(hr);
  1813. }
  1814. HRESULT
  1815. verbGetCAPropInfo(
  1816. IN WCHAR const *pwszOption,
  1817. OPTIONAL IN WCHAR const *pwszInfoName,
  1818. OPTIONAL IN WCHAR const *pwszNumber,
  1819. IN WCHAR const *pwszArg3,
  1820. IN WCHAR const *pwszArg4)
  1821. {
  1822. HRESULT hr;
  1823. HRESULT hr2 = S_OK;
  1824. DISPATCHINTERFACE diProp;
  1825. BOOL fV1 = g_fV1Interface;
  1826. BOOL fMustRelease = FALSE;
  1827. LONG cCASigCerts;
  1828. LONG cCAXchgCerts;
  1829. LONG cKRACerts;
  1830. LONG cExitMods;
  1831. LONG lPropIdMax;
  1832. LONG lPropId;
  1833. BSTR strDisplayName = NULL;
  1834. InitPropFunctionPointers();
  1835. hr = (*g_pfnProp_Init)(g_DispatchFlags, &diProp);
  1836. _JumpIfError(hr, error, "g_pfnProp_Init");
  1837. fMustRelease = TRUE;
  1838. hr = GetCACounts(
  1839. &diProp,
  1840. &fV1,
  1841. &cCASigCerts,
  1842. &cCAXchgCerts,
  1843. &cKRACerts,
  1844. &cExitMods,
  1845. &lPropIdMax);
  1846. _JumpIfError(hr, error, "GetCACounts");
  1847. for (lPropId = 1; lPropId <= lPropIdMax; lPropId++)
  1848. {
  1849. LONG lPropFlags;
  1850. // don't use the display name twice!
  1851. if (NULL != strDisplayName)
  1852. {
  1853. SysFreeString(strDisplayName);
  1854. strDisplayName = NULL;
  1855. }
  1856. hr = (*g_pfnProp2_GetCAPropertyFlags)(
  1857. &diProp,
  1858. g_pwszConfig,
  1859. lPropId,
  1860. &lPropFlags);
  1861. _PrintIfError(hr, "g_pfnProp2_GetCAPropertyFlags");
  1862. if (S_OK == hr)
  1863. {
  1864. hr = (*g_pfnProp2_GetCAPropertyDisplayName)(
  1865. &diProp,
  1866. g_pwszConfig,
  1867. lPropId,
  1868. &strDisplayName);
  1869. _PrintIfError(hr, "g_pfnProp2_GetCAPropertyDisplayName");
  1870. wprintf(L"%3d: ", lPropId);
  1871. cuPrintSchemaEntry(
  1872. NULL, // pwszName
  1873. NULL != strDisplayName? strDisplayName : g_wszEmpty,
  1874. lPropFlags,
  1875. 0); // cbMax
  1876. }
  1877. }
  1878. error:
  1879. if (fMustRelease)
  1880. {
  1881. (*g_pfnProp_Release)(&diProp);
  1882. }
  1883. if (NULL != strDisplayName)
  1884. {
  1885. SysFreeString(strDisplayName);
  1886. }
  1887. return(hr);
  1888. }
  1889. HRESULT
  1890. verbGetConfig(
  1891. IN WCHAR const *pwszOption,
  1892. IN WCHAR const *pwszArg1,
  1893. IN WCHAR const *pwszArg2,
  1894. IN WCHAR const *pwszArg3,
  1895. IN WCHAR const *pwszArg4)
  1896. {
  1897. wprintf(
  1898. myLoadResourceString(IDS_FORMAT_CONFIG_STRING), // "Config String: ""%ws"""
  1899. g_pwszConfig);
  1900. wprintf(wszNewLine);
  1901. return(S_OK);
  1902. }
  1903. HRESULT
  1904. verbGetConfig2(
  1905. IN WCHAR const *pwszOption,
  1906. IN WCHAR const *pwszFlags,
  1907. IN WCHAR const *pwszArg2,
  1908. IN WCHAR const *pwszArg3,
  1909. IN WCHAR const *pwszArg4)
  1910. {
  1911. HRESULT hr;
  1912. ICertGetConfig *pConfig = NULL;
  1913. BSTR strConfig = NULL;
  1914. LONG Flags;
  1915. hr = CoCreateInstance(
  1916. CLSID_CCertGetConfig,
  1917. NULL, // pUnkOuter
  1918. CLSCTX_INPROC_SERVER,
  1919. IID_ICertGetConfig,
  1920. (VOID **) &pConfig);
  1921. _JumpIfError(hr, error, "CoCreateInstance");
  1922. Flags = CC_LOCALCONFIG;
  1923. if (NULL != pwszFlags)
  1924. {
  1925. hr = myGetLong(pwszFlags, &Flags);
  1926. _JumpIfError(hr, error, "Flags must be a number");
  1927. }
  1928. hr = pConfig->GetConfig(Flags, &strConfig);
  1929. _JumpIfError(hr, error, "GetConfig");
  1930. wprintf(
  1931. myLoadResourceString(IDS_FORMAT_ICERTCONFIG_CONFIG_STRING), // "ICertGetConfig Config String: ""%ws"""
  1932. strConfig);
  1933. wprintf(wszNewLine);
  1934. error:
  1935. if (NULL != strConfig)
  1936. {
  1937. SysFreeString(strConfig);
  1938. }
  1939. if (NULL != pConfig)
  1940. {
  1941. pConfig->Release();
  1942. }
  1943. return(hr);
  1944. }
  1945. HRESULT
  1946. verbGetConfig3(
  1947. IN WCHAR const *pwszOption,
  1948. IN WCHAR const *pwszFlags,
  1949. IN WCHAR const *pwszArg2,
  1950. IN WCHAR const *pwszArg3,
  1951. IN WCHAR const *pwszArg4)
  1952. {
  1953. HRESULT hr;
  1954. LONG count;
  1955. DISPATCHINTERFACE diConfig;
  1956. BOOL fRelease = FALSE;
  1957. BSTR strConfig = NULL;
  1958. LONG Flags;
  1959. hr = Config_Init(g_DispatchFlags, &diConfig);
  1960. _JumpIfError(hr, error, "Config_Init");
  1961. fRelease = TRUE;
  1962. hr = Config_Reset(&diConfig, 0, &count);
  1963. _JumpIfError(hr, error, "Config_Reset");
  1964. Flags = CC_UIPICKCONFIG;
  1965. if (NULL != pwszFlags)
  1966. {
  1967. hr = myGetLong(pwszFlags, &Flags);
  1968. _JumpIfError(hr, error, "Flags must be a number");
  1969. }
  1970. hr = Config_GetConfig(&diConfig, Flags, &strConfig);
  1971. _JumpIfError(hr, error, "Config_GetConfig");
  1972. hr = ConfigDumpEntry(&diConfig, NULL, -1, NULL);
  1973. _JumpIfError(hr, error, "ConfigDumpEntry");
  1974. error:
  1975. if (NULL != strConfig)
  1976. {
  1977. SysFreeString(strConfig);
  1978. }
  1979. if (fRelease)
  1980. {
  1981. Config_Release(&diConfig);
  1982. }
  1983. return(hr);
  1984. }
  1985. HRESULT
  1986. verbErrorDump(
  1987. IN WCHAR const *pwszOption,
  1988. IN WCHAR const *pwszErrorCode,
  1989. IN WCHAR const *pwszArg2,
  1990. IN WCHAR const *pwszArg3,
  1991. IN WCHAR const *pwszArg4)
  1992. {
  1993. HRESULT hr;
  1994. HRESULT hrDump;
  1995. WCHAR awchr[cwcHRESULTSTRING];
  1996. WCHAR const *pwszError = NULL;
  1997. hr = myGetSignedLong(pwszErrorCode, &hrDump);
  1998. _JumpIfError(hr, error, "bad numeric operand");
  1999. wprintf(
  2000. L"%ws -- %u (%d)\n",
  2001. myHResultToString(awchr, hrDump),
  2002. hrDump,
  2003. hrDump);
  2004. pwszError = myGetErrorMessageText(hrDump, g_fVerbose);
  2005. wprintf(
  2006. myLoadResourceString(IDS_FORMAT_MESSAGE_TEXT), // "Error message text: %ws"
  2007. pwszError);
  2008. wprintf(wszNewLine);
  2009. hr = S_OK;
  2010. error:
  2011. if (NULL != pwszError)
  2012. {
  2013. LocalFree(const_cast<WCHAR *>(pwszError));
  2014. }
  2015. return(hr);
  2016. }
  2017. HRESULT
  2018. RequestCACertificateAndComplete(
  2019. IN DWORD Flags,
  2020. OPTIONAL IN WCHAR const *pwszParentMachine,
  2021. OPTIONAL IN WCHAR const *pwszParentCA,
  2022. OPTIONAL IN WCHAR const *pwszfnCACert,
  2023. OPTIONAL OUT WCHAR **ppwszRequestFile)
  2024. {
  2025. HRESULT hr;
  2026. WCHAR *pwszCAName = NULL;
  2027. WCHAR *pwszFinalCAName;
  2028. pwszFinalCAName = wcschr(g_pwszConfig, L'\\');
  2029. if (NULL != pwszFinalCAName)
  2030. {
  2031. pwszFinalCAName++;
  2032. }
  2033. else
  2034. {
  2035. hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGACTIVE, &pwszCAName);
  2036. _JumpIfErrorStr(hr, error, "myGetCertRegStrValue", wszREGACTIVE);
  2037. pwszFinalCAName = pwszCAName;
  2038. }
  2039. if (g_fForce)
  2040. {
  2041. Flags |= CSRF_OVERWRITE;
  2042. }
  2043. if (g_fCryptSilent)
  2044. {
  2045. Flags |= CSRF_UNATTENDED;
  2046. }
  2047. hr = CertServerRequestCACertificateAndComplete(
  2048. g_hInstance, // hInstance
  2049. NULL, // hwnd
  2050. Flags, // Flags
  2051. pwszFinalCAName, // pwszCAName
  2052. pwszParentMachine, // pwszParentMachine
  2053. pwszParentCA, // pwszParentCA
  2054. pwszfnCACert, // pwszCAChainFile
  2055. ppwszRequestFile); // ppwszRequestFile
  2056. _JumpIfError(hr, error, "CertServerRequestCACertificateAndComplete");
  2057. error:
  2058. if (NULL != pwszCAName)
  2059. {
  2060. LocalFree(pwszCAName);
  2061. }
  2062. return(hr);
  2063. }
  2064. HRESULT
  2065. verbInstallCACert(
  2066. IN WCHAR const *pwszOption,
  2067. IN WCHAR const *pwszfnCACert,
  2068. IN WCHAR const *pwszArg2,
  2069. IN WCHAR const *pwszArg3,
  2070. IN WCHAR const *pwszArg4)
  2071. {
  2072. HRESULT hr;
  2073. hr = RequestCACertificateAndComplete(
  2074. CSRF_INSTALLCACERT,
  2075. NULL, // pwszParentMachine
  2076. NULL, // pwszParentCA
  2077. pwszfnCACert, // pwszfnCACert
  2078. NULL); // ppwszRequestFile
  2079. _JumpIfError(hr, error, "RequestCACertificateAndComplete");
  2080. error:
  2081. return(hr);
  2082. }
  2083. HRESULT
  2084. verbRenewCACert(
  2085. IN WCHAR const *pwszOption,
  2086. IN WCHAR const *pwszReuseKeys,
  2087. IN WCHAR const *pwszParentConfig,
  2088. IN WCHAR const *pwszArg3,
  2089. IN WCHAR const *pwszArg4)
  2090. {
  2091. HRESULT hr;
  2092. DWORD Flags = CSRF_RENEWCACERT | CSRF_NEWKEYS;
  2093. WCHAR *pwszParentMachine = NULL;
  2094. WCHAR *pwszParentCA = NULL;
  2095. WCHAR *pwszRequestFile = NULL;
  2096. if (NULL != pwszReuseKeys)
  2097. {
  2098. if (0 == LSTRCMPIS(pwszReuseKeys, L"ReuseKeys"))
  2099. {
  2100. Flags &= ~CSRF_NEWKEYS;
  2101. }
  2102. else if (NULL == pwszParentConfig)
  2103. {
  2104. pwszParentConfig = pwszReuseKeys;
  2105. }
  2106. if (NULL != pwszParentConfig)
  2107. {
  2108. hr = mySplitConfigString(
  2109. pwszParentConfig,
  2110. &pwszParentMachine,
  2111. &pwszParentCA);
  2112. _JumpIfErrorStr(hr, error, "mySplitConfigString", pwszParentConfig);
  2113. }
  2114. }
  2115. hr = RequestCACertificateAndComplete(
  2116. Flags, // Flags
  2117. pwszParentMachine, // pwszParentMachine
  2118. pwszParentCA, // pwszParentCA
  2119. NULL, // pwszfnCACert
  2120. &pwszRequestFile); // ppwszRequestFile
  2121. _JumpIfError(hr, error, "RequestCACertificateAndComplete");
  2122. if (NULL != pwszRequestFile)
  2123. {
  2124. wprintf(
  2125. L"%ws %ws\n",
  2126. myLoadResourceString(IDS_REQUEST_FILE_COLON),
  2127. pwszRequestFile);
  2128. }
  2129. error:
  2130. if (NULL != pwszRequestFile)
  2131. {
  2132. LocalFree(pwszRequestFile);
  2133. }
  2134. if (NULL != pwszParentMachine)
  2135. {
  2136. LocalFree(pwszParentMachine);
  2137. }
  2138. if (NULL != pwszParentCA)
  2139. {
  2140. LocalFree(pwszParentCA);
  2141. }
  2142. return(hr);
  2143. }
  2144. VOID
  2145. cuPrintVRootDisposition(
  2146. IN DWORD idmsg,
  2147. IN DWORD Disposition)
  2148. {
  2149. DWORD idDisp = 0;
  2150. switch (0x0000ffff & Disposition)
  2151. {
  2152. case VFD_CREATED: idDisp = IDS_VROOTDISP_CREATED; break;
  2153. case VFD_DELETED: idDisp = IDS_VROOTDISP_DELETED; break;
  2154. case VFD_EXISTS: idDisp = IDS_VROOTDISP_EXISTS; break;
  2155. case VFD_NOTFOUND: idDisp = IDS_VROOTDISP_NOTFOUND; break;
  2156. case VFD_CREATEERROR: idDisp = IDS_VROOTDISP_CREATEERROR; break;
  2157. case VFD_DELETEERROR: idDisp = IDS_VROOTDISP_DELETERROR; break;
  2158. case VFD_NOTSUPPORTED: idDisp = IDS_VROOTDISP_NOTSUPPORTED; break;
  2159. }
  2160. if (0 != idDisp)
  2161. {
  2162. wprintf(myLoadResourceString(idmsg), myLoadResourceString(idDisp));
  2163. wprintf(wszNewLine);
  2164. }
  2165. idDisp = 0;
  2166. switch (Disposition >> 16) // display ASP disposition
  2167. {
  2168. case VFD_CREATED: idDisp = IDS_VROOTDISP_ENABLEDASP; break;
  2169. case VFD_EXISTS: idDisp = IDS_VROOTDISP_ASPALREADYENABLED; break;
  2170. case VFD_CREATEERROR: idDisp = IDS_VROOTDISP_ENABLEASPERROR; break;
  2171. }
  2172. if (0 != idDisp)
  2173. {
  2174. wprintf(L"%ws\n", myLoadResourceString(idDisp));
  2175. }
  2176. }
  2177. HRESULT
  2178. verbCreateVRoots(
  2179. IN WCHAR const *pwszOption,
  2180. IN WCHAR const *pwszDelete,
  2181. IN WCHAR const *pwszArg2,
  2182. IN WCHAR const *pwszArg3,
  2183. IN WCHAR const *pwszArg4)
  2184. {
  2185. HRESULT hr;
  2186. DWORD VRootDisposition = 0;
  2187. DWORD ShareDisposition = 0;
  2188. DWORD Flags;
  2189. WCHAR* pwszPath = NULL;
  2190. ENUM_CATYPES CAType = ENUM_UNKNOWN_CA;
  2191. DWORD cb = sizeof(ENUM_CATYPES);
  2192. DWORD dwType;
  2193. HKEY hkey = NULL;
  2194. hr = myRegOpenRelativeKey(
  2195. NULL,
  2196. L"ca",
  2197. RORKF_CREATESUBKEYS,
  2198. &pwszPath,
  2199. NULL, // ppwszName
  2200. &hkey);
  2201. if (S_OK == hr)
  2202. {
  2203. cb = sizeof(CAType);
  2204. hr = RegQueryValueEx(
  2205. hkey,
  2206. wszREGCATYPE,
  2207. 0,
  2208. &dwType,
  2209. (BYTE *) &CAType,
  2210. &cb);
  2211. _JumpIfErrorStr(hr, error, "RegQueryValueEx", wszREGCATYPE);
  2212. }
  2213. else
  2214. {
  2215. hr = myRegOpenRelativeKey(
  2216. NULL,
  2217. L"",
  2218. RORKF_CREATESUBKEYS,
  2219. &pwszPath,
  2220. NULL, // ppwszName
  2221. &hkey);
  2222. _JumpIfError(hr, error, "myRegOpenRelativeKey");
  2223. cb = sizeof(CAType);
  2224. hr = RegQueryValueEx(
  2225. hkey,
  2226. wszREGWEBCLIENTCATYPE,
  2227. 0,
  2228. &dwType,
  2229. (BYTE *) &CAType,
  2230. &cb);
  2231. _JumpIfErrorStr(hr, error, "RegQueryValueEx", wszREGWEBCLIENTCATYPE);
  2232. }
  2233. if (0 != LSTRCMPIS(pwszDelete, L"delete"))
  2234. {
  2235. Flags = VFF_CREATEVROOTS |
  2236. VFF_CREATEFILESHARES |
  2237. VFF_CLEARREGFLAGIFOK |
  2238. VFF_ENABLEASP;
  2239. }
  2240. else
  2241. {
  2242. Flags = VFF_DELETEVROOTS | VFF_DELETEFILESHARES;
  2243. }
  2244. hr = myModifyVirtualRootsAndFileShares(
  2245. Flags,
  2246. CAType,
  2247. FALSE, // synchronous -- blocking call
  2248. INFINITE, // will block for good
  2249. &VRootDisposition,
  2250. &ShareDisposition);
  2251. cuPrintVRootDisposition(IDS_FORMAT_VROOT, VRootDisposition);
  2252. cuPrintVRootDisposition(IDS_FORMAT_FILESHARE, ShareDisposition);
  2253. _JumpIfError(hr, error, "myModifyVirtualRootsAndFileShares");
  2254. error:
  2255. if (pwszPath)
  2256. LocalFree(pwszPath);
  2257. if (hkey)
  2258. RegCloseKey(hkey);
  2259. return(hr);
  2260. }
  2261. HRESULT
  2262. cuPingCertSrv(
  2263. IN WCHAR const *pwszConfig,
  2264. OPTIONAL OUT CAINFO **ppCAInfo)
  2265. {
  2266. HRESULT hr;
  2267. WCHAR *pwszzCANames = NULL;
  2268. DWORD dwServerVersion;
  2269. WCHAR wszVersion[12];
  2270. if (NULL != ppCAInfo)
  2271. {
  2272. *ppCAInfo = NULL;
  2273. }
  2274. wprintf(
  2275. myLoadResourceString(IDS_FORMAT_CONNECTING), // "Connecting to %ws"
  2276. pwszConfig);
  2277. hr = myPingCertSrv(
  2278. pwszConfig,
  2279. NULL,
  2280. &pwszzCANames,
  2281. NULL,
  2282. ppCAInfo,
  2283. &dwServerVersion,
  2284. NULL);
  2285. wprintf(wszNewLine);
  2286. if (S_OK != hr)
  2287. {
  2288. cuPrintErrorAndString(
  2289. NULL,
  2290. IDS_FORMAT_SERVER_DEAD, // "Server could not be reached: %ws"
  2291. hr,
  2292. NULL);
  2293. }
  2294. _JumpIfError(hr, error, "Ping");
  2295. if (1 == dwServerVersion)
  2296. {
  2297. wszVersion[0] = L'\0';
  2298. }
  2299. else
  2300. {
  2301. swprintf(wszVersion, L"%u", dwServerVersion);
  2302. }
  2303. wprintf(
  2304. myLoadResourceString(IDS_FORMAT_SERVER_ALIVE), // "Server ""%ws"" ICertRequest%ws interface is alive"
  2305. pwszzCANames, // Assume only one CA Name for now
  2306. wszVersion);
  2307. error:
  2308. wprintf(wszNewLine);
  2309. if (NULL != pwszzCANames)
  2310. {
  2311. LocalFree(pwszzCANames);
  2312. }
  2313. return(hr);
  2314. }
  2315. HRESULT
  2316. verbPing(
  2317. IN WCHAR const *pwszOption,
  2318. IN WCHAR const *pwszArg1,
  2319. IN WCHAR const *pwszArg2,
  2320. IN WCHAR const *pwszArg3,
  2321. IN WCHAR const *pwszArg4)
  2322. {
  2323. HRESULT hr;
  2324. hr = cuPingCertSrv(g_pwszConfig, NULL);
  2325. _JumpIfError(hr, error, "cuPingCertSrv");
  2326. error:
  2327. return(hr);
  2328. }
  2329. HRESULT
  2330. OpenAdminServer(
  2331. OPTIONAL OUT WCHAR const **ppwszAuthority,
  2332. OUT DWORD *pdwServerVersion,
  2333. OUT ICertAdminD2 **ppICertAdminD)
  2334. {
  2335. HRESULT hr;
  2336. *pdwServerVersion = 0;
  2337. hr = myOpenAdminDComConnection(
  2338. g_pwszConfig,
  2339. ppwszAuthority,
  2340. NULL,
  2341. pdwServerVersion,
  2342. ppICertAdminD);
  2343. _JumpIfError(hr, error, "myOpenDComConnection");
  2344. CSASSERT(0 != *pdwServerVersion);
  2345. error:
  2346. return(hr);
  2347. }
  2348. VOID
  2349. CloseAdminServer(
  2350. IN OUT ICertAdminD2 **ppICertAdminD)
  2351. {
  2352. myCloseDComConnection((IUnknown **) ppICertAdminD, NULL);
  2353. }
  2354. HRESULT
  2355. verbPingAdmin(
  2356. IN WCHAR const *pwszOption,
  2357. IN WCHAR const *pwszArg1,
  2358. IN WCHAR const *pwszArg2,
  2359. IN WCHAR const *pwszArg3,
  2360. IN WCHAR const *pwszArg4)
  2361. {
  2362. HRESULT hr;
  2363. ICertAdminD2 *pICertAdminD = NULL;
  2364. WCHAR const *pwszAuthority;
  2365. WCHAR wszVersion[12];
  2366. DWORD dwServerVersion = 0;
  2367. wprintf(
  2368. myLoadResourceString(IDS_FORMAT_CONNECTING), // "Connecting to %ws"
  2369. g_pwszConfig);
  2370. hr = OpenAdminServer(&pwszAuthority, &dwServerVersion, &pICertAdminD);
  2371. _JumpIfError(hr, error, "OpenAdminServer");
  2372. CSASSERT(0 != dwServerVersion);
  2373. if (1 == dwServerVersion)
  2374. {
  2375. wszVersion[0] = L'\0';
  2376. }
  2377. else
  2378. {
  2379. swprintf(wszVersion, L"%u", dwServerVersion);
  2380. }
  2381. if (2 <= dwServerVersion)
  2382. {
  2383. hr = pICertAdminD->Ping2(pwszAuthority);
  2384. _JumpIfError(hr, error, "Ping2");
  2385. }
  2386. else
  2387. {
  2388. hr = pICertAdminD->Ping(pwszAuthority);
  2389. _JumpIfError(hr, error, "Ping");
  2390. }
  2391. wprintf(wszNewLine);
  2392. wprintf(
  2393. myLoadResourceString(IDS_ADMIN_INTERFACE_ALIVE), // "Server ICertAdmin%ws interface is alive"
  2394. wszVersion);
  2395. error:
  2396. wprintf(wszNewLine);
  2397. if (NULL != pICertAdminD)
  2398. {
  2399. CloseAdminServer(&pICertAdminD);
  2400. }
  2401. return(hr);
  2402. }
  2403. HRESULT
  2404. verbGetMapiInfo(
  2405. IN WCHAR const *pwszOption,
  2406. IN WCHAR const *pwszArg1,
  2407. IN WCHAR const *pwszArg2,
  2408. IN WCHAR const *pwszArg3,
  2409. IN WCHAR const *pwszArg4)
  2410. {
  2411. HRESULT hr;
  2412. WCHAR *pwszProfileName = NULL; // obsolete
  2413. WCHAR *pwszLogonName = NULL;
  2414. WCHAR *pwszPassword = NULL;
  2415. DWORD cwc;
  2416. hr = myGetMapiInfo(NULL, &pwszProfileName, &pwszLogonName, &pwszPassword);
  2417. _JumpIfError2(
  2418. hr,
  2419. error,
  2420. "myGetMapiInfo",
  2421. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  2422. wprintf(L"\"%ws\" \"", pwszLogonName);
  2423. for (cwc = wcslen(pwszPassword); cwc != 0; cwc--)
  2424. {
  2425. wprintf(L"*");
  2426. }
  2427. wprintf(L"\"\n");
  2428. hr = S_OK;
  2429. error:
  2430. if (NULL != pwszProfileName)
  2431. {
  2432. LocalFree(pwszProfileName);
  2433. }
  2434. if (NULL != pwszLogonName)
  2435. {
  2436. LocalFree(pwszLogonName);
  2437. }
  2438. if (NULL != pwszPassword)
  2439. {
  2440. myZeroDataString(pwszPassword); // password data
  2441. LocalFree(pwszPassword);
  2442. }
  2443. return(hr);
  2444. }
  2445. HRESULT
  2446. verbSetMapiInfo(
  2447. IN WCHAR const *pwszOption,
  2448. IN WCHAR const *pwszLogonName,
  2449. IN WCHAR const *pwszArg2,
  2450. IN WCHAR const *pwszArg3,
  2451. IN WCHAR const *pwszArg4)
  2452. {
  2453. HRESULT hr;
  2454. WCHAR wszPassword[MAX_PATH];
  2455. WCHAR const *pwszPassword;
  2456. WCHAR const *pwszProfileName = L"";
  2457. verbGetMapiInfo(pwszOption, NULL, NULL, NULL, NULL);
  2458. hr = cuGetPassword(
  2459. 0, // idsPrompt
  2460. NULL, // pwszfn
  2461. g_pwszPassword,
  2462. TRUE, // fVerify
  2463. wszPassword,
  2464. ARRAYSIZE(wszPassword),
  2465. &pwszPassword);
  2466. _JumpIfError(hr, error, "cuGetPassword");
  2467. hr = mySaveMapiInfo(NULL, pwszProfileName, pwszLogonName, pwszPassword);
  2468. _JumpIfError(hr, error, "mySaveMapiInfo");
  2469. hr = verbGetMapiInfo(pwszOption, NULL, NULL, NULL, NULL);
  2470. _JumpIfError(hr, error, "verbGetMapiInfo");
  2471. error:
  2472. SecureZeroMemory(wszPassword, sizeof(wszPassword)); // password data
  2473. return(hr);
  2474. }
  2475. HRESULT
  2476. verbGetCertFromUI(
  2477. IN WCHAR const *pwszOption,
  2478. IN WCHAR const *pwszObjId,
  2479. IN WCHAR const *pwszCNArg,
  2480. IN WCHAR const *pwszArg3,
  2481. IN WCHAR const *pwszArg4)
  2482. {
  2483. HRESULT hr;
  2484. char *pszObjId = NULL;
  2485. WCHAR const *pwszCommonName = NULL;
  2486. CERT_CONTEXT const *pCert = NULL;
  2487. BOOL fKRA = FALSE;
  2488. BOOL fERA = FALSE;
  2489. DWORD i;
  2490. if (NULL != pwszObjId)
  2491. {
  2492. hr = S_FALSE;
  2493. if (iswdigit(*pwszObjId))
  2494. {
  2495. hr = myVerifyObjId(pwszObjId);
  2496. if (S_OK == hr)
  2497. {
  2498. if (!myConvertWszToSz(&pszObjId, pwszObjId, -1))
  2499. {
  2500. hr = E_OUTOFMEMORY;
  2501. _JumpError(hr, error, "myConvertWszToSz");
  2502. }
  2503. cuDumpOIDAndDescriptionA(pszObjId);
  2504. wprintf(wszNewLine);
  2505. }
  2506. }
  2507. if (S_OK != hr)
  2508. {
  2509. if (0 == LSTRCMPIS(pwszObjId, L"KRA"))
  2510. {
  2511. fKRA = TRUE;
  2512. }
  2513. else if (0 == LSTRCMPIS(pwszObjId, L"ERA"))
  2514. {
  2515. fERA = TRUE;
  2516. }
  2517. else
  2518. {
  2519. pwszCommonName = pwszObjId;
  2520. }
  2521. }
  2522. }
  2523. if (NULL != pwszCNArg)
  2524. {
  2525. if (NULL != pwszCommonName)
  2526. {
  2527. hr = E_INVALIDARG;
  2528. _JumpError(hr, error, "bad arg");
  2529. }
  2530. pwszCommonName = pwszCNArg;
  2531. }
  2532. if (fKRA)
  2533. {
  2534. hr = myGetKRACertificateFromPicker(
  2535. g_hInstance,
  2536. NULL, // hwndParent
  2537. IDS_GETCERT_TITLE,
  2538. IDS_GETCERT_SUBTITLE_KRA,
  2539. pwszCommonName,
  2540. TRUE, // is DS available?
  2541. g_fCryptSilent,
  2542. &pCert);
  2543. _JumpIfError(hr, error, "myGetKRACertificateFromPicker");
  2544. }
  2545. else if (fERA)
  2546. {
  2547. hr = myGetERACertificateFromPicker(
  2548. g_hInstance,
  2549. NULL, // hwndParent
  2550. IDS_GETCERT_TITLE,
  2551. IDS_GETCERT_SUBTITLE_ERA,
  2552. pwszCommonName,
  2553. g_fCryptSilent,
  2554. &pCert);
  2555. _JumpIfError(hr, error, "myGetERACertificateFromPicker");
  2556. }
  2557. else
  2558. {
  2559. hr = myGetCertificateFromPicker(
  2560. g_hInstance,
  2561. NULL, // hwndParent
  2562. IDS_GETCERT_TITLE,
  2563. NULL != pszObjId?
  2564. IDS_GETCERT_SUBTITLE_OBJID :
  2565. IDS_GETCERT_SUBTITLE,
  2566. // dwFlags: HKLM+HKCU My store
  2567. CUCS_MYSTORE |
  2568. CUCS_CASTORE |
  2569. CUCS_KRASTORE |
  2570. CUCS_ROOTSTORE |
  2571. CUCS_MACHINESTORE |
  2572. CUCS_USERSTORE |
  2573. CUCS_DSSTORE |
  2574. (g_fCryptSilent? CUCS_SILENT : 0),
  2575. pwszCommonName,
  2576. 0,
  2577. NULL,
  2578. NULL != pszObjId? 1 : 0, // cpszObjId
  2579. NULL != pszObjId? &pszObjId : NULL,
  2580. &pCert);
  2581. _JumpIfError(hr, error, "myGetCertificateFromPicker");
  2582. }
  2583. if (NULL != pCert)
  2584. {
  2585. hr = cuDumpAsnBinary(
  2586. pCert->pbCertEncoded,
  2587. pCert->cbCertEncoded,
  2588. MAXDWORD);
  2589. _JumpIfError(hr, error, "cuDumpAsnBinary(cert)");
  2590. }
  2591. error:
  2592. if (NULL != pCert)
  2593. {
  2594. CertFreeCertificateContext(pCert);
  2595. }
  2596. if (NULL != pszObjId)
  2597. {
  2598. LocalFree(pszObjId);
  2599. }
  2600. return(hr);
  2601. }