| 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/base/cert_verifier.h" | 5 #include "net/base/multi_threaded_cert_verifier.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "net/base/cert_test_util.h" | 11 #include "net/base/cert_test_util.h" |
| 12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
| 13 #include "net/base/net_log.h" | 13 #include "net/base/net_log.h" |
| 14 #include "net/base/test_completion_callback.h" | 14 #include "net/base/test_completion_callback.h" |
| 15 #include "net/base/x509_certificate.h" | 15 #include "net/base/x509_certificate.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 namespace net { | 18 namespace net { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 void FailTest(int /* result */) { | 22 void FailTest(int /* result */) { |
| 23 FAIL(); | 23 FAIL(); |
| 24 } | 24 } |
| 25 | 25 |
| 26 } // namespace; | 26 } // namespace; |
| 27 | 27 |
| 28 // Tests a cache hit, which should result in synchronous completion. | 28 // Tests a cache hit, which should result in synchronous completion. |
| 29 TEST(CertVerifierTest, CacheHit) { | 29 TEST(MultiThreadedCertVerifierTest, CacheHit) { |
| 30 CertVerifier verifier; | 30 MultiThreadedCertVerifier verifier; |
| 31 | 31 |
| 32 FilePath certs_dir = GetTestCertsDirectory(); | 32 FilePath certs_dir = GetTestCertsDirectory(); |
| 33 scoped_refptr<X509Certificate> test_cert( | 33 scoped_refptr<X509Certificate> test_cert( |
| 34 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 34 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
| 35 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); | 35 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); |
| 36 | 36 |
| 37 int error; | 37 int error; |
| 38 CertVerifyResult verify_result; | 38 CertVerifyResult verify_result; |
| 39 TestCompletionCallback callback; | 39 TestCompletionCallback callback; |
| 40 CertVerifier::RequestHandle request_handle; | 40 CertVerifier::RequestHandle request_handle; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 58 ASSERT_TRUE(request_handle == NULL); | 58 ASSERT_TRUE(request_handle == NULL); |
| 59 ASSERT_EQ(2u, verifier.requests()); | 59 ASSERT_EQ(2u, verifier.requests()); |
| 60 ASSERT_EQ(1u, verifier.cache_hits()); | 60 ASSERT_EQ(1u, verifier.cache_hits()); |
| 61 ASSERT_EQ(0u, verifier.inflight_joins()); | 61 ASSERT_EQ(0u, verifier.inflight_joins()); |
| 62 ASSERT_EQ(1u, verifier.GetCacheSize()); | 62 ASSERT_EQ(1u, verifier.GetCacheSize()); |
| 63 } | 63 } |
| 64 | 64 |
| 65 // Tests the same server certificate with different intermediate CA | 65 // Tests the same server certificate with different intermediate CA |
| 66 // certificates. These should be treated as different certificate chains even | 66 // certificates. These should be treated as different certificate chains even |
| 67 // though the two X509Certificate objects contain the same server certificate. | 67 // though the two X509Certificate objects contain the same server certificate. |
| 68 TEST(CertVerifierTest, DifferentCACerts) { | 68 TEST(MultiThreadedCertVerifierTest, DifferentCACerts) { |
| 69 CertVerifier verifier; | 69 MultiThreadedCertVerifier verifier; |
| 70 | 70 |
| 71 FilePath certs_dir = GetTestCertsDirectory(); | 71 FilePath certs_dir = GetTestCertsDirectory(); |
| 72 | 72 |
| 73 scoped_refptr<X509Certificate> server_cert = | 73 scoped_refptr<X509Certificate> server_cert = |
| 74 ImportCertFromFile(certs_dir, "salesforce_com_test.pem"); | 74 ImportCertFromFile(certs_dir, "salesforce_com_test.pem"); |
| 75 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); | 75 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); |
| 76 | 76 |
| 77 scoped_refptr<X509Certificate> intermediate_cert1 = | 77 scoped_refptr<X509Certificate> intermediate_cert1 = |
| 78 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem"); | 78 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem"); |
| 79 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1); | 79 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 ASSERT_TRUE(request_handle != NULL); | 118 ASSERT_TRUE(request_handle != NULL); |
| 119 error = callback.WaitForResult(); | 119 error = callback.WaitForResult(); |
| 120 ASSERT_TRUE(IsCertificateError(error)); | 120 ASSERT_TRUE(IsCertificateError(error)); |
| 121 ASSERT_EQ(2u, verifier.requests()); | 121 ASSERT_EQ(2u, verifier.requests()); |
| 122 ASSERT_EQ(0u, verifier.cache_hits()); | 122 ASSERT_EQ(0u, verifier.cache_hits()); |
| 123 ASSERT_EQ(0u, verifier.inflight_joins()); | 123 ASSERT_EQ(0u, verifier.inflight_joins()); |
| 124 ASSERT_EQ(2u, verifier.GetCacheSize()); | 124 ASSERT_EQ(2u, verifier.GetCacheSize()); |
| 125 } | 125 } |
| 126 | 126 |
| 127 // Tests an inflight join. | 127 // Tests an inflight join. |
| 128 TEST(CertVerifierTest, InflightJoin) { | 128 TEST(MultiThreadedCertVerifierTest, InflightJoin) { |
| 129 CertVerifier verifier; | 129 MultiThreadedCertVerifier verifier; |
| 130 | 130 |
| 131 FilePath certs_dir = GetTestCertsDirectory(); | 131 FilePath certs_dir = GetTestCertsDirectory(); |
| 132 scoped_refptr<X509Certificate> test_cert( | 132 scoped_refptr<X509Certificate> test_cert( |
| 133 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 133 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
| 134 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); | 134 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); |
| 135 | 135 |
| 136 int error; | 136 int error; |
| 137 CertVerifyResult verify_result; | 137 CertVerifyResult verify_result; |
| 138 TestCompletionCallback callback; | 138 TestCompletionCallback callback; |
| 139 CertVerifier::RequestHandle request_handle; | 139 CertVerifier::RequestHandle request_handle; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 153 error = callback.WaitForResult(); | 153 error = callback.WaitForResult(); |
| 154 ASSERT_TRUE(IsCertificateError(error)); | 154 ASSERT_TRUE(IsCertificateError(error)); |
| 155 error = callback2.WaitForResult(); | 155 error = callback2.WaitForResult(); |
| 156 ASSERT_TRUE(IsCertificateError(error)); | 156 ASSERT_TRUE(IsCertificateError(error)); |
| 157 ASSERT_EQ(2u, verifier.requests()); | 157 ASSERT_EQ(2u, verifier.requests()); |
| 158 ASSERT_EQ(0u, verifier.cache_hits()); | 158 ASSERT_EQ(0u, verifier.cache_hits()); |
| 159 ASSERT_EQ(1u, verifier.inflight_joins()); | 159 ASSERT_EQ(1u, verifier.inflight_joins()); |
| 160 } | 160 } |
| 161 | 161 |
| 162 // Tests that the callback of a canceled request is never made. | 162 // Tests that the callback of a canceled request is never made. |
| 163 TEST(CertVerifierTest, CancelRequest) { | 163 TEST(MultiThreadedCertVerifierTest, CancelRequest) { |
| 164 CertVerifier verifier; | 164 MultiThreadedCertVerifier verifier; |
| 165 | 165 |
| 166 FilePath certs_dir = GetTestCertsDirectory(); | 166 FilePath certs_dir = GetTestCertsDirectory(); |
| 167 scoped_refptr<X509Certificate> test_cert( | 167 scoped_refptr<X509Certificate> test_cert( |
| 168 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 168 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
| 169 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); | 169 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); |
| 170 | 170 |
| 171 int error; | 171 int error; |
| 172 CertVerifyResult verify_result; | 172 CertVerifyResult verify_result; |
| 173 CertVerifier::RequestHandle request_handle; | 173 CertVerifier::RequestHandle request_handle; |
| 174 | 174 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 188 test_cert, "www2.example.com", 0, NULL, &verify_result, | 188 test_cert, "www2.example.com", 0, NULL, &verify_result, |
| 189 callback.callback(), &request_handle, BoundNetLog()); | 189 callback.callback(), &request_handle, BoundNetLog()); |
| 190 ASSERT_EQ(ERR_IO_PENDING, error); | 190 ASSERT_EQ(ERR_IO_PENDING, error); |
| 191 ASSERT_TRUE(request_handle != NULL); | 191 ASSERT_TRUE(request_handle != NULL); |
| 192 error = callback.WaitForResult(); | 192 error = callback.WaitForResult(); |
| 193 verifier.ClearCache(); | 193 verifier.ClearCache(); |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 | 196 |
| 197 // Tests that a canceled request is not leaked. | 197 // Tests that a canceled request is not leaked. |
| 198 TEST(CertVerifierTest, CancelRequestThenQuit) { | 198 TEST(MultiThreadedCertVerifierTest, CancelRequestThenQuit) { |
| 199 CertVerifier verifier; | 199 MultiThreadedCertVerifier verifier; |
| 200 | 200 |
| 201 FilePath certs_dir = GetTestCertsDirectory(); | 201 FilePath certs_dir = GetTestCertsDirectory(); |
| 202 scoped_refptr<X509Certificate> test_cert( | 202 scoped_refptr<X509Certificate> test_cert( |
| 203 ImportCertFromFile(certs_dir, "ok_cert.pem")); | 203 ImportCertFromFile(certs_dir, "ok_cert.pem")); |
| 204 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); | 204 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert); |
| 205 | 205 |
| 206 int error; | 206 int error; |
| 207 CertVerifyResult verify_result; | 207 CertVerifyResult verify_result; |
| 208 TestCompletionCallback callback; | 208 TestCompletionCallback callback; |
| 209 CertVerifier::RequestHandle request_handle; | 209 CertVerifier::RequestHandle request_handle; |
| 210 | 210 |
| 211 error = verifier.Verify(test_cert, "www.example.com", 0, NULL, &verify_result, | 211 error = verifier.Verify(test_cert, "www.example.com", 0, NULL, &verify_result, |
| 212 callback.callback(), &request_handle, BoundNetLog()); | 212 callback.callback(), &request_handle, BoundNetLog()); |
| 213 ASSERT_EQ(ERR_IO_PENDING, error); | 213 ASSERT_EQ(ERR_IO_PENDING, error); |
| 214 ASSERT_TRUE(request_handle != NULL); | 214 ASSERT_TRUE(request_handle != NULL); |
| 215 verifier.CancelRequest(request_handle); | 215 verifier.CancelRequest(request_handle); |
| 216 // Destroy |verifier| by going out of scope. | 216 // Destroy |verifier| by going out of scope. |
| 217 } | 217 } |
| 218 | 218 |
| 219 TEST(CertVerifierTest, RequestParamsComparators) { | 219 TEST(MultiThreadedCertVerifierTest, RequestParamsComparators) { |
| 220 SHA1Fingerprint a_key; | 220 SHA1Fingerprint a_key; |
| 221 memset(a_key.data, 'a', sizeof(a_key.data)); | 221 memset(a_key.data, 'a', sizeof(a_key.data)); |
| 222 | 222 |
| 223 SHA1Fingerprint z_key; | 223 SHA1Fingerprint z_key; |
| 224 memset(z_key.data, 'z', sizeof(z_key.data)); | 224 memset(z_key.data, 'z', sizeof(z_key.data)); |
| 225 | 225 |
| 226 struct { | 226 struct { |
| 227 // Keys to test | 227 // Keys to test |
| 228 CertVerifier::RequestParams key1; | 228 MultiThreadedCertVerifier::RequestParams key1; |
| 229 CertVerifier::RequestParams key2; | 229 MultiThreadedCertVerifier::RequestParams key2; |
| 230 | 230 |
| 231 // Expectation: | 231 // Expectation: |
| 232 // -1 means key1 is less than key2 | 232 // -1 means key1 is less than key2 |
| 233 // 0 means key1 equals key2 | 233 // 0 means key1 equals key2 |
| 234 // 1 means key1 is greater than key2 | 234 // 1 means key1 is greater than key2 |
| 235 int expected_result; | 235 int expected_result; |
| 236 } tests[] = { | 236 } tests[] = { |
| 237 { // Test for basic equivalence. | 237 { // Test for basic equivalence. |
| 238 CertVerifier::RequestParams(a_key, a_key, "www.example.test", 0), | 238 MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", |
| 239 CertVerifier::RequestParams(a_key, a_key, "www.example.test", 0), | 239 0), |
| 240 MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", |
| 241 0), |
| 240 0, | 242 0, |
| 241 }, | 243 }, |
| 242 { // Test that different certificates but with the same CA and for | 244 { // Test that different certificates but with the same CA and for |
| 243 // the same host are different validation keys. | 245 // the same host are different validation keys. |
| 244 CertVerifier::RequestParams(a_key, a_key, "www.example.test", 0), | 246 MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", |
| 245 CertVerifier::RequestParams(z_key, a_key, "www.example.test", 0), | 247 0), |
| 248 MultiThreadedCertVerifier::RequestParams(z_key, a_key, "www.example.test", |
| 249 0), |
| 246 -1, | 250 -1, |
| 247 }, | 251 }, |
| 248 { // Test that the same EE certificate for the same host, but with | 252 { // Test that the same EE certificate for the same host, but with |
| 249 // different chains are different validation keys. | 253 // different chains are different validation keys. |
| 250 CertVerifier::RequestParams(a_key, z_key, "www.example.test", 0), | 254 MultiThreadedCertVerifier::RequestParams(a_key, z_key, "www.example.test", |
| 251 CertVerifier::RequestParams(a_key, a_key, "www.example.test", 0), | 255 0), |
| 256 MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", |
| 257 0), |
| 252 1, | 258 1, |
| 253 }, | 259 }, |
| 254 { // The same certificate, with the same chain, but for different | 260 { // The same certificate, with the same chain, but for different |
| 255 // hosts are different validation keys. | 261 // hosts are different validation keys. |
| 256 CertVerifier::RequestParams(a_key, a_key, "www1.example.test", 0), | 262 MultiThreadedCertVerifier::RequestParams(a_key, a_key, |
| 257 CertVerifier::RequestParams(a_key, a_key, "www2.example.test", 0), | 263 "www1.example.test", 0), |
| 264 MultiThreadedCertVerifier::RequestParams(a_key, a_key, |
| 265 "www2.example.test", 0), |
| 258 -1, | 266 -1, |
| 259 }, | 267 }, |
| 260 { // The same certificate, chain, and host, but with different flags | 268 { // The same certificate, chain, and host, but with different flags |
| 261 // are different validation keys. | 269 // are different validation keys. |
| 262 CertVerifier::RequestParams(a_key, a_key, "www.example.test", | 270 MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", |
| 263 X509Certificate::VERIFY_EV_CERT), | 271 X509Certificate::VERIFY_EV_CERT), |
| 264 CertVerifier::RequestParams(a_key, a_key, "www.example.test", 0), | 272 MultiThreadedCertVerifier::RequestParams(a_key, a_key, "www.example.test", |
| 273 0), |
| 265 1, | 274 1, |
| 266 } | 275 } |
| 267 }; | 276 }; |
| 268 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 277 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 269 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i)); | 278 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i)); |
| 270 | 279 |
| 271 const CertVerifier::RequestParams& key1 = tests[i].key1; | 280 const MultiThreadedCertVerifier::RequestParams& key1 = tests[i].key1; |
| 272 const CertVerifier::RequestParams& key2 = tests[i].key2; | 281 const MultiThreadedCertVerifier::RequestParams& key2 = tests[i].key2; |
| 273 | 282 |
| 274 switch (tests[i].expected_result) { | 283 switch (tests[i].expected_result) { |
| 275 case -1: | 284 case -1: |
| 276 EXPECT_TRUE(key1 < key2); | 285 EXPECT_TRUE(key1 < key2); |
| 277 EXPECT_FALSE(key2 < key1); | 286 EXPECT_FALSE(key2 < key1); |
| 278 break; | 287 break; |
| 279 case 0: | 288 case 0: |
| 280 EXPECT_FALSE(key1 < key2); | 289 EXPECT_FALSE(key1 < key2); |
| 281 EXPECT_FALSE(key2 < key1); | 290 EXPECT_FALSE(key2 < key1); |
| 282 break; | 291 break; |
| 283 case 1: | 292 case 1: |
| 284 EXPECT_FALSE(key1 < key2); | 293 EXPECT_FALSE(key1 < key2); |
| 285 EXPECT_TRUE(key2 < key1); | 294 EXPECT_TRUE(key2 < key1); |
| 286 break; | 295 break; |
| 287 default: | 296 default: |
| 288 FAIL() << "Invalid expectation. Can be only -1, 0, 1"; | 297 FAIL() << "Invalid expectation. Can be only -1, 0, 1"; |
| 289 } | 298 } |
| 290 } | 299 } |
| 291 } | 300 } |
| 292 | 301 |
| 293 } // namespace net | 302 } // namespace net |
| OLD | NEW |