OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 "base/time/time.h" | 5 #include "base/time/time.h" |
6 #include "components/cast_certificate/cast_cert_validator.h" | 6 #include "components/cast_certificate/cast_cert_validator.h" |
7 #include "components/cast_certificate/cast_cert_validator_test_helpers.h" | 7 #include "components/cast_certificate/cast_cert_validator_test_helpers.h" |
8 #include "components/cast_certificate/cast_crl.h" | 8 #include "components/cast_certificate/cast_crl.h" |
9 #include "components/cast_certificate/proto/test_suite.pb.h" | 9 #include "components/cast_certificate/proto/test_suite.pb.h" |
10 #include "net/cert/internal/cert_errors.h" | 10 #include "net/cert/internal/cert_errors.h" |
11 #include "net/cert/internal/trust_store_in_memory.h" | 11 #include "net/cert/internal/trust_store_in_memory.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 namespace cast_certificate { | 14 namespace cast_certificate { |
15 namespace { | 15 namespace { |
16 | 16 |
17 // Creates a trust store using the test roots encoded in the PEM file at |path|. | |
18 std::unique_ptr<net::TrustStoreInMemory> CreateTrustStoreFromFile( | |
19 const std::string& path) { | |
20 std::unique_ptr<net::TrustStoreInMemory> trust_store( | |
21 new net::TrustStoreInMemory()); | |
22 const auto trusted_test_roots = | |
23 cast_certificate::testing::ReadCertificateChainFromFile(path); | |
24 for (const auto& trusted_root : trusted_test_roots) { | |
25 net::CertErrors errors; | |
26 scoped_refptr<net::ParsedCertificate> cert( | |
27 net::ParsedCertificate::Create(trusted_root, {}, &errors)); | |
28 EXPECT_TRUE(cert) << errors.ToDebugString(); | |
29 scoped_refptr<net::TrustAnchor> anchor = | |
30 net::TrustAnchor::CreateFromCertificateWithConstraints(std::move(cert)); | |
31 trust_store->AddTrustAnchor(std::move(anchor)); | |
32 } | |
33 return trust_store; | |
34 } | |
35 | |
36 // Converts uint64_t unix timestamp in seconds to base::Time. | |
37 base::Time ConvertUnixTimestampSeconds(uint64_t time) { | |
38 return base::Time::UnixEpoch() + | |
39 base::TimeDelta::FromMilliseconds(time * 1000); | |
40 } | |
41 | |
42 // Indicates the expected result of test step's verification. | 17 // Indicates the expected result of test step's verification. |
43 enum TestStepResult { | 18 enum TestStepResult { |
44 RESULT_SUCCESS, | 19 RESULT_SUCCESS, |
45 RESULT_FAIL, | 20 RESULT_FAIL, |
46 }; | 21 }; |
47 | 22 |
48 // Verifies that the provided certificate chain is valid at the specified time | 23 // Verifies that the provided certificate chain is valid at the specified time |
49 // and chains up to a trust anchor. | 24 // and chains up to a trust anchor. |
50 bool TestVerifyCertificate(TestStepResult expected_result, | 25 bool TestVerifyCertificate(TestStepResult expected_result, |
51 const std::vector<std::string>& certificate_chain, | 26 const std::vector<std::string>& certificate_chain, |
52 const base::Time& time, | 27 const base::Time& time, |
53 net::TrustStore* cast_trust_store) { | 28 net::TrustStore* cast_trust_store) { |
54 std::unique_ptr<CertVerificationContext> context; | 29 std::unique_ptr<CertVerificationContext> context; |
55 CastDeviceCertPolicy policy; | 30 CastDeviceCertPolicy policy; |
56 int result; | 31 int result = VerifyDeviceCertUsingCustomTrustStore( |
57 if (cast_trust_store != nullptr) { | 32 certificate_chain, time, &context, &policy, nullptr, |
58 result = VerifyDeviceCertForTest(certificate_chain, time, &context, &policy, | 33 CRLPolicy::CRL_OPTIONAL, cast_trust_store); |
59 nullptr, CRLPolicy::CRL_OPTIONAL, | |
60 cast_trust_store); | |
61 } else { | |
62 result = VerifyDeviceCert(certificate_chain, time, &context, &policy, | |
63 nullptr, CRLPolicy::CRL_OPTIONAL); | |
64 } | |
65 if (expected_result != RESULT_SUCCESS) { | 34 if (expected_result != RESULT_SUCCESS) { |
66 EXPECT_FALSE(result); | 35 EXPECT_FALSE(result); |
67 return !result; | 36 return !result; |
68 } | 37 } |
69 EXPECT_TRUE(result); | 38 EXPECT_TRUE(result); |
70 return result; | 39 return result; |
71 } | 40 } |
72 | 41 |
73 // Verifies that the provided Cast CRL is signed by a trusted issuer | 42 // Verifies that the provided Cast CRL is signed by a trusted issuer |
74 // and that the CRL can be parsed successfully. | 43 // and that the CRL can be parsed successfully. |
75 // The validity of the CRL is also checked at the specified time. | 44 // The validity of the CRL is also checked at the specified time. |
76 bool TestVerifyCRL(TestStepResult expected_result, | 45 bool TestVerifyCRL(TestStepResult expected_result, |
77 const std::string& crl_bundle, | 46 const std::string& crl_bundle, |
78 const base::Time& time, | 47 const base::Time& time, |
79 net::TrustStore* crl_trust_store) { | 48 net::TrustStore* crl_trust_store) { |
80 std::unique_ptr<CastCRL> crl; | 49 std::unique_ptr<CastCRL> crl = |
81 if (crl_trust_store != nullptr) { | 50 ParseAndVerifyCRLUsingCustomTrustStore(crl_bundle, time, crl_trust_store); |
82 crl = ParseAndVerifyCRLForTest(crl_bundle, time, crl_trust_store); | 51 |
83 } else { | |
84 crl = ParseAndVerifyCRL(crl_bundle, time); | |
85 } | |
86 if (expected_result != RESULT_SUCCESS) { | 52 if (expected_result != RESULT_SUCCESS) { |
87 EXPECT_EQ(crl, nullptr); | 53 EXPECT_EQ(crl, nullptr); |
88 return crl == nullptr; | 54 return crl == nullptr; |
89 } | 55 } |
90 EXPECT_NE(crl, nullptr); | 56 EXPECT_NE(crl, nullptr); |
91 return crl != nullptr; | 57 return crl != nullptr; |
92 } | 58 } |
93 | 59 |
94 // Verifies that the certificate chain provided is not revoked according to | 60 // Verifies that the certificate chain provided is not revoked according to |
95 // the provided Cast CRL at |cert_time|. | 61 // the provided Cast CRL at |cert_time|. |
96 // The provided CRL is verified at |crl_time|. | 62 // The provided CRL is verified at |crl_time|. |
97 // If |crl_required| is set, then a valid Cast CRL must be provided. | 63 // If |crl_required| is set, then a valid Cast CRL must be provided. |
98 // Otherwise, a missing CRL is be ignored. | 64 // Otherwise, a missing CRL is be ignored. |
99 bool TestVerifyRevocation(TestStepResult expected_result, | 65 bool TestVerifyRevocation(TestStepResult expected_result, |
100 const std::vector<std::string>& certificate_chain, | 66 const std::vector<std::string>& certificate_chain, |
101 const std::string& crl_bundle, | 67 const std::string& crl_bundle, |
102 const base::Time& crl_time, | 68 const base::Time& crl_time, |
103 const base::Time& cert_time, | 69 const base::Time& cert_time, |
104 bool crl_required, | 70 bool crl_required, |
105 net::TrustStore* cast_trust_store, | 71 net::TrustStore* cast_trust_store, |
106 net::TrustStore* crl_trust_store) { | 72 net::TrustStore* crl_trust_store) { |
107 std::unique_ptr<CastCRL> crl; | 73 std::unique_ptr<CastCRL> crl; |
108 if (!crl_bundle.empty()) { | 74 if (!crl_bundle.empty()) { |
109 if (crl_trust_store != nullptr) { | 75 crl = ParseAndVerifyCRLUsingCustomTrustStore(crl_bundle, crl_time, |
110 crl = ParseAndVerifyCRLForTest(crl_bundle, crl_time, crl_trust_store); | 76 crl_trust_store); |
111 } else { | |
112 crl = ParseAndVerifyCRL(crl_bundle, crl_time); | |
113 } | |
114 EXPECT_NE(crl.get(), nullptr); | 77 EXPECT_NE(crl.get(), nullptr); |
115 } | 78 } |
116 | 79 |
117 std::unique_ptr<CertVerificationContext> context; | 80 std::unique_ptr<CertVerificationContext> context; |
118 CastDeviceCertPolicy policy; | 81 CastDeviceCertPolicy policy; |
119 CRLPolicy crl_policy = CRLPolicy::CRL_REQUIRED; | 82 CRLPolicy crl_policy = CRLPolicy::CRL_REQUIRED; |
120 if (!crl_required) | 83 if (!crl_required) |
121 crl_policy = CRLPolicy::CRL_OPTIONAL; | 84 crl_policy = CRLPolicy::CRL_OPTIONAL; |
122 int result; | 85 int result = VerifyDeviceCertUsingCustomTrustStore( |
123 if (cast_trust_store != nullptr) { | 86 certificate_chain, cert_time, &context, &policy, crl.get(), crl_policy, |
124 result = | 87 cast_trust_store); |
125 VerifyDeviceCertForTest(certificate_chain, cert_time, &context, &policy, | |
126 crl.get(), crl_policy, cast_trust_store); | |
127 } else { | |
128 result = VerifyDeviceCert(certificate_chain, cert_time, &context, &policy, | |
129 crl.get(), crl_policy); | |
130 } | |
131 if (expected_result != RESULT_SUCCESS) { | 88 if (expected_result != RESULT_SUCCESS) { |
132 EXPECT_FALSE(result); | 89 EXPECT_FALSE(result); |
133 return !result; | 90 return !result; |
134 } | 91 } |
135 EXPECT_TRUE(result); | 92 EXPECT_TRUE(result); |
136 return result; | 93 return result; |
137 } | 94 } |
138 | 95 |
139 // Runs a single test case. | 96 // Runs a single test case. |
140 bool RunTest(const DeviceCertTest& test_case) { | 97 bool RunTest(const DeviceCertTest& test_case) { |
141 std::unique_ptr<net::TrustStoreInMemory> crl_trust_store; | 98 std::unique_ptr<net::TrustStoreInMemory> crl_trust_store; |
142 std::unique_ptr<net::TrustStoreInMemory> cast_trust_store; | 99 std::unique_ptr<net::TrustStoreInMemory> cast_trust_store; |
143 if (test_case.use_test_trust_anchors()) { | 100 if (test_case.use_test_trust_anchors()) { |
144 crl_trust_store = | 101 crl_trust_store = testing::CreateTrustStoreFromFile( |
145 CreateTrustStoreFromFile("certificates/cast_crl_test_root_ca.pem"); | 102 "certificates/cast_crl_test_root_ca.pem"); |
146 cast_trust_store = | 103 cast_trust_store = |
147 CreateTrustStoreFromFile("certificates/cast_test_root_ca.pem"); | 104 testing::CreateTrustStoreFromFile("certificates/cast_test_root_ca.pem"); |
148 | 105 |
149 EXPECT_TRUE(crl_trust_store.get()); | 106 EXPECT_TRUE(crl_trust_store.get()); |
150 EXPECT_TRUE(cast_trust_store.get()); | 107 EXPECT_TRUE(cast_trust_store.get()); |
151 } | 108 } |
152 | 109 |
153 std::vector<std::string> certificate_chain; | 110 std::vector<std::string> certificate_chain; |
154 for (auto const& cert : test_case.der_cert_path()) { | 111 for (auto const& cert : test_case.der_cert_path()) { |
155 certificate_chain.push_back(cert); | 112 certificate_chain.push_back(cert); |
156 } | 113 } |
157 | 114 |
158 base::Time cert_verification_time = | 115 base::Time cert_verification_time = testing::ConvertUnixTimestampSeconds( |
159 ConvertUnixTimestampSeconds(test_case.cert_verification_time_seconds()); | 116 test_case.cert_verification_time_seconds()); |
160 | 117 |
161 uint64_t crl_verify_time = test_case.crl_verification_time_seconds(); | 118 uint64_t crl_verify_time = test_case.crl_verification_time_seconds(); |
162 base::Time crl_verification_time = | 119 base::Time crl_verification_time = |
163 ConvertUnixTimestampSeconds(crl_verify_time); | 120 testing::ConvertUnixTimestampSeconds(crl_verify_time); |
164 if (crl_verify_time == 0) | 121 if (crl_verify_time == 0) |
165 crl_verification_time = cert_verification_time; | 122 crl_verification_time = cert_verification_time; |
166 | 123 |
167 std::string crl_bundle = test_case.crl_bundle(); | 124 std::string crl_bundle = test_case.crl_bundle(); |
168 switch (test_case.expected_result()) { | 125 switch (test_case.expected_result()) { |
169 case PATH_VERIFICATION_FAILED: | 126 case PATH_VERIFICATION_FAILED: |
170 return TestVerifyCertificate(RESULT_FAIL, certificate_chain, | 127 return TestVerifyCertificate(RESULT_FAIL, certificate_chain, |
171 cert_verification_time, | 128 cert_verification_time, |
172 cast_trust_store.get()); | 129 cast_trust_store.get()); |
173 break; | |
174 case CRL_VERIFICATION_FAILED: | 130 case CRL_VERIFICATION_FAILED: |
175 return TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time, | 131 return TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time, |
176 crl_trust_store.get()); | 132 crl_trust_store.get()); |
177 break; | |
178 case REVOCATION_CHECK_FAILED_WITHOUT_CRL: | 133 case REVOCATION_CHECK_FAILED_WITHOUT_CRL: |
179 return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, | 134 return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, |
180 cert_verification_time, | 135 cert_verification_time, |
181 cast_trust_store.get()) && | 136 cast_trust_store.get()) && |
182 TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time, | 137 TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time, |
183 crl_trust_store.get()) && | 138 crl_trust_store.get()) && |
184 TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, | 139 TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, |
185 crl_verification_time, cert_verification_time, | 140 crl_verification_time, cert_verification_time, |
186 true, cast_trust_store.get(), | 141 true, cast_trust_store.get(), |
187 crl_trust_store.get()); | 142 crl_trust_store.get()); |
188 break; | 143 case CRL_EXPIRED_AFTER_INITIAL_VERIFICATION: |
| 144 // Fall-through intended. |
189 case REVOCATION_CHECK_FAILED: | 145 case REVOCATION_CHECK_FAILED: |
190 return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, | 146 return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, |
191 cert_verification_time, | 147 cert_verification_time, |
192 cast_trust_store.get()) && | 148 cast_trust_store.get()) && |
193 TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time, | 149 TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time, |
194 crl_trust_store.get()) && | 150 crl_trust_store.get()) && |
195 TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, | 151 TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, |
196 crl_verification_time, cert_verification_time, | 152 crl_verification_time, cert_verification_time, |
197 false, cast_trust_store.get(), | 153 false, cast_trust_store.get(), |
198 crl_trust_store.get()); | 154 crl_trust_store.get()); |
199 break; | |
200 case SUCCESS: | 155 case SUCCESS: |
201 return (crl_bundle.empty() || | 156 return (crl_bundle.empty() || |
202 TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time, | 157 TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time, |
203 crl_trust_store.get())) && | 158 crl_trust_store.get())) && |
204 TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, | 159 TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, |
205 cert_verification_time, | 160 cert_verification_time, |
206 cast_trust_store.get()) && | 161 cast_trust_store.get()) && |
207 TestVerifyRevocation(RESULT_SUCCESS, certificate_chain, crl_bundle, | 162 TestVerifyRevocation(RESULT_SUCCESS, certificate_chain, crl_bundle, |
208 crl_verification_time, cert_verification_time, | 163 crl_verification_time, cert_verification_time, |
209 !crl_bundle.empty(), cast_trust_store.get(), | 164 !crl_bundle.empty(), cast_trust_store.get(), |
210 crl_trust_store.get()); | 165 crl_trust_store.get()); |
211 break; | |
212 case UNSPECIFIED: | 166 case UNSPECIFIED: |
213 return false; | 167 return false; |
214 break; | |
215 } | 168 } |
216 return false; | 169 return false; |
217 } | 170 } |
218 | 171 |
219 // Parses the provided test suite provided in wire-format proto. | 172 // Parses the provided test suite provided in wire-format proto. |
220 // Each test contains the inputs and the expected output. | 173 // Each test contains the inputs and the expected output. |
221 // To see the description of the test, execute the test. | 174 // To see the description of the test, execute the test. |
222 // These tests are generated by a test generator in google3. | 175 // These tests are generated by a test generator in google3. |
223 void RunTestSuite(const std::string& test_suite_file_name) { | 176 void RunTestSuite(const std::string& test_suite_file_name) { |
224 std::string testsuite_raw = | 177 std::string testsuite_raw = |
(...skipping 26 matching lines...) Expand all Loading... |
251 } | 204 } |
252 } | 205 } |
253 | 206 |
254 TEST(CastCertificateTest, TestSuite1) { | 207 TEST(CastCertificateTest, TestSuite1) { |
255 RunTestSuite("testsuite/testsuite1.pb"); | 208 RunTestSuite("testsuite/testsuite1.pb"); |
256 } | 209 } |
257 | 210 |
258 } // namespace | 211 } // namespace |
259 | 212 |
260 } // namespace cast_certificate | 213 } // namespace cast_certificate |
OLD | NEW |