summaryrefslogtreecommitdiffstats
path: root/net/base/cert_verifier.cc
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 23:04:05 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 23:04:05 +0000
commite388313b2b6ffb83e7a21bcd187fed5dad9a125e (patch)
treee4e51894211779324f03f7191e649ba9b87857d7 /net/base/cert_verifier.cc
parent5c47775ab01603c6884eca0acdf867beda1f2c38 (diff)
downloadchromium_src-e388313b2b6ffb83e7a21bcd187fed5dad9a125e.zip
chromium_src-e388313b2b6ffb83e7a21bcd187fed5dad9a125e.tar.gz
chromium_src-e388313b2b6ffb83e7a21bcd187fed5dad9a125e.tar.bz2
Revert 123565 - Broke the "ASAN Tests (1)" bot: http://build.chromium.org/p/chromium.memory/buildstatus?builder=ASAN%20Tests%20%281%29&number=6260
Have the HostCache and CertVerifier cache use the common ExpiringCache. BUG=114343 TEST=net_unittests:CertVerifier*, net_unittests:HostCache* Review URL: http://codereview.chromium.org/9436003 TBR=rsleevi@chromium.org Review URL: https://chromiumcodereview.appspot.com/9463028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123571 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/cert_verifier.cc')
-rw-r--r--net/base/cert_verifier.cc97
1 files changed, 79 insertions, 18 deletions
diff --git a/net/base/cert_verifier.cc b/net/base/cert_verifier.cc
index f5f0bc2..cb4734b 100644
--- a/net/base/cert_verifier.cc
+++ b/net/base/cert_verifier.cc
@@ -74,11 +74,22 @@ const unsigned kMaxCacheEntries = 256;
// The number of seconds for which we'll cache a cache entry.
const unsigned kTTLSecs = 1800; // 30 minutes.
+class DefaultTimeService : public CertVerifier::TimeService {
+ public:
+ // CertVerifier::TimeService methods:
+ virtual base::Time Now() { return base::Time::Now(); }
+};
+
} // namespace
-CertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {}
+CachedCertVerifyResult::CachedCertVerifyResult() : error(ERR_FAILED) {
+}
-CertVerifier::CachedResult::~CachedResult() {}
+CachedCertVerifyResult::~CachedCertVerifyResult() {}
+
+bool CachedCertVerifyResult::HasExpired(const base::Time current_time) const {
+ return current_time >= expiry;
+}
// Represents the output and result callback of a request.
class CertVerifierRequest {
@@ -105,7 +116,7 @@ class CertVerifierRequest {
// Copies the contents of |verify_result| to the caller's
// CertVerifyResult and calls the callback.
- void Post(const CertVerifier::CachedResult& verify_result) {
+ void Post(const CachedCertVerifyResult& verify_result) {
if (!callback_.is_null()) {
net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST, NULL);
*verify_result_ = verify_result.result;
@@ -278,7 +289,7 @@ class CertVerifierJob {
requests_.push_back(request);
}
- void HandleResult(const CertVerifier::CachedResult& verify_result) {
+ void HandleResult(const CachedCertVerifyResult& verify_result) {
worker_ = NULL;
net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB, NULL);
UMA_HISTOGRAM_CUSTOM_TIMES("Net.CertVerifier_Job_Latency",
@@ -290,7 +301,7 @@ class CertVerifierJob {
}
private:
- void PostAll(const CertVerifier::CachedResult& verify_result) {
+ void PostAll(const CachedCertVerifyResult& verify_result) {
std::vector<CertVerifierRequest*> requests;
requests_.swap(requests);
@@ -318,8 +329,19 @@ class CertVerifierJob {
const BoundNetLog net_log_;
};
+
CertVerifier::CertVerifier()
- : cache_(kMaxCacheEntries),
+ : time_service_(new DefaultTimeService),
+ max_cache_entries_(kMaxCacheEntries),
+ requests_(0),
+ cache_hits_(0),
+ inflight_joins_(0) {
+ CertDatabase::AddObserver(this);
+}
+
+CertVerifier::CertVerifier(TimeService* time_service)
+ : time_service_(time_service),
+ max_cache_entries_(kMaxCacheEntries),
requests_(0),
cache_hits_(0),
inflight_joins_(0) {
@@ -351,13 +373,18 @@ int CertVerifier::Verify(X509Certificate* cert,
const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(),
hostname, flags);
- const CertVerifierCache::value_type* cached_entry =
- cache_.Get(key, base::TimeTicks::Now());
- if (cached_entry) {
- ++cache_hits_;
- *out_req = NULL;
- *verify_result = cached_entry->result;
- return cached_entry->error;
+ // First check the cache.
+ std::map<RequestParams, CachedCertVerifyResult>::iterator i;
+ i = cache_.find(key);
+ if (i != cache_.end()) {
+ if (!i->second.HasExpired(time_service_->Now())) {
+ cache_hits_++;
+ *out_req = NULL;
+ *verify_result = i->second.result;
+ return i->second.error;
+ }
+ // Cache entry has expired.
+ cache_.erase(i);
}
// No cache hit. See if an identical request is currently in flight.
@@ -400,6 +427,19 @@ void CertVerifier::CancelRequest(RequestHandle req) {
request->Cancel();
}
+void CertVerifier::ClearCache() {
+ DCHECK(CalledOnValidThread());
+
+ cache_.clear();
+ // Leaves inflight_ alone.
+}
+
+size_t CertVerifier::GetCacheSize() const {
+ DCHECK(CalledOnValidThread());
+
+ return cache_.size();
+}
+
// HandleResult is called by CertVerifierWorker on the origin message loop.
// It deletes CertVerifierJob.
void CertVerifier::HandleResult(X509Certificate* cert,
@@ -409,14 +449,35 @@ void CertVerifier::HandleResult(X509Certificate* cert,
const CertVerifyResult& verify_result) {
DCHECK(CalledOnValidThread());
- const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(),
- hostname, flags);
+ const base::Time current_time(time_service_->Now());
- CachedResult cached_result;
+ CachedCertVerifyResult cached_result;
cached_result.error = error;
cached_result.result = verify_result;
- cache_.Put(key, cached_result, base::TimeTicks::Now(),
- base::TimeDelta::FromSeconds(kTTLSecs));
+ uint32 ttl = kTTLSecs;
+ cached_result.expiry = current_time + base::TimeDelta::FromSeconds(ttl);
+
+ const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(),
+ hostname, flags);
+
+ DCHECK_GE(max_cache_entries_, 1u);
+ DCHECK_LE(cache_.size(), max_cache_entries_);
+ if (cache_.size() == max_cache_entries_) {
+ // Need to remove an element of the cache.
+ std::map<RequestParams, CachedCertVerifyResult>::iterator i, cur;
+ for (i = cache_.begin(); i != cache_.end(); ) {
+ cur = i++;
+ if (cur->second.HasExpired(current_time))
+ cache_.erase(cur);
+ }
+ }
+ if (cache_.size() == max_cache_entries_) {
+ // If we didn't clear out any expired entries, we just remove the first
+ // element. Crummy but simple.
+ cache_.erase(cache_.begin());
+ }
+
+ cache_.insert(std::make_pair(key, cached_result));
std::map<RequestParams, CertVerifierJob*>::iterator j;
j = inflight_.find(key);