| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
 |    2 // Use of this source code is governed by a BSD-style license that can be | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #include "net/base/cert_verifier.h" | 
 |    6  | 
 |    7 #include "base/callback.h" | 
 |    8 #include "base/stringprintf.h" | 
 |    9 #include "net/base/net_errors.h" | 
 |   10 #include "net/base/test_certificate_data.h" | 
 |   11 #include "net/base/test_completion_callback.h" | 
 |   12 #include "net/base/x509_certificate.h" | 
 |   13 #include "testing/gtest/include/gtest/gtest.h" | 
 |   14  | 
 |   15 namespace net { | 
 |   16  | 
 |   17 class TestTimeService : public CertVerifier::TimeService { | 
 |   18  public: | 
 |   19   // CertVerifier::TimeService methods: | 
 |   20   virtual base::Time Now() { return current_time_; } | 
 |   21  | 
 |   22   void set_current_time(base::Time now) { current_time_ = now; } | 
 |   23  | 
 |   24  private: | 
 |   25   base::Time current_time_; | 
 |   26 }; | 
 |   27  | 
 |   28 class CertVerifierTest : public testing::Test { | 
 |   29 }; | 
 |   30  | 
 |   31 class ExplodingCallback : public CallbackRunner<Tuple1<int> > { | 
 |   32  public: | 
 |   33   virtual void RunWithParams(const Tuple1<int>& params) { | 
 |   34     FAIL(); | 
 |   35   } | 
 |   36 }; | 
 |   37  | 
 |   38 // Tests a cache hit, which should results in synchronous completion. | 
 |   39 TEST_F(CertVerifierTest, CacheHit) { | 
 |   40   TestTimeService* time_service = new TestTimeService; | 
 |   41   base::Time current_time = base::Time::Now(); | 
 |   42   time_service->set_current_time(current_time); | 
 |   43   CertVerifier verifier(time_service); | 
 |   44  | 
 |   45   scoped_refptr<X509Certificate> google_cert( | 
 |   46       X509Certificate::CreateFromBytes( | 
 |   47           reinterpret_cast<const char*>(google_der), sizeof(google_der))); | 
 |   48  | 
 |   49   int error; | 
 |   50   CertVerifyResult verify_result; | 
 |   51   TestCompletionCallback callback; | 
 |   52   CertVerifier::RequestHandle request_handle; | 
 |   53  | 
 |   54   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |   55                           &callback, &request_handle); | 
 |   56   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |   57   ASSERT_TRUE(request_handle != NULL); | 
 |   58   error = callback.WaitForResult(); | 
 |   59   ASSERT_TRUE(IsCertificateError(error)); | 
 |   60   ASSERT_EQ(1u, verifier.requests()); | 
 |   61   ASSERT_EQ(0u, verifier.cache_hits()); | 
 |   62   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |   63  | 
 |   64   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |   65                           &callback, &request_handle); | 
 |   66   // Synchronous completion. | 
 |   67   ASSERT_NE(ERR_IO_PENDING, error); | 
 |   68   ASSERT_TRUE(IsCertificateError(error)); | 
 |   69   ASSERT_TRUE(request_handle == NULL); | 
 |   70   ASSERT_EQ(2u, verifier.requests()); | 
 |   71   ASSERT_EQ(1u, verifier.cache_hits()); | 
 |   72   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |   73 } | 
 |   74  | 
 |   75 // Tests an inflight join. | 
 |   76 TEST_F(CertVerifierTest, InflightJoin) { | 
 |   77   TestTimeService* time_service = new TestTimeService; | 
 |   78   base::Time current_time = base::Time::Now(); | 
 |   79   time_service->set_current_time(current_time); | 
 |   80   CertVerifier verifier(time_service); | 
 |   81  | 
 |   82   scoped_refptr<X509Certificate> google_cert( | 
 |   83       X509Certificate::CreateFromBytes( | 
 |   84           reinterpret_cast<const char*>(google_der), sizeof(google_der))); | 
 |   85  | 
 |   86   int error; | 
 |   87   CertVerifyResult verify_result; | 
 |   88   TestCompletionCallback callback; | 
 |   89   CertVerifier::RequestHandle request_handle; | 
 |   90   CertVerifyResult verify_result2; | 
 |   91   TestCompletionCallback callback2; | 
 |   92   CertVerifier::RequestHandle request_handle2; | 
 |   93  | 
 |   94   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |   95                           &callback, &request_handle); | 
 |   96   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |   97   ASSERT_TRUE(request_handle != NULL); | 
 |   98   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result2, | 
 |   99                           &callback2, &request_handle2); | 
 |  100   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  101   ASSERT_TRUE(request_handle2 != NULL); | 
 |  102   error = callback.WaitForResult(); | 
 |  103   ASSERT_TRUE(IsCertificateError(error)); | 
 |  104   error = callback2.WaitForResult(); | 
 |  105   ASSERT_TRUE(IsCertificateError(error)); | 
 |  106   ASSERT_EQ(2u, verifier.requests()); | 
 |  107   ASSERT_EQ(0u, verifier.cache_hits()); | 
 |  108   ASSERT_EQ(1u, verifier.inflight_joins()); | 
 |  109 } | 
 |  110  | 
 |  111 // Tests cache entry expiration. | 
 |  112 TEST_F(CertVerifierTest, ExpiredCacheEntry) { | 
 |  113   TestTimeService* time_service = new TestTimeService; | 
 |  114   base::Time current_time = base::Time::Now(); | 
 |  115   time_service->set_current_time(current_time); | 
 |  116   CertVerifier verifier(time_service); | 
 |  117  | 
 |  118   scoped_refptr<X509Certificate> google_cert( | 
 |  119       X509Certificate::CreateFromBytes( | 
 |  120           reinterpret_cast<const char*>(google_der), sizeof(google_der))); | 
 |  121  | 
 |  122   int error; | 
 |  123   CertVerifyResult verify_result; | 
 |  124   TestCompletionCallback callback; | 
 |  125   CertVerifier::RequestHandle request_handle; | 
 |  126  | 
 |  127   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |  128                           &callback, &request_handle); | 
 |  129   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  130   ASSERT_TRUE(request_handle != NULL); | 
 |  131   error = callback.WaitForResult(); | 
 |  132   ASSERT_TRUE(IsCertificateError(error)); | 
 |  133   ASSERT_EQ(1u, verifier.requests()); | 
 |  134   ASSERT_EQ(0u, verifier.cache_hits()); | 
 |  135   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |  136  | 
 |  137   // Before expiration, should have a cache hit. | 
 |  138   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |  139                           &callback, &request_handle); | 
 |  140   // Synchronous completion. | 
 |  141   ASSERT_NE(ERR_IO_PENDING, error); | 
 |  142   ASSERT_TRUE(IsCertificateError(error)); | 
 |  143   ASSERT_TRUE(request_handle == NULL); | 
 |  144   ASSERT_EQ(2u, verifier.requests()); | 
 |  145   ASSERT_EQ(1u, verifier.cache_hits()); | 
 |  146   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |  147  | 
 |  148   // After expiration, should not have a cache hit. | 
 |  149   ASSERT_EQ(1, verifier.GetCacheSize()); | 
 |  150   current_time += base::TimeDelta::FromMinutes(60); | 
 |  151   time_service->set_current_time(current_time); | 
 |  152   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |  153                           &callback, &request_handle); | 
 |  154   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  155   ASSERT_TRUE(request_handle != NULL); | 
 |  156   ASSERT_EQ(0, verifier.GetCacheSize()); | 
 |  157   error = callback.WaitForResult(); | 
 |  158   ASSERT_TRUE(IsCertificateError(error)); | 
 |  159   ASSERT_EQ(3u, verifier.requests()); | 
 |  160   ASSERT_EQ(1u, verifier.cache_hits()); | 
 |  161   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |  162 } | 
 |  163  | 
 |  164 // Tests a full cache. | 
 |  165 TEST_F(CertVerifierTest, FullCache) { | 
 |  166   TestTimeService* time_service = new TestTimeService; | 
 |  167   base::Time current_time = base::Time::Now(); | 
 |  168   time_service->set_current_time(current_time); | 
 |  169   CertVerifier verifier(time_service); | 
 |  170  | 
 |  171   scoped_refptr<X509Certificate> google_cert( | 
 |  172       X509Certificate::CreateFromBytes( | 
 |  173           reinterpret_cast<const char*>(google_der), sizeof(google_der))); | 
 |  174  | 
 |  175   int error; | 
 |  176   CertVerifyResult verify_result; | 
 |  177   TestCompletionCallback callback; | 
 |  178   CertVerifier::RequestHandle request_handle; | 
 |  179  | 
 |  180   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |  181                           &callback, &request_handle); | 
 |  182   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  183   ASSERT_TRUE(request_handle != NULL); | 
 |  184   error = callback.WaitForResult(); | 
 |  185   ASSERT_TRUE(IsCertificateError(error)); | 
 |  186   ASSERT_EQ(1u, verifier.requests()); | 
 |  187   ASSERT_EQ(0u, verifier.cache_hits()); | 
 |  188   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |  189  | 
 |  190   const int kCacheSize = 64; | 
 |  191  | 
 |  192   for (int i = 0; i < kCacheSize; i++) { | 
 |  193     std::string hostname = base::StringPrintf("www%d.example.com", i + 1); | 
 |  194     error = verifier.Verify(google_cert, hostname, 0, &verify_result, | 
 |  195                             &callback, &request_handle); | 
 |  196     ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  197     ASSERT_TRUE(request_handle != NULL); | 
 |  198     error = callback.WaitForResult(); | 
 |  199     ASSERT_TRUE(IsCertificateError(error)); | 
 |  200   } | 
 |  201   ASSERT_EQ(kCacheSize + 1, verifier.requests()); | 
 |  202   ASSERT_EQ(0u, verifier.cache_hits()); | 
 |  203   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |  204  | 
 |  205   ASSERT_EQ(kCacheSize, verifier.GetCacheSize()); | 
 |  206   current_time += base::TimeDelta::FromMinutes(60); | 
 |  207   time_service->set_current_time(current_time); | 
 |  208   error = verifier.Verify(google_cert, "www100.example.com", 0, &verify_result, | 
 |  209                           &callback, &request_handle); | 
 |  210   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  211   ASSERT_TRUE(request_handle != NULL); | 
 |  212   ASSERT_EQ(kCacheSize, verifier.GetCacheSize()); | 
 |  213   error = callback.WaitForResult(); | 
 |  214   ASSERT_EQ(1, verifier.GetCacheSize()); | 
 |  215   ASSERT_TRUE(IsCertificateError(error)); | 
 |  216   ASSERT_EQ(kCacheSize + 2, verifier.requests()); | 
 |  217   ASSERT_EQ(0u, verifier.cache_hits()); | 
 |  218   ASSERT_EQ(0u, verifier.inflight_joins()); | 
 |  219 } | 
 |  220  | 
 |  221 // Tests that the callback of a canceled request is never made. | 
 |  222 TEST_F(CertVerifierTest, CancelRequest) { | 
 |  223   CertVerifier verifier; | 
 |  224   scoped_refptr<X509Certificate> google_cert( | 
 |  225       X509Certificate::CreateFromBytes( | 
 |  226           reinterpret_cast<const char*>(google_der), sizeof(google_der))); | 
 |  227   int error; | 
 |  228   CertVerifyResult verify_result; | 
 |  229   ExplodingCallback exploding_callback; | 
 |  230   CertVerifier::RequestHandle request_handle; | 
 |  231  | 
 |  232   error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, | 
 |  233                           &exploding_callback, &request_handle); | 
 |  234   ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  235   ASSERT_TRUE(request_handle != NULL); | 
 |  236   verifier.CancelRequest(request_handle); | 
 |  237  | 
 |  238   // Issue a few more requests to the worker pool and wait for their | 
 |  239   // completion, so that the task of the canceled request (which runs on a | 
 |  240   // worker thread) is likely to complete by the end of this test. | 
 |  241   TestCompletionCallback callback; | 
 |  242   for (int i = 0; i < 5; ++i) { | 
 |  243     error = verifier.Verify(google_cert, "www2.example.com", 0, &verify_result, | 
 |  244                             &callback, &request_handle); | 
 |  245     ASSERT_EQ(ERR_IO_PENDING, error); | 
 |  246     ASSERT_TRUE(request_handle != NULL); | 
 |  247     error = callback.WaitForResult(); | 
 |  248     verifier.ClearCache(); | 
 |  249   } | 
 |  250 } | 
 |  251  | 
 |  252 }  // namespace net | 
| OLD | NEW |