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.

2450 lines
85 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1997
  6. //
  7. // File: ttrust.cpp
  8. //
  9. // Contents: WinVerifyTrust Chain Tests
  10. //
  11. // See Usage() for a list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 06-Feb-98 philh created
  17. //--------------------------------------------------------------------------
  18. #define CERT_CHAIN_PARA_HAS_EXTRA_FIELDS 1
  19. #include <windows.h>
  20. #include <assert.h>
  21. #include "wincrypt.h"
  22. #include "wintrust.h"
  23. #include "wintrustp.h"
  24. #include "softpub.h"
  25. #include "certtest.h"
  26. #include "crypthlp.h"
  27. #include "unicode.h"
  28. #include "wininet.h"
  29. #ifndef SECURITY_FLAG_IGNORE_REVOCATION
  30. # define SECURITY_FLAG_IGNORE_REVOCATION 0x00000080
  31. # define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100
  32. #endif
  33. #ifndef SECURITY_FLAG_IGNORE_WRONG_USAGE
  34. # define SECURITY_FLAG_IGNORE_WRONG_USAGE 0x00000200
  35. #endif
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include <memory.h>
  40. #include <time.h>
  41. #include <winwlx.h>
  42. BOOL fFlushCrl = FALSE;
  43. extern BOOL WINAPI ChainWlxLogoffEvent (PWLX_NOTIFICATION_INFO pNotificationInfo);
  44. static void PrintStatus(
  45. IN LPCSTR pszMsg,
  46. IN LONG lStatus
  47. )
  48. {
  49. printf("%s", pszMsg);
  50. switch (lStatus) {
  51. case CRYPT_E_MSG_ERROR:
  52. printf("CRYPT_E_MSG_ERROR");
  53. break;
  54. case CRYPT_E_UNKNOWN_ALGO:
  55. printf("CRYPT_E_UNKNOWN_ALGO");
  56. break;
  57. case CRYPT_E_OID_FORMAT:
  58. printf("CRYPT_E_OID_FORMAT");
  59. break;
  60. case CRYPT_E_INVALID_MSG_TYPE:
  61. printf("CRYPT_E_INVALID_MSG_TYPE");
  62. break;
  63. case CRYPT_E_UNEXPECTED_ENCODING:
  64. printf("CRYPT_E_UNEXPECTED_ENCODING");
  65. break;
  66. case CRYPT_E_AUTH_ATTR_MISSING:
  67. printf("CRYPT_E_AUTH_ATTR_MISSING");
  68. break;
  69. case CRYPT_E_HASH_VALUE:
  70. printf("CRYPT_E_HASH_VALUE");
  71. break;
  72. case CRYPT_E_INVALID_INDEX:
  73. printf("CRYPT_E_INVALID_INDEX");
  74. break;
  75. case CRYPT_E_ALREADY_DECRYPTED:
  76. printf("CRYPT_E_ALREADY_DECRYPTED");
  77. break;
  78. case CRYPT_E_NOT_DECRYPTED:
  79. printf("CRYPT_E_NOT_DECRYPTED");
  80. break;
  81. case CRYPT_E_RECIPIENT_NOT_FOUND:
  82. printf("CRYPT_E_RECIPIENT_NOT_FOUND");
  83. break;
  84. case CRYPT_E_CONTROL_TYPE:
  85. printf("CRYPT_E_CONTROL_TYPE");
  86. break;
  87. case CRYPT_E_ISSUER_SERIALNUMBER:
  88. printf("CRYPT_E_ISSUER_SERIALNUMBER");
  89. break;
  90. case CRYPT_E_SIGNER_NOT_FOUND:
  91. printf("CRYPT_E_SIGNER_NOT_FOUND");
  92. break;
  93. case CRYPT_E_ATTRIBUTES_MISSING:
  94. printf("CRYPT_E_ATTRIBUTES_MISSING");
  95. break;
  96. case CRYPT_E_STREAM_MSG_NOT_READY:
  97. printf("CRYPT_E_STREAM_MSG_NOT_READY");
  98. break;
  99. case CRYPT_E_STREAM_INSUFFICIENT_DATA:
  100. printf("CRYPT_E_STREAM_INSUFFICIENT_DATA");
  101. break;
  102. case CRYPT_E_BAD_LEN:
  103. printf("CRYPT_E_BAD_LEN");
  104. break;
  105. case CRYPT_E_BAD_ENCODE:
  106. printf("CRYPT_E_BAD_ENCODE");
  107. break;
  108. case CRYPT_E_FILE_ERROR:
  109. printf("CRYPT_E_FILE_ERROR");
  110. break;
  111. case CRYPT_E_NOT_FOUND:
  112. printf("CRYPT_E_NOT_FOUND");
  113. break;
  114. case CRYPT_E_EXISTS:
  115. printf("CRYPT_E_EXISTS");
  116. break;
  117. case CRYPT_E_NO_PROVIDER:
  118. printf("CRYPT_E_NO_PROVIDER");
  119. break;
  120. case CRYPT_E_SELF_SIGNED:
  121. printf("CRYPT_E_SELF_SIGNED");
  122. break;
  123. case CRYPT_E_DELETED_PREV:
  124. printf("CRYPT_E_DELETED_PREV");
  125. break;
  126. case CRYPT_E_NO_MATCH:
  127. printf("CRYPT_E_NO_MATCH");
  128. break;
  129. case CRYPT_E_UNEXPECTED_MSG_TYPE:
  130. printf("CRYPT_E_UNEXPECTED_MSG_TYPE");
  131. break;
  132. case CRYPT_E_NO_KEY_PROPERTY:
  133. printf("CRYPT_E_NO_KEY_PROPERTY");
  134. break;
  135. case CRYPT_E_NO_DECRYPT_CERT:
  136. printf("CRYPT_E_NO_DECRYPT_CERT");
  137. break;
  138. case CRYPT_E_BAD_MSG:
  139. printf("CRYPT_E_BAD_MSG");
  140. break;
  141. case CRYPT_E_NO_SIGNER:
  142. printf("CRYPT_E_NO_SIGNER");
  143. break;
  144. case CRYPT_E_PENDING_CLOSE:
  145. printf("CRYPT_E_PENDING_CLOSE");
  146. break;
  147. case CRYPT_E_REVOKED:
  148. printf("CRYPT_E_REVOKED");
  149. break;
  150. case CRYPT_E_NO_REVOCATION_DLL:
  151. printf("CRYPT_E_NO_REVOCATION_DLL");
  152. break;
  153. case CRYPT_E_NO_REVOCATION_CHECK:
  154. printf("CRYPT_E_NO_REVOCATION_CHECK");
  155. break;
  156. case CRYPT_E_REVOCATION_OFFLINE:
  157. printf("CRYPT_E_REVOCATION_OFFLINE");
  158. break;
  159. case CRYPT_E_NOT_IN_REVOCATION_DATABASE:
  160. printf("CRYPT_E_NOT_IN_REVOCATION_DATABASE");
  161. break;
  162. case CRYPT_E_INVALID_NUMERIC_STRING:
  163. printf("CRYPT_E_INVALID_NUMERIC_STRING");
  164. break;
  165. case CRYPT_E_INVALID_PRINTABLE_STRING:
  166. printf("CRYPT_E_INVALID_PRINTABLE_STRING");
  167. break;
  168. case CRYPT_E_INVALID_IA5_STRING:
  169. printf("CRYPT_E_INVALID_IA5_STRING");
  170. break;
  171. case CRYPT_E_INVALID_X500_STRING:
  172. printf("CRYPT_E_INVALID_X500_STRING");
  173. break;
  174. case CRYPT_E_NOT_CHAR_STRING:
  175. printf("CRYPT_E_NOT_CHAR_STRING");
  176. break;
  177. case CRYPT_E_FILERESIZED:
  178. printf("CRYPT_E_FILERESIZED");
  179. break;
  180. case CRYPT_E_SECURITY_SETTINGS:
  181. printf("CRYPT_E_SECURITY_SETTINGS");
  182. break;
  183. case CRYPT_E_NO_VERIFY_USAGE_DLL:
  184. printf("CRYPT_E_NO_VERIFY_USAGE_DLL");
  185. break;
  186. case CRYPT_E_NO_VERIFY_USAGE_CHECK:
  187. printf("CRYPT_E_NO_VERIFY_USAGE_CHECK");
  188. break;
  189. case CRYPT_E_VERIFY_USAGE_OFFLINE:
  190. printf("CRYPT_E_VERIFY_USAGE_OFFLINE");
  191. break;
  192. case CRYPT_E_NOT_IN_CTL:
  193. printf("CRYPT_E_NOT_IN_CTL");
  194. break;
  195. case CRYPT_E_NO_TRUSTED_SIGNER:
  196. printf("CRYPT_E_NO_TRUSTED_SIGNER");
  197. break;
  198. case CERTSRV_E_BAD_REQUESTSUBJECT:
  199. printf("CERTSRV_E_BAD_REQUESTSUBJECT");
  200. break;
  201. case CERTSRV_E_NO_REQUEST:
  202. printf("CERTSRV_E_NO_REQUEST");
  203. break;
  204. case CERTSRV_E_BAD_REQUESTSTATUS:
  205. printf("CERTSRV_E_BAD_REQUESTSTATUS");
  206. break;
  207. case CERTSRV_E_PROPERTY_EMPTY:
  208. printf("CERTSRV_E_PROPERTY_EMPTY");
  209. break;
  210. case TRUST_E_SYSTEM_ERROR:
  211. printf("TRUST_E_SYSTEM_ERROR");
  212. break;
  213. case TRUST_E_NO_SIGNER_CERT:
  214. printf("TRUST_E_NO_SIGNER_CERT");
  215. break;
  216. case TRUST_E_COUNTER_SIGNER:
  217. printf("TRUST_E_COUNTER_SIGNER");
  218. break;
  219. case TRUST_E_CERT_SIGNATURE:
  220. printf("TRUST_E_CERT_SIGNATURE");
  221. break;
  222. case TRUST_E_TIME_STAMP:
  223. printf("TRUST_E_TIME_STAMP");
  224. break;
  225. case TRUST_E_BAD_DIGEST:
  226. printf("TRUST_E_BAD_DIGEST");
  227. break;
  228. case TRUST_E_BASIC_CONSTRAINTS:
  229. printf("TRUST_E_BASIC_CONSTRAINTS");
  230. break;
  231. case TRUST_E_FINANCIAL_CRITERIA:
  232. printf("TRUST_E_FINANCIAL_CRITERIA");
  233. break;
  234. case TRUST_E_PROVIDER_UNKNOWN:
  235. printf("TRUST_E_PROVIDER_UNKNOWN");
  236. break;
  237. case TRUST_E_ACTION_UNKNOWN:
  238. printf("TRUST_E_ACTION_UNKNOWN");
  239. break;
  240. case TRUST_E_SUBJECT_FORM_UNKNOWN:
  241. printf("TRUST_E_SUBJECT_FORM_UNKNOWN");
  242. break;
  243. case TRUST_E_SUBJECT_NOT_TRUSTED:
  244. printf("TRUST_E_SUBJECT_NOT_TRUSTED");
  245. break;
  246. case TRUST_E_EXPLICIT_DISTRUST:
  247. printf("TRUST_E_EXPLICIT_DISTRUST");
  248. break;
  249. case DIGSIG_E_ENCODE:
  250. printf("DIGSIG_E_ENCODE");
  251. break;
  252. case DIGSIG_E_DECODE:
  253. printf("DIGSIG_E_DECODE");
  254. break;
  255. case DIGSIG_E_EXTENSIBILITY:
  256. printf("DIGSIG_E_EXTENSIBILITY");
  257. break;
  258. case DIGSIG_E_CRYPTO:
  259. printf("DIGSIG_E_CRYPTO");
  260. break;
  261. case PERSIST_E_SIZEDEFINITE:
  262. printf("PERSIST_E_SIZEDEFINITE");
  263. break;
  264. case PERSIST_E_SIZEINDEFINITE:
  265. printf("PERSIST_E_SIZEINDEFINITE");
  266. break;
  267. case PERSIST_E_NOTSELFSIZING:
  268. printf("PERSIST_E_NOTSELFSIZING");
  269. break;
  270. case TRUST_E_NOSIGNATURE:
  271. printf("TRUST_E_NOSIGNATURE");
  272. break;
  273. case CERT_E_EXPIRED:
  274. printf("CERT_E_EXPIRED");
  275. break;
  276. case CERT_E_VALIDITYPERIODNESTING:
  277. printf("CERT_E_VALIDITYPERIODNESTING");
  278. break;
  279. case CERT_E_ROLE:
  280. printf("CERT_E_ROLE");
  281. break;
  282. case CERT_E_PATHLENCONST:
  283. printf("CERT_E_PATHLENCONST");
  284. break;
  285. case CERT_E_CRITICAL:
  286. printf("CERT_E_CRITICAL");
  287. break;
  288. case CERT_E_PURPOSE:
  289. printf("CERT_E_PURPOSE");
  290. break;
  291. case CERT_E_ISSUERCHAINING:
  292. printf("CERT_E_ISSUERCHAINING");
  293. break;
  294. case CERT_E_MALFORMED:
  295. printf("CERT_E_MALFORMED");
  296. break;
  297. case CERT_E_UNTRUSTEDROOT:
  298. printf("CERT_E_UNTRUSTEDROOT");
  299. break;
  300. case CERT_E_UNTRUSTEDCA:
  301. printf("CERT_E_UNTRUSTEDCA");
  302. break;
  303. case CERT_E_CHAINING:
  304. printf("CERT_E_CHAINING");
  305. break;
  306. case TRUST_E_FAIL:
  307. printf("TRUST_E_FAIL");
  308. break;
  309. case CERT_E_REVOKED:
  310. printf("CERT_E_REVOKED");
  311. break;
  312. case CERT_E_UNTRUSTEDTESTROOT:
  313. printf("CERT_E_UNTRUSTEDTESTROOT");
  314. break;
  315. case CERT_E_REVOCATION_FAILURE:
  316. printf("CERT_E_REVOCATION_FAILURE");
  317. break;
  318. case CERT_E_CN_NO_MATCH:
  319. printf("CERT_E_CN_NO_MATCH");
  320. break;
  321. case CERT_E_WRONG_USAGE:
  322. printf("CERT_E_WRONG_USAGE");
  323. break;
  324. default:
  325. break;
  326. }
  327. printf (" 0x%x (%d)\n", lStatus, lStatus);
  328. }
  329. static void PrintError(
  330. IN LPCSTR pszMsg,
  331. IN DWORD dwErr
  332. )
  333. {
  334. PrintStatus(pszMsg, (LONG) dwErr);
  335. }
  336. static void Usage(void)
  337. {
  338. printf("Usage: ttrust [options] <filename>\n");
  339. printf("Options are:\n");
  340. printf(" -Cert - Default\n");
  341. printf(" -File\n");
  342. printf(" -Driver\n");
  343. printf(" -Https\n");
  344. printf(" -Chain\n");
  345. printf(" -ChainCallback\n");
  346. printf(" -NTAuth\n");
  347. printf(" -NTAuthNameConstraint\n");
  348. printf(" -Safer\n");
  349. printf("\n");
  350. printf(" -UseIE4Trust\n");
  351. printf(" -NoIE4Chain\n");
  352. printf(" -NoUsage\n");
  353. printf(" -OrUsage\n");
  354. printf(" -OrPolicy\n");
  355. printf(" -LifetimeSigning\n");
  356. printf(" -MicrosoftRoot\n");
  357. printf(" -MicrosoftTestRoot\n");
  358. printf(" -NotMicrosoftRoot\n");
  359. printf(" -FlushCrl\n");
  360. printf(" -DeferClosing\n");
  361. printf("\n");
  362. printf(" -DisplayKnownUsages\n");
  363. printf(" -LogoffNotification\n");
  364. printf("\n");
  365. printf(" -UINone - Default\n");
  366. printf(" -UIAll\n");
  367. printf(" -UINoBad\n");
  368. printf(" -UINoGood\n");
  369. printf("\n");
  370. printf(" -RevokeNone - Default\n");
  371. printf(" -RevokeChain\n");
  372. printf("\n");
  373. printf(" -DontOpenStores\n");
  374. printf(" -OpenOnlyRoot\n");
  375. printf("\n");
  376. printf(" -HttpsIgnoreRevocation\n");
  377. printf(" -HttpsIgnoreUnknownCa\n");
  378. printf(" -HttpsIgnoreWrongUsage\n");
  379. printf(" -HttpsIgnoreCertDateInvalid\n");
  380. printf(" -HttpsIgnoreCertCNInvalid\n");
  381. printf("\n");
  382. printf(" -Client - Default\n");
  383. printf(" -Server\n");
  384. printf("\n");
  385. printf(" -InstallThreadDefaultContext\n");
  386. printf(" -InstallProcessDefaultContext\n");
  387. printf(" -AutoReleaseDefaultContext\n");
  388. printf(" -NULLDefaultContext\n");
  389. printf(" -MultiDefaultContext\n");
  390. printf("\n");
  391. printf(" -AuthenticodeFlags <Number>\n");
  392. printf(" -DeleteSaferRegKey\n");
  393. printf(" -EnableRootAutoUpdate\n");
  394. printf(" -DisableRootAutoUpdate\n");
  395. printf(" -EnableUntrustedRootLogging\n");
  396. printf(" -DisableUntrustedRootLogging\n");
  397. printf(" -EnablePartialChainLogging\n");
  398. printf(" -DisablePartialChainLogging\n");
  399. printf(" -EnableNTAuthRequired\n");
  400. printf(" -DisableNTAuthRequired\n");
  401. printf(" -EnableNotDefinedNameConstraint\n");
  402. printf(" -DisableNotDefinedNameConstraint\n");
  403. printf(" -EnableAuthRoot\n");
  404. printf(" -DisableAuthRoot\n");
  405. printf(" -RegistryOnlyExit\n");
  406. printf("\n");
  407. printf("Cert Chain Config Registry Values (0xFFFFFFFF deletes):\n");
  408. printf(" -DisableMandatoryBasicConstraints <Number>\n");
  409. printf(" -DisableAIAUrlRetrieval <Number>\n");
  410. printf(" -MaxAIAUrlCountInCert <Number>\n");
  411. printf(" -MaxAIAUrlRetrievalCountPerChain <Number>\n");
  412. printf(" -MaxAIAUrlRetrievalByteCount <Number>\n");
  413. printf(" -MaxAIAUrlRetrievalCertCount <Number>\n");
  414. printf("\n");
  415. printf(" -h - This message\n");
  416. printf(" -b - Brief\n");
  417. printf(" -v - Verbose\n");
  418. printf(" -q[<Number>] - Quiet, expected error\n");
  419. printf(" -e<Number> - Expected trust error status\n");
  420. printf(" -i<Number> - Expected trust info status\n");
  421. printf(" -u<OID String> - Usage OID string -u1.3.6.1.5.5.7.3.3\n");
  422. printf(" -p<OID String> - Policy OID string -u1.3.6.1.5.5.7.3.3\n");
  423. printf(" -s<SystemStore> - Additional System Store\n");
  424. printf(" -S<FileSystemStore> - Additional File System Store\n");
  425. printf(" -n<ServerName> - Https ServerName\n");
  426. printf(" -f<Number> - Flags\n");
  427. printf(" -t<Number> - Url timeout (milliseconds)\n");
  428. printf(" -r<Number> - Revocation freshness (seconds)\n");
  429. printf("\n");
  430. }
  431. static PCCERT_CONTEXT ReadCert(
  432. IN LPSTR pszCert
  433. )
  434. {
  435. BOOL fResult;
  436. BYTE *pbEncoded;
  437. DWORD cbEncoded;
  438. PCCERT_CONTEXT pCert;
  439. if (!ReadDERFromFile(pszCert, &pbEncoded, &cbEncoded)) {
  440. PrintLastError("ReadCert");
  441. return NULL;
  442. }
  443. pCert = CertCreateCertificateContext(
  444. dwCertEncodingType,
  445. pbEncoded,
  446. cbEncoded
  447. );
  448. if (pCert == NULL)
  449. PrintLastError("CertCreateCertificateContext");
  450. TestFree(pbEncoded);
  451. return pCert;
  452. }
  453. static void DisplayPeterSigner(
  454. IN CRYPT_PROVIDER_SGNR *pProvSign,
  455. IN DWORD dwDisplayFlags
  456. )
  457. {
  458. DWORD idxCert;
  459. printf("Verify Time: %s\n", FileTimeText(&pProvSign->sftVerifyAsOf));
  460. if (pProvSign->dwSignerType) {
  461. printf("Signer Type: 0x%x", pProvSign->dwSignerType);
  462. if (pProvSign->dwSignerType == SGNR_TYPE_TIMESTAMP)
  463. printf(" TIMESTAMP");
  464. printf("\n");
  465. }
  466. if (pProvSign->dwError)
  467. PrintError("Error: ", pProvSign->dwError);
  468. if (0 == pProvSign->csCertChain) {
  469. printf("No Certificates\n");
  470. return;
  471. }
  472. for (idxCert = 0; idxCert < pProvSign->csCertChain; idxCert++) {
  473. CRYPT_PROVIDER_CERT *pProvCert;
  474. printf("----- Cert [%d] -----\n", idxCert);
  475. pProvCert = WTHelperGetProvCertFromChain(pProvSign, idxCert);
  476. if (pProvCert) {
  477. if (pProvCert->dwError)
  478. PrintError("Error: ", pProvCert->dwError);
  479. if (pProvCert->dwRevokedReason)
  480. PrintError("RevokedReason: ", pProvCert->dwRevokedReason);
  481. printf("Confidence:: 0x%x ", pProvCert->dwConfidence);
  482. if ((pProvCert->dwConfidence & CERT_CONFIDENCE_HIGHEST) ==
  483. CERT_CONFIDENCE_HIGHEST)
  484. printf("Highest ");
  485. else {
  486. if (pProvCert->dwConfidence & CERT_CONFIDENCE_SIG)
  487. printf("Signature ");
  488. if (pProvCert->dwConfidence & CERT_CONFIDENCE_TIME)
  489. printf("Time ");
  490. if (pProvCert->dwConfidence & CERT_CONFIDENCE_TIMENEST)
  491. printf("TimeNest ");
  492. if (pProvCert->dwConfidence & CERT_CONFIDENCE_AUTHIDEXT)
  493. printf("AuthorityID ");
  494. if (pProvCert->dwConfidence & CERT_CONFIDENCE_HYGIENE)
  495. printf("Hygiene ");
  496. }
  497. printf("\n");
  498. if (pProvCert->fTrustListSignerCert)
  499. printf("TrustListSignerCert ");
  500. if (pProvCert->fCommercial)
  501. printf("Commercial ");
  502. if (pProvCert->fTrustedRoot)
  503. printf("TrustedRoot ");
  504. if (pProvCert->fSelfSigned)
  505. printf("SelfSigned ");
  506. if (pProvCert->fTestCert)
  507. printf("TestCert ");
  508. printf("\n");
  509. DisplayCert(pProvCert->pCert, dwDisplayFlags);
  510. if (pProvCert->pTrustListContext) {
  511. printf("----- Outlook CTL -----\n");
  512. DisplayCtl(
  513. (PCCTL_CONTEXT) pProvCert->pTrustListContext,
  514. dwDisplayFlags
  515. );
  516. }
  517. if (pProvCert->dwCtlError)
  518. PrintError("Ctl Error: ", pProvCert->dwCtlError);
  519. if (pProvCert->pCtlContext) {
  520. printf("----- CTL -----\n");
  521. DisplayCtl(pProvCert->pCtlContext, dwDisplayFlags);
  522. }
  523. }
  524. }
  525. }
  526. //+---------------------------------------------------------------------------
  527. //
  528. // Synopsis: Chain Display Functions
  529. //
  530. //----------------------------------------------------------------------------
  531. LPSTR rgszErrorStatus[] = {
  532. "CERT_TRUST_IS_NOT_TIME_VALID", // 0x00000001
  533. "CERT_TRUST_IS_NOT_TIME_NESTED", // 0x00000002
  534. "CERT_TRUST_IS_REVOKED", // 0x00000004
  535. "CERT_TRUST_IS_NOT_SIGNATURE_VALID", // 0x00000008
  536. "CERT_TRUST_IS_NOT_VALID_FOR_USAGE", // 0x00000010
  537. "CERT_TRUST_IS_UNTRUSTED_ROOT", // 0x00000020
  538. "CERT_TRUST_REVOCATION_STATUS_UNKNOWN", // 0x00000040
  539. "CERT_TRUST_IS_CYCLIC", // 0x00000080
  540. "CERT_TRUST_INVALID_EXTENSION", // 0x00000100
  541. "CERT_TRUST_INVALID_POLICY_CONSTRAINTS", // 0x00000200
  542. "CERT_TRUST_INVALID_BASIC_CONSTRAINTS", // 0x00000400
  543. "CERT_TRUST_INVALID_NAME_CONSTRAINTS", // 0x00000800
  544. "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT", // 0x00001000
  545. "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT",// 0x00002000
  546. "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT", // 0x00004000
  547. "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT", // 0x00008000
  548. "CERT_TRUST_IS_PARTIAL_CHAIN", // 0x00010000
  549. "CERT_TRUST_CTL_IS_NOT_TIME_VALID", // 0x00020000
  550. "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID", // 0x00040000
  551. "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE", // 0x00080000
  552. "Unknown Error Status", // 0x00100000
  553. "Unknown Error Status", // 0x00200000
  554. "Unknown Error Status", // 0x00400000
  555. "Unknown Error Status", // 0x00800000
  556. "CERT_TRUST_IS_OFFLINE_REVOCATION", // 0x01000000
  557. "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY", // 0x02000000
  558. "Unknown Error Status", // 0x04000000
  559. "Unknown Error Status", // 0x08000000
  560. "Unknown Error Status", // 0x10000000
  561. "Unknown Error Status", // 0x20000000
  562. "Unknown Error Status", // 0x40000000
  563. "Unknown Error Status" // 0x80000000
  564. };
  565. LPSTR rgszInfoStatus[] = {
  566. "CERT_TRUST_HAS_EXACT_MATCH_ISSUER",// 0x00000001
  567. "CERT_TRUST_HAS_KEY_MATCH_ISSUER", // 0x00000002
  568. "CERT_TRUST_HAS_NAME_MATCH_ISSUER", // 0x00000004
  569. "CERT_TRUST_IS_SELF_SIGNED", // 0x00000008
  570. "Unknown Info Status", // 0x00000010
  571. "Unknown Info Status", // 0x00000020
  572. "Unknown Info Status", // 0x00000040
  573. "Unknown Info Status", // 0x00000080
  574. "CERT_TRUST_HAS_PREFERRED_ISSUER", // 0x00000100
  575. "CERT_TRUST_HAS_ISSUANCE_CHAIN_POLICY", // 0x00000200
  576. "CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS", // 0x00000400
  577. "Unknown Info Status", // 0x00000800
  578. "Unknown Info Status", // 0x00001000
  579. "Unknown Info Status", // 0x00002000
  580. "Unknown Info Status", // 0x00004000
  581. "Unknown Info Status", // 0x00008000
  582. "CERT_TRUST_IS_COMPLEX_CHAIN", // 0x00010000
  583. "Unknown Info Status", // 0x00020000
  584. "Unknown Info Status", // 0x00040000
  585. "Unknown Info Status", // 0x00080000
  586. "Unknown Info Status", // 0x00100000
  587. "Unknown Info Status", // 0x00200000
  588. "Unknown Info Status", // 0x00400000
  589. "Unknown Info Status", // 0x00800000
  590. "Unknown Info Status", // 0x01000000
  591. "Unknown Info Status", // 0x02000000
  592. "Unknown Info Status", // 0x04000000
  593. "Unknown Info Status", // 0x08000000
  594. "Unknown Info Status", // 0x10000000
  595. "Unknown Info Status", // 0x20000000
  596. "Unknown Info Status", // 0x40000000
  597. "Unknown Info Status" // 0x80000000
  598. };
  599. void DisplayTrustStatus(
  600. IN PCERT_TRUST_STATUS pStatus
  601. )
  602. {
  603. DWORD dwMask;
  604. DWORD cCount;
  605. printf(
  606. "Trust Status (E=0x%lx,I=0x%lx)\n\n",
  607. pStatus->dwErrorStatus,
  608. pStatus->dwInfoStatus
  609. );
  610. dwMask = 1;
  611. for ( cCount = 0; cCount < 32; cCount++ )
  612. {
  613. if ( pStatus->dwErrorStatus & dwMask )
  614. {
  615. if ( strcmp( rgszErrorStatus[ cCount ], "Unknown Error Status" ) != 0 )
  616. {
  617. printf("%s\n", rgszErrorStatus[ cCount ]);
  618. }
  619. }
  620. dwMask = dwMask << 1;
  621. }
  622. dwMask = 1;
  623. for ( cCount = 0; cCount < 32; cCount++ )
  624. {
  625. if ( pStatus->dwInfoStatus & dwMask )
  626. {
  627. if ( strcmp( rgszInfoStatus[ cCount ], "Unknown Info Status" ) != 0 )
  628. {
  629. printf("%s\n", rgszInfoStatus[ cCount ]);
  630. }
  631. }
  632. dwMask = dwMask << 1;
  633. }
  634. printf("\n");
  635. }
  636. void DisplayRevocationFreshnessTime(
  637. IN DWORD dwTime // seconds
  638. )
  639. {
  640. DWORD dwRemain;
  641. DWORD dwSec;
  642. DWORD dwMin;
  643. DWORD dwHour;
  644. DWORD dwDay;
  645. dwRemain = dwTime;
  646. dwSec = dwRemain % 60;
  647. dwRemain /= 60; // total minutes
  648. dwMin = dwRemain % 60;
  649. dwRemain /= 60; // total hours
  650. dwHour = dwRemain % 24;
  651. dwDay = dwRemain / 24;
  652. printf("Revocation Freshness Time : %d (%d day %d hour %d min %d sec)\n",
  653. dwTime, dwDay, dwHour, dwMin, dwSec);
  654. }
  655. void DisplayChainElement(
  656. IN PCERT_CHAIN_ELEMENT pElement,
  657. IN DWORD dwDisplayFlags
  658. )
  659. {
  660. DisplayCert( pElement->pCertContext, dwDisplayFlags );
  661. printf("\n");
  662. if (pElement->pRevocationInfo) {
  663. PCERT_REVOCATION_INFO pRevocationInfo = pElement->pRevocationInfo;
  664. PrintError("RevocationResult: ", pRevocationInfo->dwRevocationResult);
  665. if (pRevocationInfo->pszRevocationOid)
  666. printf("RevocationOid: %s\n", pRevocationInfo->pszRevocationOid);
  667. if (pRevocationInfo->fHasFreshnessTime)
  668. DisplayRevocationFreshnessTime(
  669. pRevocationInfo->dwFreshnessTime);
  670. if (pRevocationInfo->pCrlInfo) {
  671. PCERT_REVOCATION_CRL_INFO pCrlInfo = pRevocationInfo->pCrlInfo;
  672. if (pCrlInfo->pBaseCrlContext) {
  673. printf("Base CRL\n");
  674. DisplayCrl(pCrlInfo->pBaseCrlContext, dwDisplayFlags );
  675. }
  676. if (pCrlInfo->pDeltaCrlContext) {
  677. printf("Delta CRL\n");
  678. DisplayCrl(pCrlInfo->pDeltaCrlContext, dwDisplayFlags );
  679. }
  680. if (pCrlInfo->pCrlEntry) {
  681. if (pCrlInfo->fDeltaCrlEntry)
  682. printf("Delta ");
  683. else
  684. printf("Base ");
  685. printf("CRL entry\n");
  686. PrintCrlEntries(1, pCrlInfo->pCrlEntry, dwDisplayFlags);
  687. }
  688. }
  689. printf("\n");
  690. }
  691. if (NULL == pElement->pIssuanceUsage)
  692. printf("Any Issuance Usages\n");
  693. else if (0 == pElement->pIssuanceUsage->cUsageIdentifier)
  694. printf("No Issuance Usages\n");
  695. else {
  696. printf("Issuance Usages\n");
  697. LPSTR *ppszId = pElement->pIssuanceUsage->rgpszUsageIdentifier;
  698. DWORD cId = pElement->pIssuanceUsage->cUsageIdentifier;
  699. DWORD i;
  700. for (i = 0; i < cId; i++, ppszId++)
  701. printf(" [%d] %s\n", i, *ppszId);
  702. }
  703. if (NULL == pElement->pApplicationUsage)
  704. printf("Any Application Usages\n");
  705. else if (0 == pElement->pApplicationUsage->cUsageIdentifier)
  706. printf("No Application Usages\n");
  707. else {
  708. printf("Application Usages\n");
  709. LPSTR *ppszId = pElement->pApplicationUsage->rgpszUsageIdentifier;
  710. DWORD cId = pElement->pApplicationUsage->cUsageIdentifier;
  711. DWORD i;
  712. for (i = 0; i < cId; i++, ppszId++)
  713. printf(" [%d] %s\n", i, *ppszId);
  714. }
  715. printf("\n");
  716. if (pElement->pwszExtendedErrorInfo) {
  717. printf("Extended Error Information::\n%S\n",
  718. pElement->pwszExtendedErrorInfo);
  719. }
  720. DisplayTrustStatus( &pElement->TrustStatus );
  721. }
  722. void DisplaySimpleChain(
  723. IN PCERT_SIMPLE_CHAIN pChain,
  724. IN DWORD dwDisplayFlags = 0
  725. )
  726. {
  727. DWORD cElement;
  728. if (pChain->fHasRevocationFreshnessTime)
  729. DisplayRevocationFreshnessTime(
  730. pChain->dwRevocationFreshnessTime);
  731. DisplayTrustStatus( &pChain->TrustStatus );
  732. if (fFlushCrl && pChain->cElement >= 2) {
  733. if (CryptFlushTimeValidObject(
  734. TIME_VALID_OID_FLUSH_CRL_FROM_CERT,
  735. (LPVOID) pChain->rgpElement[0]->pCertContext, // pvPara
  736. pChain->rgpElement[1]->pCertContext, // pIssuer
  737. 0, // dwFlags
  738. NULL // pvReserved
  739. ))
  740. printf("Successful FlushCrl\n");
  741. else
  742. PrintLastError("FlushCrl");
  743. }
  744. printf("Chain Element Count = %d\n", pChain->cElement);
  745. for ( cElement = 0; cElement < pChain->cElement; cElement++ )
  746. {
  747. printf("Chain Element [%d]\n", cElement);
  748. DisplayChainElement( pChain->rgpElement[ cElement ], dwDisplayFlags );
  749. }
  750. }
  751. void DisplayKirtChain(
  752. IN PCCERT_CHAIN_CONTEXT pChainContext,
  753. IN DWORD dwDisplayFlags
  754. )
  755. {
  756. DWORD cChain;
  757. if (NULL == pChainContext)
  758. return;
  759. printf("Chain Context\n\n");
  760. if (pChainContext->fHasRevocationFreshnessTime)
  761. DisplayRevocationFreshnessTime(
  762. pChainContext->dwRevocationFreshnessTime);
  763. DisplayTrustStatus( (PCERT_TRUST_STATUS)&pChainContext->TrustStatus );
  764. printf("Simple Chain Count = %d\n\n", pChainContext->cChain );
  765. for ( cChain = 0; cChain < pChainContext->cChain; cChain++ )
  766. {
  767. printf("Simple Chain [%d]\n", cChain);
  768. DisplaySimpleChain( pChainContext->rgpChain[ cChain ], dwDisplayFlags );
  769. }
  770. if (pChainContext->cLowerQualityChainContext) {
  771. DWORD i;
  772. printf("Lower Quality Chain Count = %d\n\n",
  773. pChainContext->cLowerQualityChainContext);
  774. for (i = 0; i < pChainContext->cLowerQualityChainContext; i++) {
  775. printf("Lower Quality Chain [%d]\n", i);
  776. DisplayKirtChain(pChainContext->rgpLowerQualityChainContext[i],
  777. dwDisplayFlags);
  778. }
  779. }
  780. }
  781. void DisplayChainPolicyCallbackSigner(
  782. IN PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pSigner
  783. )
  784. {
  785. if (pSigner->dwSignerType) {
  786. printf("Signer Type: 0x%x", pSigner->dwSignerType);
  787. if (pSigner->dwSignerType == SGNR_TYPE_TIMESTAMP)
  788. printf(" TIMESTAMP");
  789. printf("\n");
  790. }
  791. if (pSigner->dwError)
  792. PrintError("Error: ", pSigner->dwError);
  793. if (pSigner->pMsgSignerInfo)
  794. printf("pMsgSignerInfo: 0x%p\n", pSigner->pMsgSignerInfo);
  795. DisplayKirtChain(pSigner->pChainContext, DISPLAY_BRIEF_FLAG);
  796. }
  797. #define CHAIN_POLICY_ARG (DWORD_PTR)0x8765beef
  798. HRESULT
  799. WINAPI
  800. ChainPolicyCallback(
  801. IN PCRYPT_PROVIDER_DATA pProvData,
  802. IN DWORD dwStepError,
  803. IN DWORD dwRegPolicySettings,
  804. IN DWORD cSigner,
  805. IN PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO *rgpSigner,
  806. IN void *pvPolicyArg
  807. )
  808. {
  809. printf(">>>>> ChainPolicyCallback <<<<<\n");
  810. if (pvPolicyArg != (void *) CHAIN_POLICY_ARG)
  811. printf("failed => wrong pvPolicyArg\n");
  812. if (dwStepError)
  813. PrintError("StepError: ", dwStepError);
  814. if (dwRegPolicySettings)
  815. printf("RegPolicySettings: 0x%p\n");
  816. if (0 == cSigner)
  817. printf("No Signers\n");
  818. else {
  819. DWORD idxSigner;
  820. for (idxSigner = 0; idxSigner < cSigner; idxSigner++) {
  821. DWORD idxCounterSigner;
  822. PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pSigner =
  823. rgpSigner[idxSigner];
  824. printf("====== Signer [%d] ======\n", idxSigner);
  825. DisplayChainPolicyCallbackSigner(pSigner);
  826. for (idxCounterSigner = 0;
  827. idxCounterSigner < pSigner->cCounterSigner;
  828. idxCounterSigner++) {
  829. PWTD_GENERIC_CHAIN_POLICY_SIGNER_INFO pCounterSigner =
  830. pSigner->rgpCounterSigner[idxCounterSigner];
  831. printf("\n");
  832. printf("====== CounterSigner [%d,%d] ======\n",
  833. idxSigner, idxCounterSigner);
  834. DisplayChainPolicyCallbackSigner(pCounterSigner);
  835. }
  836. }
  837. }
  838. return TRUST_E_FAIL;
  839. }
  840. static BOOL fInstallDefaultContext = FALSE;
  841. static DWORD dwDefaultContextFlags = 0;
  842. static BOOL fNULLDefaultContext = FALSE;
  843. static BOOL fMultiDefaultContext = FALSE;
  844. static LPSTR rgpszDefaultContextOID[] = {
  845. // 0
  846. szOID_OIWSEC_sha1RSASign,
  847. // 1
  848. szOID_OIWSEC_shaRSA,
  849. // 2
  850. szOID_RSA_MD5RSA,
  851. // 3
  852. szOID_OIWSEC_md5RSA,
  853. // 4
  854. szOID_RSA_MD2RSA,
  855. // 5
  856. szOID_RSA_MD4RSA,
  857. // 6
  858. szOID_OIWSEC_md4RSA,
  859. // 7
  860. szOID_OIWSEC_md4RSA2,
  861. // 8
  862. szOID_OIWDIR_md2RSA,
  863. // 9
  864. szOID_RSA_SHA1RSA,
  865. };
  866. static CRYPT_DEFAULT_CONTEXT_MULTI_OID_PARA rgMultiOIDPara[] = {
  867. 1, &rgpszDefaultContextOID[3],
  868. 2, &rgpszDefaultContextOID[2],
  869. 10, &rgpszDefaultContextOID[0],
  870. 4, &rgpszDefaultContextOID[6],
  871. 1, &rgpszDefaultContextOID[8],
  872. };
  873. #define NUM_MULTI_OID_PARA (sizeof(rgMultiOIDPara) / sizeof(rgMultiOIDPara[0]))
  874. static HCRYPTDEFAULTCONTEXT rghDefaultContext[NUM_MULTI_OID_PARA];
  875. static DWORD cDefaultContext = 0;
  876. static HCRYPTPROV hDefaultContextProv = 0;
  877. static void InstallDefaultContext()
  878. {
  879. if (!CryptAcquireContext(
  880. &hDefaultContextProv,
  881. NULL, // pszContainer
  882. NULL, // pszProvider,
  883. PROV_RSA_FULL,
  884. CRYPT_VERIFYCONTEXT // dwFlags
  885. )) {
  886. PrintLastError(
  887. "CryptAcquireContext(PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)");
  888. hDefaultContextProv = 0;
  889. return;
  890. }
  891. if (fMultiDefaultContext) {
  892. DWORD dwFlags = dwDefaultContextFlags;
  893. for (cDefaultContext = 0; cDefaultContext < NUM_MULTI_OID_PARA;
  894. cDefaultContext++) {
  895. if (!CryptInstallDefaultContext(
  896. hDefaultContextProv,
  897. CRYPT_DEFAULT_CONTEXT_MULTI_CERT_SIGN_OID,
  898. (const void *) &rgMultiOIDPara[cDefaultContext],
  899. dwFlags,
  900. NULL, // pvReserved
  901. &rghDefaultContext[cDefaultContext]
  902. )) {
  903. PrintLastError("CryptInstallDefaultContext");
  904. break;
  905. }
  906. dwFlags &= ~CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG;
  907. }
  908. } else {
  909. LPSTR pszOID;
  910. if (fNULLDefaultContext)
  911. pszOID = NULL;
  912. else
  913. pszOID = szOID_RSA_MD5RSA;
  914. if (!CryptInstallDefaultContext(
  915. hDefaultContextProv,
  916. CRYPT_DEFAULT_CONTEXT_CERT_SIGN_OID,
  917. (const void *) pszOID,
  918. dwDefaultContextFlags,
  919. NULL, // pvReserved
  920. &rghDefaultContext[0]
  921. ))
  922. PrintLastError("CryptInstallDefaultContext");
  923. else
  924. cDefaultContext = 1;
  925. }
  926. if (0 == cDefaultContext) {
  927. CryptReleaseContext(hDefaultContextProv, 0);
  928. hDefaultContextProv = 0;
  929. }
  930. }
  931. static void FreeDefaultContext()
  932. {
  933. if (dwDefaultContextFlags & CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG)
  934. return;
  935. if (0 < cDefaultContext) {
  936. if (!CryptUninstallDefaultContext(
  937. rghDefaultContext[0],
  938. 0, // dwFlags
  939. NULL // pvReserved
  940. ))
  941. PrintLastError("CryptUninstallDefaultContext");
  942. rghDefaultContext[0] = NULL;
  943. while (cDefaultContext-- > 0){
  944. if (!CryptUninstallDefaultContext(
  945. rghDefaultContext[cDefaultContext],
  946. 0, // dwFlags
  947. NULL // pvReserved
  948. ))
  949. PrintLastError("CryptUninstallDefaultContext");
  950. }
  951. }
  952. if (hDefaultContextProv)
  953. CryptReleaseContext(hDefaultContextProv, 0);
  954. }
  955. BOOL NTAuthVerify(
  956. IN PCCERT_CHAIN_CONTEXT pChainContext,
  957. IN DWORD dwExpectedErr
  958. )
  959. {
  960. BOOL fResult = TRUE;
  961. DWORD dwErr;
  962. HCERTSTORE hNTAuthStore = NULL;
  963. PCERT_SIMPLE_CHAIN pChain;
  964. PCCERT_CONTEXT pCACert; // don't free
  965. PCCERT_CONTEXT pAddCert = NULL;
  966. CERT_CHAIN_POLICY_PARA PolicyPara;
  967. memset(&PolicyPara, 0, sizeof(PolicyPara));
  968. PolicyPara.cbSize = sizeof(PolicyPara);
  969. PolicyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG |
  970. CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG;
  971. CERT_CHAIN_POLICY_STATUS PolicyStatus;
  972. memset(&PolicyStatus, 0, sizeof(PolicyStatus));
  973. PolicyStatus.cbSize = sizeof(PolicyStatus);
  974. if (!CertVerifyCertificateChainPolicy(
  975. CERT_CHAIN_POLICY_NT_AUTH,
  976. pChainContext,
  977. &PolicyPara,
  978. &PolicyStatus
  979. )) {
  980. PrintLastError(
  981. "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)");
  982. goto ErrorReturn;
  983. }
  984. dwErr = PolicyStatus.dwError;
  985. if ((CRYPT_E_NO_REVOCATION_CHECK == dwExpectedErr ||
  986. CRYPT_E_REVOCATION_OFFLINE == dwExpectedErr)) {
  987. if (CERT_E_UNTRUSTEDCA != dwErr) {
  988. PrintStatus("NTAuth failed without CERT_E_UNTRUSTEDCA when revocation checking => ", (LONG) dwErr);
  989. fResult = FALSE;
  990. }
  991. } else if (dwExpectedErr != dwErr) {
  992. PrintStatus("Expected => ", (LONG) dwExpectedErr);
  993. PrintStatus("NTAuth failed => ", (LONG) dwErr);
  994. fResult = FALSE;
  995. }
  996. if (CERT_E_UNTRUSTEDCA != dwErr)
  997. goto CommonReturn;
  998. pChain = pChainContext->rgpChain[0];
  999. if (2 > pChain->cElement) {
  1000. printf("NTAuth:: failed => missing CA cert\n");
  1001. goto ErrorReturn;
  1002. }
  1003. pCACert = pChain->rgpElement[1]->pCertContext;
  1004. hNTAuthStore = CertOpenStore(
  1005. CERT_STORE_PROV_SYSTEM_REGISTRY_W,
  1006. 0, // dwEncodingType
  1007. 0, // hCryptProv
  1008. CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
  1009. L"NTAuth"
  1010. );
  1011. if (NULL == hNTAuthStore) {
  1012. PrintLastError("CertOpenStore(NTAuth)");
  1013. goto ErrorReturn;
  1014. }
  1015. if (!CertAddCertificateContextToStore(
  1016. hNTAuthStore,
  1017. pCACert,
  1018. CERT_STORE_ADD_NEW,
  1019. &pAddCert
  1020. )) {
  1021. PrintLastError("CertAddCertificateContextToStore(NTAuth CA)");
  1022. goto ErrorReturn;
  1023. }
  1024. // Need to sleep to allow the registry notification to occur.
  1025. Sleep(200);
  1026. // With the CA cert added, the verify policy should succeed
  1027. if (!CertVerifyCertificateChainPolicy(
  1028. CERT_CHAIN_POLICY_NT_AUTH,
  1029. pChainContext,
  1030. &PolicyPara,
  1031. &PolicyStatus
  1032. )) {
  1033. PrintLastError(
  1034. "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)");
  1035. fResult = FALSE;
  1036. } else if (0 != PolicyStatus.dwError) {
  1037. if ((CRYPT_E_NO_REVOCATION_CHECK == dwExpectedErr ||
  1038. CRYPT_E_REVOCATION_OFFLINE == dwExpectedErr)
  1039. &&
  1040. dwExpectedErr == PolicyStatus.dwError) {
  1041. PrintStatus("NTAuth got expected error adding NTAuth CA = ",
  1042. (LONG) dwExpectedErr);
  1043. } else {
  1044. PrintStatus("NTAuth failed after adding NTAuth CA with dwError = ",
  1045. (LONG) PolicyStatus.dwError);
  1046. fResult = FALSE;
  1047. }
  1048. }
  1049. CertDeleteCertificateFromStore(pAddCert);
  1050. pAddCert = NULL;
  1051. // Need to sleep to allow the registry notification to occur.
  1052. Sleep(200);
  1053. // With the CA cert deleted, the verify policy should fail
  1054. if (!CertVerifyCertificateChainPolicy(
  1055. CERT_CHAIN_POLICY_NT_AUTH,
  1056. pChainContext,
  1057. &PolicyPara,
  1058. &PolicyStatus
  1059. )) {
  1060. PrintLastError(
  1061. "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)");
  1062. fResult = FALSE;
  1063. } else if (CERT_E_UNTRUSTEDCA != PolicyStatus.dwError) {
  1064. PrintStatus("NTAuth failed without CERT_E_UNTRUSTEDCA after deleting NTAuth CA with dwError = ",
  1065. (LONG) PolicyStatus.dwError);
  1066. fResult = FALSE;
  1067. }
  1068. CommonReturn:
  1069. if (hNTAuthStore)
  1070. CertCloseStore(hNTAuthStore, 0);
  1071. return fResult;
  1072. ErrorReturn:
  1073. if (pAddCert)
  1074. CertDeleteCertificateFromStore(pAddCert);
  1075. fResult = FALSE;
  1076. goto CommonReturn;
  1077. }
  1078. BOOL NTAuthNameConstraintVerify(
  1079. IN PCCERT_CHAIN_CONTEXT pChainContext,
  1080. IN DWORD dwExpectedErr
  1081. )
  1082. {
  1083. BOOL fResult = FALSE;
  1084. DWORD dwErr;
  1085. CERT_CHAIN_POLICY_PARA PolicyPara;
  1086. memset(&PolicyPara, 0, sizeof(PolicyPara));
  1087. PolicyPara.cbSize = sizeof(PolicyPara);
  1088. PolicyPara.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;
  1089. CERT_CHAIN_POLICY_STATUS PolicyStatus;
  1090. memset(&PolicyStatus, 0, sizeof(PolicyStatus));
  1091. PolicyStatus.cbSize = sizeof(PolicyStatus);
  1092. if (!CertVerifyCertificateChainPolicy(
  1093. CERT_CHAIN_POLICY_NT_AUTH,
  1094. pChainContext,
  1095. &PolicyPara,
  1096. &PolicyStatus
  1097. )) {
  1098. PrintLastError(
  1099. "CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_NT_AUTH)");
  1100. goto CommonReturn;
  1101. }
  1102. dwErr = PolicyStatus.dwError;
  1103. if (dwExpectedErr == dwErr) {
  1104. PrintStatus("NTAuthNameConstraint returned expected => ",
  1105. (LONG) dwExpectedErr);
  1106. fResult = TRUE;
  1107. } else {
  1108. PrintStatus("Expected => ", (LONG) dwExpectedErr);
  1109. PrintStatus("NTAuthNameConstraint failed => ", (LONG) dwErr);
  1110. }
  1111. CommonReturn:
  1112. return fResult;
  1113. }
  1114. void DeleteSaferRegKey()
  1115. {
  1116. HKEY hKey = NULL;
  1117. LONG err;
  1118. if (ERROR_SUCCESS != (err = RegOpenKeyExU(
  1119. HKEY_LOCAL_MACHINE,
  1120. CERT_TRUST_PUB_SAFER_LOCAL_MACHINE_REGPATH,
  1121. 0, // dwReserved
  1122. KEY_ALL_ACCESS,
  1123. &hKey
  1124. ))) {
  1125. if (ERROR_FILE_NOT_FOUND != err)
  1126. PrintError("RegOpenKey(SAFER) failed", (DWORD) err);
  1127. goto CommonReturn;
  1128. }
  1129. RegDeleteValueU(hKey, CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME);
  1130. CommonReturn:
  1131. if (hKey)
  1132. RegCloseKey(hKey);
  1133. }
  1134. void SetSaferRegKeyValue(
  1135. IN LPCWSTR pwszValueName,
  1136. IN DWORD dwValue
  1137. )
  1138. {
  1139. LONG err;
  1140. DWORD dwDisposition;
  1141. HKEY hKey = NULL;
  1142. if (ERROR_SUCCESS != (err = RegCreateKeyExU(
  1143. HKEY_LOCAL_MACHINE,
  1144. CERT_TRUST_PUB_SAFER_LOCAL_MACHINE_REGPATH,
  1145. 0, // dwReserved
  1146. NULL, // lpClass
  1147. REG_OPTION_NON_VOLATILE,
  1148. MAXIMUM_ALLOWED,
  1149. NULL, // lpSecurityAttributes
  1150. &hKey,
  1151. &dwDisposition))) {
  1152. PrintError("RegCreateKey(SAFER) failed", (DWORD) err);
  1153. goto CommonReturn;
  1154. }
  1155. if (ERROR_SUCCESS != (err = RegSetValueExU(
  1156. hKey,
  1157. pwszValueName,
  1158. 0, // dwReserved
  1159. REG_DWORD,
  1160. (BYTE *) &dwValue,
  1161. sizeof(DWORD)))) {
  1162. PrintError("RegSetValue(SAFER) failed", (DWORD) err);
  1163. goto CommonReturn;
  1164. }
  1165. CommonReturn:
  1166. if (hKey)
  1167. RegCloseKey(hKey);
  1168. }
  1169. void SetRootAutoUpdateValue(
  1170. IN DWORD dwValue
  1171. )
  1172. {
  1173. LONG err;
  1174. DWORD dwDisposition;
  1175. HKEY hKey = NULL;
  1176. if (ERROR_SUCCESS != (err = RegCreateKeyExU(
  1177. HKEY_LOCAL_MACHINE,
  1178. CERT_OCM_SUBCOMPONENTS_LOCAL_MACHINE_REGPATH,
  1179. 0, // dwReserved
  1180. NULL, // lpClass
  1181. REG_OPTION_NON_VOLATILE,
  1182. MAXIMUM_ALLOWED,
  1183. NULL, // lpSecurityAttributes
  1184. &hKey,
  1185. &dwDisposition))) {
  1186. PrintError("RegCreateKey(OCM Subcomponents) failed", (DWORD) err);
  1187. goto CommonReturn;
  1188. }
  1189. if (ERROR_SUCCESS != (err = RegSetValueExU(
  1190. hKey,
  1191. CERT_OCM_SUBCOMPONENTS_ROOT_AUTO_UPDATE_VALUE_NAME,
  1192. 0, // dwReserved
  1193. REG_DWORD,
  1194. (BYTE *) &dwValue,
  1195. sizeof(DWORD)))) {
  1196. PrintError("RegSetValue(RootAutoUpdate) failed", (DWORD) err);
  1197. goto CommonReturn;
  1198. }
  1199. CommonReturn:
  1200. if (hKey)
  1201. RegCloseKey(hKey);
  1202. }
  1203. void SetAuthRootAutoUpdateFlags(
  1204. IN DWORD dwSetValue,
  1205. IN BOOL fEnable
  1206. )
  1207. {
  1208. LONG err;
  1209. DWORD dwDisposition;
  1210. HKEY hKey = NULL;
  1211. DWORD dwValue = 0;
  1212. DWORD cbValue = sizeof(dwValue);
  1213. DWORD dwType = 0;
  1214. if (ERROR_SUCCESS != (err = RegCreateKeyExU(
  1215. HKEY_LOCAL_MACHINE,
  1216. CERT_AUTH_ROOT_AUTO_UPDATE_LOCAL_MACHINE_REGPATH,
  1217. 0, // dwReserved
  1218. NULL, // lpClass
  1219. REG_OPTION_NON_VOLATILE,
  1220. MAXIMUM_ALLOWED,
  1221. NULL, // lpSecurityAttributes
  1222. &hKey,
  1223. &dwDisposition))) {
  1224. PrintError("RegCreateKey(AuthRootAutoUpdate) failed", (DWORD) err);
  1225. goto CommonReturn;
  1226. }
  1227. RegQueryValueExU(
  1228. hKey,
  1229. CERT_AUTH_ROOT_AUTO_UPDATE_FLAGS_VALUE_NAME,
  1230. NULL, // pdwReserved
  1231. &dwType,
  1232. (BYTE *) &dwValue,
  1233. &cbValue
  1234. );
  1235. if (fEnable)
  1236. dwValue |= dwSetValue;
  1237. else
  1238. dwValue &= ~dwSetValue;
  1239. if (ERROR_SUCCESS != (err = RegSetValueExU(
  1240. hKey,
  1241. CERT_AUTH_ROOT_AUTO_UPDATE_FLAGS_VALUE_NAME,
  1242. 0, // dwReserved
  1243. REG_DWORD,
  1244. (BYTE *) &dwValue,
  1245. sizeof(DWORD)))) {
  1246. PrintError("RegSetValue(AuthRootAutoUpdate) failed", (DWORD) err);
  1247. goto CommonReturn;
  1248. }
  1249. CommonReturn:
  1250. if (hKey)
  1251. RegCloseKey(hKey);
  1252. }
  1253. void SetProtectedRootsFlags(
  1254. IN DWORD dwSetValue,
  1255. IN BOOL fEnable
  1256. )
  1257. {
  1258. LONG err;
  1259. DWORD dwDisposition;
  1260. HKEY hKey = NULL;
  1261. DWORD dwValue = 0;
  1262. DWORD cbValue = sizeof(dwValue);
  1263. DWORD dwType = 0;
  1264. if (ERROR_SUCCESS != (err = RegCreateKeyExU(
  1265. HKEY_LOCAL_MACHINE,
  1266. CERT_PROT_ROOT_FLAGS_REGPATH,
  1267. 0, // dwReserved
  1268. NULL, // lpClass
  1269. REG_OPTION_NON_VOLATILE,
  1270. MAXIMUM_ALLOWED,
  1271. NULL, // lpSecurityAttributes
  1272. &hKey,
  1273. &dwDisposition))) {
  1274. PrintError("RegCreateKey(ProtectedRoots) failed", (DWORD) err);
  1275. goto CommonReturn;
  1276. }
  1277. RegQueryValueExU(
  1278. hKey,
  1279. CERT_PROT_ROOT_FLAGS_VALUE_NAME,
  1280. NULL, // pdwReserved
  1281. &dwType,
  1282. (BYTE *) &dwValue,
  1283. &cbValue
  1284. );
  1285. if (fEnable)
  1286. dwValue |= dwSetValue;
  1287. else
  1288. dwValue &= ~dwSetValue;
  1289. if (ERROR_SUCCESS != (err = RegSetValueExU(
  1290. hKey,
  1291. CERT_PROT_ROOT_FLAGS_VALUE_NAME,
  1292. 0, // dwReserved
  1293. REG_DWORD,
  1294. (BYTE *) &dwValue,
  1295. sizeof(DWORD)))) {
  1296. PrintError("RegSetValue(ProtectedRootsFlags) failed", (DWORD) err);
  1297. goto CommonReturn;
  1298. }
  1299. CommonReturn:
  1300. if (hKey)
  1301. RegCloseKey(hKey);
  1302. }
  1303. void SetCertChainConfigRegKeyValue(
  1304. IN LPCSTR pszValueName,
  1305. IN DWORD dwValue
  1306. )
  1307. {
  1308. LONG err;
  1309. DWORD dwDisposition;
  1310. HKEY hKey = NULL;
  1311. if (ERROR_SUCCESS != (err = RegCreateKeyExU(
  1312. HKEY_LOCAL_MACHINE,
  1313. CERT_CHAIN_CONFIG_REGPATH,
  1314. 0, // dwReserved
  1315. NULL, // lpClass
  1316. REG_OPTION_NON_VOLATILE,
  1317. MAXIMUM_ALLOWED,
  1318. NULL, // lpSecurityAttributes
  1319. &hKey,
  1320. &dwDisposition))) {
  1321. PrintError("RegCreateKey(CERT_CHAIN_CONFIG) failed", (DWORD) err);
  1322. goto CommonReturn;
  1323. }
  1324. if (0xFFFFFFFF == dwValue) {
  1325. err = RegDeleteValueA(hKey, pszValueName);
  1326. if (ERROR_FILE_NOT_FOUND == err)
  1327. ;
  1328. else if (ERROR_SUCCESS != err) {
  1329. printf("RegDeleteValue(%s) failed => 0x%x (%d)\n",
  1330. pszValueName, (DWORD) err, (DWORD) err);
  1331. goto CommonReturn;
  1332. }
  1333. } else {
  1334. if (ERROR_SUCCESS != (err = RegSetValueExA(
  1335. hKey,
  1336. pszValueName,
  1337. 0, // dwReserved
  1338. REG_DWORD,
  1339. (BYTE *) &dwValue,
  1340. sizeof(DWORD)))) {
  1341. printf("RegSetValue(%s) failed => 0x%x (%d)\n",
  1342. pszValueName, (DWORD) err, (DWORD) err);
  1343. goto CommonReturn;
  1344. goto CommonReturn;
  1345. }
  1346. }
  1347. CommonReturn:
  1348. if (hKey)
  1349. RegCloseKey(hKey);
  1350. }
  1351. int _cdecl main(int argc, char * argv[])
  1352. {
  1353. BOOL fResult;
  1354. int status;
  1355. LONG lStatus;
  1356. DWORD dwDisplayFlags = 0;
  1357. DWORD i;
  1358. #define TRUST_TYPE_CERT 1
  1359. #define TRUST_TYPE_FILE 2
  1360. #define TRUST_TYPE_HTTPS 3
  1361. #define TRUST_TYPE_DRIVER 4
  1362. DWORD dwTrustType = TRUST_TYPE_CERT;
  1363. BOOL fChain = FALSE;
  1364. BOOL fChainCallback = FALSE;
  1365. DWORD dwFlags = 0;
  1366. BOOL fQuiet = FALSE;
  1367. LONG lWVTExpected = 0;
  1368. LPSTR pszCertOrFile = NULL; // not allocated
  1369. LPSTR pszUsageOID = NULL; // not allocated
  1370. LPSTR pszSignerUsage = szOID_KP_CTL_USAGE_SIGNING;
  1371. GUID wvtFileActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  1372. GUID wvtCertActionID = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
  1373. GUID wvtHttpsActionID = HTTPSPROV_ACTION;
  1374. GUID wvtDriverActionID = DRIVER_ACTION_VERIFY;
  1375. GUID wvtChainActionID = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY;
  1376. GUID *pwvtActionID;
  1377. CRYPT_PROVIDER_DATA *pProvData; // not allocated
  1378. WINTRUST_FILE_INFO wvtFileInfo;
  1379. memset(&wvtFileInfo, 0, sizeof(wvtFileInfo));
  1380. wvtFileInfo.cbStruct = sizeof(wvtFileInfo);
  1381. wvtFileInfo.pcwszFilePath = NULL;
  1382. #define MAX_CERT_STORE 10
  1383. HCERTSTORE rghStore[MAX_CERT_STORE];
  1384. WINTRUST_CERT_INFO wvtCertInfo;
  1385. memset(&wvtCertInfo, 0, sizeof(wvtCertInfo));
  1386. wvtCertInfo.cbStruct = sizeof(wvtCertInfo);
  1387. wvtCertInfo.psCertContext = NULL;
  1388. wvtCertInfo.chStores = 0;
  1389. wvtCertInfo.pahStores = rghStore;
  1390. wvtCertInfo.dwFlags = 0;
  1391. wvtCertInfo.pcwszDisplayName = L"Cert Display Name";
  1392. HTTPSPolicyCallbackData httpsPolicyCallbackData;
  1393. memset(&httpsPolicyCallbackData, 0, sizeof(httpsPolicyCallbackData));
  1394. httpsPolicyCallbackData.cbStruct = sizeof(httpsPolicyCallbackData);
  1395. httpsPolicyCallbackData.dwAuthType = AUTHTYPE_CLIENT;
  1396. httpsPolicyCallbackData.fdwChecks = 0;
  1397. DRIVER_VER_INFO DriverVerInfo;
  1398. memset(&DriverVerInfo, 0, sizeof(DriverVerInfo));
  1399. DriverVerInfo.cbStruct = sizeof(DriverVerInfo);
  1400. CERT_CHAIN_PARA ChainPara;
  1401. memset(&ChainPara, 0, sizeof(ChainPara));
  1402. ChainPara.cbSize = sizeof(ChainPara);
  1403. #define MAX_USAGE_CNT 16
  1404. LPSTR rgpszUsageOID[MAX_USAGE_CNT];
  1405. DWORD cUsageOID = 0;
  1406. DWORD dwUsageType = USAGE_MATCH_TYPE_AND;
  1407. #define MAX_POLICY_CNT 16
  1408. LPSTR rgpszPolicyOID[MAX_POLICY_CNT];
  1409. DWORD cPolicyOID = 0;
  1410. DWORD dwPolicyUsageType = USAGE_MATCH_TYPE_AND;
  1411. WTD_GENERIC_CHAIN_POLICY_CREATE_INFO ChainInfo;
  1412. memset(&ChainInfo, 0, sizeof(ChainInfo));
  1413. ChainInfo.cbSize = sizeof(ChainInfo);
  1414. ChainInfo.pChainPara = &ChainPara;
  1415. WTD_GENERIC_CHAIN_POLICY_DATA wtdChainPolicyData;
  1416. memset(&wtdChainPolicyData, 0, sizeof(wtdChainPolicyData));
  1417. wtdChainPolicyData.cbSize = sizeof(wtdChainPolicyData);
  1418. wtdChainPolicyData.pvPolicyArg = (void *) CHAIN_POLICY_ARG;
  1419. WINTRUST_DATA wvtData;
  1420. memset(&wvtData, 0, sizeof(wvtData));
  1421. wvtData.cbStruct = sizeof(wvtData);
  1422. wvtData.pPolicyCallbackData = NULL;
  1423. wvtData.dwUIChoice = WTD_UI_NONE;
  1424. wvtData.fdwRevocationChecks = WTD_REVOKE_NONE;
  1425. wvtData.dwUnionChoice = WTD_CHOICE_CERT;
  1426. wvtData.pCert = &wvtCertInfo;
  1427. wvtData.dwStateAction = WTD_STATEACTION_IGNORE;
  1428. wvtData.hWVTStateData = NULL;
  1429. wvtData.dwProvFlags = 0;
  1430. BOOL fDisplayKnownUsages = FALSE;
  1431. BOOL fNTAuth = FALSE;
  1432. BOOL fNTAuthNameConstraint = FALSE;
  1433. BOOL fLogoffNotification = FALSE;
  1434. BOOL fDeferClosing = FALSE;
  1435. BOOL fExpectedTrustErrorStatus = FALSE;
  1436. DWORD dwExpectedTrustErrorStatus = 0;
  1437. BOOL fExpectedTrustInfoStatus = FALSE;
  1438. DWORD dwExpectedTrustInfoStatus = 0;
  1439. DWORD dwUrlRetrievalTimeout = 0;
  1440. BOOL fCheckRevocationFreshnessTime = FALSE;
  1441. DWORD dwRevocationFreshnessTime;
  1442. BOOL fSafer = FALSE;
  1443. BOOL fMicrosoftRoot = FALSE;
  1444. BOOL fMicrosoftTestRoot = FALSE;
  1445. BOOL fNotMicrosoftRoot = FALSE;
  1446. while (--argc>0) {
  1447. if (**++argv == '-')
  1448. {
  1449. if (0 == _stricmp(argv[0]+1, "Cert")) {
  1450. wvtData.dwUnionChoice = WTD_CHOICE_CERT;
  1451. dwTrustType = TRUST_TYPE_CERT;
  1452. } else if (0 == _stricmp(argv[0]+1, "File")) {
  1453. wvtData.dwUnionChoice = WTD_CHOICE_FILE;
  1454. dwTrustType = TRUST_TYPE_FILE;
  1455. } else if (0 == _stricmp(argv[0]+1, "Driver")) {
  1456. wvtData.dwUnionChoice = WTD_CHOICE_FILE;
  1457. dwTrustType = TRUST_TYPE_DRIVER;
  1458. } else if (0 == _stricmp(argv[0]+1, "Https")) {
  1459. wvtData.dwUnionChoice = WTD_CHOICE_CERT;
  1460. dwTrustType = TRUST_TYPE_HTTPS;
  1461. } else if (0 == _stricmp(argv[0]+1, "Chain")) {
  1462. fChain = TRUE;
  1463. } else if (0 == _stricmp(argv[0]+1, "ChainCallback")) {
  1464. fChain = TRUE;
  1465. fChainCallback = TRUE;
  1466. } else if (0 == _stricmp(argv[0]+1, "NTAuth")) {
  1467. fNTAuth = TRUE;
  1468. } else if (0 == _stricmp(argv[0]+1, "NTAuthNameConstraint")) {
  1469. fNTAuth = TRUE;
  1470. fNTAuthNameConstraint = TRUE;
  1471. } else if (0 == _stricmp(argv[0]+1, "Safer")) {
  1472. wvtData.dwUnionChoice = WTD_CHOICE_FILE;
  1473. dwTrustType = TRUST_TYPE_FILE;
  1474. fSafer = TRUE;
  1475. } else if (0 == _stricmp(argv[0]+1, "Client")) {
  1476. httpsPolicyCallbackData.dwAuthType = AUTHTYPE_CLIENT;
  1477. } else if (0 == _stricmp(argv[0]+1, "Server")) {
  1478. httpsPolicyCallbackData.dwAuthType = AUTHTYPE_SERVER;
  1479. } else if (0 == _stricmp(argv[0]+1, "UIAll")) {
  1480. wvtData.dwUIChoice = WTD_UI_ALL;
  1481. } else if (0 == _stricmp(argv[0]+1, "UINone")) {
  1482. wvtData.dwUIChoice = WTD_UI_NONE;
  1483. } else if (0 == _stricmp(argv[0]+1, "UINoBad")) {
  1484. wvtData.dwUIChoice = WTD_UI_NOBAD;
  1485. } else if (0 == _stricmp(argv[0]+1, "UINoGood")) {
  1486. wvtData.dwUIChoice = WTD_UI_NOGOOD;
  1487. } else if (0 == _stricmp(argv[0]+1, "RevokeNone")) {
  1488. wvtData.fdwRevocationChecks = WTD_REVOKE_NONE;
  1489. } else if (0 == _stricmp(argv[0]+1, "RevokeChain")) {
  1490. wvtData.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
  1491. } else if (0 == _stricmp(argv[0]+1, "UseIE4Trust")) {
  1492. wvtData.dwProvFlags |= WTD_USE_IE4_TRUST_FLAG;
  1493. } else if (0 == _stricmp(argv[0]+1, "NoIE4Chain")) {
  1494. wvtData.dwProvFlags |= WTD_NO_IE4_CHAIN_FLAG;
  1495. } else if (0 == _stricmp(argv[0]+1, "NoUsage")) {
  1496. wvtData.dwProvFlags |= WTD_NO_POLICY_USAGE_FLAG;
  1497. } else if (0 == _stricmp(argv[0]+1, "OrUsage")) {
  1498. dwUsageType = USAGE_MATCH_TYPE_OR;
  1499. } else if (0 == _stricmp(argv[0]+1, "OrPolicy")) {
  1500. dwPolicyUsageType = USAGE_MATCH_TYPE_OR;
  1501. } else if (0 == _stricmp(argv[0]+1, "LifetimeSigning")) {
  1502. wvtData.dwProvFlags |= WTD_LIFETIME_SIGNING_FLAG;
  1503. } else if (0 == _stricmp(argv[0]+1, "MicrosoftRoot")) {
  1504. fMicrosoftRoot = TRUE;
  1505. } else if (0 == _stricmp(argv[0]+1, "MicrosoftTestRoot")) {
  1506. fMicrosoftTestRoot = TRUE;
  1507. fMicrosoftRoot = TRUE;
  1508. } else if (0 == _stricmp(argv[0]+1, "NotMicrosoftRoot")) {
  1509. fNotMicrosoftRoot = TRUE;
  1510. } else if (0 == _stricmp(argv[0]+1, "FlushCrl")) {
  1511. fFlushCrl = TRUE;
  1512. } else if (0 == _stricmp(argv[0]+1, "DeferClosing")) {
  1513. fDeferClosing = TRUE;
  1514. } else if (0 == _stricmp(argv[0]+1, "DisplayKnownUsages")) {
  1515. fDisplayKnownUsages = TRUE;
  1516. } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreRevocation")) {
  1517. httpsPolicyCallbackData.fdwChecks |=
  1518. SECURITY_FLAG_IGNORE_REVOCATION;
  1519. } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreUnknownCA")) {
  1520. httpsPolicyCallbackData.fdwChecks |=
  1521. SECURITY_FLAG_IGNORE_UNKNOWN_CA;
  1522. } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreWrongUsage")) {
  1523. httpsPolicyCallbackData.fdwChecks |=
  1524. SECURITY_FLAG_IGNORE_WRONG_USAGE;
  1525. } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreCertDateInvalid")) {
  1526. httpsPolicyCallbackData.fdwChecks |=
  1527. SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
  1528. } else if (0 == _stricmp(argv[0]+1, "HttpsIgnoreCertCNInvalid")) {
  1529. httpsPolicyCallbackData.fdwChecks |=
  1530. SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
  1531. } else if (0 == _stricmp(argv[0]+1, "DontOpenStores")) {
  1532. wvtCertInfo.dwFlags = WTCI_DONT_OPEN_STORES;
  1533. } else if (0 == _stricmp(argv[0]+1, "OpenOnlyRoot")) {
  1534. wvtCertInfo.dwFlags = WTCI_OPEN_ONLY_ROOT;
  1535. } else if (0 == _stricmp(argv[0]+1,
  1536. "InstallThreadDefaultContext")) {
  1537. fInstallDefaultContext = TRUE;
  1538. dwDefaultContextFlags &= ~CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG;
  1539. } else if (0 == _stricmp(argv[0]+1,
  1540. "InstallProcessDefaultContext")) {
  1541. fInstallDefaultContext = TRUE;
  1542. dwDefaultContextFlags |= CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG;
  1543. } else if (0 == _stricmp(argv[0]+1,
  1544. "AutoReleaseDefaultContext")) {
  1545. dwDefaultContextFlags |=
  1546. CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG;
  1547. } else if (0 == _stricmp(argv[0]+1,
  1548. "NULLDefaultContext")) {
  1549. fNULLDefaultContext = TRUE;
  1550. } else if (0 == _stricmp(argv[0]+1,
  1551. "MultiDefaultContext")) {
  1552. fMultiDefaultContext = TRUE;
  1553. } else if (0 == _stricmp(argv[0]+1,
  1554. "LogoffNotification")) {
  1555. fLogoffNotification = TRUE;
  1556. } else if (0 == _stricmp(argv[0]+1, "AuthenticodeFlags")) {
  1557. DWORD dwFlags;
  1558. if (argc < 2 || argv[1][0] == '-') {
  1559. printf("Option (-AuthenticodeFlags) : missing number argument\n");
  1560. goto BadUsage;
  1561. }
  1562. dwFlags = strtoul(argv[1], NULL, 0);
  1563. argc -= 1;
  1564. argv += 1;
  1565. SetSaferRegKeyValue(
  1566. CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME, dwFlags);
  1567. } else if (0 == _stricmp(argv[0]+1, "DisableMandatoryBasicConstraints") ||
  1568. 0 == _stricmp(argv[0]+1, "DisableAIAUrlRetrieval") ||
  1569. 0 == _stricmp(argv[0]+1, "MaxAIAUrlCountInCert") ||
  1570. 0 == _stricmp(argv[0]+1, "MaxAIAUrlRetrievalCountPerChain") ||
  1571. 0 == _stricmp(argv[0]+1, "MaxAIAUrlRetrievalByteCount") ||
  1572. 0 == _stricmp(argv[0]+1, "MaxAIAUrlRetrievalCertCount")) {
  1573. LPCSTR pszOption = argv[0]+1;
  1574. DWORD dwValue;
  1575. if (argc < 2 || argv[1][0] == '-') {
  1576. printf("Option (-%s) : missing number argument\n",
  1577. pszOption);
  1578. goto BadUsage;
  1579. }
  1580. dwValue = strtoul(argv[1], NULL, 0);
  1581. argc -= 1;
  1582. argv += 1;
  1583. SetCertChainConfigRegKeyValue(pszOption, dwValue);
  1584. } else if (0 == _stricmp(argv[0]+1, "DeleteSaferRegKey")) {
  1585. DeleteSaferRegKey();
  1586. } else if (0 == _stricmp(argv[0]+1, "EnableRootAutoUpdate")) {
  1587. SetRootAutoUpdateValue(0x1);
  1588. } else if (0 == _stricmp(argv[0]+1, "DisableRootAutoUpdate")) {
  1589. SetRootAutoUpdateValue(0x0);
  1590. } else if (0 == _stricmp(argv[0]+1, "EnableUntrustedRootLogging")) {
  1591. SetAuthRootAutoUpdateFlags(
  1592. CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_UNTRUSTED_ROOT_LOGGING_FLAG,
  1593. FALSE);
  1594. } else if (0 == _stricmp(argv[0]+1,
  1595. "DisableUntrustedRootLogging")) {
  1596. SetAuthRootAutoUpdateFlags(
  1597. CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_UNTRUSTED_ROOT_LOGGING_FLAG,
  1598. TRUE);
  1599. } else if (0 == _stricmp(argv[0]+1, "EnablePartialChainLogging")) {
  1600. SetAuthRootAutoUpdateFlags(
  1601. CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_PARTIAL_CHAIN_LOGGING_FLAG,
  1602. FALSE);
  1603. } else if (0 == _stricmp(argv[0]+1,
  1604. "DisablePartialChainLogging")) {
  1605. SetAuthRootAutoUpdateFlags(
  1606. CERT_AUTH_ROOT_AUTO_UPDATE_DISABLE_PARTIAL_CHAIN_LOGGING_FLAG,
  1607. TRUE);
  1608. } else if (0 == _stricmp(argv[0]+1, "EnableNTAuthRequired")) {
  1609. SetProtectedRootsFlags(
  1610. CERT_PROT_ROOT_DISABLE_NT_AUTH_REQUIRED_FLAG,
  1611. FALSE);
  1612. } else if (0 == _stricmp(argv[0]+1,
  1613. "DisableNTAuthRequired")) {
  1614. SetProtectedRootsFlags(
  1615. CERT_PROT_ROOT_DISABLE_NT_AUTH_REQUIRED_FLAG,
  1616. TRUE);
  1617. } else if (0 == _stricmp(argv[0]+1, "EnableNotDefinedNameConstraint")) {
  1618. SetProtectedRootsFlags(
  1619. CERT_PROT_ROOT_DISABLE_NOT_DEFINED_NAME_CONSTRAINT_FLAG,
  1620. FALSE);
  1621. } else if (0 == _stricmp(argv[0]+1, "DisableNotDefinedNameConstraint")) {
  1622. SetProtectedRootsFlags(
  1623. CERT_PROT_ROOT_DISABLE_NOT_DEFINED_NAME_CONSTRAINT_FLAG,
  1624. TRUE);
  1625. } else if (0 == _stricmp(argv[0]+1, "EnableAuthRoot")) {
  1626. SetProtectedRootsFlags(
  1627. CERT_PROT_ROOT_DISABLE_LM_AUTH_FLAG,
  1628. FALSE);
  1629. } else if (0 == _stricmp(argv[0]+1, "DisableAuthRoot")) {
  1630. SetProtectedRootsFlags(
  1631. CERT_PROT_ROOT_DISABLE_LM_AUTH_FLAG,
  1632. TRUE);
  1633. } else if (0 == _stricmp(argv[0]+1, "RegistryOnlyExit")) {
  1634. goto RegistryOnlyExit;
  1635. } else {
  1636. switch(argv[0][1])
  1637. {
  1638. case 's':
  1639. case 'S':
  1640. if (wvtCertInfo.chStores >= MAX_CERT_STORE) {
  1641. printf("Exceed maximum number of stores %d\n",
  1642. MAX_CERT_STORE);
  1643. goto BadUsage;
  1644. }
  1645. if (NULL == (rghStore[wvtCertInfo.chStores] =
  1646. OpenSystemStoreOrFile(
  1647. argv[0][1] == 's', // fSystemStore
  1648. argv[0]+2,
  1649. 0 // dwFlags
  1650. )))
  1651. goto BadUsage;
  1652. wvtCertInfo.chStores++;
  1653. break;
  1654. case 'b':
  1655. dwDisplayFlags |= DISPLAY_BRIEF_FLAG;
  1656. break;
  1657. case 'v':
  1658. dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
  1659. break;
  1660. case 'u':
  1661. if (MAX_USAGE_CNT <= cUsageOID) {
  1662. printf("Too many usages\n");
  1663. goto BadUsage;
  1664. }
  1665. if (0 == cUsageOID)
  1666. pszUsageOID = argv[0]+2;
  1667. rgpszUsageOID[cUsageOID++] = argv[0]+2;
  1668. break;
  1669. case 'p':
  1670. if (MAX_POLICY_CNT <= cPolicyOID) {
  1671. printf("Too many policies\n");
  1672. goto BadUsage;
  1673. }
  1674. rgpszPolicyOID[cPolicyOID++] = argv[0]+2;
  1675. break;
  1676. case 'n':
  1677. httpsPolicyCallbackData.pwszServerName =
  1678. AllocAndSzToWsz(argv[0]+2);
  1679. break;
  1680. case 'f':
  1681. dwFlags = (DWORD) strtoul(argv[0]+2, NULL, 0);
  1682. break;
  1683. case 'e':
  1684. fExpectedTrustErrorStatus = TRUE;
  1685. dwExpectedTrustErrorStatus =
  1686. (DWORD) strtoul(argv[0]+2, NULL, 0);
  1687. break;
  1688. case 'i':
  1689. fExpectedTrustInfoStatus = TRUE;
  1690. dwExpectedTrustInfoStatus =
  1691. (DWORD) strtoul(argv[0]+2, NULL, 0);
  1692. break;
  1693. case 't':
  1694. dwUrlRetrievalTimeout = (DWORD) strtoul(argv[0]+2, NULL, 0);
  1695. break;
  1696. case 'r':
  1697. fCheckRevocationFreshnessTime = TRUE;
  1698. dwRevocationFreshnessTime =
  1699. (DWORD) strtoul(argv[0]+2, NULL, 0);
  1700. break;
  1701. case 'q':
  1702. fQuiet = TRUE;
  1703. if (argv[0][2])
  1704. lWVTExpected = (LONG) strtoul(argv[0]+2, NULL, 0);
  1705. break;
  1706. case 'h':
  1707. default:
  1708. goto BadUsage;
  1709. }
  1710. }
  1711. } else {
  1712. if (pszCertOrFile) {
  1713. printf("Multiple certs or filenames not supported\n");
  1714. goto BadUsage;
  1715. }
  1716. pszCertOrFile = argv[0];
  1717. }
  1718. }
  1719. if (NULL == pszCertOrFile) {
  1720. printf("Missing cert or filename\n");
  1721. goto BadUsage;
  1722. }
  1723. printf("command line: %s\n", GetCommandLine());
  1724. if (fDisplayKnownUsages) {
  1725. PCCRYPT_OID_INFO *ppOidInfo = NULL;
  1726. if (WTHelperGetKnownUsages(WTH_ALLOC, &ppOidInfo)) {
  1727. for (DWORD i = 0; ppOidInfo[i]; i++)
  1728. printf("Usage[%d]:: OID: %s Name: %S\n",
  1729. i, ppOidInfo[i]->pszOID, ppOidInfo[i]->pwszName);
  1730. WTHelperGetKnownUsages(WTH_FREE, &ppOidInfo);
  1731. }
  1732. }
  1733. switch (wvtData.dwUnionChoice) {
  1734. case WTD_CHOICE_FILE:
  1735. if (TRUST_TYPE_DRIVER == dwTrustType) {
  1736. pwvtActionID = &wvtDriverActionID;
  1737. wvtData.pPolicyCallbackData = (void *) &DriverVerInfo;
  1738. } else {
  1739. pwvtActionID = &wvtFileActionID;
  1740. }
  1741. wvtData.pFile = &wvtFileInfo;
  1742. wvtFileInfo.pcwszFilePath = AllocAndSzToWsz(pszCertOrFile);
  1743. break;
  1744. case WTD_CHOICE_CERT:
  1745. if (TRUST_TYPE_HTTPS == dwTrustType) {
  1746. pwvtActionID = &wvtHttpsActionID;
  1747. wvtData.pPolicyCallbackData =
  1748. (void *) &httpsPolicyCallbackData;
  1749. } else {
  1750. pwvtActionID = &wvtCertActionID;
  1751. wvtData.pPolicyCallbackData = (void *) pszUsageOID;
  1752. }
  1753. wvtData.pCert = &wvtCertInfo;
  1754. if (NULL == (wvtCertInfo.psCertContext =
  1755. (CERT_CONTEXT *) ReadCert(pszCertOrFile)))
  1756. goto ErrorReturn;
  1757. if (fDeferClosing && 1 == wvtCertInfo.chStores) {
  1758. HCERTSTORE hDeferStore = NULL;
  1759. PCCERT_CONTEXT pDeferCert = NULL;
  1760. PCCERT_CONTEXT pAddCert = NULL;
  1761. PCCERT_CHAIN_CONTEXT pDeferChain = NULL;
  1762. CERT_CHAIN_PARA DeferChainPara;
  1763. if (NULL == (hDeferStore = CertOpenStore(
  1764. CERT_STORE_PROV_MEMORY,
  1765. X509_ASN_ENCODING,
  1766. 0,
  1767. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
  1768. NULL))) {
  1769. PrintLastError("CertOpenStore(DeferClosing)");
  1770. goto ErrorReturn;
  1771. }
  1772. while (pAddCert = CertEnumCertificatesInStore(
  1773. wvtCertInfo.pahStores[0],
  1774. pAddCert))
  1775. CertAddCertificateContextToStore(
  1776. hDeferStore,
  1777. pAddCert,
  1778. CERT_STORE_ADD_USE_EXISTING,
  1779. NULL
  1780. );
  1781. if (!CertAddCertificateContextToStore(
  1782. hDeferStore,
  1783. wvtCertInfo.psCertContext,
  1784. CERT_STORE_ADD_USE_EXISTING,
  1785. &pDeferCert
  1786. )) {
  1787. PrintLastError("CertAddCertificateContextToStore(DeferClosing)");
  1788. CertCloseStore(hDeferStore, 0);
  1789. goto ErrorReturn;
  1790. }
  1791. CertCloseStore(hDeferStore, 0);
  1792. memset(&DeferChainPara, 0, sizeof(DeferChainPara));
  1793. DeferChainPara.cbSize = sizeof(DeferChainPara);
  1794. CertGetCertificateChain(
  1795. NULL, // hChainEngine
  1796. pDeferCert,
  1797. NULL, // pTime
  1798. hDeferStore,
  1799. &DeferChainPara,
  1800. CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL,
  1801. NULL, // pvReserved
  1802. &pDeferChain
  1803. );
  1804. CertFreeCertificateContext(pDeferCert);
  1805. if (pDeferChain)
  1806. CertFreeCertificateChain(pDeferChain);
  1807. }
  1808. break;
  1809. default:
  1810. goto BadUsage;
  1811. }
  1812. if (fChain) {
  1813. pwvtActionID = &wvtChainActionID;
  1814. if (fChainCallback || dwFlags || cUsageOID || cPolicyOID ||
  1815. 0 != dwUrlRetrievalTimeout || fCheckRevocationFreshnessTime) {
  1816. wvtData.pPolicyCallbackData = (void *) &wtdChainPolicyData;
  1817. if (fChainCallback)
  1818. wtdChainPolicyData.pfnPolicyCallback = ChainPolicyCallback;
  1819. if (dwFlags || cUsageOID || cPolicyOID ||
  1820. 0 != dwUrlRetrievalTimeout ||
  1821. fCheckRevocationFreshnessTime) {
  1822. ChainInfo.dwFlags = dwFlags;
  1823. wtdChainPolicyData.pSignerChainInfo = &ChainInfo;
  1824. wtdChainPolicyData.pCounterSignerChainInfo = &ChainInfo;
  1825. ChainPara.RequestedUsage.dwType = dwUsageType;
  1826. ChainPara.RequestedUsage.Usage.cUsageIdentifier = cUsageOID;
  1827. ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier =
  1828. rgpszUsageOID;
  1829. ChainPara.RequestedIssuancePolicy.dwType = dwPolicyUsageType;
  1830. ChainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier =
  1831. cPolicyOID;
  1832. ChainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier =
  1833. rgpszPolicyOID;
  1834. ChainPara.dwUrlRetrievalTimeout = dwUrlRetrievalTimeout;
  1835. ChainPara.fCheckRevocationFreshnessTime =
  1836. fCheckRevocationFreshnessTime;
  1837. ChainPara.dwRevocationFreshnessTime = dwRevocationFreshnessTime;
  1838. }
  1839. }
  1840. if (0 != (dwFlags & CERT_CHAIN_CACHE_END_CERT) &&
  1841. WTD_CHOICE_CERT == wvtData.dwUnionChoice) {
  1842. // Do an extra verify to ensure the cache is loaded on the
  1843. // next call
  1844. wvtData.dwStateAction = WTD_STATEACTION_IGNORE;
  1845. WinVerifyTrust(
  1846. NULL, // hwnd
  1847. pwvtActionID,
  1848. &wvtData
  1849. );
  1850. CertFreeCertificateContext(wvtCertInfo.psCertContext);
  1851. if (NULL == (wvtCertInfo.psCertContext =
  1852. (CERT_CONTEXT *) ReadCert(pszCertOrFile)))
  1853. goto ErrorReturn;
  1854. }
  1855. }
  1856. if (fExpectedTrustErrorStatus || fExpectedTrustInfoStatus)
  1857. wvtData.dwStateAction = WTD_STATEACTION_VERIFY;
  1858. else if (fQuiet && !fNTAuth)
  1859. wvtData.dwStateAction = WTD_STATEACTION_IGNORE;
  1860. else
  1861. wvtData.dwStateAction = WTD_STATEACTION_VERIFY;
  1862. if (fInstallDefaultContext)
  1863. InstallDefaultContext();
  1864. if (fSafer) {
  1865. DWORD dwFlags;
  1866. BOOL fHasValue;
  1867. DWORD dwLastError;
  1868. wvtData.dwProvFlags |= WTD_SAFER_FLAG;
  1869. lStatus = WinVerifyTrust(
  1870. NULL, // hwnd
  1871. pwvtActionID,
  1872. &wvtData
  1873. );
  1874. dwLastError = GetLastError();
  1875. fHasValue = I_CryptReadTrustedPublisherDWORDValueFromRegistry(
  1876. CERT_TRUST_PUB_AUTHENTICODE_FLAGS_VALUE_NAME,
  1877. &dwFlags
  1878. );
  1879. printf("AuthenticodeFlags: ");
  1880. if (fHasValue)
  1881. printf("0x%x\n", dwFlags);
  1882. else
  1883. printf("NONE\n");
  1884. dwFlags = 0;
  1885. WintrustGetRegPolicyFlags(&dwFlags);
  1886. printf("WintrustFlags: 0x%x\n", dwFlags);
  1887. PrintStatus("LastError: ", (LONG) dwLastError);
  1888. if (wvtFileInfo.pcwszFilePath) {
  1889. BYTE rgbFileHash[20];
  1890. DWORD cbFileHash = 20;
  1891. ALG_ID HashAlgid = 0;
  1892. LONG lHashStatus;
  1893. PCCRYPT_OID_INFO pOIDInfo;
  1894. lHashStatus = WTHelperGetFileHash(
  1895. wvtFileInfo.pcwszFilePath,
  1896. 0, // dwFlags
  1897. NULL, // pvReserved
  1898. rgbFileHash,
  1899. &cbFileHash,
  1900. &HashAlgid
  1901. );
  1902. PrintStatus("HashStatus: ", lHashStatus);
  1903. printf("HashAlgid: 0x%x", HashAlgid);
  1904. pOIDInfo = CryptFindOIDInfo(
  1905. CRYPT_OID_INFO_ALGID_KEY,
  1906. &HashAlgid,
  1907. CRYPT_HASH_ALG_OID_GROUP_ID
  1908. );
  1909. if (pOIDInfo)
  1910. printf(" %S", pOIDInfo->pwszName);
  1911. printf("\n");
  1912. if (cbFileHash) {
  1913. PrintBytes("File Hash:: ", rgbFileHash, cbFileHash);
  1914. }
  1915. }
  1916. } else
  1917. lStatus = WinVerifyTrust(
  1918. NULL, // hwnd
  1919. pwvtActionID,
  1920. &wvtData
  1921. );
  1922. if (fExpectedTrustErrorStatus || fExpectedTrustInfoStatus) {
  1923. if (NULL == (pProvData = WTHelperProvDataFromStateData(
  1924. wvtData.hWVTStateData))) {
  1925. printf("TrustStatus:: failed => no WVTStateData\n");
  1926. goto ErrorReturn;
  1927. }
  1928. fResult = FALSE;
  1929. if (0 == pProvData->csSigners)
  1930. printf("TrustStatus:: failed => No Signers\n");
  1931. else {
  1932. CRYPT_PROVIDER_SGNR *pProvSign;
  1933. pProvSign = WTHelperGetProvSignerFromChain(
  1934. pProvData,
  1935. 0, // idxSigner
  1936. FALSE, // fCounterSigner
  1937. 0 // idxCounterSigner
  1938. );
  1939. if (pProvSign && pProvSign->pChainContext) {
  1940. const CERT_TRUST_STATUS *pTrustStatus =
  1941. &pProvSign->pChainContext->TrustStatus;
  1942. fResult = TRUE;
  1943. if (fExpectedTrustErrorStatus) {
  1944. if (dwExpectedTrustErrorStatus == pTrustStatus->dwErrorStatus) {
  1945. if (0 != dwExpectedTrustErrorStatus)
  1946. printf("ChainContext has Expected TrustErrorStatus => 0x%x\n",
  1947. dwExpectedTrustErrorStatus);
  1948. } else {
  1949. fResult = FALSE;
  1950. printf("Expected => 0x%x ChainContext TrustErrorStatus failed => 0x%x\n",
  1951. dwExpectedTrustErrorStatus,
  1952. pTrustStatus->dwErrorStatus
  1953. );
  1954. }
  1955. }
  1956. if (fExpectedTrustInfoStatus) {
  1957. if (dwExpectedTrustInfoStatus == pTrustStatus->dwInfoStatus) {
  1958. if (0 != dwExpectedTrustInfoStatus)
  1959. printf("ChainContext has Expected TrustInfoStatus => 0x%x\n",
  1960. dwExpectedTrustInfoStatus);
  1961. } else {
  1962. fResult = FALSE;
  1963. printf("Expected => 0x%x ChainContext TrustInfoStatus failed => 0x%x\n",
  1964. dwExpectedTrustInfoStatus,
  1965. pTrustStatus->dwInfoStatus
  1966. );
  1967. }
  1968. }
  1969. if (fMicrosoftRoot || fNotMicrosoftRoot) {
  1970. // Check if the top level certificate contains the public
  1971. // key for the Microsoft root.
  1972. CERT_CHAIN_POLICY_PARA MicrosoftRootPolicyPara;
  1973. CERT_CHAIN_POLICY_STATUS MicrosoftRootPolicyStatus;
  1974. memset(&MicrosoftRootPolicyPara, 0,
  1975. sizeof(MicrosoftRootPolicyPara));
  1976. MicrosoftRootPolicyPara.cbSize =
  1977. sizeof(MicrosoftRootPolicyPara);
  1978. memset(&MicrosoftRootPolicyStatus, 0,
  1979. sizeof(MicrosoftRootPolicyStatus));
  1980. MicrosoftRootPolicyStatus.cbSize =
  1981. sizeof(MicrosoftRootPolicyStatus);
  1982. if (fMicrosoftTestRoot)
  1983. MicrosoftRootPolicyPara.dwFlags |=
  1984. MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG;
  1985. if (!CertVerifyCertificateChainPolicy(
  1986. CERT_CHAIN_POLICY_MICROSOFT_ROOT,
  1987. pProvSign->pChainContext,
  1988. &MicrosoftRootPolicyPara,
  1989. &MicrosoftRootPolicyStatus
  1990. )) {
  1991. PrintLastError("CERT_CHAIN_POLICY_MICROSOFT_ROOT");
  1992. } else {
  1993. if (fMicrosoftRoot) {
  1994. if (0 == MicrosoftRootPolicyStatus.dwError)
  1995. printf("ChainContext has Expected Microsoft Root\n");
  1996. else
  1997. printf("failed => not a Microsoft Root\n");
  1998. }
  1999. if (fNotMicrosoftRoot) {
  2000. if (0 != MicrosoftRootPolicyStatus.dwError)
  2001. printf("ChainContext has Expected Not a Microsoft Root\n");
  2002. else
  2003. printf("failed => has a Microsoft Root\n");
  2004. }
  2005. }
  2006. }
  2007. } else
  2008. printf("TrustStatus:: failed => no first signer\n");
  2009. }
  2010. wvtData.dwStateAction = WTD_STATEACTION_CLOSE;
  2011. WinVerifyTrust(
  2012. NULL, // hwnd
  2013. pwvtActionID,
  2014. &wvtData
  2015. );
  2016. if (fResult)
  2017. goto SuccessReturn;
  2018. else
  2019. goto ErrorReturn;
  2020. } else if (fQuiet) {
  2021. if (TRUST_TYPE_DRIVER == dwTrustType) {
  2022. if (DriverVerInfo.pcSignerCertContext) {
  2023. CertFreeCertificateContext(DriverVerInfo.pcSignerCertContext);
  2024. }
  2025. }
  2026. if (fNTAuth) {
  2027. if (NULL == (pProvData = WTHelperProvDataFromStateData(
  2028. wvtData.hWVTStateData))) {
  2029. printf("NTAuth:: failed => no WVTStateData\n");
  2030. goto ErrorReturn;
  2031. }
  2032. fResult = FALSE;
  2033. if (0 == pProvData->csSigners)
  2034. printf("NTAuth:: failed => No Signers\n");
  2035. else {
  2036. CRYPT_PROVIDER_SGNR *pProvSign;
  2037. pProvSign = WTHelperGetProvSignerFromChain(
  2038. pProvData,
  2039. 0, // idxSigner
  2040. FALSE, // fCounterSigner
  2041. 0 // idxCounterSigner
  2042. );
  2043. if (pProvSign && pProvSign->pChainContext) {
  2044. if (fNTAuthNameConstraint)
  2045. fResult = NTAuthNameConstraintVerify(
  2046. pProvSign->pChainContext, (DWORD) lWVTExpected);
  2047. else
  2048. fResult = NTAuthVerify(pProvSign->pChainContext,
  2049. (DWORD) lWVTExpected);
  2050. } else
  2051. printf("NTAuth:: failed => no first signer\n");
  2052. }
  2053. wvtData.dwStateAction = WTD_STATEACTION_CLOSE;
  2054. WinVerifyTrust(
  2055. NULL, // hwnd
  2056. pwvtActionID,
  2057. &wvtData
  2058. );
  2059. if (fResult)
  2060. goto SuccessReturn;
  2061. else
  2062. goto ErrorReturn;
  2063. } else if (lStatus == lWVTExpected) {
  2064. if (ERROR_SUCCESS != lStatus)
  2065. PrintStatus("WinVerifyTrust returned expected => ", lStatus);
  2066. goto SuccessReturn;
  2067. } else {
  2068. PrintStatus("Expected => ", lWVTExpected);
  2069. PrintStatus("WinVerifyTrust(Verify) failed => ", lStatus);
  2070. goto ErrorReturn;
  2071. }
  2072. }
  2073. if (ERROR_SUCCESS != lStatus) {
  2074. if (fFlushCrl && CERT_E_EXPIRED == lStatus)
  2075. ;
  2076. else
  2077. PrintStatus("WinVerifyTrust(Verify) failed => ", lStatus);
  2078. }
  2079. if (NULL == (pProvData = WTHelperProvDataFromStateData(
  2080. wvtData.hWVTStateData))) {
  2081. printf("failed => no WVTStateData\n");
  2082. goto ErrorReturn;
  2083. }
  2084. if (pProvData->dwError)
  2085. PrintError("Low Level system error: ", pProvData->dwError);
  2086. for (i = 0; i < pProvData->cdwTrustStepErrors; i++) {
  2087. if (pProvData->padwTrustStepErrors[i]) {
  2088. printf(">>>>> Step Error [%d] : ", i);
  2089. PrintError("", pProvData->padwTrustStepErrors[i]);
  2090. }
  2091. }
  2092. if (TRUST_TYPE_DRIVER == dwTrustType) {
  2093. if (DriverVerInfo.pcSignerCertContext) {
  2094. CertFreeCertificateContext(DriverVerInfo.pcSignerCertContext);
  2095. }
  2096. printf("Driver version: %S signedBy: %S\n",
  2097. DriverVerInfo.wszVersion, DriverVerInfo.wszSignedBy);
  2098. }
  2099. if (0 == pProvData->csSigners)
  2100. printf("No Signers\n");
  2101. else {
  2102. DWORD idxSigner;
  2103. for (idxSigner = 0; idxSigner < pProvData->csSigners; idxSigner++) {
  2104. CRYPT_PROVIDER_SGNR *pProvSign;
  2105. printf("====== Signer [%d] ======\n", idxSigner);
  2106. pProvSign = WTHelperGetProvSignerFromChain(
  2107. pProvData,
  2108. idxSigner,
  2109. FALSE, // fCounterSigner
  2110. 0 // idxCounterSigner
  2111. );
  2112. if (pProvSign) {
  2113. DWORD idxCounterSigner;
  2114. DisplayPeterSigner(pProvSign, dwDisplayFlags);
  2115. DisplayKirtChain(pProvSign->pChainContext, dwDisplayFlags);
  2116. if (fNTAuth && !fNTAuthNameConstraint &&
  2117. pProvSign->pChainContext)
  2118. NTAuthVerify(pProvSign->pChainContext, CERT_E_UNTRUSTEDCA);
  2119. for (idxCounterSigner = 0;
  2120. idxCounterSigner < pProvSign->csCounterSigners;
  2121. idxCounterSigner++) {
  2122. CRYPT_PROVIDER_SGNR *pProvCounterSign;
  2123. printf("\n");
  2124. printf("====== CounterSigner [%d,%d] ======\n",
  2125. idxSigner, idxCounterSigner);
  2126. pProvCounterSign = WTHelperGetProvSignerFromChain(
  2127. pProvData,
  2128. idxSigner,
  2129. TRUE, // fCounterSigner
  2130. idxCounterSigner
  2131. );
  2132. DisplayPeterSigner(pProvCounterSign, dwDisplayFlags);
  2133. DisplayKirtChain(pProvCounterSign->pChainContext,
  2134. dwDisplayFlags);
  2135. }
  2136. }
  2137. }
  2138. }
  2139. wvtData.dwStateAction = WTD_STATEACTION_CLOSE;
  2140. lStatus = WinVerifyTrust(
  2141. NULL, // hwnd
  2142. pwvtActionID,
  2143. &wvtData
  2144. );
  2145. if (ERROR_SUCCESS != lStatus) {
  2146. PrintStatus("WinVerifyTrust(Close) failed => ", lStatus);
  2147. goto ErrorReturn;
  2148. }
  2149. SuccessReturn:
  2150. printf("Passed\n");
  2151. RegistryOnlyExit:
  2152. status = 0;
  2153. CommonReturn:
  2154. if (fLogoffNotification) {
  2155. int c;
  2156. fputs("Waiting to call ChainWlxLogoffEvent ->", stdout);
  2157. fflush(stdin);
  2158. fflush(stdout);
  2159. c = getchar();
  2160. ChainWlxLogoffEvent(NULL);
  2161. fputs("Finished call ->", stdout);
  2162. fflush(stdin);
  2163. fflush(stdout);
  2164. c = getchar();
  2165. }
  2166. if (fInstallDefaultContext)
  2167. FreeDefaultContext();
  2168. while(wvtCertInfo.chStores--) {
  2169. if (!CertCloseStore(wvtCertInfo.pahStores[wvtCertInfo.chStores],
  2170. CERT_CLOSE_STORE_CHECK_FLAG))
  2171. PrintLastError("CertCloseStore");
  2172. }
  2173. CertFreeCertificateContext(wvtCertInfo.psCertContext);
  2174. TestFree((LPWSTR) wvtFileInfo.pcwszFilePath);
  2175. TestFree(httpsPolicyCallbackData.pwszServerName);
  2176. return status;
  2177. ErrorReturn:
  2178. status = -1;
  2179. printf("Failed\n");
  2180. goto CommonReturn;
  2181. BadUsage:
  2182. Usage();
  2183. goto ErrorReturn;
  2184. }