| 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 "base/time/time.h" |
| 6 #include "components/cast_certificate/cast_cert_validator.h" |
| 7 #include "components/cast_certificate/cast_cert_validator_test_helpers.h" |
| 8 #include "components/cast_certificate/cast_crl.h" |
| 9 #include "components/cast_certificate/proto/test_suite.pb.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 |
| 12 namespace cast_certificate { |
| 13 namespace { |
| 14 |
| 15 // Converts uint64_t unix timestamp in seconds to base::Time. |
| 16 base::Time ConvertUnixTimestampSeconds(uint64_t time) { |
| 17 return base::Time::UnixEpoch() + |
| 18 base::TimeDelta::FromMilliseconds(time * 1000); |
| 19 } |
| 20 |
| 21 // Indicates the expected result of test step's verification. |
| 22 enum TestStepResult { |
| 23 RESULT_SUCCESS, |
| 24 RESULT_FAIL, |
| 25 }; |
| 26 |
| 27 // Verifies that the provided certificate chain is valid at the specified time |
| 28 // and chains up to a trust anchor. |
| 29 bool TestVerifyCertificate(TestStepResult expected_result, |
| 30 const std::vector<std::string>& certificate_chain, |
| 31 const base::Time& time) { |
| 32 std::unique_ptr<CertVerificationContext> context; |
| 33 CastDeviceCertPolicy policy; |
| 34 bool result = VerifyDeviceCert(certificate_chain, time, &context, &policy, |
| 35 nullptr, CRLPolicy::CRL_OPTIONAL); |
| 36 if (expected_result != RESULT_SUCCESS) { |
| 37 EXPECT_FALSE(result); |
| 38 return !result; |
| 39 } |
| 40 EXPECT_TRUE(result); |
| 41 return result; |
| 42 } |
| 43 |
| 44 // Verifies that the provided Cast CRL is signed by a trusted issuer |
| 45 // and that the CRL can be parsed successfully. |
| 46 // The validity of the CRL is also checked at the specified time. |
| 47 bool TestVerifyCRL(TestStepResult expected_result, |
| 48 const std::string& crl_bundle, |
| 49 const base::Time& time) { |
| 50 std::unique_ptr<CastCRL> crl = ParseAndVerifyCRL(crl_bundle, time); |
| 51 if (expected_result != RESULT_SUCCESS) { |
| 52 EXPECT_EQ(crl, nullptr); |
| 53 return crl == nullptr; |
| 54 } |
| 55 EXPECT_NE(crl, nullptr); |
| 56 return crl != nullptr; |
| 57 } |
| 58 |
| 59 // Verifies that the certificate chain provided is not revoked according to |
| 60 // the provided Cast CRL at |cert_time|. |
| 61 // The provided CRL is verified at |crl_time|. |
| 62 // If |crl_required| is set, then a valid Cast CRL must be provided. |
| 63 // Otherwise, a missing CRL is be ignored. |
| 64 bool TestVerifyRevocation(TestStepResult expected_result, |
| 65 const std::vector<std::string>& certificate_chain, |
| 66 const std::string& crl_bundle, |
| 67 const base::Time& crl_time, |
| 68 const base::Time& cert_time, |
| 69 bool crl_required) { |
| 70 std::unique_ptr<CastCRL> crl; |
| 71 if (!crl_bundle.empty()) { |
| 72 crl = ParseAndVerifyCRL(crl_bundle, crl_time); |
| 73 EXPECT_NE(crl.get(), nullptr); |
| 74 } |
| 75 |
| 76 std::unique_ptr<CertVerificationContext> context; |
| 77 CastDeviceCertPolicy policy; |
| 78 CRLPolicy crl_policy = CRLPolicy::CRL_REQUIRED; |
| 79 if (!crl_required) |
| 80 crl_policy = CRLPolicy::CRL_OPTIONAL; |
| 81 int result = VerifyDeviceCert(certificate_chain, cert_time, &context, &policy, |
| 82 crl.get(), crl_policy); |
| 83 if (expected_result != RESULT_SUCCESS) { |
| 84 EXPECT_FALSE(result); |
| 85 return !result; |
| 86 } |
| 87 EXPECT_TRUE(result); |
| 88 return result; |
| 89 } |
| 90 |
| 91 // Runs a single test case. |
| 92 bool RunTest(const DeviceCertTest& test_case) { |
| 93 bool use_test_trust_anchors = test_case.use_test_trust_anchors(); |
| 94 if (use_test_trust_anchors) { |
| 95 const auto crl_test_root = |
| 96 cast_certificate::testing::ReadCertificateChainFromFile( |
| 97 "certificates/cast_crl_test_root_ca.pem"); |
| 98 EXPECT_EQ(crl_test_root.size(), 1u); |
| 99 EXPECT_TRUE(SetCRLTrustAnchorForTest(crl_test_root[0])); |
| 100 const auto cast_test_root = |
| 101 cast_certificate::testing::ReadCertificateChainFromFile( |
| 102 "certificates/cast_test_root_ca.pem"); |
| 103 EXPECT_EQ(cast_test_root.size(), 1u); |
| 104 EXPECT_TRUE(SetTrustAnchorForTest(cast_test_root[0])); |
| 105 } |
| 106 |
| 107 VerificationResult expected_result = test_case.expected_result(); |
| 108 |
| 109 std::vector<std::string> certificate_chain; |
| 110 for (auto const& cert : test_case.der_cert_path()) { |
| 111 certificate_chain.push_back(cert); |
| 112 } |
| 113 |
| 114 base::Time cert_verification_time = |
| 115 ConvertUnixTimestampSeconds(test_case.cert_verification_time_seconds()); |
| 116 |
| 117 uint64_t crl_verify_time = test_case.crl_verification_time_seconds(); |
| 118 base::Time crl_verification_time = |
| 119 ConvertUnixTimestampSeconds(crl_verify_time); |
| 120 if (crl_verify_time == 0) |
| 121 crl_verification_time = cert_verification_time; |
| 122 |
| 123 std::string crl_bundle = test_case.crl_bundle(); |
| 124 switch (expected_result) { |
| 125 case PATH_VERIFICATION_FAILED: |
| 126 return TestVerifyCertificate(RESULT_FAIL, certificate_chain, |
| 127 cert_verification_time); |
| 128 break; |
| 129 case CRL_VERIFICATION_FAILED: |
| 130 return TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time); |
| 131 break; |
| 132 case REVOCATION_CHECK_FAILED_WITHOUT_CRL: |
| 133 return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, |
| 134 cert_verification_time) && |
| 135 TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time) && |
| 136 TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, |
| 137 crl_verification_time, cert_verification_time, |
| 138 true); |
| 139 break; |
| 140 case REVOCATION_CHECK_FAILED: |
| 141 return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, |
| 142 cert_verification_time) && |
| 143 TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time) && |
| 144 TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle, |
| 145 crl_verification_time, cert_verification_time, |
| 146 false); |
| 147 break; |
| 148 case SUCCESS: |
| 149 return (crl_bundle.empty() || TestVerifyCRL(RESULT_SUCCESS, crl_bundle, |
| 150 crl_verification_time)) && |
| 151 TestVerifyCertificate(RESULT_SUCCESS, certificate_chain, |
| 152 cert_verification_time) && |
| 153 TestVerifyRevocation(RESULT_SUCCESS, certificate_chain, crl_bundle, |
| 154 crl_verification_time, cert_verification_time, |
| 155 !crl_bundle.empty()); |
| 156 break; |
| 157 case UNSPECIFIED: |
| 158 return false; |
| 159 break; |
| 160 } |
| 161 return false; |
| 162 } |
| 163 |
| 164 // Parses the provided test suite provided in wire-format proto. |
| 165 // Each test contains the inputs and the expected output. |
| 166 // To see the description of the test, execute the test. |
| 167 // These tests are generated by a test generator in google3. |
| 168 void RunTestSuite(const std::string& test_suite_file_name) { |
| 169 std::string testsuite_raw = |
| 170 cast_certificate::testing::ReadTestFileToString(test_suite_file_name); |
| 171 DeviceCertTestSuite test_suite; |
| 172 EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw)); |
| 173 uint16_t success = 0; |
| 174 uint16_t failed = 0; |
| 175 std::vector<std::string> failed_tests; |
| 176 |
| 177 for (auto const& test_case : test_suite.tests()) { |
| 178 LOG(INFO) << "[ RUN ] " << test_case.description(); |
| 179 bool result = RunTest(test_case); |
| 180 EXPECT_TRUE(result); |
| 181 if (!result) { |
| 182 LOG(INFO) << "[ FAILED ] " << test_case.description(); |
| 183 ++failed; |
| 184 failed_tests.push_back(test_case.description()); |
| 185 } else { |
| 186 LOG(INFO) << "[ PASSED ] " << test_case.description(); |
| 187 ++success; |
| 188 } |
| 189 } |
| 190 LOG(INFO) << "[ PASSED ] " << success << " test(s)."; |
| 191 if (failed) { |
| 192 LOG(INFO) << "[ FAILED ] " << failed << " test(s), listed below:"; |
| 193 for (const auto& failed_test : failed_tests) { |
| 194 LOG(INFO) << "[ FAILED ] " << failed_test; |
| 195 } |
| 196 } |
| 197 } |
| 198 |
| 199 TEST(CastCertificateTest, TestSuite1) { |
| 200 RunTestSuite("testsuite/testsuite1.pb"); |
| 201 } |
| 202 |
| 203 } // namespace |
| 204 |
| 205 } // namespace cast_certificate |
| OLD | NEW |