OLD | NEW |
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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/leak_annotations.h" | 8 #include "base/debug/leak_annotations.h" |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 | 78 |
79 TEST_F(MultiThreadedCertVerifierTest, CacheHit) { | 79 TEST_F(MultiThreadedCertVerifierTest, CacheHit) { |
80 base::FilePath certs_dir = GetTestCertsDirectory(); | 80 base::FilePath certs_dir = GetTestCertsDirectory(); |
81 scoped_refptr<X509Certificate> test_cert( | 81 scoped_refptr<X509Certificate> test_cert( |
82 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 82 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
83 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | 83 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); |
84 | 84 |
85 int error; | 85 int error; |
86 CertVerifyResult verify_result; | 86 CertVerifyResult verify_result; |
87 TestCompletionCallback callback; | 87 TestCompletionCallback callback; |
88 CertVerifier::RequestHandle request_handle; | 88 scoped_ptr<CertVerifier::Request> request_handle; |
89 | 89 |
90 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, | 90 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, |
91 NULL, &verify_result, callback.callback(), | 91 NULL, &verify_result, callback.callback(), |
92 &request_handle, BoundNetLog()); | 92 &request_handle, BoundNetLog()); |
93 ASSERT_EQ(ERR_IO_PENDING, error); | 93 ASSERT_EQ(ERR_IO_PENDING, error); |
94 EXPECT_TRUE(request_handle); | 94 EXPECT_TRUE(request_handle); |
95 error = callback.WaitForResult(); | 95 error = callback.WaitForResult(); |
96 ASSERT_TRUE(IsCertificateError(error)); | 96 ASSERT_TRUE(IsCertificateError(error)); |
97 ASSERT_EQ(1u, verifier_.requests()); | 97 ASSERT_EQ(1u, verifier_.requests()); |
98 ASSERT_EQ(0u, verifier_.cache_hits()); | 98 ASSERT_EQ(0u, verifier_.cache_hits()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 138 |
139 intermediates.clear(); | 139 intermediates.clear(); |
140 intermediates.push_back(intermediate_cert2->os_cert_handle()); | 140 intermediates.push_back(intermediate_cert2->os_cert_handle()); |
141 scoped_refptr<X509Certificate> cert_chain2 = | 141 scoped_refptr<X509Certificate> cert_chain2 = |
142 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), | 142 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), |
143 intermediates); | 143 intermediates); |
144 | 144 |
145 int error; | 145 int error; |
146 CertVerifyResult verify_result; | 146 CertVerifyResult verify_result; |
147 TestCompletionCallback callback; | 147 TestCompletionCallback callback; |
148 CertVerifier::RequestHandle request_handle; | 148 scoped_ptr<CertVerifier::Request> request_handle; |
149 | 149 |
150 error = verifier_.Verify(cert_chain1.get(), "www.example.com", std::string(), | 150 error = verifier_.Verify(cert_chain1.get(), "www.example.com", std::string(), |
151 0, NULL, &verify_result, callback.callback(), | 151 0, NULL, &verify_result, callback.callback(), |
152 &request_handle, BoundNetLog()); | 152 &request_handle, BoundNetLog()); |
153 ASSERT_EQ(ERR_IO_PENDING, error); | 153 ASSERT_EQ(ERR_IO_PENDING, error); |
154 EXPECT_TRUE(request_handle); | 154 EXPECT_TRUE(request_handle); |
155 error = callback.WaitForResult(); | 155 error = callback.WaitForResult(); |
156 ASSERT_TRUE(IsCertificateError(error)); | 156 ASSERT_TRUE(IsCertificateError(error)); |
157 ASSERT_EQ(1u, verifier_.requests()); | 157 ASSERT_EQ(1u, verifier_.requests()); |
158 ASSERT_EQ(0u, verifier_.cache_hits()); | 158 ASSERT_EQ(0u, verifier_.cache_hits()); |
(...skipping 16 matching lines...) Expand all Loading... |
175 // Tests an inflight join. | 175 // Tests an inflight join. |
176 TEST_F(MultiThreadedCertVerifierTest, InflightJoin) { | 176 TEST_F(MultiThreadedCertVerifierTest, InflightJoin) { |
177 base::FilePath certs_dir = GetTestCertsDirectory(); | 177 base::FilePath certs_dir = GetTestCertsDirectory(); |
178 scoped_refptr<X509Certificate> test_cert( | 178 scoped_refptr<X509Certificate> test_cert( |
179 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 179 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
180 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | 180 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); |
181 | 181 |
182 int error; | 182 int error; |
183 CertVerifyResult verify_result; | 183 CertVerifyResult verify_result; |
184 TestCompletionCallback callback; | 184 TestCompletionCallback callback; |
185 CertVerifier::RequestHandle request_handle; | 185 scoped_ptr<CertVerifier::Request> request_handle; |
186 CertVerifyResult verify_result2; | 186 CertVerifyResult verify_result2; |
187 TestCompletionCallback callback2; | 187 TestCompletionCallback callback2; |
188 CertVerifier::RequestHandle request_handle2; | 188 scoped_ptr<CertVerifier::Request> request_handle2; |
189 | 189 |
190 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, | 190 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, |
191 NULL, &verify_result, callback.callback(), | 191 NULL, &verify_result, callback.callback(), |
192 &request_handle, BoundNetLog()); | 192 &request_handle, BoundNetLog()); |
193 ASSERT_EQ(ERR_IO_PENDING, error); | 193 ASSERT_EQ(ERR_IO_PENDING, error); |
194 EXPECT_TRUE(request_handle); | 194 EXPECT_TRUE(request_handle); |
195 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, | 195 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, |
196 NULL, &verify_result2, callback2.callback(), | 196 NULL, &verify_result2, callback2.callback(), |
197 &request_handle2, BoundNetLog()); | 197 &request_handle2, BoundNetLog()); |
198 EXPECT_EQ(ERR_IO_PENDING, error); | 198 EXPECT_EQ(ERR_IO_PENDING, error); |
199 EXPECT_TRUE(request_handle2 != NULL); | 199 EXPECT_TRUE(request_handle2); |
200 error = callback.WaitForResult(); | 200 error = callback.WaitForResult(); |
201 EXPECT_TRUE(IsCertificateError(error)); | 201 EXPECT_TRUE(IsCertificateError(error)); |
202 error = callback2.WaitForResult(); | 202 error = callback2.WaitForResult(); |
203 ASSERT_TRUE(IsCertificateError(error)); | 203 ASSERT_TRUE(IsCertificateError(error)); |
204 ASSERT_EQ(2u, verifier_.requests()); | 204 ASSERT_EQ(2u, verifier_.requests()); |
205 ASSERT_EQ(0u, verifier_.cache_hits()); | 205 ASSERT_EQ(0u, verifier_.cache_hits()); |
206 ASSERT_EQ(1u, verifier_.inflight_joins()); | 206 ASSERT_EQ(1u, verifier_.inflight_joins()); |
207 } | 207 } |
208 | 208 |
209 // Tests that the callback of a canceled request is never made. | 209 // Tests that the callback of a canceled request is never made. |
210 TEST_F(MultiThreadedCertVerifierTest, CancelRequest) { | 210 TEST_F(MultiThreadedCertVerifierTest, CancelRequest) { |
211 base::FilePath certs_dir = GetTestCertsDirectory(); | 211 base::FilePath certs_dir = GetTestCertsDirectory(); |
212 scoped_refptr<X509Certificate> test_cert( | 212 scoped_refptr<X509Certificate> test_cert( |
213 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 213 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
214 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | 214 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); |
215 | 215 |
216 int error; | 216 int error; |
217 CertVerifyResult verify_result; | 217 CertVerifyResult verify_result; |
218 CertVerifier::RequestHandle request_handle; | 218 scoped_ptr<CertVerifier::Request> request_handle; |
219 | 219 |
220 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, | 220 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, |
221 NULL, &verify_result, base::Bind(&FailTest), | 221 NULL, &verify_result, base::Bind(&FailTest), |
222 &request_handle, BoundNetLog()); | 222 &request_handle, BoundNetLog()); |
223 ASSERT_EQ(ERR_IO_PENDING, error); | 223 ASSERT_EQ(ERR_IO_PENDING, error); |
224 ASSERT_TRUE(request_handle != NULL); | 224 ASSERT_TRUE(request_handle); |
225 verifier_.CancelRequest(request_handle); | 225 request_handle.reset(); |
226 | 226 |
227 // Issue a few more requests to the worker pool and wait for their | 227 // Issue a few more requests to the worker pool and wait for their |
228 // completion, so that the task of the canceled request (which runs on a | 228 // completion, so that the task of the canceled request (which runs on a |
229 // worker thread) is likely to complete by the end of this test. | 229 // worker thread) is likely to complete by the end of this test. |
230 TestCompletionCallback callback; | 230 TestCompletionCallback callback; |
231 for (int i = 0; i < 5; ++i) { | 231 for (int i = 0; i < 5; ++i) { |
232 error = verifier_.Verify(test_cert.get(), "www2.example.com", std::string(), | 232 error = verifier_.Verify(test_cert.get(), "www2.example.com", std::string(), |
233 0, NULL, &verify_result, callback.callback(), | 233 0, NULL, &verify_result, callback.callback(), |
234 &request_handle, BoundNetLog()); | 234 &request_handle, BoundNetLog()); |
235 ASSERT_EQ(ERR_IO_PENDING, error); | 235 ASSERT_EQ(ERR_IO_PENDING, error); |
236 EXPECT_TRUE(request_handle); | 236 EXPECT_TRUE(request_handle); |
237 error = callback.WaitForResult(); | 237 error = callback.WaitForResult(); |
238 verifier_.ClearCache(); | 238 verifier_.ClearCache(); |
239 } | 239 } |
240 } | 240 } |
241 | 241 |
242 // Tests that a canceled request is not leaked. | 242 // Tests that a canceled request is not leaked. |
243 TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) { | 243 TEST_F(MultiThreadedCertVerifierTest, CancelRequestThenQuit) { |
244 base::FilePath certs_dir = GetTestCertsDirectory(); | 244 base::FilePath certs_dir = GetTestCertsDirectory(); |
245 scoped_refptr<X509Certificate> test_cert( | 245 scoped_refptr<X509Certificate> test_cert( |
246 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 246 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
247 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | 247 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); |
248 | 248 |
249 int error; | 249 int error; |
250 CertVerifyResult verify_result; | 250 CertVerifyResult verify_result; |
251 TestCompletionCallback callback; | 251 TestCompletionCallback callback; |
252 CertVerifier::RequestHandle request_handle; | 252 scoped_ptr<CertVerifier::Request> request_handle; |
253 | 253 |
254 { | 254 { |
255 // Because shutdown intentionally doesn't join worker threads, a | 255 // Because shutdown intentionally doesn't join worker threads, a |
256 // CertVerifyWorker may be leaked if the main thread shuts down before the | 256 // CertVerifyWorker may be leaked if the main thread shuts down before the |
257 // worker thread. | 257 // worker thread. |
258 ANNOTATE_SCOPED_MEMORY_LEAK; | 258 ANNOTATE_SCOPED_MEMORY_LEAK; |
259 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), | 259 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), |
260 0, NULL, &verify_result, callback.callback(), | 260 0, NULL, &verify_result, callback.callback(), |
261 &request_handle, BoundNetLog()); | 261 &request_handle, BoundNetLog()); |
262 } | 262 } |
263 ASSERT_EQ(ERR_IO_PENDING, error); | 263 ASSERT_EQ(ERR_IO_PENDING, error); |
264 EXPECT_TRUE(request_handle); | 264 EXPECT_TRUE(request_handle); |
265 verifier_.CancelRequest(request_handle); | 265 request_handle.reset(); |
266 // Destroy |verifier| by going out of scope. | 266 // Destroy |verifier| by going out of scope. |
267 } | 267 } |
268 | 268 |
269 TEST_F(MultiThreadedCertVerifierTest, RequestParamsComparators) { | 269 TEST_F(MultiThreadedCertVerifierTest, RequestParamsComparators) { |
270 SHA1HashValue a_key; | 270 SHA1HashValue a_key; |
271 memset(a_key.data, 'a', sizeof(a_key.data)); | 271 memset(a_key.data, 'a', sizeof(a_key.data)); |
272 | 272 |
273 SHA1HashValue z_key; | 273 SHA1HashValue z_key; |
274 memset(z_key.data, 'z', sizeof(z_key.data)); | 274 memset(z_key.data, 'z', sizeof(z_key.data)); |
275 | 275 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 | 386 |
387 const CertificateList empty_cert_list; | 387 const CertificateList empty_cert_list; |
388 CertificateList cert_list; | 388 CertificateList cert_list; |
389 cert_list.push_back(test_cert); | 389 cert_list.push_back(test_cert); |
390 | 390 |
391 // Check that Verify() asks the |trust_provider| for the current list of | 391 // Check that Verify() asks the |trust_provider| for the current list of |
392 // additional trust anchors. | 392 // additional trust anchors. |
393 int error; | 393 int error; |
394 CertVerifyResult verify_result; | 394 CertVerifyResult verify_result; |
395 TestCompletionCallback callback; | 395 TestCompletionCallback callback; |
396 CertVerifier::RequestHandle request_handle; | 396 scoped_ptr<CertVerifier::Request> request_handle; |
397 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) | 397 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) |
398 .WillOnce(ReturnRef(empty_cert_list)); | 398 .WillOnce(ReturnRef(empty_cert_list)); |
399 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, | 399 error = verifier_.Verify(test_cert.get(), "www.example.com", std::string(), 0, |
400 NULL, &verify_result, callback.callback(), | 400 NULL, &verify_result, callback.callback(), |
401 &request_handle, BoundNetLog()); | 401 &request_handle, BoundNetLog()); |
402 Mock::VerifyAndClearExpectations(&trust_provider); | 402 Mock::VerifyAndClearExpectations(&trust_provider); |
403 ASSERT_EQ(ERR_IO_PENDING, error); | 403 ASSERT_EQ(ERR_IO_PENDING, error); |
404 EXPECT_TRUE(request_handle); | 404 EXPECT_TRUE(request_handle); |
405 error = callback.WaitForResult(); | 405 error = callback.WaitForResult(); |
406 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); | 406 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); |
(...skipping 21 matching lines...) Expand all Loading... |
428 &request_handle, BoundNetLog()); | 428 &request_handle, BoundNetLog()); |
429 Mock::VerifyAndClearExpectations(&trust_provider); | 429 Mock::VerifyAndClearExpectations(&trust_provider); |
430 ASSERT_EQ(ERR_IO_PENDING, error); | 430 ASSERT_EQ(ERR_IO_PENDING, error); |
431 EXPECT_TRUE(request_handle); | 431 EXPECT_TRUE(request_handle); |
432 error = callback.WaitForResult(); | 432 error = callback.WaitForResult(); |
433 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); | 433 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); |
434 ASSERT_EQ(3u, verifier_.requests()); | 434 ASSERT_EQ(3u, verifier_.requests()); |
435 ASSERT_EQ(1u, verifier_.cache_hits()); | 435 ASSERT_EQ(1u, verifier_.cache_hits()); |
436 } | 436 } |
437 | 437 |
| 438 // Tests de-duplication of requests. |
| 439 // Starts up 5 requests, of which 3 are unique. |
| 440 TEST_F(MultiThreadedCertVerifierTest, MultipleInflightJoin) { |
| 441 base::FilePath certs_dir = GetTestCertsDirectory(); |
| 442 scoped_refptr<X509Certificate> test_cert( |
| 443 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
| 444 ASSERT_NE(static_cast<X509Certificate*>(nullptr), test_cert.get()); |
| 445 |
| 446 int error; |
| 447 CertVerifyResult verify_result1; |
| 448 TestCompletionCallback callback1; |
| 449 scoped_ptr<CertVerifier::Request> request_handle1; |
| 450 CertVerifyResult verify_result2; |
| 451 TestCompletionCallback callback2; |
| 452 scoped_ptr<CertVerifier::Request> request_handle2; |
| 453 CertVerifyResult verify_result3; |
| 454 TestCompletionCallback callback3; |
| 455 scoped_ptr<CertVerifier::Request> request_handle3; |
| 456 CertVerifyResult verify_result4; |
| 457 TestCompletionCallback callback4; |
| 458 scoped_ptr<CertVerifier::Request> request_handle4; |
| 459 CertVerifyResult verify_result5; |
| 460 TestCompletionCallback callback5; |
| 461 scoped_ptr<CertVerifier::Request> request_handle5; |
| 462 |
| 463 const char domain1[] = "www.example1.com"; |
| 464 const char domain2[] = "www.exampleB.com"; |
| 465 const char domain3[] = "www.example3.com"; |
| 466 |
| 467 // Start 3 unique requests. |
| 468 error = verifier_.Verify(test_cert.get(), domain2, std::string(), 0, nullptr, |
| 469 &verify_result1, callback1.callback(), |
| 470 &request_handle1, BoundNetLog()); |
| 471 ASSERT_EQ(ERR_IO_PENDING, error); |
| 472 EXPECT_TRUE(request_handle1); |
| 473 |
| 474 error = verifier_.Verify(test_cert.get(), domain2, std::string(), 0, nullptr, |
| 475 &verify_result2, callback2.callback(), |
| 476 &request_handle2, BoundNetLog()); |
| 477 EXPECT_EQ(ERR_IO_PENDING, error); |
| 478 EXPECT_TRUE(request_handle2); |
| 479 |
| 480 error = verifier_.Verify(test_cert.get(), domain3, std::string(), 0, nullptr, |
| 481 &verify_result3, callback3.callback(), |
| 482 &request_handle3, BoundNetLog()); |
| 483 EXPECT_EQ(ERR_IO_PENDING, error); |
| 484 EXPECT_TRUE(request_handle3); |
| 485 |
| 486 // Start duplicate requests (which should join to existing jobs). |
| 487 error = verifier_.Verify(test_cert.get(), domain1, std::string(), 0, nullptr, |
| 488 &verify_result4, callback4.callback(), |
| 489 &request_handle4, BoundNetLog()); |
| 490 EXPECT_EQ(ERR_IO_PENDING, error); |
| 491 EXPECT_TRUE(request_handle4); |
| 492 |
| 493 error = verifier_.Verify(test_cert.get(), domain2, std::string(), 0, nullptr, |
| 494 &verify_result5, callback5.callback(), |
| 495 &request_handle5, BoundNetLog()); |
| 496 EXPECT_EQ(ERR_IO_PENDING, error); |
| 497 EXPECT_TRUE(request_handle5); |
| 498 |
| 499 error = callback1.WaitForResult(); |
| 500 EXPECT_TRUE(IsCertificateError(error)); |
| 501 error = callback2.WaitForResult(); |
| 502 ASSERT_TRUE(IsCertificateError(error)); |
| 503 error = callback4.WaitForResult(); |
| 504 ASSERT_TRUE(IsCertificateError(error)); |
| 505 |
| 506 // Let the other requests automatically cancel. |
| 507 ASSERT_EQ(5u, verifier_.requests()); |
| 508 ASSERT_EQ(0u, verifier_.cache_hits()); |
| 509 ASSERT_EQ(2u, verifier_.inflight_joins()); |
| 510 } |
| 511 |
438 } // namespace net | 512 } // namespace net |
OLD | NEW |