OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/multi_threaded_cert_verifier.h" | 5 #include "net/cert/multi_threaded_cert_verifier.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 crl_set_(crl_set), | 197 crl_set_(crl_set), |
198 additional_trust_anchors_(additional_trust_anchors), | 198 additional_trust_anchors_(additional_trust_anchors), |
199 origin_loop_(base::MessageLoop::current()), | 199 origin_loop_(base::MessageLoop::current()), |
200 cert_verifier_(cert_verifier), | 200 cert_verifier_(cert_verifier), |
201 canceled_(false), | 201 canceled_(false), |
202 error_(ERR_FAILED) { | 202 error_(ERR_FAILED) { |
203 } | 203 } |
204 | 204 |
205 // Returns the certificate being verified. May only be called /before/ | 205 // Returns the certificate being verified. May only be called /before/ |
206 // Start() is called. | 206 // Start() is called. |
207 X509Certificate* certificate() const { return cert_; } | 207 X509Certificate* certificate() const { return cert_.get(); } |
208 | 208 |
209 bool Start() { | 209 bool Start() { |
210 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); | 210 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); |
211 | 211 |
212 return base::WorkerPool::PostTask( | 212 return base::WorkerPool::PostTask( |
213 FROM_HERE, base::Bind(&CertVerifierWorker::Run, base::Unretained(this)), | 213 FROM_HERE, base::Bind(&CertVerifierWorker::Run, base::Unretained(this)), |
214 true /* task is slow */); | 214 true /* task is slow */); |
215 } | 215 } |
216 | 216 |
217 // Cancel is called from the origin loop when the MultiThreadedCertVerifier is | 217 // Cancel is called from the origin loop when the MultiThreadedCertVerifier is |
218 // getting deleted. | 218 // getting deleted. |
219 void Cancel() { | 219 void Cancel() { |
220 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); | 220 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); |
221 base::AutoLock locked(lock_); | 221 base::AutoLock locked(lock_); |
222 canceled_ = true; | 222 canceled_ = true; |
223 } | 223 } |
224 | 224 |
225 private: | 225 private: |
226 void Run() { | 226 void Run() { |
227 // Runs on a worker thread. | 227 // Runs on a worker thread. |
228 error_ = verify_proc_->Verify(cert_, hostname_, flags_, crl_set_, | 228 error_ = verify_proc_->Verify(cert_.get(), |
229 additional_trust_anchors_, &verify_result_); | 229 hostname_, |
| 230 flags_, |
| 231 crl_set_.get(), |
| 232 additional_trust_anchors_, |
| 233 &verify_result_); |
230 #if defined(USE_NSS) || defined(OS_IOS) | 234 #if defined(USE_NSS) || defined(OS_IOS) |
231 // Detach the thread from NSPR. | 235 // Detach the thread from NSPR. |
232 // Calling NSS functions attaches the thread to NSPR, which stores | 236 // Calling NSS functions attaches the thread to NSPR, which stores |
233 // the NSPR thread ID in thread-specific data. | 237 // the NSPR thread ID in thread-specific data. |
234 // The threads in our thread pool terminate after we have called | 238 // The threads in our thread pool terminate after we have called |
235 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets | 239 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets |
236 // segfaults on shutdown when the threads' thread-specific data | 240 // segfaults on shutdown when the threads' thread-specific data |
237 // destructors run. | 241 // destructors run. |
238 PR_DetachThread(); | 242 PR_DetachThread(); |
239 #endif | 243 #endif |
240 Finish(); | 244 Finish(); |
241 } | 245 } |
242 | 246 |
243 // DoReply runs on the origin thread. | 247 // DoReply runs on the origin thread. |
244 void DoReply() { | 248 void DoReply() { |
245 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); | 249 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); |
246 { | 250 { |
247 // We lock here because the worker thread could still be in Finished, | 251 // We lock here because the worker thread could still be in Finished, |
248 // after the PostTask, but before unlocking |lock_|. If we do not lock in | 252 // after the PostTask, but before unlocking |lock_|. If we do not lock in |
249 // this case, we will end up deleting a locked Lock, which can lead to | 253 // this case, we will end up deleting a locked Lock, which can lead to |
250 // memory leaks or worse errors. | 254 // memory leaks or worse errors. |
251 base::AutoLock locked(lock_); | 255 base::AutoLock locked(lock_); |
252 if (!canceled_) { | 256 if (!canceled_) { |
253 cert_verifier_->HandleResult(cert_, hostname_, flags_, | 257 cert_verifier_->HandleResult(cert_.get(), |
254 additional_trust_anchors_, error_, | 258 hostname_, |
| 259 flags_, |
| 260 additional_trust_anchors_, |
| 261 error_, |
255 verify_result_); | 262 verify_result_); |
256 } | 263 } |
257 } | 264 } |
258 delete this; | 265 delete this; |
259 } | 266 } |
260 | 267 |
261 void Finish() { | 268 void Finish() { |
262 // Runs on the worker thread. | 269 // Runs on the worker thread. |
263 // We assume that the origin loop outlives the MultiThreadedCertVerifier. If | 270 // We assume that the origin loop outlives the MultiThreadedCertVerifier. If |
264 // the MultiThreadedCertVerifier is deleted, it will call Cancel on us. If | 271 // the MultiThreadedCertVerifier is deleted, it will call Cancel on us. If |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 std::map<RequestParams, CertVerifierJob*>::const_iterator j; | 448 std::map<RequestParams, CertVerifierJob*>::const_iterator j; |
442 j = inflight_.find(key); | 449 j = inflight_.find(key); |
443 if (j != inflight_.end()) { | 450 if (j != inflight_.end()) { |
444 // An identical request is in flight already. We'll just attach our | 451 // An identical request is in flight already. We'll just attach our |
445 // callback. | 452 // callback. |
446 inflight_joins_++; | 453 inflight_joins_++; |
447 job = j->second; | 454 job = j->second; |
448 } else { | 455 } else { |
449 // Need to make a new request. | 456 // Need to make a new request. |
450 CertVerifierWorker* worker = | 457 CertVerifierWorker* worker = |
451 new CertVerifierWorker(verify_proc_, cert, hostname, flags, crl_set, | 458 new CertVerifierWorker(verify_proc_.get(), |
452 additional_trust_anchors, this); | 459 cert, |
| 460 hostname, |
| 461 flags, |
| 462 crl_set, |
| 463 additional_trust_anchors, |
| 464 this); |
453 job = new CertVerifierJob( | 465 job = new CertVerifierJob( |
454 worker, | 466 worker, |
455 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); | 467 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); |
456 if (!worker->Start()) { | 468 if (!worker->Start()) { |
457 delete job; | 469 delete job; |
458 delete worker; | 470 delete worker; |
459 *out_req = NULL; | 471 *out_req = NULL; |
460 // TODO(wtc): log to the NetLog. | 472 // TODO(wtc): log to the NetLog. |
461 LOG(ERROR) << "CertVerifierWorker couldn't be started."; | 473 LOG(ERROR) << "CertVerifierWorker couldn't be started."; |
462 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. | 474 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 } | 557 } |
546 | 558 |
547 void MultiThreadedCertVerifier::OnCertTrustChanged( | 559 void MultiThreadedCertVerifier::OnCertTrustChanged( |
548 const X509Certificate* cert) { | 560 const X509Certificate* cert) { |
549 DCHECK(CalledOnValidThread()); | 561 DCHECK(CalledOnValidThread()); |
550 | 562 |
551 ClearCache(); | 563 ClearCache(); |
552 } | 564 } |
553 | 565 |
554 } // namespace net | 566 } // namespace net |
OLD | NEW |