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

Side by Side Diff: net/cert/multi_threaded_cert_verifier_unittest.cc

Issue 1991653002: Move caching out of MultiThreadedCertVerifier (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@request_params
Patch Set: Now with caching Created 4 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/multi_threaded_cert_verifier.h" 5 #include "net/cert/multi_threaded_cert_verifier.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/leak_annotations.h" 10 #include "base/debug/leak_annotations.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "net/base/net_errors.h" 14 #include "net/base/net_errors.h"
15 #include "net/base/test_completion_callback.h" 15 #include "net/base/test_completion_callback.h"
16 #include "net/base/test_data_directory.h" 16 #include "net/base/test_data_directory.h"
17 #include "net/cert/cert_trust_anchor_provider.h"
18 #include "net/cert/cert_verifier.h" 17 #include "net/cert/cert_verifier.h"
19 #include "net/cert/cert_verify_proc.h" 18 #include "net/cert/cert_verify_proc.h"
20 #include "net/cert/cert_verify_result.h" 19 #include "net/cert/cert_verify_result.h"
21 #include "net/cert/x509_certificate.h" 20 #include "net/cert/x509_certificate.h"
22 #include "net/log/net_log.h" 21 #include "net/log/net_log.h"
23 #include "net/test/cert_test_util.h" 22 #include "net/test/cert_test_util.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
26 24
27 using testing::Mock;
28 using testing::ReturnRef;
29
30 namespace net { 25 namespace net {
31 26
32 namespace { 27 namespace {
33 28
34 void FailTest(int /* result */) { 29 void FailTest(int /* result */) {
35 FAIL(); 30 FAIL();
36 } 31 }
37 32
38 class MockCertVerifyProc : public CertVerifyProc { 33 class MockCertVerifyProc : public CertVerifyProc {
39 public: 34 public:
(...skipping 13 matching lines...) Expand all
53 CRLSet* crl_set, 48 CRLSet* crl_set,
54 const CertificateList& additional_trust_anchors, 49 const CertificateList& additional_trust_anchors,
55 CertVerifyResult* verify_result) override { 50 CertVerifyResult* verify_result) override {
56 verify_result->Reset(); 51 verify_result->Reset();
57 verify_result->verified_cert = cert; 52 verify_result->verified_cert = cert;
58 verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID; 53 verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID;
59 return ERR_CERT_COMMON_NAME_INVALID; 54 return ERR_CERT_COMMON_NAME_INVALID;
60 } 55 }
61 }; 56 };
62 57
63 class MockCertTrustAnchorProvider : public CertTrustAnchorProvider {
64 public:
65 MockCertTrustAnchorProvider() {}
66 virtual ~MockCertTrustAnchorProvider() {}
67
68 MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&());
69 };
70
71 } // namespace 58 } // namespace
72 59
73 class MultiThreadedCertVerifierTest : public ::testing::Test { 60 class MultiThreadedCertVerifierTest : public ::testing::Test {
74 public: 61 public:
75 MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {} 62 MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {}
76 ~MultiThreadedCertVerifierTest() override {} 63 ~MultiThreadedCertVerifierTest() override {}
77 64
78 protected: 65 protected:
79 MultiThreadedCertVerifier verifier_; 66 MultiThreadedCertVerifier verifier_;
80 }; 67 };
81 68
82 TEST_F(MultiThreadedCertVerifierTest, CacheHit) {
83 base::FilePath certs_dir = GetTestCertsDirectory();
84 scoped_refptr<X509Certificate> test_cert(
85 ImportCertFromFile(certs_dir, "ok_cert.pem"));
86 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
87
88 int error;
89 CertVerifyResult verify_result;
90 TestCompletionCallback callback;
91 std::unique_ptr<CertVerifier::Request> request;
92
93 error = verifier_.Verify(
94 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
95 std::string(), CertificateList()),
96 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
97 ASSERT_EQ(ERR_IO_PENDING, error);
98 EXPECT_TRUE(request);
99 error = callback.WaitForResult();
100 ASSERT_TRUE(IsCertificateError(error));
101 ASSERT_EQ(1u, verifier_.requests());
102 ASSERT_EQ(0u, verifier_.cache_hits());
103 ASSERT_EQ(0u, verifier_.inflight_joins());
104 ASSERT_EQ(1u, verifier_.GetCacheSize());
105
106 error = verifier_.Verify(
107 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
108 std::string(), CertificateList()),
109 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
110 // Synchronous completion.
111 ASSERT_NE(ERR_IO_PENDING, error);
112 ASSERT_TRUE(IsCertificateError(error));
113 ASSERT_FALSE(request);
114 ASSERT_EQ(2u, verifier_.requests());
115 ASSERT_EQ(1u, verifier_.cache_hits());
116 ASSERT_EQ(0u, verifier_.inflight_joins());
117 ASSERT_EQ(1u, verifier_.GetCacheSize());
118 }
119
120 // Tests the same server certificate with different intermediate CA
121 // certificates. These should be treated as different certificate chains even
122 // though the two X509Certificate objects contain the same server certificate.
123 TEST_F(MultiThreadedCertVerifierTest, DifferentCACerts) {
124 base::FilePath certs_dir = GetTestCertsDirectory();
125
126 scoped_refptr<X509Certificate> server_cert =
127 ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
128 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
129
130 scoped_refptr<X509Certificate> intermediate_cert1 =
131 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
132 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1.get());
133
134 scoped_refptr<X509Certificate> intermediate_cert2 =
135 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
136 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2.get());
137
138 X509Certificate::OSCertHandles intermediates;
139 intermediates.push_back(intermediate_cert1->os_cert_handle());
140 scoped_refptr<X509Certificate> cert_chain1 =
141 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
142 intermediates);
143
144 intermediates.clear();
145 intermediates.push_back(intermediate_cert2->os_cert_handle());
146 scoped_refptr<X509Certificate> cert_chain2 =
147 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
148 intermediates);
149
150 int error;
151 CertVerifyResult verify_result;
152 TestCompletionCallback callback;
153 std::unique_ptr<CertVerifier::Request> request;
154
155 error = verifier_.Verify(
156 CertVerifier::RequestParams(cert_chain1, "www.example.com", 0,
157 std::string(), CertificateList()),
158 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
159 ASSERT_EQ(ERR_IO_PENDING, error);
160 EXPECT_TRUE(request);
161 error = callback.WaitForResult();
162 ASSERT_TRUE(IsCertificateError(error));
163 ASSERT_EQ(1u, verifier_.requests());
164 ASSERT_EQ(0u, verifier_.cache_hits());
165 ASSERT_EQ(0u, verifier_.inflight_joins());
166 ASSERT_EQ(1u, verifier_.GetCacheSize());
167
168 error = verifier_.Verify(
169 CertVerifier::RequestParams(cert_chain2, "www.example.com", 0,
170 std::string(), CertificateList()),
171 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
172 ASSERT_EQ(ERR_IO_PENDING, error);
173 EXPECT_TRUE(request);
174 error = callback.WaitForResult();
175 ASSERT_TRUE(IsCertificateError(error));
176 ASSERT_EQ(2u, verifier_.requests());
177 ASSERT_EQ(0u, verifier_.cache_hits());
178 ASSERT_EQ(0u, verifier_.inflight_joins());
179 ASSERT_EQ(2u, verifier_.GetCacheSize());
180 }
181
182 // Tests an inflight join. 69 // Tests an inflight join.
183 TEST_F(MultiThreadedCertVerifierTest, InflightJoin) { 70 TEST_F(MultiThreadedCertVerifierTest, InflightJoin) {
184 base::FilePath certs_dir = GetTestCertsDirectory(); 71 base::FilePath certs_dir = GetTestCertsDirectory();
185 scoped_refptr<X509Certificate> test_cert( 72 scoped_refptr<X509Certificate> test_cert(
186 ImportCertFromFile(certs_dir, "ok_cert.pem")); 73 ImportCertFromFile(certs_dir, "ok_cert.pem"));
187 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 74 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
188 75
189 int error; 76 int error;
190 CertVerifyResult verify_result; 77 CertVerifyResult verify_result;
191 TestCompletionCallback callback; 78 TestCompletionCallback callback;
(...skipping 12 matching lines...) Expand all
204 CertVerifier::RequestParams(test_cert, "www.example.com", 0, 91 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
205 std::string(), CertificateList()), 92 std::string(), CertificateList()),
206 NULL, &verify_result2, callback2.callback(), &request2, BoundNetLog()); 93 NULL, &verify_result2, callback2.callback(), &request2, BoundNetLog());
207 EXPECT_EQ(ERR_IO_PENDING, error); 94 EXPECT_EQ(ERR_IO_PENDING, error);
208 EXPECT_TRUE(request2); 95 EXPECT_TRUE(request2);
209 error = callback.WaitForResult(); 96 error = callback.WaitForResult();
210 EXPECT_TRUE(IsCertificateError(error)); 97 EXPECT_TRUE(IsCertificateError(error));
211 error = callback2.WaitForResult(); 98 error = callback2.WaitForResult();
212 ASSERT_TRUE(IsCertificateError(error)); 99 ASSERT_TRUE(IsCertificateError(error));
213 ASSERT_EQ(2u, verifier_.requests()); 100 ASSERT_EQ(2u, verifier_.requests());
214 ASSERT_EQ(0u, verifier_.cache_hits());
215 ASSERT_EQ(1u, verifier_.inflight_joins()); 101 ASSERT_EQ(1u, verifier_.inflight_joins());
216 } 102 }
217 103
218 // Tests that the callback of a canceled request is never made. 104 // Tests that the callback of a canceled request is never made.
219 TEST_F(MultiThreadedCertVerifierTest, CancelRequest) { 105 TEST_F(MultiThreadedCertVerifierTest, CancelRequest) {
220 base::FilePath certs_dir = GetTestCertsDirectory(); 106 base::FilePath certs_dir = GetTestCertsDirectory();
221 scoped_refptr<X509Certificate> test_cert( 107 scoped_refptr<X509Certificate> test_cert(
222 ImportCertFromFile(certs_dir, "ok_cert.pem")); 108 ImportCertFromFile(certs_dir, "ok_cert.pem"));
223 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 109 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
224 110
(...skipping 14 matching lines...) Expand all
239 // worker thread) is likely to complete by the end of this test. 125 // worker thread) is likely to complete by the end of this test.
240 TestCompletionCallback callback; 126 TestCompletionCallback callback;
241 for (int i = 0; i < 5; ++i) { 127 for (int i = 0; i < 5; ++i) {
242 error = verifier_.Verify( 128 error = verifier_.Verify(
243 CertVerifier::RequestParams(test_cert, "www2.example.com", 0, 129 CertVerifier::RequestParams(test_cert, "www2.example.com", 0,
244 std::string(), CertificateList()), 130 std::string(), CertificateList()),
245 NULL, &verify_result, callback.callback(), &request, BoundNetLog()); 131 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
246 ASSERT_EQ(ERR_IO_PENDING, error); 132 ASSERT_EQ(ERR_IO_PENDING, error);
247 EXPECT_TRUE(request); 133 EXPECT_TRUE(request);
248 error = callback.WaitForResult(); 134 error = callback.WaitForResult();
249 verifier_.ClearCache();
250 } 135 }
251 } 136 }
252 137
253 // Tests that a canceled request is not leaked. 138 // Tests that a canceled request is not leaked.
254 TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) { 139 TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) {
255 base::FilePath certs_dir = GetTestCertsDirectory(); 140 base::FilePath certs_dir = GetTestCertsDirectory();
256 scoped_refptr<X509Certificate> test_cert( 141 scoped_refptr<X509Certificate> test_cert(
257 ImportCertFromFile(certs_dir, "ok_cert.pem")); 142 ImportCertFromFile(certs_dir, "ok_cert.pem"));
258 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 143 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
259 144
(...skipping 14 matching lines...) Expand all
274 CertVerifier::RequestParams(test_cert, "www.example.com", 0, 159 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
275 std::string(), CertificateList()), 160 std::string(), CertificateList()),
276 NULL, &verify_result, callback.callback(), &request, BoundNetLog()); 161 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
277 } 162 }
278 ASSERT_EQ(ERR_IO_PENDING, error); 163 ASSERT_EQ(ERR_IO_PENDING, error);
279 EXPECT_TRUE(request); 164 EXPECT_TRUE(request);
280 request.reset(); 165 request.reset();
281 // Destroy |verifier| by going out of scope. 166 // Destroy |verifier| by going out of scope.
282 } 167 }
283 168
284 TEST_F(MultiThreadedCertVerifierTest, CertTrustAnchorProvider) {
285 MockCertTrustAnchorProvider trust_provider;
286 verifier_.SetCertTrustAnchorProvider(&trust_provider);
287
288 scoped_refptr<X509Certificate> test_cert(
289 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
290 ASSERT_TRUE(test_cert.get());
291
292 const CertificateList empty_cert_list;
293 CertificateList cert_list;
294 cert_list.push_back(test_cert);
295
296 // Check that Verify() asks the |trust_provider| for the current list of
297 // additional trust anchors.
298 int error;
299 CertVerifyResult verify_result;
300 TestCompletionCallback callback;
301 std::unique_ptr<CertVerifier::Request> request;
302 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
303 .WillOnce(ReturnRef(empty_cert_list));
304 error = verifier_.Verify(
305 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
306 std::string(), CertificateList()),
307 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
308 Mock::VerifyAndClearExpectations(&trust_provider);
309 ASSERT_EQ(ERR_IO_PENDING, error);
310 EXPECT_TRUE(request);
311 error = callback.WaitForResult();
312 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
313 ASSERT_EQ(1u, verifier_.requests());
314 ASSERT_EQ(0u, verifier_.cache_hits());
315
316 // The next Verify() uses the cached result.
317 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
318 .WillOnce(ReturnRef(empty_cert_list));
319 error = verifier_.Verify(
320 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
321 std::string(), CertificateList()),
322 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
323 Mock::VerifyAndClearExpectations(&trust_provider);
324 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
325 EXPECT_FALSE(request);
326 ASSERT_EQ(2u, verifier_.requests());
327 ASSERT_EQ(1u, verifier_.cache_hits());
328
329 // Another Verify() for the same certificate but with a different list of
330 // trust anchors will not reuse the cache.
331 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors())
332 .WillOnce(ReturnRef(cert_list));
333 error = verifier_.Verify(
334 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
335 std::string(), CertificateList()),
336 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
337 Mock::VerifyAndClearExpectations(&trust_provider);
338 ASSERT_EQ(ERR_IO_PENDING, error);
339 EXPECT_TRUE(request);
340 error = callback.WaitForResult();
341 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
342 ASSERT_EQ(3u, verifier_.requests());
343 ASSERT_EQ(1u, verifier_.cache_hits());
344 }
345
346 // Tests de-duplication of requests. 169 // Tests de-duplication of requests.
347 // Starts up 5 requests, of which 3 are unique. 170 // Starts up 5 requests, of which 3 are unique.
348 TEST_F(MultiThreadedCertVerifierTest, MultipleInflightJoin) { 171 TEST_F(MultiThreadedCertVerifierTest, MultipleInflightJoin) {
349 base::FilePath certs_dir = GetTestCertsDirectory(); 172 base::FilePath certs_dir = GetTestCertsDirectory();
350 scoped_refptr<X509Certificate> test_cert( 173 scoped_refptr<X509Certificate> test_cert(
351 ImportCertFromFile(certs_dir, "ok_cert.pem")); 174 ImportCertFromFile(certs_dir, "ok_cert.pem"));
352 ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get()); 175 ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get());
353 176
354 int error; 177 int error;
355 CertVerifyResult verify_result1; 178 CertVerifyResult verify_result1;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 234
412 error = callback1.WaitForResult(); 235 error = callback1.WaitForResult();
413 EXPECT_TRUE(IsCertificateError(error)); 236 EXPECT_TRUE(IsCertificateError(error));
414 error = callback2.WaitForResult(); 237 error = callback2.WaitForResult();
415 ASSERT_TRUE(IsCertificateError(error)); 238 ASSERT_TRUE(IsCertificateError(error));
416 error = callback4.WaitForResult(); 239 error = callback4.WaitForResult();
417 ASSERT_TRUE(IsCertificateError(error)); 240 ASSERT_TRUE(IsCertificateError(error));
418 241
419 // Let the other requests automatically cancel. 242 // Let the other requests automatically cancel.
420 ASSERT_EQ(5u, verifier_.requests()); 243 ASSERT_EQ(5u, verifier_.requests());
421 ASSERT_EQ(0u, verifier_.cache_hits());
422 ASSERT_EQ(2u, verifier_.inflight_joins()); 244 ASSERT_EQ(2u, verifier_.inflight_joins());
423 } 245 }
424 246
425 } // namespace net 247 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698