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