Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: net/base/cert_verifier.cc

Issue 8342054: net: enable CRL sets behind a command line flag. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/cert_verifier.h" 5 #include "net/base/cert_verifier.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/synchronization/lock.h" 12 #include "base/synchronization/lock.h"
13 #include "base/time.h" 13 #include "base/time.h"
14 #include "base/threading/worker_pool.h" 14 #include "base/threading/worker_pool.h"
15 #include "net/base/crl_set.h"
15 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
16 #include "net/base/net_log.h" 17 #include "net/base/net_log.h"
17 #include "net/base/x509_certificate.h" 18 #include "net/base/x509_certificate.h"
18 19
19 #if defined(USE_NSS) 20 #if defined(USE_NSS)
20 #include <private/pprthred.h> // PR_DetachThread 21 #include <private/pprthred.h> // PR_DetachThread
21 #endif 22 #endif
22 23
23 namespace net { 24 namespace net {
24 25
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 135
135 136
136 // CertVerifierWorker runs on a worker thread and takes care of the blocking 137 // CertVerifierWorker runs on a worker thread and takes care of the blocking
137 // process of performing the certificate verification. Deletes itself 138 // process of performing the certificate verification. Deletes itself
138 // eventually if Start() succeeds. 139 // eventually if Start() succeeds.
139 class CertVerifierWorker { 140 class CertVerifierWorker {
140 public: 141 public:
141 CertVerifierWorker(X509Certificate* cert, 142 CertVerifierWorker(X509Certificate* cert,
142 const std::string& hostname, 143 const std::string& hostname,
143 int flags, 144 int flags,
145 CRLSet* crl_set,
144 CertVerifier* cert_verifier) 146 CertVerifier* cert_verifier)
145 : cert_(cert), 147 : cert_(cert),
146 hostname_(hostname), 148 hostname_(hostname),
147 flags_(flags), 149 flags_(flags),
150 crl_set_(crl_set),
148 origin_loop_(MessageLoop::current()), 151 origin_loop_(MessageLoop::current()),
149 cert_verifier_(cert_verifier), 152 cert_verifier_(cert_verifier),
150 canceled_(false), 153 canceled_(false),
151 error_(ERR_FAILED) { 154 error_(ERR_FAILED) {
152 } 155 }
153 156
154 bool Start() { 157 bool Start() {
155 DCHECK_EQ(MessageLoop::current(), origin_loop_); 158 DCHECK_EQ(MessageLoop::current(), origin_loop_);
156 159
157 return base::WorkerPool::PostTask( 160 return base::WorkerPool::PostTask(
158 FROM_HERE, NewRunnableMethod(this, &CertVerifierWorker::Run), 161 FROM_HERE, NewRunnableMethod(this, &CertVerifierWorker::Run),
159 true /* task is slow */); 162 true /* task is slow */);
160 } 163 }
161 164
162 // Cancel is called from the origin loop when the CertVerifier is getting 165 // Cancel is called from the origin loop when the CertVerifier is getting
163 // deleted. 166 // deleted.
164 void Cancel() { 167 void Cancel() {
165 DCHECK_EQ(MessageLoop::current(), origin_loop_); 168 DCHECK_EQ(MessageLoop::current(), origin_loop_);
166 base::AutoLock locked(lock_); 169 base::AutoLock locked(lock_);
167 canceled_ = true; 170 canceled_ = true;
168 } 171 }
169 172
170 private: 173 private:
171 void Run() { 174 void Run() {
172 // Runs on a worker thread. 175 // Runs on a worker thread.
173 error_ = cert_->Verify(hostname_, flags_, &verify_result_); 176 error_ = cert_->Verify(hostname_, flags_, &verify_result_,
177 crl_set_.get());
wtc 2011/10/21 23:17:31 Nit: omit .get().
agl 2011/10/24 20:44:27 Done.
174 #if defined(USE_NSS) 178 #if defined(USE_NSS)
175 // Detach the thread from NSPR. 179 // Detach the thread from NSPR.
176 // Calling NSS functions attaches the thread to NSPR, which stores 180 // Calling NSS functions attaches the thread to NSPR, which stores
177 // the NSPR thread ID in thread-specific data. 181 // the NSPR thread ID in thread-specific data.
178 // The threads in our thread pool terminate after we have called 182 // The threads in our thread pool terminate after we have called
179 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets 183 // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets
180 // segfaults on shutdown when the threads' thread-specific data 184 // segfaults on shutdown when the threads' thread-specific data
181 // destructors run. 185 // destructors run.
182 PR_DetachThread(); 186 PR_DetachThread();
183 #endif 187 #endif
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 } 226 }
223 } 227 }
224 228
225 if (canceled) 229 if (canceled)
226 delete this; 230 delete this;
227 } 231 }
228 232
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_;
236 scoped_refptr<CRLSet> crl_set_;
232 MessageLoop* const origin_loop_; 237 MessageLoop* const origin_loop_;
233 CertVerifier* const cert_verifier_; 238 CertVerifier* const cert_verifier_;
234 239
235 // lock_ protects canceled_. 240 // lock_ protects canceled_.
236 base::Lock lock_; 241 base::Lock lock_;
237 242
238 // If canceled_ is true, 243 // If canceled_ is true,
239 // * origin_loop_ cannot be accessed by the worker thread, 244 // * origin_loop_ cannot be accessed by the worker thread,
240 // * cert_verifier_ cannot be accessed by any thread. 245 // * cert_verifier_ cannot be accessed by any thread.
241 bool canceled_; 246 bool canceled_;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 342
338 CertVerifier::~CertVerifier() { 343 CertVerifier::~CertVerifier() {
339 STLDeleteValues(&inflight_); 344 STLDeleteValues(&inflight_);
340 345
341 CertDatabase::RemoveObserver(this); 346 CertDatabase::RemoveObserver(this);
342 } 347 }
343 348
344 int CertVerifier::Verify(X509Certificate* cert, 349 int CertVerifier::Verify(X509Certificate* cert,
345 const std::string& hostname, 350 const std::string& hostname,
346 int flags, 351 int flags,
352 CRLSet* crl_set,
347 CertVerifyResult* verify_result, 353 CertVerifyResult* verify_result,
348 const CompletionCallback& callback, 354 const CompletionCallback& callback,
349 RequestHandle* out_req, 355 RequestHandle* out_req,
350 const BoundNetLog& net_log) { 356 const BoundNetLog& net_log) {
351 DCHECK(CalledOnValidThread()); 357 DCHECK(CalledOnValidThread());
352 358
353 if (callback.is_null() || !verify_result || hostname.empty()) { 359 if (callback.is_null() || !verify_result || hostname.empty()) {
354 *out_req = NULL; 360 *out_req = NULL;
355 return ERR_INVALID_ARGUMENT; 361 return ERR_INVALID_ARGUMENT;
356 } 362 }
(...skipping 20 matching lines...) Expand all
377 std::map<RequestParams, CertVerifierJob*>::const_iterator j; 383 std::map<RequestParams, CertVerifierJob*>::const_iterator j;
378 j = inflight_.find(key); 384 j = inflight_.find(key);
379 if (j != inflight_.end()) { 385 if (j != inflight_.end()) {
380 // An identical request is in flight already. We'll just attach our 386 // An identical request is in flight already. We'll just attach our
381 // callback. 387 // callback.
382 inflight_joins_++; 388 inflight_joins_++;
383 job = j->second; 389 job = j->second;
384 } else { 390 } else {
385 // Need to make a new request. 391 // Need to make a new request.
386 CertVerifierWorker* worker = new CertVerifierWorker(cert, hostname, flags, 392 CertVerifierWorker* worker = new CertVerifierWorker(cert, hostname, flags,
387 this); 393 crl_set, this);
388 job = new CertVerifierJob( 394 job = new CertVerifierJob(
389 worker, 395 worker,
390 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB)); 396 BoundNetLog::Make(net_log.net_log(), NetLog::SOURCE_CERT_VERIFIER_JOB));
391 if (!worker->Start()) { 397 if (!worker->Start()) {
392 delete job; 398 delete job;
393 delete worker; 399 delete worker;
394 *out_req = NULL; 400 *out_req = NULL;
395 // TODO(wtc): log to the NetLog. 401 // TODO(wtc): log to the NetLog.
396 LOG(ERROR) << "CertVerifierWorker couldn't be started."; 402 LOG(ERROR) << "CertVerifierWorker couldn't be started.";
397 return ERR_INSUFFICIENT_RESOURCES; // Just a guess. 403 return ERR_INSUFFICIENT_RESOURCES; // Just a guess.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 SingleRequestCertVerifier::~SingleRequestCertVerifier() { 500 SingleRequestCertVerifier::~SingleRequestCertVerifier() {
495 if (cur_request_) { 501 if (cur_request_) {
496 cert_verifier_->CancelRequest(cur_request_); 502 cert_verifier_->CancelRequest(cur_request_);
497 cur_request_ = NULL; 503 cur_request_ = NULL;
498 } 504 }
499 } 505 }
500 506
501 int SingleRequestCertVerifier::Verify(X509Certificate* cert, 507 int SingleRequestCertVerifier::Verify(X509Certificate* cert,
502 const std::string& hostname, 508 const std::string& hostname,
503 int flags, 509 int flags,
510 CRLSet* crl_set,
504 CertVerifyResult* verify_result, 511 CertVerifyResult* verify_result,
505 const CompletionCallback& callback, 512 const CompletionCallback& callback,
506 const BoundNetLog& net_log) { 513 const BoundNetLog& net_log) {
507 // Should not be already in use. 514 // Should not be already in use.
508 DCHECK(!cur_request_ && cur_request_callback_.is_null()); 515 DCHECK(!cur_request_ && cur_request_callback_.is_null());
509 516
510 // Do a synchronous verification. 517 // Do a synchronous verification.
511 if (callback.is_null()) 518 if (callback.is_null())
512 return cert->Verify(hostname, flags, verify_result); 519 return cert->Verify(hostname, flags, verify_result, crl_set);
513 520
514 CertVerifier::RequestHandle request = NULL; 521 CertVerifier::RequestHandle request = NULL;
515 522
516 // We need to be notified of completion before |callback| is called, so that 523 // We need to be notified of completion before |callback| is called, so that
517 // we can clear out |cur_request_*|. 524 // we can clear out |cur_request_*|.
518 int rv = cert_verifier_->Verify( 525 int rv = cert_verifier_->Verify(
519 cert, hostname, flags, verify_result, 526 cert, hostname, flags, crl_set, verify_result,
520 base::Bind(&SingleRequestCertVerifier::OnVerifyCompletion, 527 base::Bind(&SingleRequestCertVerifier::OnVerifyCompletion,
521 base::Unretained(this)), 528 base::Unretained(this)),
522 &request, net_log); 529 &request, net_log);
523 530
524 if (rv == ERR_IO_PENDING) { 531 if (rv == ERR_IO_PENDING) {
525 // Cleared in OnVerifyCompletion(). 532 // Cleared in OnVerifyCompletion().
526 cur_request_ = request; 533 cur_request_ = request;
527 cur_request_callback_ = callback; 534 cur_request_callback_ = callback;
528 } 535 }
529 536
530 return rv; 537 return rv;
531 } 538 }
532 539
533 void SingleRequestCertVerifier::OnVerifyCompletion(int result) { 540 void SingleRequestCertVerifier::OnVerifyCompletion(int result) {
534 DCHECK(cur_request_ && !cur_request_callback_.is_null()); 541 DCHECK(cur_request_ && !cur_request_callback_.is_null());
535 542
536 CompletionCallback callback = cur_request_callback_; 543 CompletionCallback callback = cur_request_callback_;
537 544
538 // Clear the outstanding request information. 545 // Clear the outstanding request information.
539 cur_request_ = NULL; 546 cur_request_ = NULL;
540 cur_request_callback_.Reset(); 547 cur_request_callback_.Reset();
541 548
542 // Call the user's original callback. 549 // Call the user's original callback.
543 callback.Run(result); 550 callback.Run(result);
544 } 551 }
545 552
546 } // namespace net 553 } // namespace net
547 554
548 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::CertVerifierWorker); 555 DISABLE_RUNNABLE_METHOD_REFCOUNT(net::CertVerifierWorker);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698