trial_comparison_cert_verifier.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/cert/trial_comparison_cert_verifier.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/location.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/metrics/histogram_macros.h"
  11. #include "base/time/time.h"
  12. #include "base/values.h"
  13. #include "build/build_config.h"
  14. #include "net/base/net_errors.h"
  15. #include "net/cert/cert_verify_proc.h"
  16. #include "net/cert/cert_verify_result.h"
  17. #include "net/cert/multi_threaded_cert_verifier.h"
  18. #include "net/cert/trial_comparison_cert_verifier_util.h"
  19. #include "net/cert/x509_util.h"
  20. #include "net/log/net_log.h"
  21. #include "net/log/net_log_event_type.h"
  22. #include "net/log/net_log_source_type.h"
  23. #include "net/log/net_log_with_source.h"
  24. namespace net {
  25. namespace {
  26. base::Value JobResultParams(bool trial_success) {
  27. base::Value::Dict results;
  28. results.Set("trial_success", trial_success);
  29. return base::Value(std::move(results));
  30. }
  31. } // namespace
  32. // The Job represents the state machine for a trial cert verification.
  33. // The Job is always owned by the TrialComparisonCertVerifier. However, a
  34. // reference to the Job is given by the CertVerifier::Request returned by
  35. // Start(), allowing the caller to indicate they're no longer interested in
  36. // the Job if it's not yet completed.
  37. //
  38. // The Job may be deleted while processing the initial verification completion,
  39. // by the client callback deleting the associated TrialComparisonCertVerifier.
  40. class TrialComparisonCertVerifier::Job {
  41. public:
  42. Job(const CertVerifier::Config& config,
  43. const CertVerifier::RequestParams& params,
  44. const NetLogWithSource& source_net_log,
  45. TrialComparisonCertVerifier* parent);
  46. Job(const Job&) = delete;
  47. Job& operator=(const Job&) = delete;
  48. ~Job();
  49. // Start the Job, attempting first to verify with the parent's primary
  50. // verifier. |client_result|, |client_callback|, and |client_request| are
  51. // the parameters to the TrialComparisonCertVerifier::Verify(), allowing the
  52. // caller to register interest in the primary results. |client_request| will
  53. // be filled with a handle that the caller can use to abort the request.
  54. int Start(CertVerifyResult* client_result,
  55. CompletionOnceCallback client_callback,
  56. std::unique_ptr<CertVerifier::Request>* client_request);
  57. void OnConfigChanged();
  58. private:
  59. class Request;
  60. friend class Request;
  61. // If the Job has not yet completed the primary verification, this can be
  62. // called to indicate that the Request is no longer interested (e.g. the
  63. // Request is being deleted).
  64. void DetachRequest();
  65. void Finish(bool is_success, TrialComparisonResult result_code);
  66. void FinishSuccess(TrialComparisonResult result_code);
  67. void FinishWithError();
  68. // Called when the primary verifier is completed.
  69. // DANGER: |this| may be deleted when calling this.
  70. void OnPrimaryJobCompleted(int result);
  71. // Called when the initial trial comparison is completed.
  72. void OnTrialJobCompleted(int result);
  73. #if BUILDFLAG(IS_APPLE)
  74. // On some versions of macOS, revocation checking is always force-enabled
  75. // for the system. For comparing with the built-in verifier to rule out
  76. // "expected" differences, it's necessary to retry verification with
  77. // revocation checking enabled, to match the (effective) configuration of
  78. // the system verifier.
  79. void OnMacRevCheckingReverificationJobCompleted(int result);
  80. #endif
  81. // The primary (system) and trial (built-in) verifiers may both construct
  82. // valid chains, but they use different paths. If that happens, a second
  83. // verification with the system verifier is used, using the path that the
  84. // built-in verifier constructed, to compare results. This is called when
  85. // that re-verification completes.
  86. void OnPrimaryReverifyWithSecondaryChainCompleted(int result);
  87. const CertVerifier::Config config_;
  88. bool config_changed_ = false;
  89. const CertVerifier::RequestParams params_;
  90. const NetLogWithSource net_log_;
  91. raw_ptr<TrialComparisonCertVerifier> parent_ = nullptr; // Non-owned.
  92. raw_ptr<Request> request_ = nullptr; // Non-owned.
  93. // Results from the primary verification.
  94. base::TimeTicks primary_start_;
  95. int primary_error_;
  96. CertVerifyResult primary_result_;
  97. std::unique_ptr<CertVerifier::Request> primary_request_;
  98. // Results from the trial verification.
  99. base::TimeTicks trial_start_;
  100. int trial_error_;
  101. CertVerifyResult trial_result_;
  102. std::unique_ptr<CertVerifier::Request> trial_request_;
  103. // Results from the re-verification attempt.
  104. CertVerifyResult reverification_result_;
  105. std::unique_ptr<CertVerifier::Request> reverification_request_;
  106. base::WeakPtrFactory<Job> weak_factory_{this};
  107. };
  108. // The Request is vended to the TrialComparisonCertVerifier::Verify() callers,
  109. // which they fully own and will ultimately destroy. It's used to coordinate
  110. // state with the Job.
  111. //
  112. // If the Job has not yet completed the primary verification request, deleting
  113. // this will abort that Job, ultimately leading to the Job being deleted.
  114. // However, if the primary verification has completed, deleting the Request
  115. // simply becomes a no-op.
  116. class TrialComparisonCertVerifier::Job::Request : public CertVerifier::Request {
  117. public:
  118. Request(TrialComparisonCertVerifier::Job* parent,
  119. CertVerifyResult* client_result,
  120. CompletionOnceCallback client_callback);
  121. Request(const Request&) = delete;
  122. Request& operator=(const Request&) = delete;
  123. ~Request() override;
  124. // Called when the Job has completed, and used to invoke the client
  125. // callback.
  126. // Note: |this| may be deleted after calling this method.
  127. void OnJobComplete(int result, const CertVerifyResult& verify_result);
  128. // Called when the Job is aborted (e.g. the underlying
  129. // TrialComparisonCertVerifier is being deleted).
  130. // Note: |this| may be deleted after calling this method.
  131. void OnJobAborted();
  132. private:
  133. raw_ptr<TrialComparisonCertVerifier::Job> parent_;
  134. raw_ptr<CertVerifyResult> client_result_;
  135. CompletionOnceCallback client_callback_;
  136. };
  137. TrialComparisonCertVerifier::Job::Job(const CertVerifier::Config& config,
  138. const CertVerifier::RequestParams& params,
  139. const NetLogWithSource& source_net_log,
  140. TrialComparisonCertVerifier* parent)
  141. : config_(config),
  142. params_(params),
  143. net_log_(
  144. NetLogWithSource::Make(source_net_log.net_log(),
  145. NetLogSourceType::TRIAL_CERT_VERIFIER_JOB)),
  146. parent_(parent) {
  147. net_log_.BeginEvent(NetLogEventType::TRIAL_CERT_VERIFIER_JOB);
  148. source_net_log.AddEventReferencingSource(
  149. NetLogEventType::TRIAL_CERT_VERIFIER_JOB_COMPARISON_STARTED,
  150. net_log_.source());
  151. }
  152. TrialComparisonCertVerifier::Job::~Job() {
  153. if (request_) {
  154. // Note: May delete |request_|.
  155. request_->OnJobAborted();
  156. request_ = nullptr;
  157. }
  158. if (parent_) {
  159. net_log_.AddEvent(NetLogEventType::CANCELLED);
  160. net_log_.EndEvent(NetLogEventType::TRIAL_CERT_VERIFIER_JOB);
  161. }
  162. }
  163. int TrialComparisonCertVerifier::Job::Start(
  164. CertVerifyResult* client_result,
  165. CompletionOnceCallback client_callback,
  166. std::unique_ptr<CertVerifier::Request>* client_request) {
  167. DCHECK(!request_);
  168. DCHECK(parent_);
  169. primary_start_ = base::TimeTicks::Now();
  170. // Unretained is safe because |primary_request_| will cancel the
  171. // callback on destruction.
  172. primary_error_ = parent_->primary_verifier()->Verify(
  173. params_, &primary_result_,
  174. base::BindOnce(&Job::OnPrimaryJobCompleted, base::Unretained(this)),
  175. &primary_request_, net_log_);
  176. if (primary_error_ != ERR_IO_PENDING) {
  177. *client_result = primary_result_;
  178. int result = primary_error_;
  179. // NOTE: |this| may be deleted here, in the event that every resulting
  180. // trial comparison also completes synchronously.
  181. OnPrimaryJobCompleted(result);
  182. return result;
  183. }
  184. // Create a new Request that will be used to manage the state for the
  185. // primary verification and allow cancellation.
  186. auto request = std::make_unique<Request>(this, client_result,
  187. std::move(client_callback));
  188. request_ = request.get();
  189. *client_request = std::move(request);
  190. return ERR_IO_PENDING;
  191. }
  192. void TrialComparisonCertVerifier::Job::OnConfigChanged() {
  193. config_changed_ = true;
  194. }
  195. void TrialComparisonCertVerifier::Job::DetachRequest() {
  196. // This should only be called while waiting for the primary verification.
  197. DCHECK(primary_request_);
  198. DCHECK(request_);
  199. request_ = nullptr;
  200. }
  201. void TrialComparisonCertVerifier::Job::Finish(
  202. bool is_success,
  203. TrialComparisonResult result_code) {
  204. // There should never be a pending initial verification.
  205. DCHECK(!request_);
  206. DCHECK(!primary_request_);
  207. UMA_HISTOGRAM_ENUMERATION("Net.CertVerifier_TrialComparisonResult",
  208. result_code);
  209. net_log_.EndEvent(NetLogEventType::TRIAL_CERT_VERIFIER_JOB,
  210. [&] { return JobResultParams(is_success); });
  211. // Reset |parent_| to indicate the Job successfully completed (i.e. it was
  212. // not deleted by the TrialComparisonCertVerifier while still waiting for
  213. // results).
  214. TrialComparisonCertVerifier* parent = parent_;
  215. parent_ = nullptr;
  216. // Invoking the report callback may result in the
  217. // TrialComparisonCertVerifier being deleted, which will delete this Job.
  218. // Guard against this by grabbing a WeakPtr to |this|.
  219. base::WeakPtr<Job> weak_this = weak_factory_.GetWeakPtr();
  220. if (!is_success) {
  221. parent->report_callback_.Run(
  222. params_.hostname(), params_.certificate(), config_.enable_rev_checking,
  223. config_.require_rev_checking_local_anchors,
  224. config_.enable_sha1_local_anchors, config_.disable_symantec_enforcement,
  225. params_.ocsp_response(), params_.sct_list(), primary_result_,
  226. trial_result_);
  227. }
  228. if (weak_this) {
  229. // If the Job is still alive, delete it now.
  230. parent->RemoveJob(this);
  231. return;
  232. }
  233. }
  234. void TrialComparisonCertVerifier::Job::FinishSuccess(
  235. TrialComparisonResult result_code) {
  236. Finish(/*is_success=*/true, result_code);
  237. }
  238. void TrialComparisonCertVerifier::Job::FinishWithError() {
  239. DCHECK(trial_error_ != primary_error_ ||
  240. !CertVerifyResultEqual(trial_result_, primary_result_));
  241. TrialComparisonResult result_code = TrialComparisonResult::kInvalid;
  242. if (primary_error_ == OK && trial_error_ == OK) {
  243. result_code = TrialComparisonResult::kBothValidDifferentDetails;
  244. } else if (primary_error_ == OK) {
  245. result_code = TrialComparisonResult::kPrimaryValidSecondaryError;
  246. } else if (trial_error_ == OK) {
  247. result_code = TrialComparisonResult::kPrimaryErrorSecondaryValid;
  248. } else {
  249. result_code = TrialComparisonResult::kBothErrorDifferentDetails;
  250. }
  251. Finish(/*is_success=*/false, result_code);
  252. }
  253. void TrialComparisonCertVerifier::Job::OnPrimaryJobCompleted(int result) {
  254. base::TimeDelta primary_latency = base::TimeTicks::Now() - primary_start_;
  255. primary_error_ = result;
  256. primary_request_.reset();
  257. // Notify the original requestor that the primary verification has now
  258. // completed. This may result in |this| being deleted (if the associated
  259. // TrialComparisonCertVerifier is deleted); to detect this situation, grab
  260. // a WeakPtr to |this|.
  261. base::WeakPtr<Job> weak_this = weak_factory_.GetWeakPtr();
  262. if (request_) {
  263. Request* request = request_;
  264. request_ = nullptr;
  265. // Note: May delete |this|.
  266. request->OnJobComplete(primary_error_, primary_result_);
  267. }
  268. if (!weak_this)
  269. return;
  270. if (config_changed_ || !parent_->trial_allowed()) {
  271. // If the trial will not be run, then delete |this|.
  272. parent_->RemoveJob(this);
  273. return;
  274. }
  275. // Only record the TrialPrimary histograms for the same set of requests
  276. // that TrialSecondary histograms will be recorded for, in order to get a
  277. // direct comparison.
  278. UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency_TrialPrimary",
  279. primary_latency, base::Milliseconds(1),
  280. base::Minutes(10), 100);
  281. trial_start_ = base::TimeTicks::Now();
  282. int rv = parent_->trial_verifier()->Verify(
  283. params_, &trial_result_,
  284. base::BindOnce(&Job::OnTrialJobCompleted, base::Unretained(this)),
  285. &trial_request_, net_log_);
  286. if (rv != ERR_IO_PENDING)
  287. OnTrialJobCompleted(rv); // Note: May delete |this|.
  288. }
  289. void TrialComparisonCertVerifier::Job::OnTrialJobCompleted(int result) {
  290. DCHECK(primary_result_.verified_cert);
  291. DCHECK(trial_result_.verified_cert);
  292. base::TimeDelta latency = base::TimeTicks::Now() - trial_start_;
  293. trial_error_ = result;
  294. UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency_TrialSecondary",
  295. latency, base::Milliseconds(1), base::Minutes(10),
  296. 100);
  297. bool errors_equal = trial_error_ == primary_error_;
  298. bool details_equal = CertVerifyResultEqual(trial_result_, primary_result_);
  299. bool trial_success = errors_equal && details_equal;
  300. if (trial_success) {
  301. // Note: Will delete |this|.
  302. FinishSuccess(TrialComparisonResult::kEqual);
  303. return;
  304. }
  305. #if BUILDFLAG(IS_APPLE)
  306. if (primary_error_ == ERR_CERT_REVOKED && !config_.enable_rev_checking &&
  307. !(primary_result_.cert_status & CERT_STATUS_REV_CHECKING_ENABLED) &&
  308. !(trial_result_.cert_status &
  309. (CERT_STATUS_REVOKED | CERT_STATUS_REV_CHECKING_ENABLED))) {
  310. if (config_changed_) {
  311. // Note: Will delete |this|.
  312. FinishSuccess(TrialComparisonResult::kIgnoredConfigurationChanged);
  313. return;
  314. }
  315. // CertVerifyProcMac does some revocation checking even if we didn't want
  316. // it. Try verifying with the trial verifier with revocation checking
  317. // enabled, see if it then returns REVOKED.
  318. int rv = parent_->revocation_trial_verifier()->Verify(
  319. params_, &reverification_result_,
  320. base::BindOnce(&Job::OnMacRevCheckingReverificationJobCompleted,
  321. base::Unretained(this)),
  322. &reverification_request_, net_log_);
  323. if (rv != ERR_IO_PENDING) {
  324. // Note: May delete |this|.
  325. OnMacRevCheckingReverificationJobCompleted(rv);
  326. }
  327. return;
  328. }
  329. #endif
  330. TrialComparisonResult ignorable_difference =
  331. IsSynchronouslyIgnorableDifference(primary_error_, primary_result_,
  332. trial_error_, trial_result_,
  333. config_.enable_sha1_local_anchors);
  334. if (ignorable_difference != TrialComparisonResult::kInvalid) {
  335. FinishSuccess(ignorable_difference); // Note: Will delete |this|.
  336. return;
  337. }
  338. const bool chains_equal = primary_result_.verified_cert->EqualsIncludingChain(
  339. trial_result_.verified_cert.get());
  340. if (!chains_equal && (trial_error_ == OK || primary_error_ != OK)) {
  341. if (config_changed_) {
  342. // Note: Will delete |this|.
  343. FinishSuccess(TrialComparisonResult::kIgnoredConfigurationChanged);
  344. return;
  345. }
  346. // Chains were different, reverify the trial_result_.verified_cert chain
  347. // using the platform verifier and compare results again.
  348. RequestParams reverification_params(
  349. trial_result_.verified_cert, params_.hostname(), params_.flags(),
  350. params_.ocsp_response(), params_.sct_list());
  351. int rv = parent_->primary_reverifier()->Verify(
  352. reverification_params, &reverification_result_,
  353. base::BindOnce(&Job::OnPrimaryReverifyWithSecondaryChainCompleted,
  354. base::Unretained(this)),
  355. &reverification_request_, net_log_);
  356. if (rv != ERR_IO_PENDING) {
  357. // Note: May delete |this|.
  358. OnPrimaryReverifyWithSecondaryChainCompleted(rv);
  359. }
  360. return;
  361. }
  362. FinishWithError(); // Note: Will delete |this|.
  363. }
  364. #if BUILDFLAG(IS_APPLE)
  365. void TrialComparisonCertVerifier::Job::
  366. OnMacRevCheckingReverificationJobCompleted(int result) {
  367. if (result == ERR_CERT_REVOKED) {
  368. // Will delete |this|.
  369. FinishSuccess(
  370. TrialComparisonResult::kIgnoredMacUndesiredRevocationChecking);
  371. return;
  372. }
  373. FinishWithError(); // Note: Will delete |this|.
  374. }
  375. #endif
  376. void TrialComparisonCertVerifier::Job::
  377. OnPrimaryReverifyWithSecondaryChainCompleted(int result) {
  378. if (result == trial_error_ &&
  379. CertVerifyResultEqual(reverification_result_, trial_result_)) {
  380. // The new result matches the builtin verifier, so this was just a
  381. // difference in the platform's path-building ability.
  382. // Ignore the difference.
  383. //
  384. // Note: Will delete |this|.
  385. FinishSuccess(
  386. TrialComparisonResult::kIgnoredDifferentPathReVerifiesEquivalent);
  387. return;
  388. }
  389. if (IsSynchronouslyIgnorableDifference(result, reverification_result_,
  390. trial_error_, trial_result_,
  391. config_.enable_sha1_local_anchors) !=
  392. TrialComparisonResult::kInvalid) {
  393. // The new result matches if ignoring differences. Still use the
  394. // |kIgnoredDifferentPathReVerifiesEquivalent| code rather than the result
  395. // of IsSynchronouslyIgnorableDifference, since it's the higher level
  396. // description of what the difference is in this case.
  397. //
  398. // Note: Will delete |this|.
  399. FinishSuccess(
  400. TrialComparisonResult::kIgnoredDifferentPathReVerifiesEquivalent);
  401. return;
  402. }
  403. // Note: Will delete |this|.
  404. FinishWithError();
  405. }
  406. TrialComparisonCertVerifier::Job::Request::Request(
  407. TrialComparisonCertVerifier::Job* parent,
  408. CertVerifyResult* client_result,
  409. CompletionOnceCallback client_callback)
  410. : parent_(parent),
  411. client_result_(client_result),
  412. client_callback_(std::move(client_callback)) {}
  413. TrialComparisonCertVerifier::Job::Request::~Request() {
  414. if (parent_)
  415. parent_->DetachRequest();
  416. }
  417. void TrialComparisonCertVerifier::Job::Request::OnJobComplete(
  418. int result,
  419. const CertVerifyResult& verify_result) {
  420. DCHECK(parent_);
  421. parent_ = nullptr;
  422. *client_result_ = verify_result;
  423. // DANGER: |this| may be deleted when this callback is run (as well as
  424. // |parent_|, but that's been reset above).
  425. std::move(client_callback_).Run(result);
  426. }
  427. void TrialComparisonCertVerifier::Job::Request::OnJobAborted() {
  428. DCHECK(parent_);
  429. parent_ = nullptr;
  430. // DANGER: |this| may be deleted when this callback is destroyed.
  431. client_callback_.Reset();
  432. }
  433. TrialComparisonCertVerifier::TrialComparisonCertVerifier(
  434. scoped_refptr<CertVerifyProc> primary_verify_proc,
  435. scoped_refptr<CertVerifyProcFactory> primary_verify_proc_factory,
  436. scoped_refptr<CertVerifyProc> trial_verify_proc,
  437. scoped_refptr<CertVerifyProcFactory> trial_verify_proc_factory,
  438. ReportCallback report_callback)
  439. : report_callback_(std::move(report_callback)),
  440. primary_verifier_(std::make_unique<MultiThreadedCertVerifier>(
  441. primary_verify_proc,
  442. primary_verify_proc_factory)),
  443. primary_reverifier_(std::make_unique<MultiThreadedCertVerifier>(
  444. primary_verify_proc,
  445. primary_verify_proc_factory)),
  446. trial_verifier_(std::make_unique<MultiThreadedCertVerifier>(
  447. trial_verify_proc,
  448. trial_verify_proc_factory)),
  449. revocation_trial_verifier_(std::make_unique<MultiThreadedCertVerifier>(
  450. trial_verify_proc,
  451. trial_verify_proc_factory)) {
  452. CertVerifier::Config config;
  453. config.enable_rev_checking = true;
  454. revocation_trial_verifier_->SetConfig(config);
  455. }
  456. TrialComparisonCertVerifier::~TrialComparisonCertVerifier() = default;
  457. int TrialComparisonCertVerifier::Verify(const RequestParams& params,
  458. CertVerifyResult* verify_result,
  459. CompletionOnceCallback callback,
  460. std::unique_ptr<Request>* out_req,
  461. const NetLogWithSource& net_log) {
  462. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  463. if (!trial_allowed()) {
  464. return primary_verifier_->Verify(params, verify_result, std::move(callback),
  465. out_req, net_log);
  466. }
  467. std::unique_ptr<Job> job =
  468. std::make_unique<Job>(config_, params, net_log, this);
  469. Job* job_ptr = job.get();
  470. jobs_.insert(std::move(job));
  471. return job_ptr->Start(verify_result, std::move(callback), out_req);
  472. }
  473. void TrialComparisonCertVerifier::SetConfig(const Config& config) {
  474. config_ = config;
  475. primary_verifier_->SetConfig(config);
  476. primary_reverifier_->SetConfig(config);
  477. trial_verifier_->SetConfig(config);
  478. // Always enable revocation checking for the revocation trial verifier.
  479. CertVerifier::Config config_with_revocation = config;
  480. config_with_revocation.enable_rev_checking = true;
  481. revocation_trial_verifier_->SetConfig(config_with_revocation);
  482. // Notify all in-process jobs that the underlying configuration has changed.
  483. for (auto& job : jobs_) {
  484. job->OnConfigChanged();
  485. }
  486. }
  487. void TrialComparisonCertVerifier::UpdateChromeRootStoreData(
  488. scoped_refptr<CertNetFetcher> cert_net_fetcher,
  489. const ChromeRootStoreData* root_store_data) {
  490. primary_verifier_->UpdateChromeRootStoreData(cert_net_fetcher,
  491. root_store_data);
  492. primary_reverifier_->UpdateChromeRootStoreData(cert_net_fetcher,
  493. root_store_data);
  494. trial_verifier_->UpdateChromeRootStoreData(cert_net_fetcher, root_store_data);
  495. revocation_trial_verifier_->UpdateChromeRootStoreData(
  496. std::move(cert_net_fetcher), root_store_data);
  497. // Treat a possible proc change as a configuration change. Notify all
  498. // in-process jobs that the underlying configuration has changed.
  499. for (auto& job : jobs_) {
  500. job->OnConfigChanged();
  501. }
  502. }
  503. void TrialComparisonCertVerifier::RemoveJob(Job* job_ptr) {
  504. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  505. auto it = jobs_.find(job_ptr);
  506. DCHECK(it != jobs_.end());
  507. jobs_.erase(it);
  508. }
  509. } // namespace net