cast_crl_unittest.cc 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. #include "components/cast_certificate/cast_crl.h"
  5. #include "base/files/file_util.h"
  6. #include "base/logging.h"
  7. #include "base/time/time.h"
  8. #include "components/cast_certificate/cast_cert_reader.h"
  9. #include "components/cast_certificate/cast_cert_test_helpers.h"
  10. #include "components/cast_certificate/cast_cert_validator.h"
  11. #include "net/cert/pki/cert_errors.h"
  12. #include "net/cert/pki/trust_store_in_memory.h"
  13. #include "testing/gtest/include/gtest/gtest.h"
  14. #include "third_party/openscreen/src/cast/common/certificate/proto/test_suite.pb.h"
  15. using cast::certificate::DeviceCertTest;
  16. using cast::certificate::DeviceCertTestSuite;
  17. namespace cast_certificate {
  18. namespace {
  19. // Indicates the expected result of test step's verification.
  20. enum TestStepResult {
  21. RESULT_SUCCESS,
  22. RESULT_FAIL,
  23. };
  24. // Verifies that the provided certificate chain is valid at the specified time
  25. // and chains up to a trust anchor.
  26. bool TestVerifyCertificate(TestStepResult expected_result,
  27. const std::vector<std::string>& certificate_chain,
  28. const base::Time& time,
  29. net::TrustStore* cast_trust_store) {
  30. std::unique_ptr<CertVerificationContext> context;
  31. CastDeviceCertPolicy policy;
  32. CastCertError result = VerifyDeviceCertUsingCustomTrustStore(
  33. certificate_chain, time, &context, &policy, nullptr,
  34. CRLPolicy::CRL_OPTIONAL, cast_trust_store);
  35. bool success = result == CastCertError::OK;
  36. if (expected_result != RESULT_SUCCESS) {
  37. success = !success;
  38. }
  39. EXPECT_TRUE(success);
  40. return success;
  41. }
  42. // Verifies that the provided Cast CRL is signed by a trusted issuer
  43. // and that the CRL can be parsed successfully.
  44. // The validity of the CRL is also checked at the specified time.
  45. bool TestVerifyCRL(TestStepResult expected_result,
  46. const std::string& crl_bundle,
  47. const base::Time& time,
  48. net::TrustStore* crl_trust_store) {
  49. std::unique_ptr<CastCRL> crl =
  50. ParseAndVerifyCRLUsingCustomTrustStore(crl_bundle, time, crl_trust_store);
  51. bool success = crl != nullptr;
  52. if (expected_result != RESULT_SUCCESS) {
  53. success = !success;
  54. }
  55. EXPECT_TRUE(success);
  56. return success;
  57. }
  58. // Verifies that the certificate chain provided is not revoked according to
  59. // the provided Cast CRL at |cert_time|.
  60. // The provided CRL is verified at |crl_time|.
  61. // If |crl_required| is set, then a valid Cast CRL must be provided.
  62. // Otherwise, a missing CRL is be ignored.
  63. bool TestVerifyRevocation(CastCertError expected_result,
  64. const std::vector<std::string>& certificate_chain,
  65. const std::string& crl_bundle,
  66. const base::Time& crl_time,
  67. const base::Time& cert_time,
  68. bool crl_required,
  69. net::TrustStore* cast_trust_store,
  70. net::TrustStore* crl_trust_store) {
  71. std::unique_ptr<CastCRL> crl;
  72. if (!crl_bundle.empty()) {
  73. crl = ParseAndVerifyCRLUsingCustomTrustStore(crl_bundle, crl_time,
  74. crl_trust_store);
  75. EXPECT_NE(crl.get(), nullptr);
  76. }
  77. std::unique_ptr<CertVerificationContext> context;
  78. CastDeviceCertPolicy policy;
  79. CRLPolicy crl_policy = CRLPolicy::CRL_REQUIRED;
  80. if (!crl_required)
  81. crl_policy = CRLPolicy::CRL_OPTIONAL;
  82. CastCertError result = VerifyDeviceCertUsingCustomTrustStore(
  83. certificate_chain, cert_time, &context, &policy, crl.get(), crl_policy,
  84. cast_trust_store);
  85. EXPECT_EQ(expected_result, result);
  86. return expected_result == result;
  87. }
  88. // Runs a single test case.
  89. bool RunTest(const DeviceCertTest& test_case) {
  90. std::unique_ptr<net::TrustStoreInMemory> cast_trust_store =
  91. test_case.use_test_trust_anchors()
  92. ? cast_certificate::testing::LoadTestCert("cast_test_root_ca.pem")
  93. : nullptr;
  94. std::unique_ptr<net::TrustStoreInMemory> crl_trust_store =
  95. test_case.use_test_trust_anchors()
  96. ? cast_certificate::testing::LoadTestCert("cast_crl_test_root_ca.pem")
  97. : nullptr;
  98. std::vector<std::string> certificate_chain;
  99. for (auto const& cert : test_case.der_cert_path()) {
  100. certificate_chain.push_back(cert);
  101. }
  102. base::Time cert_verification_time = testing::ConvertUnixTimestampSeconds(
  103. test_case.cert_verification_time_seconds());
  104. uint64_t crl_verify_time = test_case.crl_verification_time_seconds();
  105. base::Time crl_verification_time =
  106. testing::ConvertUnixTimestampSeconds(crl_verify_time);
  107. if (crl_verify_time == 0)
  108. crl_verification_time = cert_verification_time;
  109. std::string crl_bundle = test_case.crl_bundle();
  110. switch (test_case.expected_result()) {
  111. case cast::certificate::PATH_VERIFICATION_FAILED:
  112. return TestVerifyCertificate(RESULT_FAIL, certificate_chain,
  113. cert_verification_time,
  114. cast_trust_store.get());
  115. case cast::certificate::CRL_VERIFICATION_FAILED:
  116. return TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time,
  117. crl_trust_store.get());
  118. case cast::certificate::REVOCATION_CHECK_FAILED_WITHOUT_CRL:
  119. return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain,
  120. cert_verification_time,
  121. cast_trust_store.get()) &&
  122. TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time,
  123. crl_trust_store.get()) &&
  124. TestVerifyRevocation(
  125. CastCertError::ERR_CRL_INVALID, certificate_chain, crl_bundle,
  126. crl_verification_time, cert_verification_time, true,
  127. cast_trust_store.get(), crl_trust_store.get());
  128. case cast::certificate::CRL_EXPIRED_AFTER_INITIAL_VERIFICATION:
  129. // Fall-through intended.
  130. case cast::certificate::REVOCATION_CHECK_FAILED:
  131. return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain,
  132. cert_verification_time,
  133. cast_trust_store.get()) &&
  134. TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time,
  135. crl_trust_store.get()) &&
  136. TestVerifyRevocation(
  137. CastCertError::ERR_CERTS_REVOKED, certificate_chain,
  138. crl_bundle, crl_verification_time, cert_verification_time,
  139. false, cast_trust_store.get(), crl_trust_store.get());
  140. case cast::certificate::SUCCESS:
  141. return (crl_bundle.empty() ||
  142. TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time,
  143. crl_trust_store.get())) &&
  144. TestVerifyCertificate(RESULT_SUCCESS, certificate_chain,
  145. cert_verification_time,
  146. cast_trust_store.get()) &&
  147. TestVerifyRevocation(CastCertError::OK, certificate_chain,
  148. crl_bundle, crl_verification_time,
  149. cert_verification_time, !crl_bundle.empty(),
  150. cast_trust_store.get(),
  151. crl_trust_store.get());
  152. case cast::certificate::UNSPECIFIED:
  153. return false;
  154. }
  155. return false;
  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. base::ReadFileToString(
  164. testing::GetCastCertificateDirectory().AppendASCII(test_suite_file_name),
  165. &testsuite_raw);
  166. DeviceCertTestSuite test_suite;
  167. EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw));
  168. uint16_t success = 0;
  169. uint16_t failed = 0;
  170. std::vector<std::string> failed_tests;
  171. for (auto const& test_case : test_suite.tests()) {
  172. LOG(INFO) << "[ RUN ] " << test_case.description();
  173. bool result = RunTest(test_case);
  174. EXPECT_TRUE(result);
  175. if (!result) {
  176. LOG(INFO) << "[ FAILED ] " << test_case.description();
  177. ++failed;
  178. failed_tests.push_back(test_case.description());
  179. } else {
  180. LOG(INFO) << "[ PASSED ] " << test_case.description();
  181. ++success;
  182. }
  183. }
  184. LOG(INFO) << "[ PASSED ] " << success << " test(s).";
  185. if (failed) {
  186. LOG(INFO) << "[ FAILED ] " << failed << " test(s), listed below:";
  187. for (const auto& failed_test : failed_tests) {
  188. LOG(INFO) << "[ FAILED ] " << failed_test;
  189. }
  190. }
  191. }
  192. TEST(CastCertificateTest, TestSuite1) {
  193. RunTestSuite("testsuite/testsuite1.pb");
  194. }
  195. } // namespace
  196. } // namespace cast_certificate