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

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: CrOS fixes Created 4 years, 6 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
« no previous file with comments | « net/cert/multi_threaded_cert_verifier.cc ('k') | net/net.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
19 #include "net/cert/cert_verify_proc.h" 17 #include "net/cert/cert_verify_proc.h"
20 #include "net/cert/cert_verify_result.h" 18 #include "net/cert/cert_verify_result.h"
21 #include "net/cert/x509_certificate.h" 19 #include "net/cert/x509_certificate.h"
22 #include "net/log/net_log.h" 20 #include "net/log/net_log.h"
23 #include "net/test/cert_test_util.h" 21 #include "net/test/cert_test_util.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
26 23
27 using testing::Mock;
28 using testing::ReturnRef;
29
30 namespace net { 24 namespace net {
31 25
32 namespace { 26 namespace {
33 27
34 void FailTest(int /* result */) { 28 void FailTest(int /* result */) {
35 FAIL(); 29 FAIL();
36 } 30 }
37 31
38 class MockCertVerifyProc : public CertVerifyProc { 32 class MockCertVerifyProc : public CertVerifyProc {
39 public: 33 public:
(...skipping 13 matching lines...) Expand all
53 CRLSet* crl_set, 47 CRLSet* crl_set,
54 const CertificateList& additional_trust_anchors, 48 const CertificateList& additional_trust_anchors,
55 CertVerifyResult* verify_result) override { 49 CertVerifyResult* verify_result) override {
56 verify_result->Reset(); 50 verify_result->Reset();
57 verify_result->verified_cert = cert; 51 verify_result->verified_cert = cert;
58 verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID; 52 verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID;
59 return ERR_CERT_COMMON_NAME_INVALID; 53 return ERR_CERT_COMMON_NAME_INVALID;
60 } 54 }
61 }; 55 };
62 56
63 class MockCertTrustAnchorProvider : public CertTrustAnchorProvider {
64 public:
65 MockCertTrustAnchorProvider() {}
66 virtual ~MockCertTrustAnchorProvider() {}
67
68 MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&());
69 };
70
71 } // namespace 57 } // namespace
72 58
73 class MultiThreadedCertVerifierTest : public ::testing::Test { 59 class MultiThreadedCertVerifierTest : public ::testing::Test {
74 public: 60 public:
75 MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {} 61 MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {}
76 ~MultiThreadedCertVerifierTest() override {} 62 ~MultiThreadedCertVerifierTest() override {}
77 63
78 protected: 64 protected:
79 MultiThreadedCertVerifier verifier_; 65 MultiThreadedCertVerifier verifier_;
80 }; 66 };
81 67
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. 68 // Tests an inflight join.
183 TEST_F(MultiThreadedCertVerifierTest, InflightJoin) { 69 TEST_F(MultiThreadedCertVerifierTest, InflightJoin) {
184 base::FilePath certs_dir = GetTestCertsDirectory(); 70 base::FilePath certs_dir = GetTestCertsDirectory();
185 scoped_refptr<X509Certificate> test_cert( 71 scoped_refptr<X509Certificate> test_cert(
186 ImportCertFromFile(certs_dir, "ok_cert.pem")); 72 ImportCertFromFile(certs_dir, "ok_cert.pem"));
187 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 73 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
188 74
189 int error; 75 int error;
190 CertVerifyResult verify_result; 76 CertVerifyResult verify_result;
191 TestCompletionCallback callback; 77 TestCompletionCallback callback;
(...skipping 12 matching lines...) Expand all
204 CertVerifier::RequestParams(test_cert, "www.example.com", 0, 90 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
205 std::string(), CertificateList()), 91 std::string(), CertificateList()),
206 NULL, &verify_result2, callback2.callback(), &request2, BoundNetLog()); 92 NULL, &verify_result2, callback2.callback(), &request2, BoundNetLog());
207 EXPECT_EQ(ERR_IO_PENDING, error); 93 EXPECT_EQ(ERR_IO_PENDING, error);
208 EXPECT_TRUE(request2); 94 EXPECT_TRUE(request2);
209 error = callback.WaitForResult(); 95 error = callback.WaitForResult();
210 EXPECT_TRUE(IsCertificateError(error)); 96 EXPECT_TRUE(IsCertificateError(error));
211 error = callback2.WaitForResult(); 97 error = callback2.WaitForResult();
212 ASSERT_TRUE(IsCertificateError(error)); 98 ASSERT_TRUE(IsCertificateError(error));
213 ASSERT_EQ(2u, verifier_.requests()); 99 ASSERT_EQ(2u, verifier_.requests());
214 ASSERT_EQ(0u, verifier_.cache_hits());
215 ASSERT_EQ(1u, verifier_.inflight_joins()); 100 ASSERT_EQ(1u, verifier_.inflight_joins());
216 } 101 }
217 102
218 // Tests that the callback of a canceled request is never made. 103 // Tests that the callback of a canceled request is never made.
219 TEST_F(MultiThreadedCertVerifierTest, CancelRequest) { 104 TEST_F(MultiThreadedCertVerifierTest, CancelRequest) {
220 base::FilePath certs_dir = GetTestCertsDirectory(); 105 base::FilePath certs_dir = GetTestCertsDirectory();
221 scoped_refptr<X509Certificate> test_cert( 106 scoped_refptr<X509Certificate> test_cert(
222 ImportCertFromFile(certs_dir, "ok_cert.pem")); 107 ImportCertFromFile(certs_dir, "ok_cert.pem"));
223 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 108 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
224 109
(...skipping 14 matching lines...) Expand all
239 // worker thread) is likely to complete by the end of this test. 124 // worker thread) is likely to complete by the end of this test.
240 TestCompletionCallback callback; 125 TestCompletionCallback callback;
241 for (int i = 0; i < 5; ++i) { 126 for (int i = 0; i < 5; ++i) {
242 error = verifier_.Verify( 127 error = verifier_.Verify(
243 CertVerifier::RequestParams(test_cert, "www2.example.com", 0, 128 CertVerifier::RequestParams(test_cert, "www2.example.com", 0,
244 std::string(), CertificateList()), 129 std::string(), CertificateList()),
245 NULL, &verify_result, callback.callback(), &request, BoundNetLog()); 130 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
246 ASSERT_EQ(ERR_IO_PENDING, error); 131 ASSERT_EQ(ERR_IO_PENDING, error);
247 EXPECT_TRUE(request); 132 EXPECT_TRUE(request);
248 error = callback.WaitForResult(); 133 error = callback.WaitForResult();
249 verifier_.ClearCache();
250 } 134 }
251 } 135 }
252 136
253 // Tests that a canceled request is not leaked. 137 // Tests that a canceled request is not leaked.
254 TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) { 138 TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) {
255 base::FilePath certs_dir = GetTestCertsDirectory(); 139 base::FilePath certs_dir = GetTestCertsDirectory();
256 scoped_refptr<X509Certificate> test_cert( 140 scoped_refptr<X509Certificate> test_cert(
257 ImportCertFromFile(certs_dir, "ok_cert.pem")); 141 ImportCertFromFile(certs_dir, "ok_cert.pem"));
258 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); 142 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
259 143
(...skipping 14 matching lines...) Expand all
274 CertVerifier::RequestParams(test_cert, "www.example.com", 0, 158 CertVerifier::RequestParams(test_cert, "www.example.com", 0,
275 std::string(), CertificateList()), 159 std::string(), CertificateList()),
276 NULL, &verify_result, callback.callback(), &request, BoundNetLog()); 160 NULL, &verify_result, callback.callback(), &request, BoundNetLog());
277 } 161 }
278 ASSERT_EQ(ERR_IO_PENDING, error); 162 ASSERT_EQ(ERR_IO_PENDING, error);
279 EXPECT_TRUE(request); 163 EXPECT_TRUE(request);
280 request.reset(); 164 request.reset();
281 // Destroy |verifier| by going out of scope. 165 // Destroy |verifier| by going out of scope.
282 } 166 }
283 167
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. 168 // Tests de-duplication of requests.
347 // Starts up 5 requests, of which 3 are unique. 169 // Starts up 5 requests, of which 3 are unique.
348 TEST_F(MultiThreadedCertVerifierTest, MultipleInflightJoin) { 170 TEST_F(MultiThreadedCertVerifierTest, MultipleInflightJoin) {
349 base::FilePath certs_dir = GetTestCertsDirectory(); 171 base::FilePath certs_dir = GetTestCertsDirectory();
350 scoped_refptr<X509Certificate> test_cert( 172 scoped_refptr<X509Certificate> test_cert(
351 ImportCertFromFile(certs_dir, "ok_cert.pem")); 173 ImportCertFromFile(certs_dir, "ok_cert.pem"));
352 ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get()); 174 ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get());
353 175
354 int error; 176 int error;
355 CertVerifyResult verify_result1; 177 CertVerifyResult verify_result1;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 233
412 error = callback1.WaitForResult(); 234 error = callback1.WaitForResult();
413 EXPECT_TRUE(IsCertificateError(error)); 235 EXPECT_TRUE(IsCertificateError(error));
414 error = callback2.WaitForResult(); 236 error = callback2.WaitForResult();
415 ASSERT_TRUE(IsCertificateError(error)); 237 ASSERT_TRUE(IsCertificateError(error));
416 error = callback4.WaitForResult(); 238 error = callback4.WaitForResult();
417 ASSERT_TRUE(IsCertificateError(error)); 239 ASSERT_TRUE(IsCertificateError(error));
418 240
419 // Let the other requests automatically cancel. 241 // Let the other requests automatically cancel.
420 ASSERT_EQ(5u, verifier_.requests()); 242 ASSERT_EQ(5u, verifier_.requests());
421 ASSERT_EQ(0u, verifier_.cache_hits());
422 ASSERT_EQ(2u, verifier_.inflight_joins()); 243 ASSERT_EQ(2u, verifier_.inflight_joins());
423 } 244 }
424 245
425 } // namespace net 246 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/multi_threaded_cert_verifier.cc ('k') | net/net.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698