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

Side by Side 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: Add unit tests. Ready for review. 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(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
willchan no longer on Chromium 2010/12/13 09:30:53 Can this code go into an anonymous namespace?
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 {
willchan no longer on Chromium 2010/12/13 09:30:53 If we don't need the fixture, can we just use 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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698