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 |