caching_cert_verifier_unittest.cc 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright 2016 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. #include "net/cert/caching_cert_verifier.h"
  5. #include "base/files/file_path.h"
  6. #include "base/memory/ref_counted.h"
  7. #include "net/base/net_errors.h"
  8. #include "net/base/test_completion_callback.h"
  9. #include "net/cert/cert_verifier.h"
  10. #include "net/cert/cert_verify_result.h"
  11. #include "net/cert/mock_cert_verifier.h"
  12. #include "net/cert/x509_certificate.h"
  13. #include "net/cert/x509_util.h"
  14. #include "net/log/net_log_with_source.h"
  15. #include "net/test/cert_test_util.h"
  16. #include "net/test/ct_test_util.h"
  17. #include "net/test/gtest_util.h"
  18. #include "net/test/test_data_directory.h"
  19. #include "net/test/test_with_task_environment.h"
  20. #include "testing/gmock/include/gmock/gmock.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. using net::test::IsError;
  23. using net::test::IsOk;
  24. using testing::_;
  25. using testing::Mock;
  26. using testing::Return;
  27. using testing::ReturnRef;
  28. namespace net {
  29. class CachingCertVerifierTest : public TestWithTaskEnvironment {
  30. public:
  31. CachingCertVerifierTest() : verifier_(std::make_unique<MockCertVerifier>()) {}
  32. ~CachingCertVerifierTest() override = default;
  33. protected:
  34. CachingCertVerifier verifier_;
  35. };
  36. TEST_F(CachingCertVerifierTest, CacheHit) {
  37. base::FilePath certs_dir = GetTestCertsDirectory();
  38. scoped_refptr<X509Certificate> test_cert(
  39. ImportCertFromFile(certs_dir, "ok_cert.pem"));
  40. ASSERT_TRUE(test_cert.get());
  41. int error;
  42. CertVerifyResult verify_result;
  43. TestCompletionCallback callback;
  44. std::unique_ptr<CertVerifier::Request> request;
  45. error = callback.GetResult(verifier_.Verify(
  46. CertVerifier::RequestParams(test_cert, "www.example.com", 0,
  47. /*ocsp_response=*/std::string(),
  48. /*sct_list=*/std::string()),
  49. &verify_result, callback.callback(), &request, NetLogWithSource()));
  50. ASSERT_TRUE(IsCertificateError(error));
  51. ASSERT_EQ(1u, verifier_.requests());
  52. ASSERT_EQ(0u, verifier_.cache_hits());
  53. ASSERT_EQ(1u, verifier_.GetCacheSize());
  54. error = verifier_.Verify(
  55. CertVerifier::RequestParams(test_cert, "www.example.com", 0,
  56. /*ocsp_response=*/std::string(),
  57. /*sct_list=*/std::string()),
  58. &verify_result, callback.callback(), &request, NetLogWithSource());
  59. // Synchronous completion.
  60. ASSERT_NE(ERR_IO_PENDING, error);
  61. ASSERT_TRUE(IsCertificateError(error));
  62. ASSERT_FALSE(request);
  63. ASSERT_EQ(2u, verifier_.requests());
  64. ASSERT_EQ(1u, verifier_.cache_hits());
  65. ASSERT_EQ(1u, verifier_.GetCacheSize());
  66. }
  67. TEST_F(CachingCertVerifierTest, CacheHitCTResultsCached) {
  68. base::FilePath certs_dir = GetTestCertsDirectory();
  69. scoped_refptr<X509Certificate> test_cert(
  70. ImportCertFromFile(certs_dir, "ok_cert.pem"));
  71. ASSERT_TRUE(test_cert.get());
  72. auto cert_verifier = std::make_unique<MockCertVerifier>();
  73. // Mock the cert verification and CT verification results.
  74. CertVerifyResult mock_result;
  75. mock_result.cert_status = OK;
  76. mock_result.verified_cert = test_cert;
  77. scoped_refptr<ct::SignedCertificateTimestamp> sct;
  78. ct::GetX509CertSCT(&sct);
  79. SignedCertificateTimestampAndStatus sct_and_status(sct, ct::SCT_STATUS_OK);
  80. SignedCertificateTimestampAndStatusList sct_list{sct_and_status};
  81. mock_result.scts = sct_list;
  82. cert_verifier->AddResultForCert(test_cert, mock_result, OK);
  83. // We don't use verifier_ here because we needed to call AddResultForCert from
  84. // the mock verifier.
  85. CachingCertVerifier cache_verifier(std::move(cert_verifier));
  86. int result;
  87. CertVerifyResult verify_result;
  88. TestCompletionCallback callback;
  89. std::unique_ptr<CertVerifier::Request> request;
  90. result = callback.GetResult(cache_verifier.Verify(
  91. CertVerifier::RequestParams(test_cert, "www.example.com", 0,
  92. /*ocsp_response=*/std::string(),
  93. /*sct_list=*/std::string()),
  94. &verify_result, callback.callback(), &request, NetLogWithSource()));
  95. ASSERT_EQ(OK, result);
  96. ASSERT_EQ(1u, verify_result.scts.size());
  97. ASSERT_EQ(ct::SCT_STATUS_OK, verify_result.scts[0].status);
  98. ASSERT_EQ(1u, cache_verifier.requests());
  99. ASSERT_EQ(0u, cache_verifier.cache_hits());
  100. ASSERT_EQ(1u, cache_verifier.GetCacheSize());
  101. result = cache_verifier.Verify(
  102. CertVerifier::RequestParams(test_cert, "www.example.com", 0,
  103. /*ocsp_response=*/std::string(),
  104. /*sct_list=*/std::string()),
  105. &verify_result, callback.callback(), &request, NetLogWithSource());
  106. // Synchronous completion.
  107. ASSERT_EQ(OK, result);
  108. ASSERT_FALSE(request);
  109. ASSERT_EQ(1u, verify_result.scts.size());
  110. ASSERT_EQ(ct::SCT_STATUS_OK, verify_result.scts[0].status);
  111. ASSERT_EQ(2u, cache_verifier.requests());
  112. ASSERT_EQ(1u, cache_verifier.cache_hits());
  113. ASSERT_EQ(1u, cache_verifier.GetCacheSize());
  114. }
  115. // Tests the same server certificate with different intermediate CA
  116. // certificates. These should be treated as different certificate chains even
  117. // though the two X509Certificate objects contain the same server certificate.
  118. TEST_F(CachingCertVerifierTest, DifferentCACerts) {
  119. base::FilePath certs_dir = GetTestCertsDirectory();
  120. scoped_refptr<X509Certificate> server_cert =
  121. ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
  122. ASSERT_TRUE(server_cert);
  123. scoped_refptr<X509Certificate> intermediate_cert1 =
  124. ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
  125. ASSERT_TRUE(intermediate_cert1);
  126. scoped_refptr<X509Certificate> intermediate_cert2 =
  127. ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
  128. ASSERT_TRUE(intermediate_cert2);
  129. std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
  130. intermediates.push_back(bssl::UpRef(intermediate_cert1->cert_buffer()));
  131. scoped_refptr<X509Certificate> cert_chain1 =
  132. X509Certificate::CreateFromBuffer(bssl::UpRef(server_cert->cert_buffer()),
  133. std::move(intermediates));
  134. ASSERT_TRUE(cert_chain1);
  135. intermediates.clear();
  136. intermediates.push_back(bssl::UpRef(intermediate_cert2->cert_buffer()));
  137. scoped_refptr<X509Certificate> cert_chain2 =
  138. X509Certificate::CreateFromBuffer(bssl::UpRef(server_cert->cert_buffer()),
  139. std::move(intermediates));
  140. ASSERT_TRUE(cert_chain2);
  141. int error;
  142. CertVerifyResult verify_result;
  143. TestCompletionCallback callback;
  144. std::unique_ptr<CertVerifier::Request> request;
  145. error = callback.GetResult(verifier_.Verify(
  146. CertVerifier::RequestParams(cert_chain1, "www.example.com", 0,
  147. /*ocsp_response=*/std::string(),
  148. /*sct_list=*/std::string()),
  149. &verify_result, callback.callback(), &request, NetLogWithSource()));
  150. ASSERT_TRUE(IsCertificateError(error));
  151. ASSERT_EQ(1u, verifier_.requests());
  152. ASSERT_EQ(0u, verifier_.cache_hits());
  153. ASSERT_EQ(1u, verifier_.GetCacheSize());
  154. error = callback.GetResult(verifier_.Verify(
  155. CertVerifier::RequestParams(cert_chain2, "www.example.com", 0,
  156. /*ocsp_response=*/std::string(),
  157. /*sct_list=*/std::string()),
  158. &verify_result, callback.callback(), &request, NetLogWithSource()));
  159. ASSERT_TRUE(IsCertificateError(error));
  160. ASSERT_EQ(2u, verifier_.requests());
  161. ASSERT_EQ(0u, verifier_.cache_hits());
  162. ASSERT_EQ(2u, verifier_.GetCacheSize());
  163. }
  164. } // namespace net