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

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

Issue 10556022: Consider the verification time as well as the expiration time when caching certificate verification… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Now with less const Created 8 years, 6 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
« no previous file with comments | « net/base/multi_threaded_cert_verifier.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/multi_threaded_cert_verifier.h" 5 #include "net/base/multi_threaded_cert_verifier.h"
6 6
7 #include <vector> 7 #include <vector>
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 // The number of seconds for which we'll cache a cache entry. 77 // The number of seconds for which we'll cache a cache entry.
78 const unsigned kTTLSecs = 1800; // 30 minutes. 78 const unsigned kTTLSecs = 1800; // 30 minutes.
79 79
80 } // namespace 80 } // namespace
81 81
82 MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} 82 MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {}
83 83
84 MultiThreadedCertVerifier::CachedResult::~CachedResult() {} 84 MultiThreadedCertVerifier::CachedResult::~CachedResult() {}
85 85
86 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod(
87 const base::Time& now)
88 : verification_time(now),
89 expiration_time(now) {
90 }
91
92 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod(
93 const base::Time& now,
94 const base::Time& expiration)
95 : verification_time(now),
96 expiration_time(expiration) {
97 }
98
99 bool MultiThreadedCertVerifier::CacheExpirationFunctor::operator()(
100 const CacheValidityPeriod& now,
101 const CacheValidityPeriod& expiration) const {
102 // Ensure this functor is being used for expiration only, and not strict
103 // weak ordering/sorting. |now| should only ever contain a single
104 // base::Time.
105 // Note: DCHECK_EQ is not used due to operator<< overloading requirements.
106 DCHECK(now.verification_time == now.expiration_time);
107
108 // |now| contains only a single time (verification_time), while |expiration|
109 // contains the validity range - both when the certificate was verified and
110 // when the verification result should expire.
111 //
112 // If the user receives a "not yet valid" message, and adjusts their clock
113 // foward to the correct time, this will (typically) cause
114 // now.verification_time to advance past expiration.expiration_time, thus
115 // treating the cached result as an expired entry and re-verifying.
116 // If the user receives a "expired" message, and adjusts their clock
117 // backwards to the correct time, this will cause now.verification_time to
118 // be less than expiration_verification_time, thus treating the cached
119 // result as an expired entry and re-verifying.
120 // If the user receives either of those messages, and does not adjust their
121 // clock, then the result will be (typically) be cached until the expiration
122 // TTL.
123 //
124 // This algorithm is only problematic if the user consistently keeps
125 // adjusting their clock backwards in increments smaller than the expiration
126 // TTL, in which case, cached elements continue to be added. However,
127 // because the cache has a fixed upper bound, if no entries are expired, a
128 // 'random' entry will be, thus keeping the memory constraints bounded over
129 // time.
130 return now.verification_time >= expiration.verification_time &&
131 now.verification_time < expiration.expiration_time;
132 };
133
134
86 // Represents the output and result callback of a request. 135 // Represents the output and result callback of a request.
87 class CertVerifierRequest { 136 class CertVerifierRequest {
88 public: 137 public:
89 CertVerifierRequest(const CompletionCallback& callback, 138 CertVerifierRequest(const CompletionCallback& callback,
90 CertVerifyResult* verify_result, 139 CertVerifyResult* verify_result,
91 const BoundNetLog& net_log) 140 const BoundNetLog& net_log)
92 : callback_(callback), 141 : callback_(callback),
93 verify_result_(verify_result), 142 verify_result_(verify_result),
94 net_log_(net_log) { 143 net_log_(net_log) {
95 net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); 144 net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 if (callback.is_null() || !verify_result || hostname.empty()) { 404 if (callback.is_null() || !verify_result || hostname.empty()) {
356 *out_req = NULL; 405 *out_req = NULL;
357 return ERR_INVALID_ARGUMENT; 406 return ERR_INVALID_ARGUMENT;
358 } 407 }
359 408
360 requests_++; 409 requests_++;
361 410
362 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), 411 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(),
363 hostname, flags); 412 hostname, flags);
364 const CertVerifierCache::value_type* cached_entry = 413 const CertVerifierCache::value_type* cached_entry =
365 cache_.Get(key, base::TimeTicks::Now()); 414 cache_.Get(key, CacheValidityPeriod(base::Time::Now()));
366 if (cached_entry) { 415 if (cached_entry) {
367 ++cache_hits_; 416 ++cache_hits_;
368 *out_req = NULL; 417 *out_req = NULL;
369 *verify_result = cached_entry->result; 418 *verify_result = cached_entry->result;
370 return cached_entry->error; 419 return cached_entry->error;
371 } 420 }
372 421
373 // No cache hit. See if an identical request is currently in flight. 422 // No cache hit. See if an identical request is currently in flight.
374 CertVerifierJob* job; 423 CertVerifierJob* job;
375 std::map<RequestParams, CertVerifierJob*>::const_iterator j; 424 std::map<RequestParams, CertVerifierJob*>::const_iterator j;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 int error, 469 int error,
421 const CertVerifyResult& verify_result) { 470 const CertVerifyResult& verify_result) {
422 DCHECK(CalledOnValidThread()); 471 DCHECK(CalledOnValidThread());
423 472
424 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), 473 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(),
425 hostname, flags); 474 hostname, flags);
426 475
427 CachedResult cached_result; 476 CachedResult cached_result;
428 cached_result.error = error; 477 cached_result.error = error;
429 cached_result.result = verify_result; 478 cached_result.result = verify_result;
430 cache_.Put(key, cached_result, base::TimeTicks::Now(), 479 base::Time now = base::Time::Now();
431 base::TimeDelta::FromSeconds(kTTLSecs)); 480 cache_.Put(
481 key, cached_result, CacheValidityPeriod(now),
482 CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs)));
432 483
433 std::map<RequestParams, CertVerifierJob*>::iterator j; 484 std::map<RequestParams, CertVerifierJob*>::iterator j;
434 j = inflight_.find(key); 485 j = inflight_.find(key);
435 if (j == inflight_.end()) { 486 if (j == inflight_.end()) {
436 NOTREACHED(); 487 NOTREACHED();
437 return; 488 return;
438 } 489 }
439 CertVerifierJob* job = j->second; 490 CertVerifierJob* job = j->second;
440 inflight_.erase(j); 491 inflight_.erase(j);
441 492
442 job->HandleResult(cached_result); 493 job->HandleResult(cached_result);
443 delete job; 494 delete job;
444 } 495 }
445 496
446 void MultiThreadedCertVerifier::OnCertTrustChanged( 497 void MultiThreadedCertVerifier::OnCertTrustChanged(
447 const X509Certificate* cert) { 498 const X509Certificate* cert) {
448 DCHECK(CalledOnValidThread()); 499 DCHECK(CalledOnValidThread());
449 500
450 ClearCache(); 501 ClearCache();
451 } 502 }
452 503
453 void MultiThreadedCertVerifier::SetCertVerifyProc(CertVerifyProc* verify_proc) { 504 void MultiThreadedCertVerifier::SetCertVerifyProc(CertVerifyProc* verify_proc) {
454 verify_proc_ = verify_proc; 505 verify_proc_ = verify_proc;
455 } 506 }
456 507
457 } // namespace net 508 } // namespace net
OLDNEW
« no previous file with comments | « net/base/multi_threaded_cert_verifier.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698