| 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/base/multi_threaded_cert_verifier.h" | 5 #include "net/base/multi_threaded_cert_verifier.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 CertVerifyResult* verify_result_; | 123 CertVerifyResult* verify_result_; |
| 124 const BoundNetLog net_log_; | 124 const BoundNetLog net_log_; |
| 125 }; | 125 }; |
| 126 | 126 |
| 127 | 127 |
| 128 // CertVerifierWorker runs on a worker thread and takes care of the blocking | 128 // CertVerifierWorker runs on a worker thread and takes care of the blocking |
| 129 // process of performing the certificate verification. Deletes itself | 129 // process of performing the certificate verification. Deletes itself |
| 130 // eventually if Start() succeeds. | 130 // eventually if Start() succeeds. |
| 131 class CertVerifierWorker { | 131 class CertVerifierWorker { |
| 132 public: | 132 public: |
| 133 CertVerifierWorker(X509Certificate* cert, | 133 CertVerifierWorker(MultiThreadedCertVerifier::VerifyProc* verify_proc, |
| 134 X509Certificate* cert, |
| 134 const std::string& hostname, | 135 const std::string& hostname, |
| 135 int flags, | 136 int flags, |
| 136 CRLSet* crl_set, | 137 CRLSet* crl_set, |
| 137 MultiThreadedCertVerifier* cert_verifier) | 138 MultiThreadedCertVerifier* cert_verifier) |
| 138 : cert_(cert), | 139 : verify_proc_(verify_proc), |
| 140 cert_(cert), |
| 139 hostname_(hostname), | 141 hostname_(hostname), |
| 140 flags_(flags), | 142 flags_(flags), |
| 141 crl_set_(crl_set), | 143 crl_set_(crl_set), |
| 142 origin_loop_(MessageLoop::current()), | 144 origin_loop_(MessageLoop::current()), |
| 143 cert_verifier_(cert_verifier), | 145 cert_verifier_(cert_verifier), |
| 144 canceled_(false), | 146 canceled_(false), |
| 145 error_(ERR_FAILED) { | 147 error_(ERR_FAILED) { |
| 146 } | 148 } |
| 147 | 149 |
| 148 // Returns the certificate being verified. May only be called /before/ | 150 // Returns the certificate being verified. May only be called /before/ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 161 // getting deleted. | 163 // getting deleted. |
| 162 void Cancel() { | 164 void Cancel() { |
| 163 DCHECK_EQ(MessageLoop::current(), origin_loop_); | 165 DCHECK_EQ(MessageLoop::current(), origin_loop_); |
| 164 base::AutoLock locked(lock_); | 166 base::AutoLock locked(lock_); |
| 165 canceled_ = true; | 167 canceled_ = true; |
| 166 } | 168 } |
| 167 | 169 |
| 168 private: | 170 private: |
| 169 void Run() { | 171 void Run() { |
| 170 // Runs on a worker thread. | 172 // Runs on a worker thread. |
| 171 error_ = cert_->Verify(hostname_, flags_, crl_set_, &verify_result_); | 173 error_ = verify_proc_->Verify(cert_, hostname_, flags_, crl_set_, |
| 174 &verify_result_); |
| 172 #if defined(USE_NSS) | 175 #if defined(USE_NSS) |
| 173 // Detach the thread from NSPR. | 176 // Detach the thread from NSPR. |
| 174 // Calling NSS functions attaches the thread to NSPR, which stores | 177 // Calling NSS functions attaches the thread to NSPR, which stores |
| 175 // the NSPR thread ID in thread-specific data. | 178 // the NSPR thread ID in thread-specific data. |
| 176 // The threads in our thread pool terminate after we have called | 179 // The threads in our thread pool terminate after we have called |
| 177 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets | 180 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets |
| 178 // segfaults on shutdown when the threads' thread-specific data | 181 // segfaults on shutdown when the threads' thread-specific data |
| 179 // destructors run. | 182 // destructors run. |
| 180 PR_DetachThread(); | 183 PR_DetachThread(); |
| 181 #endif | 184 #endif |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 origin_loop_->PostTask( | 222 origin_loop_->PostTask( |
| 220 FROM_HERE, base::Bind( | 223 FROM_HERE, base::Bind( |
| 221 &CertVerifierWorker::DoReply, base::Unretained(this))); | 224 &CertVerifierWorker::DoReply, base::Unretained(this))); |
| 222 } | 225 } |
| 223 } | 226 } |
| 224 | 227 |
| 225 if (canceled) | 228 if (canceled) |
| 226 delete this; | 229 delete this; |
| 227 } | 230 } |
| 228 | 231 |
| 232 scoped_refptr<MultiThreadedCertVerifier::VerifyProc> verify_proc_; |
| 229 scoped_refptr<X509Certificate> cert_; | 233 scoped_refptr<X509Certificate> cert_; |
| 230 const std::string hostname_; | 234 const std::string hostname_; |
| 231 const int flags_; | 235 const int flags_; |
| 232 scoped_refptr<CRLSet> crl_set_; | 236 scoped_refptr<CRLSet> crl_set_; |
| 233 MessageLoop* const origin_loop_; | 237 MessageLoop* const origin_loop_; |
| 234 MultiThreadedCertVerifier* const cert_verifier_; | 238 MultiThreadedCertVerifier* const cert_verifier_; |
| 235 | 239 |
| 236 // lock_ protects canceled_. | 240 // lock_ protects canceled_. |
| 237 base::Lock lock_; | 241 base::Lock lock_; |
| 238 | 242 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 } | 317 } |
| 314 } | 318 } |
| 315 } | 319 } |
| 316 | 320 |
| 317 const base::TimeTicks start_time_; | 321 const base::TimeTicks start_time_; |
| 318 std::vector<CertVerifierRequest*> requests_; | 322 std::vector<CertVerifierRequest*> requests_; |
| 319 CertVerifierWorker* worker_; | 323 CertVerifierWorker* worker_; |
| 320 const BoundNetLog net_log_; | 324 const BoundNetLog net_log_; |
| 321 }; | 325 }; |
| 322 | 326 |
| 323 MultiThreadedCertVerifier::MultiThreadedCertVerifier() | 327 MultiThreadedCertVerifier::MultiThreadedCertVerifier(VerifyProc* verifier) |
| 324 : cache_(kMaxCacheEntries), | 328 : cache_(kMaxCacheEntries), |
| 329 verifier_(verifier), |
| 325 requests_(0), | 330 requests_(0), |
| 326 cache_hits_(0), | 331 cache_hits_(0), |
| 327 inflight_joins_(0) { | 332 inflight_joins_(0) { |
| 328 CertDatabase::AddObserver(this); | 333 CertDatabase::AddObserver(this); |
| 329 } | 334 } |
| 330 | 335 |
| 331 MultiThreadedCertVerifier::~MultiThreadedCertVerifier() { | 336 MultiThreadedCertVerifier::~MultiThreadedCertVerifier() { |
| 332 STLDeleteValues(&inflight_); | 337 STLDeleteValues(&inflight_); |
| 333 | 338 |
| 334 CertDatabase::RemoveObserver(this); | 339 CertDatabase::RemoveObserver(this); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 CertVerifierJob* job; | 371 CertVerifierJob* job; |
| 367 std::map<RequestParams, CertVerifierJob*>::const_iterator j; | 372 std::map<RequestParams, CertVerifierJob*>::const_iterator j; |
| 368 j = inflight_.find(key); | 373 j = inflight_.find(key); |
| 369 if (j != inflight_.end()) { | 374 if (j != inflight_.end()) { |
| 370 // An identical request is in flight already. We'll just attach our | 375 // An identical request is in flight already. We'll just attach our |
| 371 // callback. | 376 // callback. |
| 372 inflight_joins_++; | 377 inflight_joins_++; |
| 373 job = j->second; | 378 job = j->second; |
| 374 } else { | 379 } else { |
| 375 // Need to make a new request. | 380 // Need to make a new request. |
| 376 CertVerifierWorker* worker = new CertVerifierWorker(cert, hostname, flags, | 381 CertVerifierWorker* worker = new CertVerifierWorker( |
| 377 crl_set, this); | 382 verifier_, cert, hostname, flags, crl_set, this); |
| 378 job = new CertVerifierJob( | 383 job = new CertVerifierJob( |
| 379 worker, | 384 worker, |
| 380 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); | 385 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); |
| 381 if (!worker->Start()) { | 386 if (!worker->Start()) { |
| 382 delete job; | 387 delete job; |
| 383 delete worker; | 388 delete worker; |
| 384 *out_req = NULL; | 389 *out_req = NULL; |
| 385 // TODO(wtc): log to the NetLog. | 390 // TODO(wtc): log to the NetLog. |
| 386 LOG(ERROR) << "CertVerifierWorker couldn't be started."; | 391 LOG(ERROR) << "CertVerifierWorker couldn't be started."; |
| 387 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. | 392 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 } | 440 } |
| 436 | 441 |
| 437 void MultiThreadedCertVerifier::OnCertTrustChanged( | 442 void MultiThreadedCertVerifier::OnCertTrustChanged( |
| 438 const X509Certificate* cert) { | 443 const X509Certificate* cert) { |
| 439 DCHECK(CalledOnValidThread()); | 444 DCHECK(CalledOnValidThread()); |
| 440 | 445 |
| 441 ClearCache(); | 446 ClearCache(); |
| 442 } | 447 } |
| 443 | 448 |
| 444 } // namespace net | 449 } // namespace net |
| OLD | NEW |