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

Unified Diff: net/cert/multi_threaded_cert_verifier.cc

Issue 1991653002: Move caching out of MultiThreadedCertVerifier (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@request_params
Patch Set: Rebased Created 4 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 side-by-side diff with in-line comments
Download patch
Index: net/cert/multi_threaded_cert_verifier.cc
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc
index a1a5fb83b750d06bdd84187a919bd221c8772d5d..50c305d375c2dafdb204ace9afe9b93d5a594182 100644
--- a/net/cert/multi_threaded_cert_verifier.cc
+++ b/net/cert/multi_threaded_cert_verifier.cc
@@ -25,7 +25,6 @@
#include "base/values.h"
#include "net/base/hash_value.h"
#include "net/base/net_errors.h"
-#include "net/cert/cert_trust_anchor_provider.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/crl_set.h"
#include "net/cert/x509_certificate.h"
@@ -79,12 +78,6 @@ namespace net {
namespace {
-// The maximum number of cache entries to use for the ExpiringCache.
-const unsigned kMaxCacheEntries = 256;
-
-// The number of seconds to cache entries.
-const unsigned kTTLSecs = 1800; // 30 minutes.
-
std::unique_ptr<base::Value> CertVerifyResultCallback(
const CertVerifyResult& verify_result,
NetLogCaptureMode capture_mode) {
@@ -115,60 +108,16 @@ std::unique_ptr<base::Value> CertVerifyResultCallback(
return std::move(results);
}
-} // namespace
-
-MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {}
-
-MultiThreadedCertVerifier::CachedResult::~CachedResult() {}
-
-MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod(
- const base::Time& now)
- : verification_time(now),
- expiration_time(now) {
-}
-
-MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod(
- const base::Time& now,
- const base::Time& expiration)
- : verification_time(now),
- expiration_time(expiration) {
-}
-
-bool MultiThreadedCertVerifier::CacheExpirationFunctor::operator()(
- const CacheValidityPeriod& now,
- const CacheValidityPeriod& expiration) const {
- // Ensure this functor is being used for expiration only, and not strict
- // weak ordering/sorting. |now| should only ever contain a single
- // base::Time.
- // Note: DCHECK_EQ is not used due to operator<< overloading requirements.
- DCHECK(now.verification_time == now.expiration_time);
-
- // |now| contains only a single time (verification_time), while |expiration|
- // contains the validity range - both when the certificate was verified and
- // when the verification result should expire.
- //
- // If the user receives a "not yet valid" message, and adjusts their clock
- // foward to the correct time, this will (typically) cause
- // now.verification_time to advance past expiration.expiration_time, thus
- // treating the cached result as an expired entry and re-verifying.
- // If the user receives a "expired" message, and adjusts their clock
- // backwards to the correct time, this will cause now.verification_time to
- // be less than expiration_verification_time, thus treating the cached
- // result as an expired entry and re-verifying.
- // If the user receives either of those messages, and does not adjust their
- // clock, then the result will be (typically) be cached until the expiration
- // TTL.
- //
- // This algorithm is only problematic if the user consistently keeps
- // adjusting their clock backwards in increments smaller than the expiration
- // TTL, in which case, cached elements continue to be added. However,
- // because the cache has a fixed upper bound, if no entries are expired, a
- // 'random' entry will be, thus keeping the memory constraints bounded over
- // time.
- return now.verification_time >= expiration.verification_time &&
- now.verification_time < expiration.expiration_time;
+// Helper structure used to keep |verify_result| alive for the lifetime of
+// the verification on the worker thread, and to communicate it back to the
+// calling thread.
+struct ResultHelper {
+ int error;
+ CertVerifyResult result;
};
+} // namespace
+
// Represents the output and result callback of a request. The
// CertVerifierRequest is owned by the caller that initiated the call to
// CertVerifier::Verify().
@@ -202,7 +151,7 @@ class CertVerifierRequest : public base::LinkNode<CertVerifierRequest>,
// Copies the contents of |verify_result| to the caller's
// CertVerifyResult and calls the callback.
- void Post(const MultiThreadedCertVerifier::CachedResult& verify_result) {
+ void Post(const ResultHelper& verify_result) {
DCHECK(job_);
job_ = nullptr;
@@ -261,7 +210,6 @@ class CertVerifierJob {
MultiThreadedCertVerifier* cert_verifier)
: key_(key),
start_time_(base::TimeTicks::Now()),
- wall_start_time_(base::Time::Now()),
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_CERT_VERIFIER_JOB)),
cert_verifier_(cert_verifier),
is_first_job_(false),
@@ -283,8 +231,7 @@ class CertVerifierJob {
bool Start(const scoped_refptr<CertVerifyProc>& verify_proc,
const scoped_refptr<CRLSet>& crl_set) {
// Owned by the bound reply callback.
- std::unique_ptr<MultiThreadedCertVerifier::CachedResult> owned_result(
- new MultiThreadedCertVerifier::CachedResult());
+ std::unique_ptr<ResultHelper> owned_result(new ResultHelper());
// Parameter evaluation order is undefined in C++. Ensure the pointer value
// is gotten before calling base::Passed().
@@ -337,8 +284,7 @@ class CertVerifierJob {
using RequestList = base::LinkedList<CertVerifierRequest>;
// Called on completion of the Job to log UMA metrics and NetLog events.
- void LogMetrics(
- const MultiThreadedCertVerifier::CachedResult& verify_result) {
+ void LogMetrics(const ResultHelper& verify_result) {
net_log_.EndEvent(
NetLog::TYPE_CERT_VERIFIER_JOB,
base::Bind(&CertVerifyResultCallback, verify_result.result));
@@ -357,14 +303,12 @@ class CertVerifierJob {
}
}
- void OnJobCompleted(
- std::unique_ptr<MultiThreadedCertVerifier::CachedResult> verify_result) {
+ void OnJobCompleted(std::unique_ptr<ResultHelper> verify_result) {
TRACE_EVENT0("net", "CertVerifierJob::OnJobCompleted");
std::unique_ptr<CertVerifierJob> keep_alive =
cert_verifier_->RemoveJob(this);
LogMetrics(*verify_result);
- cert_verifier_->SaveResultToCache(key_, wall_start_time_, *verify_result);
cert_verifier_ = nullptr;
// TODO(eroman): If the cert_verifier_ is deleted from within one of the
@@ -382,11 +326,6 @@ class CertVerifierJob {
// the job actually took to complete.
const base::TimeTicks start_time_;
- // The wall time of when the job started. This is to account for situations
- // where the system clock may have changed after the Job had started, which
- // could otherwise result in caching the wrong data.
- const base::Time wall_start_time_;
-
RequestList requests_; // Non-owned.
const BoundNetLog net_log_;
@@ -398,24 +337,10 @@ class CertVerifierJob {
MultiThreadedCertVerifier::MultiThreadedCertVerifier(
CertVerifyProc* verify_proc)
- : cache_(kMaxCacheEntries),
- requests_(0),
- cache_hits_(0),
- inflight_joins_(0),
- verify_proc_(verify_proc),
- trust_anchor_provider_(NULL) {
- CertDatabase::GetInstance()->AddObserver(this);
-}
+ : requests_(0), inflight_joins_(0), verify_proc_(verify_proc) {}
MultiThreadedCertVerifier::~MultiThreadedCertVerifier() {
STLDeleteElements(&inflight_);
- CertDatabase::GetInstance()->RemoveObserver(this);
-}
-
-void MultiThreadedCertVerifier::SetCertTrustAnchorProvider(
- CertTrustAnchorProvider* trust_anchor_provider) {
- DCHECK(CalledOnValidThread());
- trust_anchor_provider_ = trust_anchor_provider;
}
int MultiThreadedCertVerifier::Verify(const RequestParams& params,
@@ -433,27 +358,8 @@ int MultiThreadedCertVerifier::Verify(const RequestParams& params,
requests_++;
- CertificateList new_trust_anchors(params.additional_trust_anchors());
- if (trust_anchor_provider_) {
- const CertificateList& trust_anchors =
- trust_anchor_provider_->GetAdditionalTrustAnchors();
- new_trust_anchors.insert(new_trust_anchors.end(), trust_anchors.begin(),
- trust_anchors.end());
- }
-
- const RequestParams key(params.certificate(), params.hostname(),
- params.flags(), params.ocsp_response(),
- new_trust_anchors);
- const CertVerifierCache::value_type* cached_entry =
- cache_.Get(key, CacheValidityPeriod(base::Time::Now()));
- if (cached_entry) {
- ++cache_hits_;
- *verify_result = cached_entry->result;
- return cached_entry->error;
- }
-
- // No cache hit. See if an identical request is currently in flight.
- CertVerifierJob* job = FindJob(key);
+ // See if an identical request is currently in flight.
+ CertVerifierJob* job = FindJob(params);
if (job) {
// An identical request is in flight already. We'll just attach our
// callback.
@@ -461,7 +367,7 @@ int MultiThreadedCertVerifier::Verify(const RequestParams& params,
} else {
// Need to make a new job.
std::unique_ptr<CertVerifierJob> new_job(
- new CertVerifierJob(key, net_log.net_log(), this));
+ new CertVerifierJob(params, net_log.net_log(), this));
if (!new_job->Start(verify_proc_, crl_set)) {
// TODO(wtc): log to the NetLog.
@@ -492,40 +398,6 @@ bool MultiThreadedCertVerifier::JobComparator::operator()(
return job1->key() < job2->key();
}
-void MultiThreadedCertVerifier::SaveResultToCache(const RequestParams& key,
- const base::Time& start_time,
- const CachedResult& result) {
- DCHECK(CalledOnValidThread());
-
- // When caching, this uses the time that validation started as the
- // beginning of the validity, rather than the time that it ended (aka
- // base::Time::Now()), to account for the fact that during validation,
- // the clock may have changed.
- //
- // If the clock has changed significantly, then this result will ideally
- // be evicted and the next time the certificate is encountered, it will
- // be revalidated.
- //
- // Because of this, it's possible for situations to arise where the
- // clock was correct at the start of validation, changed to an
- // incorrect time during validation (such as too far in the past or
- // future), and then was reset to the correct time. If this happens,
- // it's likely that the result will not be a valid/correct result,
- // but will still be used from the cache because the clock was reset
- // to the correct time after the (bad) validation result completed.
- //
- // However, this solution optimizes for the case where the clock is
- // bad at the start of validation, and subsequently is corrected. In
- // that situation, the result is also incorrect, but because the clock
- // was corrected after validation, if the cache validity period was
- // computed at the end of validation, it would continue to serve an
- // invalid result for kTTLSecs.
- cache_.Put(
- key, result, CacheValidityPeriod(start_time),
- CacheValidityPeriod(start_time,
- start_time + base::TimeDelta::FromSeconds(kTTLSecs)));
-}
-
std::unique_ptr<CertVerifierJob> MultiThreadedCertVerifier::RemoveJob(
CertVerifierJob* job) {
DCHECK(CalledOnValidThread());
@@ -534,13 +406,6 @@ std::unique_ptr<CertVerifierJob> MultiThreadedCertVerifier::RemoveJob(
return base::WrapUnique(job);
}
-void MultiThreadedCertVerifier::OnCACertChanged(
- const X509Certificate* cert) {
- DCHECK(CalledOnValidThread());
-
- ClearCache();
-}
-
struct MultiThreadedCertVerifier::JobToRequestParamsComparator {
bool operator()(const CertVerifierJob* job,
const CertVerifier::RequestParams& value) const {

Powered by Google App Engine
This is Rietveld 408576698