Avi Drissman | 6459548 | 2022-09-14 20:52:29 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 6e7845ae | 2013-03-29 21:48:11 | [diff] [blame] | 5 | #include "net/cert/multi_threaded_cert_verifier.h" |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 6 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 7 | #include "base/check_op.h" |
Avi Drissman | 41c4a41 | 2023-01-11 22:45:37 | [diff] [blame^] | 8 | #include "base/functional/bind.h" |
| 9 | #include "base/functional/callback_helpers.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 10 | #include "base/memory/raw_ptr.h" |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 11 | #include "base/memory/weak_ptr.h" |
Gabriel Charette | d5c656c | 2020-02-26 16:35:22 | [diff] [blame] | 12 | #include "base/task/thread_pool.h" |
Francois Doray | d56d158d | 2017-10-19 19:26:34 | [diff] [blame] | 13 | #include "base/threading/thread_restrictions.h" |
ssid | 6d6b4010 | 2016-04-05 18:59:56 | [diff] [blame] | 14 | #include "base/trace_event/trace_event.h" |
Collin | 5baeeba5 | 2022-01-20 02:07:59 | [diff] [blame] | 15 | #include "crypto/crypto_buildflags.h" |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 16 | #include "net/base/net_errors.h" |
xunjieli | 0b7f5b6 | 2016-12-06 20:43:48 | [diff] [blame] | 17 | #include "net/base/trace_constants.h" |
[email protected] | 6e7845ae | 2013-03-29 21:48:11 | [diff] [blame] | 18 | #include "net/cert/cert_verify_proc.h" |
rsleevi | 6df5418 | 2016-06-13 14:34:23 | [diff] [blame] | 19 | #include "net/cert/cert_verify_result.h" |
[email protected] | 6e7845ae | 2013-03-29 21:48:11 | [diff] [blame] | 20 | #include "net/cert/crl_set.h" |
| 21 | #include "net/cert/x509_certificate.h" |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 22 | #include "net/log/net_log_event_type.h" |
| 23 | #include "net/log/net_log_source_type.h" |
| 24 | #include "net/log/net_log_with_source.h" |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 25 | |
Collin | 5baeeba5 | 2022-01-20 02:07:59 | [diff] [blame] | 26 | #if BUILDFLAG(USE_NSS_CERTS) |
Matthew Denton | b6730bf | 2020-06-25 04:54:11 | [diff] [blame] | 27 | #include "net/cert/x509_util_nss.h" |
| 28 | #endif |
| 29 | |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 30 | namespace net { |
| 31 | |
Francois Doray | d56d158d | 2017-10-19 19:26:34 | [diff] [blame] | 32 | // Allows DoVerifyOnWorkerThread to wait on a base::WaitableEvent. |
| 33 | // DoVerifyOnWorkerThread may wait on network operations done on a separate |
| 34 | // sequence. For instance when using the NSS-based implementation of certificate |
| 35 | // verification, the library requires a blocking callback for fetching OCSP and |
| 36 | // AIA responses. |
| 37 | class MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives |
| 38 | : public base::ScopedAllowBaseSyncPrimitives {}; |
| 39 | |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 40 | namespace { |
| 41 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 42 | // Used to pass the result of DoVerifyOnWorkerThread() to |
| 43 | // MultiThreadedCertVerifier::InternalRequest::OnJobComplete(). |
rsleevi | 6df5418 | 2016-06-13 14:34:23 | [diff] [blame] | 44 | struct ResultHelper { |
| 45 | int error; |
| 46 | CertVerifyResult result; |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 47 | NetLogWithSource net_log; |
[email protected] | 94bf72f | 2012-06-19 19:37:28 | [diff] [blame] | 48 | }; |
| 49 | |
Ryan Sleevi | 24fe268 | 2018-08-16 21:33:46 | [diff] [blame] | 50 | int GetFlagsForConfig(const CertVerifier::Config& config) { |
| 51 | int flags = 0; |
| 52 | |
| 53 | if (config.enable_rev_checking) |
| 54 | flags |= CertVerifyProc::VERIFY_REV_CHECKING_ENABLED; |
| 55 | if (config.require_rev_checking_local_anchors) |
| 56 | flags |= CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; |
| 57 | if (config.enable_sha1_local_anchors) |
| 58 | flags |= CertVerifyProc::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS; |
| 59 | if (config.disable_symantec_enforcement) |
| 60 | flags |= CertVerifyProc::VERIFY_DISABLE_SYMANTEC_ENFORCEMENT; |
| 61 | |
| 62 | return flags; |
| 63 | } |
| 64 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 65 | // Runs the verification synchronously on a worker thread. |
Francois Doray | 524a99e | 2017-09-26 18:48:17 | [diff] [blame] | 66 | std::unique_ptr<ResultHelper> DoVerifyOnWorkerThread( |
| 67 | const scoped_refptr<CertVerifyProc>& verify_proc, |
| 68 | const scoped_refptr<X509Certificate>& cert, |
| 69 | const std::string& hostname, |
| 70 | const std::string& ocsp_response, |
Matt Mueller | 7d5464b | 2019-05-15 20:18:45 | [diff] [blame] | 71 | const std::string& sct_list, |
Francois Doray | 524a99e | 2017-09-26 18:48:17 | [diff] [blame] | 72 | int flags, |
| 73 | const scoped_refptr<CRLSet>& crl_set, |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 74 | const CertificateList& additional_trust_anchors, |
| 75 | const NetLogWithSource& net_log) { |
Alexandr Ilin | 3312663 | 2018-11-14 14:48:17 | [diff] [blame] | 76 | TRACE_EVENT0(NetTracingCategory(), "DoVerifyOnWorkerThread"); |
Francois Doray | 524a99e | 2017-09-26 18:48:17 | [diff] [blame] | 77 | auto verify_result = std::make_unique<ResultHelper>(); |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 78 | verify_result->net_log = net_log; |
Francois Doray | d56d158d | 2017-10-19 19:26:34 | [diff] [blame] | 79 | MultiThreadedCertVerifierScopedAllowBaseSyncPrimitives |
| 80 | allow_base_sync_primitives; |
Francois Doray | 524a99e | 2017-09-26 18:48:17 | [diff] [blame] | 81 | verify_result->error = verify_proc->Verify( |
Matt Mueller | 7d5464b | 2019-05-15 20:18:45 | [diff] [blame] | 82 | cert.get(), hostname, ocsp_response, sct_list, flags, crl_set.get(), |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 83 | additional_trust_anchors, &verify_result->result, net_log); |
Matt Mueller | cc42ea1 | 2019-08-14 23:27:37 | [diff] [blame] | 84 | // The CertVerifyResult is created and populated on the worker thread and |
| 85 | // then returned to the network thread. Detach now before returning the |
| 86 | // result, since any further access will be on the network thread. |
| 87 | verify_result->result.DetachFromSequence(); |
Francois Doray | 524a99e | 2017-09-26 18:48:17 | [diff] [blame] | 88 | return verify_result; |
eroman | 7f9236a | 2015-05-11 21:23:43 | [diff] [blame] | 89 | } |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 90 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 91 | } // namespace |
| 92 | |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 93 | // Helper to allow callers to cancel pending CertVerifier::Verify requests. |
| 94 | // Note that because the CertVerifyProc is blocking, it's not actually |
| 95 | // possible to cancel the in-progress request; instead, this simply guarantees |
| 96 | // that the provided callback will not be invoked if the Request is deleted. |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 97 | class MultiThreadedCertVerifier::InternalRequest |
| 98 | : public CertVerifier::Request, |
| 99 | public base::LinkNode<InternalRequest> { |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 100 | public: |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 101 | InternalRequest(CompletionOnceCallback callback, |
| 102 | CertVerifyResult* caller_result); |
| 103 | ~InternalRequest() override; |
eroman | 7f9236a | 2015-05-11 21:23:43 | [diff] [blame] | 104 | |
Francois Doray | 524a99e | 2017-09-26 18:48:17 | [diff] [blame] | 105 | void Start(const scoped_refptr<CertVerifyProc>& verify_proc, |
Ryan Sleevi | 24fe268 | 2018-08-16 21:33:46 | [diff] [blame] | 106 | const CertVerifier::Config& config, |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 107 | const CertVerifier::RequestParams& params, |
| 108 | const NetLogWithSource& caller_net_log); |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 109 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 110 | void ResetCallback() { callback_.Reset(); } |
| 111 | |
eroman | 7f9236a | 2015-05-11 21:23:43 | [diff] [blame] | 112 | private: |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 113 | // This is a static method with a |self| weak pointer instead of a regular |
| 114 | // method, so that PostTask will still run it even if the weakptr is no |
| 115 | // longer valid. |
| 116 | static void OnJobComplete(base::WeakPtr<InternalRequest> self, |
| 117 | std::unique_ptr<ResultHelper> verify_result); |
eroman | 7f9236a | 2015-05-11 21:23:43 | [diff] [blame] | 118 | |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 119 | CompletionOnceCallback callback_; |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 120 | raw_ptr<CertVerifyResult> caller_result_; |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 121 | |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 122 | base::WeakPtrFactory<InternalRequest> weak_factory_{this}; |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 123 | }; |
| 124 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 125 | MultiThreadedCertVerifier::InternalRequest::InternalRequest( |
| 126 | CompletionOnceCallback callback, |
| 127 | CertVerifyResult* caller_result) |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 128 | : callback_(std::move(callback)), caller_result_(caller_result) {} |
| 129 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 130 | MultiThreadedCertVerifier::InternalRequest::~InternalRequest() { |
| 131 | if (callback_) { |
| 132 | // This InternalRequest was eagerly cancelled as the callback is still |
| 133 | // valid, so |this| needs to be removed from MultiThreadedCertVerifier's |
| 134 | // list. |
| 135 | RemoveFromList(); |
| 136 | } |
| 137 | } |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 138 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 139 | void MultiThreadedCertVerifier::InternalRequest::Start( |
| 140 | const scoped_refptr<CertVerifyProc>& verify_proc, |
| 141 | const CertVerifier::Config& config, |
| 142 | const CertVerifier::RequestParams& params, |
| 143 | const NetLogWithSource& caller_net_log) { |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 144 | const NetLogWithSource net_log(NetLogWithSource::Make( |
| 145 | caller_net_log.net_log(), NetLogSourceType::CERT_VERIFIER_TASK)); |
| 146 | net_log.BeginEvent(NetLogEventType::CERT_VERIFIER_TASK); |
| 147 | caller_net_log.AddEventReferencingSource( |
| 148 | NetLogEventType::CERT_VERIFIER_TASK_BOUND, net_log.source()); |
| 149 | |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 150 | int flags = GetFlagsForConfig(config); |
| 151 | if (params.flags() & CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES) { |
| 152 | flags &= ~CertVerifyProc::VERIFY_REV_CHECKING_ENABLED; |
| 153 | flags &= ~CertVerifyProc::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; |
| 154 | } |
| 155 | DCHECK(config.crl_set); |
Gabriel Charette | d5c656c | 2020-02-26 16:35:22 | [diff] [blame] | 156 | base::ThreadPool::PostTaskAndReplyWithResult( |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 157 | FROM_HERE, |
Gabriel Charette | d5c656c | 2020-02-26 16:35:22 | [diff] [blame] | 158 | {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 159 | base::BindOnce(&DoVerifyOnWorkerThread, verify_proc, params.certificate(), |
| 160 | params.hostname(), params.ocsp_response(), |
| 161 | params.sct_list(), flags, config.crl_set, |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 162 | config.additional_trust_anchors, net_log), |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 163 | base::BindOnce(&MultiThreadedCertVerifier::InternalRequest::OnJobComplete, |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 164 | weak_factory_.GetWeakPtr())); |
| 165 | } |
| 166 | |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 167 | // static |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 168 | void MultiThreadedCertVerifier::InternalRequest::OnJobComplete( |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 169 | base::WeakPtr<InternalRequest> self, |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 170 | std::unique_ptr<ResultHelper> verify_result) { |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 171 | // Always log the EndEvent, even if the Request has been destroyed. |
| 172 | verify_result->net_log.EndEvent(NetLogEventType::CERT_VERIFIER_TASK); |
| 173 | |
| 174 | // Check |self| weakptr and don't continue if the Request was destroyed. |
| 175 | if (!self) |
| 176 | return; |
| 177 | |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 178 | DCHECK(verify_result); |
| 179 | |
| 180 | // If the MultiThreadedCertVerifier has been deleted, the callback will have |
| 181 | // been reset to null. |
| 182 | if (!self->callback_) |
| 183 | return; |
| 184 | |
| 185 | // If ~MultiThreadedCertVerifier has not Reset() our callback, then this |
| 186 | // InternalRequest will not have been removed from MultiThreadedCertVerifier's |
| 187 | // list yet. |
| 188 | self->RemoveFromList(); |
| 189 | |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 190 | *self->caller_result_ = verify_result->result; |
| 191 | // Note: May delete |self|. |
| 192 | std::move(self->callback_).Run(verify_result->error); |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 193 | } |
| 194 | |
[email protected] | ec012fe2 | 2012-09-19 04:17:02 | [diff] [blame] | 195 | MultiThreadedCertVerifier::MultiThreadedCertVerifier( |
Sergey Ulanov | 4908557 | 2017-07-10 23:25:46 | [diff] [blame] | 196 | scoped_refptr<CertVerifyProc> verify_proc) |
Hubert Chao | 2a000d7 | 2022-04-25 19:43:30 | [diff] [blame] | 197 | : MultiThreadedCertVerifier(std::move(verify_proc), nullptr) {} |
| 198 | |
| 199 | MultiThreadedCertVerifier::MultiThreadedCertVerifier( |
| 200 | scoped_refptr<CertVerifyProc> verify_proc, |
| 201 | scoped_refptr<CertVerifyProcFactory> verify_proc_factory) |
| 202 | : verify_proc_(std::move(verify_proc)), |
| 203 | verify_proc_factory_(std::move(verify_proc_factory)) { |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 204 | // Guarantee there is always a CRLSet (this can be overridden via SetConfig). |
Matthew Braithwaite | 468ae9b7d | 2019-03-06 03:57:21 | [diff] [blame] | 205 | config_.crl_set = CRLSet::BuiltinCRLSet(); |
| 206 | } |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 207 | |
| 208 | MultiThreadedCertVerifier::~MultiThreadedCertVerifier() { |
gab | 47aa7da | 2017-06-02 16:09:43 | [diff] [blame] | 209 | DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 210 | // Reset the callbacks for each InternalRequest to fulfill the respective |
| 211 | // net::CertVerifier contract. |
Matthew Denton | 19aeffd4 | 2020-12-15 01:09:52 | [diff] [blame] | 212 | for (base::LinkNode<InternalRequest>* node = request_list_.head(); |
| 213 | node != request_list_.end();) { |
| 214 | // Resetting the callback may delete the request, so save a pointer to the |
| 215 | // next node first. |
| 216 | base::LinkNode<InternalRequest>* next_node = node->next(); |
| 217 | node->value()->ResetCallback(); |
| 218 | node = next_node; |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 219 | } |
[email protected] | ef15512 | 2013-03-23 19:11:24 | [diff] [blame] | 220 | } |
| 221 | |
rsleevi | 06bd7855 | 2016-06-08 22:34:46 | [diff] [blame] | 222 | int MultiThreadedCertVerifier::Verify(const RequestParams& params, |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 223 | CertVerifyResult* verify_result, |
Bence Béky | 9387759c | 2018-07-04 18:51:33 | [diff] [blame] | 224 | CompletionOnceCallback callback, |
danakj | 3a4770d | 2016-04-16 03:09:29 | [diff] [blame] | 225 | std::unique_ptr<Request>* out_req, |
tfarina | 4283411 | 2016-09-22 13:38:20 | [diff] [blame] | 226 | const NetLogWithSource& net_log) { |
eroman | 7f9236a | 2015-05-11 21:23:43 | [diff] [blame] | 227 | out_req->reset(); |
| 228 | |
gab | 47aa7da | 2017-06-02 16:09:43 | [diff] [blame] | 229 | DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 230 | |
rsleevi | 06bd7855 | 2016-06-08 22:34:46 | [diff] [blame] | 231 | if (callback.is_null() || !verify_result || params.hostname().empty()) |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 232 | return ERR_INVALID_ARGUMENT; |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 233 | |
Ryan Sleevi | 2cb6817 | 2019-10-09 14:03:11 | [diff] [blame] | 234 | std::unique_ptr<InternalRequest> request = |
| 235 | std::make_unique<InternalRequest>(std::move(callback), verify_result); |
Matt Mueller | 78742234 | 2020-03-27 23:28:18 | [diff] [blame] | 236 | request->Start(verify_proc_, config_, params, net_log); |
Matthew Denton | 9d571bb | 2020-04-30 23:23:49 | [diff] [blame] | 237 | request_list_.Append(request.get()); |
dcheng | c7eeda42 | 2015-12-26 03:56:48 | [diff] [blame] | 238 | *out_req = std::move(request); |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 239 | return ERR_IO_PENDING; |
| 240 | } |
| 241 | |
Hubert Chao | 2a000d7 | 2022-04-25 19:43:30 | [diff] [blame] | 242 | void MultiThreadedCertVerifier::UpdateChromeRootStoreData( |
| 243 | scoped_refptr<CertNetFetcher> cert_net_fetcher, |
| 244 | const ChromeRootStoreData* root_store_data) { |
| 245 | DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 246 | // TODO(hchao): investigate to see if we can make this a DCHECK. |
| 247 | if (verify_proc_factory_) { |
| 248 | verify_proc_ = verify_proc_factory_->CreateCertVerifyProc( |
| 249 | std::move(cert_net_fetcher), root_store_data); |
| 250 | } |
| 251 | } |
| 252 | |
Ryan Sleevi | 24fe268 | 2018-08-16 21:33:46 | [diff] [blame] | 253 | void MultiThreadedCertVerifier::SetConfig(const CertVerifier::Config& config) { |
Matt Mueller | 5267894 | 2022-03-02 21:33:14 | [diff] [blame] | 254 | DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
Matthew Denton | ef6b10c | 2020-04-28 10:49:44 | [diff] [blame] | 255 | LOG_IF(DFATAL, verify_proc_ && |
| 256 | !verify_proc_->SupportsAdditionalTrustAnchors() && |
| 257 | !config.additional_trust_anchors.empty()) |
| 258 | << "Attempted to set a CertVerifier::Config with additional trust " |
| 259 | "anchors, but |verify_proc_| does not support additional trust " |
| 260 | "anchors."; |
Matthew Denton | b6730bf | 2020-06-25 04:54:11 | [diff] [blame] | 261 | |
| 262 | // TODO(https://crbug.com/978854): Pass these into the actual CertVerifyProc |
| 263 | // rather than relying on global side-effects. |
Collin | 5baeeba5 | 2022-01-20 02:07:59 | [diff] [blame] | 264 | #if !BUILDFLAG(USE_NSS_CERTS) |
Matthew Denton | b6730bf | 2020-06-25 04:54:11 | [diff] [blame] | 265 | // Not yet implemented. |
| 266 | DCHECK(config.additional_untrusted_authorities.empty()); |
| 267 | #else |
Matt Mueller | c156113 | 2022-04-27 22:53:47 | [diff] [blame] | 268 | // Construct a temporary list and then swap that into the member variable, to |
| 269 | // be polite to any verifications that might be in progress in a background |
| 270 | // thread. This ensures that, at least for certs that are present in both the |
| 271 | // old and new config, there will not be a time when the refcount drops to |
| 272 | // zero. For the case where a cert was in the old config and is not in the |
| 273 | // new config, it might be removed while a verification is still going on |
| 274 | // that might be able to use it. Oh well. Ideally the list should be passed |
| 275 | // into CertVerifyProc as noted by the TODO(https://crbug.com/978854), since |
| 276 | // the workers could then keep a reference to the appropriate certs as long |
| 277 | // as they need. |
| 278 | net::ScopedCERTCertificateList temp_certs; |
Matthew Denton | b6730bf | 2020-06-25 04:54:11 | [diff] [blame] | 279 | for (const auto& cert : config.additional_untrusted_authorities) { |
Matt Mueller | c156113 | 2022-04-27 22:53:47 | [diff] [blame] | 280 | ScopedCERTCertificate nss_cert = |
Matthew Denton | b6730bf | 2020-06-25 04:54:11 | [diff] [blame] | 281 | x509_util::CreateCERTCertificateFromX509Certificate(cert.get()); |
Matt Mueller | c156113 | 2022-04-27 22:53:47 | [diff] [blame] | 282 | if (nss_cert) |
| 283 | temp_certs.push_back(std::move(nss_cert)); |
Matthew Denton | b6730bf | 2020-06-25 04:54:11 | [diff] [blame] | 284 | } |
Matt Mueller | c156113 | 2022-04-27 22:53:47 | [diff] [blame] | 285 | temp_certs_ = std::move(temp_certs); |
Matthew Denton | b6730bf | 2020-06-25 04:54:11 | [diff] [blame] | 286 | #endif |
| 287 | |
Ryan Sleevi | 24fe268 | 2018-08-16 21:33:46 | [diff] [blame] | 288 | config_ = config; |
Matthew Braithwaite | 468ae9b7d | 2019-03-06 03:57:21 | [diff] [blame] | 289 | if (!config_.crl_set) |
| 290 | config_.crl_set = CRLSet::BuiltinCRLSet(); |
eroman | 7f9236a | 2015-05-11 21:23:43 | [diff] [blame] | 291 | } |
| 292 | |
[email protected] | 9f59fac | 2012-03-21 23:18:11 | [diff] [blame] | 293 | } // namespace net |