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