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

Side by Side Diff: net/cert/cert_verifier_cache_persister_unittest.cc

Issue 1892033002: Cert - protobufs to serialize and deserialize CertVerifierCache. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
(Empty)
1 // Copyright (c) 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/cert_verifier_cache_persister.h"
6
7 #include "base/files/file_path.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/test_completion_callback.h"
12 #include "net/base/test_data_directory.h"
13 #include "net/cert/cert_trust_anchor_provider.h"
14 #include "net/cert/cert_verify_proc.h"
15 #include "net/cert/cert_verify_result.h"
16 #include "net/cert/multi_threaded_cert_verifier.h"
17 #include "net/cert/x509_certificate.h"
18 #include "net/log/net_log.h"
19 #include "net/test/cert_test_util.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace net {
24
25 namespace {
26
27 class MockCertVerifyProc : public CertVerifyProc {
28 public:
29 MockCertVerifyProc() {}
30
31 private:
32 ~MockCertVerifyProc() override {}
33
34 // CertVerifyProc implementation
35 bool SupportsAdditionalTrustAnchors() const override { return false; }
36 bool SupportsOCSPStapling() const override { return false; }
37
38 int VerifyInternal(X509Certificate* cert,
39 const std::string& hostname,
40 const std::string& ocsp_response,
41 int flags,
42 CRLSet* crl_set,
43 const CertificateList& additional_trust_anchors,
44 CertVerifyResult* verify_result) override {
45 verify_result->Reset();
46 verify_result->verified_cert = cert;
47 verify_result->cert_status = CERT_STATUS_COMMON_NAME_INVALID;
48 return ERR_CERT_COMMON_NAME_INVALID;
49 }
50 };
51
52 bool HashValueVectorEqual(const HashValueVector& a, const HashValueVector& b) {
53 size_t size = a.size();
54
55 if (size != b.size())
56 return false;
57
58 for (size_t i = 0; i < size; ++i) {
59 if (!a[i].Equals(b[i]))
60 return false;
61 }
62
63 return true;
64 }
65
66 } // namespace
67
68 class CertVerifierCachePersisterTest : public ::testing::Test {
69 public:
70 CertVerifierCachePersisterTest()
71 : verifier_(new MockCertVerifyProc()), persister_(&verifier_) {}
72 ~CertVerifierCachePersisterTest() override {}
73
74 protected:
75 MultiThreadedCertVerifier verifier_;
76 CertVerifierCachePersister persister_;
77 };
78
79 TEST_F(CertVerifierCachePersisterTest, PersistCache) {
80 base::FilePath certs_dir = GetTestCertsDirectory();
81 scoped_refptr<X509Certificate> test_cert(
82 ImportCertFromFile(certs_dir, "ok_cert.pem"));
83 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
84
85 std::string example_hostname("www.example.com");
86 std::string ocsp_response;
87 int flags = 0;
88 CRLSet* crl_set = NULL;
89 int error;
90 CertVerifyResult verify_result;
91 TestCompletionCallback callback;
92 scoped_ptr<CertVerifier::Request> request;
93
94 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response,
95 flags, crl_set, &verify_result, callback.callback(),
96 &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 CertVerifyResult verify_result_serialized;
107 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response,
108 flags, crl_set, &verify_result_serialized,
109 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 std::string data;
120 persister_.SerializeCache(&data);
121 EXPECT_FALSE(data.empty());
122
123 // Clear the cache.
124 verifier_.ClearCache();
125 ASSERT_EQ(0u, verifier_.GetCacheSize());
126
127 // Restore the cache data
128 EXPECT_TRUE(persister_.LoadCache(data));
129 ASSERT_EQ(1u, verifier_.GetCacheSize());
130
131 CertVerifyResult verify_result_deserialized;
132 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response,
133 flags, crl_set, &verify_result_deserialized,
134 callback.callback(), &request, BoundNetLog());
135 // Synchronous completion.
136 ASSERT_NE(ERR_IO_PENDING, error);
137 ASSERT_TRUE(IsCertificateError(error));
138 ASSERT_FALSE(request);
139 ASSERT_EQ(3u, verifier_.requests());
140 ASSERT_EQ(2u, verifier_.cache_hits());
141 ASSERT_EQ(0u, verifier_.inflight_joins());
142 ASSERT_EQ(1u, verifier_.GetCacheSize());
143
144 // Verify the result after deserialized is same as the result before
145 // searilization.
146 ASSERT_EQ(verify_result_serialized.cert_status,
147 verify_result_deserialized.cert_status);
148 ASSERT_EQ(verify_result_serialized.has_md2,
149 verify_result_deserialized.has_md2);
150 ASSERT_EQ(verify_result_serialized.has_md4,
151 verify_result_deserialized.has_md4);
152 ASSERT_EQ(verify_result_serialized.has_md5,
153 verify_result_deserialized.has_md5);
154 ASSERT_EQ(verify_result_serialized.has_sha1,
155 verify_result_deserialized.has_sha1);
156 ASSERT_EQ(verify_result_serialized.has_sha1_leaf,
157 verify_result_deserialized.has_sha1_leaf);
158 ASSERT_EQ(verify_result_serialized.is_issued_by_known_root,
159 verify_result_deserialized.is_issued_by_known_root);
160 ASSERT_EQ(verify_result_serialized.is_issued_by_additional_trust_anchor,
161 verify_result_deserialized.is_issued_by_additional_trust_anchor);
162 ASSERT_EQ(verify_result_serialized.has_md2,
163 verify_result_deserialized.has_md2);
164 ASSERT_EQ(verify_result_serialized.common_name_fallback_used,
165 verify_result_deserialized.common_name_fallback_used);
166 EXPECT_TRUE(verify_result_serialized.verified_cert.get()->Equals(
167 verify_result_deserialized.verified_cert.get()));
168 EXPECT_TRUE(
169 HashValueVectorEqual(verify_result_serialized.public_key_hashes,
170 verify_result_deserialized.public_key_hashes));
171
172 // Verify that cache by using the CertVerifierCacheIterator.
173 MultiThreadedCertVerifier::CertVerifierCacheIterator iterator(verifier_);
174 EXPECT_TRUE(iterator.HasNext());
175 ASSERT_EQ(example_hostname, iterator.hostname());
176 ASSERT_EQ(flags, iterator.flags());
177 ASSERT_EQ(error, iterator.error());
178 const CertVerifyResult& result = iterator.result();
179 ASSERT_EQ(verify_result_serialized.cert_status, result.cert_status);
180 ASSERT_EQ(verify_result_serialized.has_md2, result.has_md2);
181 ASSERT_EQ(verify_result_serialized.has_md4, result.has_md4);
182 ASSERT_EQ(verify_result_serialized.has_md5, result.has_md5);
183 ASSERT_EQ(verify_result_serialized.has_sha1, result.has_sha1);
184 ASSERT_EQ(verify_result_serialized.has_sha1_leaf, result.has_sha1_leaf);
185 ASSERT_EQ(verify_result_serialized.is_issued_by_known_root,
186 result.is_issued_by_known_root);
187 ASSERT_EQ(verify_result_serialized.is_issued_by_additional_trust_anchor,
188 result.is_issued_by_additional_trust_anchor);
189 ASSERT_EQ(verify_result_serialized.has_md2, result.has_md2);
190 ASSERT_EQ(verify_result_serialized.common_name_fallback_used,
191 result.common_name_fallback_used);
192 EXPECT_TRUE(HashValueVectorEqual(verify_result_serialized.public_key_hashes,
193 result.public_key_hashes));
194 EXPECT_TRUE(verify_result_serialized.verified_cert.get()->Equals(
195 result.verified_cert.get()));
196
197 iterator.Advance();
198 EXPECT_FALSE(iterator.HasNext());
199 }
200
201 TEST_F(CertVerifierCachePersisterTest, PersistCacheExpiredEntry) {
202 base::FilePath certs_dir = GetTestCertsDirectory();
203 scoped_refptr<X509Certificate> test_cert(
204 ImportCertFromFile(certs_dir, "ok_cert.pem"));
205 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
206
207 std::string example_hostname("www.example.com");
208 std::string ocsp_response;
209 int flags = 0;
210 CRLSet* crl_set = NULL;
211 int error;
212 CertVerifyResult verify_result;
213 TestCompletionCallback callback;
214 scoped_ptr<CertVerifier::Request> request;
215
216 // Verify that there is no cache hit.
217 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response,
218 flags, crl_set, &verify_result, callback.callback(),
219 &request, BoundNetLog());
220 ASSERT_EQ(ERR_IO_PENDING, error);
221 EXPECT_TRUE(request);
222 error = callback.WaitForResult();
223 ASSERT_TRUE(IsCertificateError(error));
224 ASSERT_EQ(1u, verifier_.requests());
225 ASSERT_EQ(0u, verifier_.cache_hits());
226 ASSERT_EQ(0u, verifier_.inflight_joins());
227 ASSERT_EQ(1u, verifier_.GetCacheSize());
228
229 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response,
230 flags, crl_set, &verify_result, callback.callback(),
231 &request, BoundNetLog());
232 // Synchronous completion and verify that there is a cache hit.
233 ASSERT_NE(ERR_IO_PENDING, error);
234 ASSERT_TRUE(IsCertificateError(error));
235 ASSERT_FALSE(request);
236 ASSERT_EQ(2u, verifier_.requests());
237 ASSERT_EQ(1u, verifier_.cache_hits()); // cache hit.
238 ASSERT_EQ(0u, verifier_.inflight_joins());
239 ASSERT_EQ(1u, verifier_.GetCacheSize());
240
241 // Test cache expiration, by adding expired data.
242 const CertificateList empty_cert_list;
243 const CertificateList& additional_trust_anchors =
244 verifier_.trust_anchor_provider_
245 ? verifier_.trust_anchor_provider_->GetAdditionalTrustAnchors()
246 : empty_cert_list;
247 const MultiThreadedCertVerifier::RequestParams key(
248 test_cert->fingerprint(), test_cert->ca_fingerprint(), example_hostname,
249 ocsp_response, flags, additional_trust_anchors);
250 const MultiThreadedCertVerifier::CertVerifierCache::value_type* cached_entry =
251 verifier_.cache_.Get(key, MultiThreadedCertVerifier::CacheValidityPeriod(
252 base::Time::Now()));
253 // TODO(rtenneti): use |kTTLSecs| instead of hardcoded 1800ms.
254 base::Time start_time =
255 base::Time::Now() - base::TimeDelta::FromSeconds(3600);
256 verifier_.cache_.Put(
257 key, *cached_entry,
258 MultiThreadedCertVerifier::CacheValidityPeriod(start_time),
259 MultiThreadedCertVerifier::CacheValidityPeriod(
260 start_time, start_time + base::TimeDelta::FromSeconds(1800)));
261
262 // Persist the data.
263 std::string data;
264 persister_.SerializeCache(&data);
265 EXPECT_FALSE(data.empty());
266
267 // Clear the cache.
268 verifier_.ClearCache();
269 ASSERT_EQ(0u, verifier_.GetCacheSize());
270
271 // Shouldn't restore expired entries.
272 EXPECT_TRUE(persister_.LoadCache(data));
273 ASSERT_EQ(0u, verifier_.GetCacheSize());
274 }
275
276 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698