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

Unified Diff: net/base/cert_verifier_unittest.cc

Issue 5386001: Cache certificate verification results in memory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Upload before checkin Created 10 years 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
« no previous file with comments | « net/base/cert_verifier.cc ('k') | net/http/disk_cache_based_ssl_host_info.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/cert_verifier_unittest.cc
===================================================================
--- net/base/cert_verifier_unittest.cc (revision 0)
+++ net/base/cert_verifier_unittest.cc (revision 0)
@@ -0,0 +1,260 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/cert_verifier.h"
+
+#include "base/callback.h"
+#include "base/file_path.h"
+#include "base/stringprintf.h"
+#include "net/base/cert_test_util.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "net/base/x509_certificate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+class TestTimeService : public CertVerifier::TimeService {
+ public:
+ // CertVerifier::TimeService methods:
+ virtual base::Time Now() { return current_time_; }
+
+ void set_current_time(base::Time now) { current_time_ = now; }
+
+ private:
+ base::Time current_time_;
+};
+
+class CertVerifierTest : public testing::Test {
+};
+
+class ExplodingCallback : public CallbackRunner<Tuple1<int> > {
+ public:
+ virtual void RunWithParams(const Tuple1<int>& params) {
+ FAIL();
+ }
+};
+
+// Tests a cache hit, which should results in synchronous completion.
+TEST_F(CertVerifierTest, CacheHit) {
+ TestTimeService* time_service = new TestTimeService;
+ base::Time current_time = base::Time::Now();
+ time_service->set_current_time(current_time);
+ CertVerifier verifier(time_service);
+
+ FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> google_cert(
+ ImportCertFromFile(certs_dir, "google.single.der"));
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
+
+ int error;
+ CertVerifyResult verify_result;
+ TestCompletionCallback callback;
+ CertVerifier::RequestHandle request_handle;
+
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ error = callback.WaitForResult();
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_EQ(1u, verifier.requests());
+ ASSERT_EQ(0u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ // Synchronous completion.
+ ASSERT_NE(ERR_IO_PENDING, error);
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_TRUE(request_handle == NULL);
+ ASSERT_EQ(2u, verifier.requests());
+ ASSERT_EQ(1u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+}
+
+// Tests an inflight join.
+TEST_F(CertVerifierTest, InflightJoin) {
+ TestTimeService* time_service = new TestTimeService;
+ base::Time current_time = base::Time::Now();
+ time_service->set_current_time(current_time);
+ CertVerifier verifier(time_service);
+
+ FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> google_cert(
+ ImportCertFromFile(certs_dir, "google.single.der"));
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
+
+ int error;
+ CertVerifyResult verify_result;
+ TestCompletionCallback callback;
+ CertVerifier::RequestHandle request_handle;
+ CertVerifyResult verify_result2;
+ TestCompletionCallback callback2;
+ CertVerifier::RequestHandle request_handle2;
+
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result2,
+ &callback2, &request_handle2);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle2 != NULL);
+ error = callback.WaitForResult();
+ ASSERT_TRUE(IsCertificateError(error));
+ error = callback2.WaitForResult();
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_EQ(2u, verifier.requests());
+ ASSERT_EQ(0u, verifier.cache_hits());
+ ASSERT_EQ(1u, verifier.inflight_joins());
+}
+
+// Tests cache entry expiration.
+TEST_F(CertVerifierTest, ExpiredCacheEntry) {
+ TestTimeService* time_service = new TestTimeService;
+ base::Time current_time = base::Time::Now();
+ time_service->set_current_time(current_time);
+ CertVerifier verifier(time_service);
+
+ FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> google_cert(
+ ImportCertFromFile(certs_dir, "google.single.der"));
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
+
+ int error;
+ CertVerifyResult verify_result;
+ TestCompletionCallback callback;
+ CertVerifier::RequestHandle request_handle;
+
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ error = callback.WaitForResult();
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_EQ(1u, verifier.requests());
+ ASSERT_EQ(0u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+
+ // Before expiration, should have a cache hit.
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ // Synchronous completion.
+ ASSERT_NE(ERR_IO_PENDING, error);
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_TRUE(request_handle == NULL);
+ ASSERT_EQ(2u, verifier.requests());
+ ASSERT_EQ(1u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+
+ // After expiration, should not have a cache hit.
+ ASSERT_EQ(1u, verifier.GetCacheSize());
+ current_time += base::TimeDelta::FromMinutes(60);
+ time_service->set_current_time(current_time);
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ ASSERT_EQ(0u, verifier.GetCacheSize());
+ error = callback.WaitForResult();
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_EQ(3u, verifier.requests());
+ ASSERT_EQ(1u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+}
+
+// Tests a full cache.
+TEST_F(CertVerifierTest, FullCache) {
+ TestTimeService* time_service = new TestTimeService;
+ base::Time current_time = base::Time::Now();
+ time_service->set_current_time(current_time);
+ CertVerifier verifier(time_service);
+
+ FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> google_cert(
+ ImportCertFromFile(certs_dir, "google.single.der"));
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
+
+ int error;
+ CertVerifyResult verify_result;
+ TestCompletionCallback callback;
+ CertVerifier::RequestHandle request_handle;
+
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ error = callback.WaitForResult();
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_EQ(1u, verifier.requests());
+ ASSERT_EQ(0u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+
+ const unsigned kCacheSize = 256;
+
+ for (unsigned i = 0; i < kCacheSize; i++) {
+ std::string hostname = base::StringPrintf("www%d.example.com", i + 1);
+ error = verifier.Verify(google_cert, hostname, 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ error = callback.WaitForResult();
+ ASSERT_TRUE(IsCertificateError(error));
+ }
+ ASSERT_EQ(kCacheSize + 1, verifier.requests());
+ ASSERT_EQ(0u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+
+ ASSERT_EQ(kCacheSize, verifier.GetCacheSize());
+ current_time += base::TimeDelta::FromMinutes(60);
+ time_service->set_current_time(current_time);
+ error = verifier.Verify(google_cert, "www999.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ ASSERT_EQ(kCacheSize, verifier.GetCacheSize());
+ error = callback.WaitForResult();
+ ASSERT_EQ(1u, verifier.GetCacheSize());
+ ASSERT_TRUE(IsCertificateError(error));
+ ASSERT_EQ(kCacheSize + 2, verifier.requests());
+ ASSERT_EQ(0u, verifier.cache_hits());
+ ASSERT_EQ(0u, verifier.inflight_joins());
+}
+
+// Tests that the callback of a canceled request is never made.
+TEST_F(CertVerifierTest, CancelRequest) {
+ CertVerifier verifier;
+
+ FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<X509Certificate> google_cert(
+ ImportCertFromFile(certs_dir, "google.single.der"));
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
+
+ int error;
+ CertVerifyResult verify_result;
+ ExplodingCallback exploding_callback;
+ CertVerifier::RequestHandle request_handle;
+
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result,
+ &exploding_callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ verifier.CancelRequest(request_handle);
+
+ // Issue a few more requests to the worker pool and wait for their
+ // completion, so that the task of the canceled request (which runs on a
+ // worker thread) is likely to complete by the end of this test.
+ TestCompletionCallback callback;
+ for (int i = 0; i < 5; ++i) {
+ error = verifier.Verify(google_cert, "www2.example.com", 0, &verify_result,
+ &callback, &request_handle);
+ ASSERT_EQ(ERR_IO_PENDING, error);
+ ASSERT_TRUE(request_handle != NULL);
+ error = callback.WaitForResult();
+ verifier.ClearCache();
+ }
+}
+
+} // namespace net
Property changes on: net\base\cert_verifier_unittest.cc
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « net/base/cert_verifier.cc ('k') | net/http/disk_cache_based_ssl_host_info.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698