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

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

Issue 9476035: Make CertVerifier a pure virtual interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Win shared fix Created 8 years, 9 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) 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/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"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 #include "base/time.h" 14 #include "base/time.h"
15 #include "base/threading/worker_pool.h" 15 #include "base/threading/worker_pool.h"
16 #include "net/base/crl_set.h" 16 #include "net/base/crl_set.h"
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 #include "net/base/net_log.h" 18 #include "net/base/net_log.h"
19 #include "net/base/x509_certificate.h" 19 #include "net/base/x509_certificate.h"
20 #include "net/base/x509_certificate_net_log_param.h" 20 #include "net/base/x509_certificate_net_log_param.h"
21 21
22 #if defined(USE_NSS) 22 #if defined(USE_NSS)
23 #include <private/pprthred.h> // PR_DetachThread 23 #include <private/pprthred.h> // PR_DetachThread
24 #endif 24 #endif
25 25
26 namespace net { 26 namespace net {
27 27
28 //////////////////////////////////////////////////////////////////////////// 28 ////////////////////////////////////////////////////////////////////////////
29 29
30 // Life of a request: 30 // Life of a request:
31 // 31 //
32 // CertVerifier CertVerifierJob CertVerifierWorker Request 32 // MultiThreadedCertVerifier CertVerifierJob CertVerifierWorker Request
33 // | (origin loop) (worker loop) 33 // | (origin loop) (worker loop)
34 // | 34 // |
35 // Verify() 35 // Verify()
36 // |---->-------------------------------------<creates>
37 // |
36 // |---->-------------------<creates> 38 // |---->-------------------<creates>
37 // | 39 // |
38 // |---->----<creates> 40 // |---->-------------------------------------------------------<creates>
39 // | 41 // |
40 // |---->---------------------------------------------------<creates> 42 // |---->---------------------------------------Start
43 // | |
44 // | PostTask
41 // | 45 // |
42 // |---->--------------------Start 46 // | <starts verifying>
43 // | | 47 // |---->-------------------AddRequest |
44 // | PostTask 48 // |
45 // | 49 // |
46 // | <starts verifying> 50 // |
47 // |---->-----AddRequest | 51 // Finish
48 // | 52 // |
49 // | 53 // PostTask
50 // |
51 // Finish
52 // |
53 // PostTask
54 // 54 //
55 // | 55 // |
56 // DoReply 56 // DoReply
57 // |----<-----------------------| 57 // |----<-----------------------------------------|
58 // HandleResult 58 // HandleResult
59 // | 59 // |
60 // |---->-----HandleResult 60 // |---->------------------HandleResult
61 // | 61 // |
62 // |------>-----------------------------------Post 62 // |------>---------------------------Post
63 // 63 //
64 // 64 //
65 // 65 //
66 // On a cache hit, CertVerifier::Verify() returns synchronously without 66 // On a cache hit, MultiThreadedCertVerifier::Verify() returns synchronously
67 // posting a task to a worker thread. 67 // without posting a task to a worker thread.
68 68
69 namespace { 69 namespace {
70 70
71 // The default value of max_cache_entries_. 71 // The default value of max_cache_entries_.
72 const unsigned kMaxCacheEntries = 256; 72 const unsigned kMaxCacheEntries = 256;
73 73
74 // The number of seconds for which we'll cache a cache entry. 74 // The number of seconds for which we'll cache a cache entry.
75 const unsigned kTTLSecs = 1800; // 30 minutes. 75 const unsigned kTTLSecs = 1800; // 30 minutes.
76 76
77 } // namespace 77 } // namespace
78 78
79 CertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} 79 MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {}
80 80
81 CertVerifier::CachedResult::~CachedResult() {} 81 MultiThreadedCertVerifier::CachedResult::~CachedResult() {}
82 82
83 // Represents the output and result callback of a request. 83 // Represents the output and result callback of a request.
84 class CertVerifierRequest { 84 class CertVerifierRequest {
85 public: 85 public:
86 CertVerifierRequest(const CompletionCallback& callback, 86 CertVerifierRequest(const CompletionCallback& callback,
87 CertVerifyResult* verify_result, 87 CertVerifyResult* verify_result,
88 const BoundNetLog& net_log) 88 const BoundNetLog& net_log)
89 : callback_(callback), 89 : callback_(callback),
90 verify_result_(verify_result), 90 verify_result_(verify_result),
91 net_log_(net_log) { 91 net_log_(net_log) {
92 net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST, NULL); 92 net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST, NULL);
93 } 93 }
94 94
95 ~CertVerifierRequest() { 95 ~CertVerifierRequest() {
96 } 96 }
97 97
98 // Ensures that the result callback will never be made. 98 // Ensures that the result callback will never be made.
99 void Cancel() { 99 void Cancel() {
100 callback_.Reset(); 100 callback_.Reset();
101 verify_result_ = NULL; 101 verify_result_ = NULL;
102 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); 102 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL);
103 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST, NULL); 103 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST, NULL);
104 } 104 }
105 105
106 // Copies the contents of |verify_result| to the caller's 106 // Copies the contents of |verify_result| to the caller's
107 // CertVerifyResult and calls the callback. 107 // CertVerifyResult and calls the callback.
108 void Post(const CertVerifier::CachedResult& verify_result) { 108 void Post(const MultiThreadedCertVerifier::CachedResult& verify_result) {
109 if (!callback_.is_null()) { 109 if (!callback_.is_null()) {
110 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST, NULL); 110 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST, NULL);
111 *verify_result_ = verify_result.result; 111 *verify_result_ = verify_result.result;
112 callback_.Run(verify_result.error); 112 callback_.Run(verify_result.error);
113 } 113 }
114 delete this; 114 delete this;
115 } 115 }
116 116
117 bool canceled() const { return callback_.is_null(); } 117 bool canceled() const { return callback_.is_null(); }
118 118
119 const BoundNetLog& net_log() const { return net_log_; } 119 const BoundNetLog& net_log() const { return net_log_; }
120 120
121 private: 121 private:
122 CompletionCallback callback_; 122 CompletionCallback callback_;
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(X509Certificate* cert,
134 const std::string& hostname, 134 const std::string& hostname,
135 int flags, 135 int flags,
136 CRLSet* crl_set, 136 CRLSet* crl_set,
137 CertVerifier* cert_verifier) 137 MultiThreadedCertVerifier* cert_verifier)
138 : cert_(cert), 138 : cert_(cert),
139 hostname_(hostname), 139 hostname_(hostname),
140 flags_(flags), 140 flags_(flags),
141 crl_set_(crl_set), 141 crl_set_(crl_set),
142 origin_loop_(MessageLoop::current()), 142 origin_loop_(MessageLoop::current()),
143 cert_verifier_(cert_verifier), 143 cert_verifier_(cert_verifier),
144 canceled_(false), 144 canceled_(false),
145 error_(ERR_FAILED) { 145 error_(ERR_FAILED) {
146 } 146 }
147 147
148 // Returns the certificate being verified. May only be called /before/ 148 // Returns the certificate being verified. May only be called /before/
149 // Start() is called. 149 // Start() is called.
150 X509Certificate* certificate() const { return cert_; } 150 X509Certificate* certificate() const { return cert_; }
151 151
152 bool Start() { 152 bool Start() {
153 DCHECK_EQ(MessageLoop::current(), origin_loop_); 153 DCHECK_EQ(MessageLoop::current(), origin_loop_);
154 154
155 return base::WorkerPool::PostTask( 155 return base::WorkerPool::PostTask(
156 FROM_HERE, base::Bind(&CertVerifierWorker::Run, base::Unretained(this)), 156 FROM_HERE, base::Bind(&CertVerifierWorker::Run, base::Unretained(this)),
157 true /* task is slow */); 157 true /* task is slow */);
158 } 158 }
159 159
160 // Cancel is called from the origin loop when the CertVerifier is getting 160 // Cancel is called from the origin loop when the MultiThreadedCertVerifier is
161 // deleted. 161 // getting deleted.
162 void Cancel() { 162 void Cancel() {
163 DCHECK_EQ(MessageLoop::current(), origin_loop_); 163 DCHECK_EQ(MessageLoop::current(), origin_loop_);
164 base::AutoLock locked(lock_); 164 base::AutoLock locked(lock_);
165 canceled_ = true; 165 canceled_ = true;
166 } 166 }
167 167
168 private: 168 private:
169 void Run() { 169 void Run() {
170 // Runs on a worker thread. 170 // Runs on a worker thread.
171 error_ = cert_->Verify(hostname_, flags_, crl_set_, &verify_result_); 171 error_ = cert_->Verify(hostname_, flags_, crl_set_, &verify_result_);
(...skipping 22 matching lines...) Expand all
194 if (!canceled_) { 194 if (!canceled_) {
195 cert_verifier_->HandleResult(cert_, hostname_, flags_, 195 cert_verifier_->HandleResult(cert_, hostname_, flags_,
196 error_, verify_result_); 196 error_, verify_result_);
197 } 197 }
198 } 198 }
199 delete this; 199 delete this;
200 } 200 }
201 201
202 void Finish() { 202 void Finish() {
203 // Runs on the worker thread. 203 // Runs on the worker thread.
204 // We assume that the origin loop outlives the CertVerifier. If the 204 // We assume that the origin loop outlives the MultiThreadedCertVerifier. If
205 // CertVerifier is deleted, it will call Cancel on us. If it does so 205 // the MultiThreadedCertVerifier is deleted, it will call Cancel on us. If
206 // before the Acquire, we'll delete ourselves and return. If it's trying to 206 // it does so before the Acquire, we'll delete ourselves and return. If it's
207 // do so concurrently, then it'll block on the lock and we'll call PostTask 207 // trying to do so concurrently, then it'll block on the lock and we'll call
208 // while the CertVerifier (and therefore the MessageLoop) is still alive. 208 // PostTask while the MultiThreadedCertVerifier (and therefore the
209 // MessageLoop) is still alive.
209 // If it does so after this function, we assume that the MessageLoop will 210 // If it does so after this function, we assume that the MessageLoop will
210 // process pending tasks. In which case we'll notice the |canceled_| flag 211 // process pending tasks. In which case we'll notice the |canceled_| flag
211 // in DoReply. 212 // in DoReply.
212 213
213 bool canceled; 214 bool canceled;
214 { 215 {
215 base::AutoLock locked(lock_); 216 base::AutoLock locked(lock_);
216 canceled = canceled_; 217 canceled = canceled_;
217 if (!canceled) { 218 if (!canceled) {
218 origin_loop_->PostTask( 219 origin_loop_->PostTask(
219 FROM_HERE, base::Bind( 220 FROM_HERE, base::Bind(
220 &CertVerifierWorker::DoReply, base::Unretained(this))); 221 &CertVerifierWorker::DoReply, base::Unretained(this)));
221 } 222 }
222 } 223 }
223 224
224 if (canceled) 225 if (canceled)
225 delete this; 226 delete this;
226 } 227 }
227 228
228 scoped_refptr<X509Certificate> cert_; 229 scoped_refptr<X509Certificate> cert_;
229 const std::string hostname_; 230 const std::string hostname_;
230 const int flags_; 231 const int flags_;
231 scoped_refptr<CRLSet> crl_set_; 232 scoped_refptr<CRLSet> crl_set_;
232 MessageLoop* const origin_loop_; 233 MessageLoop* const origin_loop_;
233 CertVerifier* const cert_verifier_; 234 MultiThreadedCertVerifier* const cert_verifier_;
234 235
235 // lock_ protects canceled_. 236 // lock_ protects canceled_.
236 base::Lock lock_; 237 base::Lock lock_;
237 238
238 // If canceled_ is true, 239 // If canceled_ is true,
239 // * origin_loop_ cannot be accessed by the worker thread, 240 // * origin_loop_ cannot be accessed by the worker thread,
240 // * cert_verifier_ cannot be accessed by any thread. 241 // * cert_verifier_ cannot be accessed by any thread.
241 bool canceled_; 242 bool canceled_;
242 243
243 int error_; 244 int error_;
(...skipping 27 matching lines...) Expand all
271 272
272 void AddRequest(CertVerifierRequest* request) { 273 void AddRequest(CertVerifierRequest* request) {
273 request->net_log().AddEvent( 274 request->net_log().AddEvent(
274 NetLog::TYPE_CERT_VERIFIER_REQUEST_BOUND_TO_JOB, 275 NetLog::TYPE_CERT_VERIFIER_REQUEST_BOUND_TO_JOB,
275 make_scoped_refptr(new NetLogSourceParameter( 276 make_scoped_refptr(new NetLogSourceParameter(
276 "source_dependency", net_log_.source()))); 277 "source_dependency", net_log_.source())));
277 278
278 requests_.push_back(request); 279 requests_.push_back(request);
279 } 280 }
280 281
281 void HandleResult(const CertVerifier::CachedResult& verify_result) { 282 void HandleResult(
283 const MultiThreadedCertVerifier::CachedResult& verify_result) {
282 worker_ = NULL; 284 worker_ = NULL;
283 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB, NULL); 285 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB, NULL);
284 UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency", 286 UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency",
285 base::TimeTicks::Now() - start_time_, 287 base::TimeTicks::Now() - start_time_,
286 base::TimeDelta::FromMilliseconds(1), 288 base::TimeDelta::FromMilliseconds(1),
287 base::TimeDelta::FromMinutes(10), 289 base::TimeDelta::FromMinutes(10),
288 100); 290 100);
289 PostAll(verify_result); 291 PostAll(verify_result);
290 } 292 }
291 293
292 private: 294 private:
293 void PostAll(const CertVerifier::CachedResult& verify_result) { 295 void PostAll(const MultiThreadedCertVerifier::CachedResult& verify_result) {
294 std::vector<CertVerifierRequest*> requests; 296 std::vector<CertVerifierRequest*> requests;
295 requests_.swap(requests); 297 requests_.swap(requests);
296 298
297 for (std::vector<CertVerifierRequest*>::iterator 299 for (std::vector<CertVerifierRequest*>::iterator
298 i = requests.begin(); i != requests.end(); i++) { 300 i = requests.begin(); i != requests.end(); i++) {
299 (*i)->Post(verify_result); 301 (*i)->Post(verify_result);
300 // Post() causes the CertVerifierRequest to delete itself. 302 // Post() causes the CertVerifierRequest to delete itself.
301 } 303 }
302 } 304 }
303 305
304 void DeleteAllCanceled() { 306 void DeleteAllCanceled() {
305 for (std::vector<CertVerifierRequest*>::iterator 307 for (std::vector<CertVerifierRequest*>::iterator
306 i = requests_.begin(); i != requests_.end(); i++) { 308 i = requests_.begin(); i != requests_.end(); i++) {
307 if ((*i)->canceled()) { 309 if ((*i)->canceled()) {
308 delete *i; 310 delete *i;
309 } else { 311 } else {
310 LOG(DFATAL) << "CertVerifierRequest leaked!"; 312 LOG(DFATAL) << "CertVerifierRequest leaked!";
311 } 313 }
312 } 314 }
313 } 315 }
314 316
315 const base::TimeTicks start_time_; 317 const base::TimeTicks start_time_;
316 std::vector<CertVerifierRequest*> requests_; 318 std::vector<CertVerifierRequest*> requests_;
317 CertVerifierWorker* worker_; 319 CertVerifierWorker* worker_;
318 const BoundNetLog net_log_; 320 const BoundNetLog net_log_;
319 }; 321 };
320 322
321 CertVerifier::CertVerifier() 323 MultiThreadedCertVerifier::MultiThreadedCertVerifier()
322 : cache_(kMaxCacheEntries), 324 : cache_(kMaxCacheEntries),
323 requests_(0), 325 requests_(0),
324 cache_hits_(0), 326 cache_hits_(0),
325 inflight_joins_(0) { 327 inflight_joins_(0) {
326 CertDatabase::AddObserver(this); 328 CertDatabase::AddObserver(this);
327 } 329 }
328 330
329 CertVerifier::~CertVerifier() { 331 MultiThreadedCertVerifier::~MultiThreadedCertVerifier() {
330 STLDeleteValues(&inflight_); 332 STLDeleteValues(&inflight_);
331 333
332 CertDatabase::RemoveObserver(this); 334 CertDatabase::RemoveObserver(this);
333 } 335 }
334 336
335 int CertVerifier::Verify(X509Certificate* cert, 337 int MultiThreadedCertVerifier::Verify(X509Certificate* cert,
336 const std::string& hostname, 338 const std::string& hostname,
337 int flags, 339 int flags,
338 CRLSet* crl_set, 340 CRLSet* crl_set,
339 CertVerifyResult* verify_result, 341 CertVerifyResult* verify_result,
340 const CompletionCallback& callback, 342 const CompletionCallback& callback,
341 RequestHandle* out_req, 343 RequestHandle* out_req,
342 const BoundNetLog& net_log) { 344 const BoundNetLog& net_log) {
343 DCHECK(CalledOnValidThread()); 345 DCHECK(CalledOnValidThread());
344 346
345 if (callback.is_null() || !verify_result || hostname.empty()) { 347 if (callback.is_null() || !verify_result || hostname.empty()) {
346 *out_req = NULL; 348 *out_req = NULL;
347 return ERR_INVALID_ARGUMENT; 349 return ERR_INVALID_ARGUMENT;
348 } 350 }
349 351
350 requests_++; 352 requests_++;
351 353
352 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), 354 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 inflight_.insert(std::make_pair(key, job)); 389 inflight_.insert(std::make_pair(key, job));
388 } 390 }
389 391
390 CertVerifierRequest* request = 392 CertVerifierRequest* request =
391 new CertVerifierRequest(callback, verify_result, net_log); 393 new CertVerifierRequest(callback, verify_result, net_log);
392 job->AddRequest(request); 394 job->AddRequest(request);
393 *out_req = request; 395 *out_req = request;
394 return ERR_IO_PENDING; 396 return ERR_IO_PENDING;
395 } 397 }
396 398
397 void CertVerifier::CancelRequest(RequestHandle req) { 399 void MultiThreadedCertVerifier::CancelRequest(RequestHandle req) {
398 DCHECK(CalledOnValidThread()); 400 DCHECK(CalledOnValidThread());
399 CertVerifierRequest* request = reinterpret_cast<CertVerifierRequest*>(req); 401 CertVerifierRequest* request = reinterpret_cast<CertVerifierRequest*>(req);
400 request->Cancel(); 402 request->Cancel();
401 } 403 }
402 404
403 // HandleResult is called by CertVerifierWorker on the origin message loop. 405 // HandleResult is called by CertVerifierWorker on the origin message loop.
404 // It deletes CertVerifierJob. 406 // It deletes CertVerifierJob.
405 void CertVerifier::HandleResult(X509Certificate* cert, 407 void MultiThreadedCertVerifier::HandleResult(
406 const std::string& hostname, 408 X509Certificate* cert,
407 int flags, 409 const std::string& hostname,
408 int error, 410 int flags,
409 const CertVerifyResult& verify_result) { 411 int error,
412 const CertVerifyResult& verify_result) {
410 DCHECK(CalledOnValidThread()); 413 DCHECK(CalledOnValidThread());
411 414
412 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), 415 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(),
413 hostname, flags); 416 hostname, flags);
414 417
415 CachedResult cached_result; 418 CachedResult cached_result;
416 cached_result.error = error; 419 cached_result.error = error;
417 cached_result.result = verify_result; 420 cached_result.result = verify_result;
418 cache_.Put(key, cached_result, base::TimeTicks::Now(), 421 cache_.Put(key, cached_result, base::TimeTicks::Now(),
419 base::TimeDelta::FromSeconds(kTTLSecs)); 422 base::TimeDelta::FromSeconds(kTTLSecs));
420 423
421 std::map<RequestParams, CertVerifierJob*>::iterator j; 424 std::map<RequestParams, CertVerifierJob*>::iterator j;
422 j = inflight_.find(key); 425 j = inflight_.find(key);
423 if (j == inflight_.end()) { 426 if (j == inflight_.end()) {
424 NOTREACHED(); 427 NOTREACHED();
425 return; 428 return;
426 } 429 }
427 CertVerifierJob* job = j->second; 430 CertVerifierJob* job = j->second;
428 inflight_.erase(j); 431 inflight_.erase(j);
429 432
430 job->HandleResult(cached_result); 433 job->HandleResult(cached_result);
431 delete job; 434 delete job;
432 } 435 }
433 436
434 void CertVerifier::OnCertTrustChanged(const X509Certificate* cert) { 437 void MultiThreadedCertVerifier::OnCertTrustChanged(
438 const X509Certificate* cert) {
435 DCHECK(CalledOnValidThread()); 439 DCHECK(CalledOnValidThread());
436 440
437 ClearCache(); 441 ClearCache();
438 } 442 }
439 443
440 /////////////////////////////////////////////////////////////////////
441
442 SingleRequestCertVerifier::SingleRequestCertVerifier(
443 CertVerifier* cert_verifier)
444 : cert_verifier_(cert_verifier),
445 cur_request_(NULL) {
446 DCHECK(cert_verifier_ != NULL);
447 }
448
449 SingleRequestCertVerifier::~SingleRequestCertVerifier() {
450 if (cur_request_) {
451 cert_verifier_->CancelRequest(cur_request_);
452 cur_request_ = NULL;
453 }
454 }
455
456 int SingleRequestCertVerifier::Verify(X509Certificate* cert,
457 const std::string& hostname,
458 int flags,
459 CRLSet* crl_set,
460 CertVerifyResult* verify_result,
461 const CompletionCallback& callback,
462 const BoundNetLog& net_log) {
463 // Should not be already in use.
464 DCHECK(!cur_request_ && cur_request_callback_.is_null());
465
466 // Do a synchronous verification.
467 if (callback.is_null())
468 return cert->Verify(hostname, flags, crl_set, verify_result);
469
470 CertVerifier::RequestHandle request = NULL;
471
472 // We need to be notified of completion before |callback| is called, so that
473 // we can clear out |cur_request_*|.
474 int rv = cert_verifier_->Verify(
475 cert, hostname, flags, crl_set, verify_result,
476 base::Bind(&SingleRequestCertVerifier::OnVerifyCompletion,
477 base::Unretained(this)),
478 &request, net_log);
479
480 if (rv == ERR_IO_PENDING) {
481 // Cleared in OnVerifyCompletion().
482 cur_request_ = request;
483 cur_request_callback_ = callback;
484 }
485
486 return rv;
487 }
488
489 void SingleRequestCertVerifier::OnVerifyCompletion(int result) {
490 DCHECK(cur_request_ && !cur_request_callback_.is_null());
491
492 CompletionCallback callback = cur_request_callback_;
493
494 // Clear the outstanding request information.
495 cur_request_ = NULL;
496 cur_request_callback_.Reset();
497
498 // Call the user's original callback.
499 callback.Run(result);
500 }
501
502 } // namespace net 444 } // namespace net
OLDNEW
« no previous file with comments | « net/base/multi_threaded_cert_verifier.h ('k') | net/base/multi_threaded_cert_verifier_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698