OLD | NEW |
---|---|
(Empty) | |
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 | |
5 #include "net/cert/caching_cert_verifier.h" | |
6 | |
7 #include <memory> | |
8 | |
9 #include "base/files/file_path.h" | |
10 #include "base/memory/ptr_util.h" | |
11 #include "base/memory/ref_counted.h" | |
12 #include "net/base/net_errors.h" | |
13 #include "net/base/test_completion_callback.h" | |
14 #include "net/base/test_data_directory.h" | |
15 #include "net/cert/cert_trust_anchor_provider.h" | |
16 #include "net/cert/cert_verifier.h" | |
17 #include "net/cert/cert_verify_result.h" | |
18 #include "net/cert/mock_cert_verifier.h" | |
19 #include "net/cert/x509_certificate.h" | |
20 #include "net/log/net_log.h" | |
21 #include "net/test/cert_test_util.h" | |
22 #include "testing/gmock/include/gmock/gmock.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | |
24 | |
25 using testing::Mock; | |
26 using testing::ReturnRef; | |
27 | |
28 namespace net { | |
29 | |
30 namespace { | |
31 | |
32 class MockCertTrustAnchorProvider : public CertTrustAnchorProvider { | |
33 public: | |
34 MockCertTrustAnchorProvider() {} | |
35 virtual ~MockCertTrustAnchorProvider() {} | |
36 | |
37 MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&()); | |
38 }; | |
39 | |
40 } // namespace | |
41 | |
42 class CachingCertVerifierTest : public ::testing::Test { | |
43 public: | |
44 CachingCertVerifierTest() : verifier_(base::MakeUnique<MockCertVerifier>()) {} | |
45 ~CachingCertVerifierTest() override {} | |
46 | |
47 protected: | |
48 CachingCertVerifier verifier_; | |
49 }; | |
50 | |
51 TEST_F(CachingCertVerifierTest, CacheHit) { | |
52 base::FilePath certs_dir = GetTestCertsDirectory(); | |
53 scoped_refptr<X509Certificate> test_cert( | |
54 ImportCertFromFile(certs_dir, "ok_cert.pem")); | |
55 ASSERT_TRUE(test_cert.get()); | |
56 | |
57 int error; | |
58 CertVerifyResult verify_result; | |
59 TestCompletionCallback callback; | |
60 std::unique_ptr<CertVerifier::Request> request; | |
61 | |
62 error = callback.GetResult(verifier_.Verify( | |
63 CertVerifier::RequestParams(test_cert, "www.example.com", 0, | |
64 std::string(), CertificateList()), | |
65 nullptr, &verify_result, callback.callback(), &request, BoundNetLog())); | |
66 ASSERT_TRUE(IsCertificateError(error)); | |
67 ASSERT_EQ(1u, verifier_.requests()); | |
68 ASSERT_EQ(0u, verifier_.cache_hits()); | |
69 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
70 | |
71 error = verifier_.Verify( | |
72 CertVerifier::RequestParams(test_cert, "www.example.com", 0, | |
73 std::string(), CertificateList()), | |
74 nullptr, &verify_result, callback.callback(), &request, BoundNetLog()); | |
75 // Synchronous completion. | |
76 ASSERT_NE(ERR_IO_PENDING, error); | |
77 ASSERT_TRUE(IsCertificateError(error)); | |
78 ASSERT_FALSE(request); | |
79 ASSERT_EQ(2u, verifier_.requests()); | |
80 ASSERT_EQ(1u, verifier_.cache_hits()); | |
81 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
82 } | |
83 | |
84 // Tests the same server certificate with different intermediate CA | |
85 // certificates. These should be treated as different certificate chains even | |
86 // though the two X509Certificate objects contain the same server certificate. | |
87 TEST_F(CachingCertVerifierTest, DifferentCACerts) { | |
88 base::FilePath certs_dir = GetTestCertsDirectory(); | |
89 | |
90 scoped_refptr<X509Certificate> server_cert = | |
91 ImportCertFromFile(certs_dir, "salesforce_com_test.pem"); | |
92 ASSERT_TRUE(server_cert); | |
93 | |
94 scoped_refptr<X509Certificate> intermediate_cert1 = | |
95 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem"); | |
96 ASSERT_TRUE(intermediate_cert1); | |
97 | |
98 scoped_refptr<X509Certificate> intermediate_cert2 = | |
99 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem"); | |
100 ASSERT_TRUE(intermediate_cert2); | |
101 | |
102 X509Certificate::OSCertHandles intermediates; | |
103 intermediates.push_back(intermediate_cert1->os_cert_handle()); | |
104 scoped_refptr<X509Certificate> cert_chain1 = | |
105 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), | |
106 intermediates); | |
107 ASSERT_TRUE(cert_chain1); | |
108 | |
109 intermediates.clear(); | |
110 intermediates.push_back(intermediate_cert2->os_cert_handle()); | |
111 scoped_refptr<X509Certificate> cert_chain2 = | |
112 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), | |
113 intermediates); | |
114 ASSERT_TRUE(cert_chain2); | |
115 | |
116 int error; | |
117 CertVerifyResult verify_result; | |
118 TestCompletionCallback callback; | |
119 std::unique_ptr<CertVerifier::Request> request; | |
120 | |
121 error = callback.GetResult(verifier_.Verify( | |
122 CertVerifier::RequestParams(cert_chain1, "www.example.com", 0, | |
123 std::string(), CertificateList()), | |
124 nullptr, &verify_result, callback.callback(), &request, BoundNetLog())); | |
125 ASSERT_TRUE(IsCertificateError(error)); | |
126 ASSERT_EQ(1u, verifier_.requests()); | |
127 ASSERT_EQ(0u, verifier_.cache_hits()); | |
128 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
129 | |
130 error = callback.GetResult(verifier_.Verify( | |
131 CertVerifier::RequestParams(cert_chain2, "www.example.com", 0, | |
132 std::string(), CertificateList()), | |
133 nullptr, &verify_result, callback.callback(), &request, BoundNetLog())); | |
134 ASSERT_TRUE(IsCertificateError(error)); | |
135 ASSERT_EQ(2u, verifier_.requests()); | |
136 ASSERT_EQ(0u, verifier_.cache_hits()); | |
137 ASSERT_EQ(2u, verifier_.GetCacheSize()); | |
138 } | |
139 | |
140 TEST_F(CachingCertVerifierTest, CertTrustAnchorProvider) { | |
eroman
2016/06/10 00:08:04
Are there any tests for asynchronous completion of
Ryan Sleevi
2016/06/10 00:41:10
Nope, mostly because I didn't opt to handle it spe
| |
141 MockCertTrustAnchorProvider trust_provider; | |
142 verifier_.SetCertTrustAnchorProvider(&trust_provider); | |
143 | |
144 scoped_refptr<X509Certificate> test_cert( | |
145 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); | |
146 ASSERT_TRUE(test_cert.get()); | |
147 | |
148 const CertificateList empty_cert_list; | |
149 CertificateList cert_list; | |
150 cert_list.push_back(test_cert); | |
151 | |
152 // Check that Verify() asks the |trust_provider| for the current list of | |
153 // additional trust anchors. | |
154 int error; | |
155 CertVerifyResult verify_result; | |
156 TestCompletionCallback callback; | |
157 std::unique_ptr<CertVerifier::Request> request; | |
158 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) | |
159 .WillOnce(ReturnRef(empty_cert_list)); | |
160 error = callback.GetResult(verifier_.Verify( | |
161 CertVerifier::RequestParams(test_cert, "www.example.com", 0, | |
162 std::string(), CertificateList()), | |
163 nullptr, &verify_result, callback.callback(), &request, BoundNetLog())); | |
164 Mock::VerifyAndClearExpectations(&trust_provider); | |
165 EXPECT_TRUE(IsCertificateError(error)); | |
166 ASSERT_EQ(1u, verifier_.requests()); | |
167 ASSERT_EQ(0u, verifier_.cache_hits()); | |
168 | |
169 // The next Verify() uses the cached result. | |
170 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) | |
171 .WillOnce(ReturnRef(empty_cert_list)); | |
172 error = callback.GetResult(verifier_.Verify( | |
173 CertVerifier::RequestParams(test_cert, "www.example.com", 0, | |
174 std::string(), CertificateList()), | |
175 nullptr, &verify_result, callback.callback(), &request, BoundNetLog())); | |
176 Mock::VerifyAndClearExpectations(&trust_provider); | |
177 EXPECT_TRUE(IsCertificateError(error)); | |
178 ASSERT_EQ(2u, verifier_.requests()); | |
179 ASSERT_EQ(1u, verifier_.cache_hits()); | |
180 | |
181 // Another Verify() for the same certificate but with a different list of | |
182 // trust anchors will not reuse the cache. | |
183 EXPECT_CALL(trust_provider, GetAdditionalTrustAnchors()) | |
184 .WillOnce(ReturnRef(cert_list)); | |
185 error = callback.GetResult(verifier_.Verify( | |
186 CertVerifier::RequestParams(test_cert, "www.example.com", 0, | |
187 std::string(), CertificateList()), | |
188 nullptr, &verify_result, callback.callback(), &request, BoundNetLog())); | |
189 Mock::VerifyAndClearExpectations(&trust_provider); | |
190 EXPECT_TRUE(IsCertificateError(error)); | |
191 ASSERT_EQ(3u, verifier_.requests()); | |
192 ASSERT_EQ(1u, verifier_.cache_hits()); | |
193 } | |
194 | |
195 } // namespace net | |
OLD | NEW |