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

Unified Diff: components/cast_certificate/cast_crl_unittest.cc

Issue 2050983002: Cast device revocation checking. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: API change: use base::Time instead of base::Time::ExplodedTime Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: components/cast_certificate/cast_crl_unittest.cc
diff --git a/components/cast_certificate/cast_crl_unittest.cc b/components/cast_certificate/cast_crl_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..974bfe2ae8bd0032bc87bdc7f7df2dc26eea5bdc
--- /dev/null
+++ b/components/cast_certificate/cast_crl_unittest.cc
@@ -0,0 +1,202 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/time/time.h"
+#include "components/cast_certificate/cast_cert_validator.h"
+#include "components/cast_certificate/cast_cert_validator_test_helpers.h"
+#include "components/cast_certificate/cast_crl.h"
+#include "components/cast_certificate/proto/test_suite.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cast_certificate {
+namespace {
+
+// Converts uint64_t unix timestamp to base::Time.
+base::Time ConvertUnixTimestamp(uint64_t time) {
+ return base::Time::UnixEpoch() + base::TimeDelta::FromMilliseconds(time);
+}
+// Indicates the expected result of test step's verification.
+enum TestStepResult {
+ RESULT_SUCCESS,
+ RESULT_FAIL,
+};
+
+// Verifies that the provided certificate chain is valid at the specified time
+// and chains up to a trust anchor.
+bool TestVerifyCertificate(TestStepResult expected_result,
+ const std::vector<std::string>& certificate_chain,
+ const base::Time& time) {
+ std::unique_ptr<CertVerificationContext> context;
+ CastDeviceCertPolicy policy;
+ bool result = VerifyDeviceCert(certificate_chain, time, &context, &policy,
+ nullptr, CRLPolicy::CRL_OPTIONAL);
+ if (expected_result != RESULT_SUCCESS) {
+ EXPECT_FALSE(result);
+ return !result;
+ }
+ EXPECT_TRUE(result);
+ return result;
+}
+
+// Verifies that the provided Cast CRL is signed by a trusted issuer
+// and that the CRL can be parsed successfully.
+// The validity of the CRL is also checked at the specified time.
+bool TestVerifyCRL(TestStepResult expected_result,
+ const std::string& crl_bundle,
+ const base::Time& time) {
+ std::unique_ptr<CastCRL> crl = ParseAndVerifyCRL(crl_bundle, time);
+ if (expected_result != RESULT_SUCCESS) {
+ EXPECT_EQ(crl, nullptr);
+ return crl == nullptr;
+ }
+ EXPECT_NE(crl, nullptr);
+ return crl != nullptr;
+}
+
+// Verifies that the certificate chain provided is not revoked according to
+// the provided Cast CRL at |cert_time|.
+// The provided CRL is verified at |crl_time|.
+// If |crl_required| is set, then a valid Cast CRL must be provided.
+// Otherwise, a missing CRL is be ignored.
+bool TestVerifyRevocation(TestStepResult expected_result,
+ const std::vector<std::string>& certificate_chain,
+ const std::string& crl_bundle,
+ const base::Time& crl_time,
+ const base::Time& cert_time,
+ bool crl_required) {
+ std::unique_ptr<CastCRL> crl;
+ if (!crl_bundle.empty()) {
+ crl = ParseAndVerifyCRL(crl_bundle, crl_time);
+ EXPECT_NE(crl.get(), nullptr);
+ }
+
+ std::unique_ptr<CertVerificationContext> context;
+ CastDeviceCertPolicy policy;
+ CRLPolicy crl_policy = CRLPolicy::CRL_REQUIRED;
+ if (!crl_required)
+ crl_policy = CRLPolicy::CRL_OPTIONAL;
+ int result = VerifyDeviceCert(certificate_chain, cert_time, &context, &policy,
+ crl.get(), crl_policy);
+ if (expected_result != RESULT_SUCCESS) {
+ EXPECT_FALSE(result);
+ return !result;
+ }
+ EXPECT_TRUE(result);
+ return result;
+}
+
+// Runs a single test case.
+bool RunTest(const DeviceCertTest& test_case) {
+ bool use_test_trust_anchors = test_case.use_test_trust_anchors();
+ if (use_test_trust_anchors) {
+ const auto crl_test_root =
+ cast_certificate::testing::ReadCertificateChainFromFile(
+ "certificates/cast_crl_test_root_ca.pem");
+ EXPECT_EQ(crl_test_root.size(), 1u);
+ EXPECT_TRUE(SetCRLTrustAnchorForTest(crl_test_root[0]));
+ const auto cast_test_root =
+ cast_certificate::testing::ReadCertificateChainFromFile(
+ "certificates/cast_test_root_ca.pem");
+ EXPECT_EQ(cast_test_root.size(), 1u);
+ EXPECT_TRUE(SetTrustAnchorForTest(cast_test_root[0]));
+ }
+
+ VerificationResult expected_result = test_case.expected_result();
+
+ std::vector<std::string> certificate_chain;
+ for (auto const& cert : test_case.der_cert_path()) {
+ certificate_chain.push_back(cert);
+ }
+
+ base::Time cert_verification_time =
+ ConvertUnixTimestamp(test_case.cert_verification_time_seconds() * 1000);
eroman 2016/07/19 01:54:59 I suggest changing ConvertUnixTimestamp to take se
ryanchung 2016/07/19 21:29:53 Done.
+
+ uint64_t crl_verify_time = test_case.crl_verification_time_seconds() * 1000;
eroman 2016/07/19 01:54:59 here for instance.
ryanchung 2016/07/19 21:29:54 Done.
+ base::Time crl_verification_time = ConvertUnixTimestamp(crl_verify_time);
+ if (crl_verify_time == 0)
+ crl_verification_time = cert_verification_time;
+
+ std::string crl_bundle = test_case.crl_bundle();
+ switch (expected_result) {
+ case PATH_VERIFICATION_FAILED:
+ return TestVerifyCertificate(RESULT_FAIL, certificate_chain,
+ cert_verification_time);
+ break;
+ case CRL_VERIFICATION_FAILED:
+ return TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time);
+ break;
+ case REVOCATION_CHECK_FAILED_WITHOUT_CRL:
+ return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain,
+ cert_verification_time) &&
+ TestVerifyCRL(RESULT_FAIL, crl_bundle, crl_verification_time) &&
+ TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle,
+ crl_verification_time, cert_verification_time,
+ true);
+ break;
+ case REVOCATION_CHECK_FAILED:
+ return TestVerifyCertificate(RESULT_SUCCESS, certificate_chain,
+ cert_verification_time) &&
+ TestVerifyCRL(RESULT_SUCCESS, crl_bundle, crl_verification_time) &&
+ TestVerifyRevocation(RESULT_FAIL, certificate_chain, crl_bundle,
+ crl_verification_time, cert_verification_time,
+ false);
+ break;
+ case SUCCESS:
+ return (crl_bundle.empty() || TestVerifyCRL(RESULT_SUCCESS, crl_bundle,
+ crl_verification_time)) &&
+ TestVerifyCertificate(RESULT_SUCCESS, certificate_chain,
+ cert_verification_time) &&
+ TestVerifyRevocation(RESULT_SUCCESS, certificate_chain, crl_bundle,
+ crl_verification_time, cert_verification_time,
+ !crl_bundle.empty());
+ break;
+ case UNSPECIFIED:
+ return false;
+ break;
+ }
+ return false;
+}
+
+// Parses the provided test suite provided in wire-format proto.
+// Each test contains the inputs and the expected output.
+// To see the description of the test, execute the test.
+// These tests are generated by a test generator in google3.
+void RunTestSuite(const std::string& test_suite_file_name) {
+ std::string testsuite_raw =
+ cast_certificate::testing::ReadTestFileToString(test_suite_file_name);
+ DeviceCertTestSuite test_suite;
+ EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw));
+ uint16_t success = 0;
+ uint16_t failed = 0;
+ std::vector<std::string> failed_tests;
+
+ for (auto const& test_case : test_suite.tests()) {
+ LOG(INFO) << "[ RUN ] " << test_case.description();
+ bool result = RunTest(test_case);
+ EXPECT_TRUE(result);
+ if (!result) {
+ LOG(INFO) << "[ FAILED ] " << test_case.description();
+ ++failed;
+ failed_tests.push_back(test_case.description());
+ } else {
+ LOG(INFO) << "[ PASSED ] " << test_case.description();
+ ++success;
+ }
+ }
+ LOG(INFO) << "[ PASSED ] " << success << " test(s).";
+ if (failed) {
+ LOG(INFO) << "[ FAILED ] " << failed << " test(s), listed below:";
+ for (const auto& failed_test : failed_tests) {
+ LOG(INFO) << "[ FAILED ] " << failed_test;
+ }
+ }
+}
+
+TEST(CastCertificateTest, TestSuite1) {
+ RunTestSuite("testsuite/testsuite1.pb");
+}
+
+} // namespace
+
+} // namespace cast_certificate

Powered by Google App Engine
This is Rietveld 408576698