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

Unified Diff: extensions/browser/api/cast_channel/cast_auth_util_unittest.cc

Issue 2303673004: Hook up Chrome Cast sender to Cast CRL. (Closed)
Patch Set: Update logger.cc to surface errors. Created 4 years, 2 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: extensions/browser/api/cast_channel/cast_auth_util_unittest.cc
diff --git a/extensions/browser/api/cast_channel/cast_auth_util_unittest.cc b/extensions/browser/api/cast_channel/cast_auth_util_unittest.cc
index 9393eac753237a0c236972e16a92d80bce9bf8c5..819daaf4b0d976764f29769c4bb0854cd7481ba1 100644
--- a/extensions/browser/api/cast_channel/cast_auth_util_unittest.cc
+++ b/extensions/browser/api/cast_channel/cast_auth_util_unittest.cc
@@ -7,8 +7,13 @@
#include <string>
#include "base/macros.h"
+#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 "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "net/cert/internal/trust_store_in_memory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
@@ -54,7 +59,10 @@ class CastAuthUtilTest : public testing::Test {
TEST_F(CastAuthUtilTest, VerifySuccess) {
std::string signed_data;
AuthResponse auth_response = CreateAuthResponse(&signed_data);
- AuthResult result = VerifyCredentials(auth_response, signed_data);
+ base::Time now = base::Time::Now();
+ AuthResult result = VerifyCredentialsForTest(
+ auth_response, signed_data, cast_certificate::CRLPolicy::CRL_OPTIONAL,
+ nullptr, nullptr, now);
EXPECT_TRUE(result.success());
EXPECT_EQ(AuthResult::POLICY_NONE, result.channel_policies);
}
@@ -96,6 +104,156 @@ TEST_F(CastAuthUtilTest, VerifyBadPeerCert) {
EXPECT_EQ(AuthResult::ERROR_SIGNED_BLOBS_MISMATCH, result.error_type);
}
+// Indicates the expected result of test step's verification.
+enum TestStepResult {
+ RESULT_SUCCESS,
+ RESULT_FAIL,
+};
+
+// Verifies that the certificate chain provided is not revoked according to
+// the provided Cast CRL at |verification_time|.
+// The provided CRL is verified at |verification_time|.
+// If |crl_required| is set, then a valid Cast CRL must be provided.
+// Otherwise, a missing CRL is be ignored.
+AuthResult TestVerifyRevocation(
+ const std::vector<std::string>& certificate_chain,
+ const std::string& crl_bundle,
+ const base::Time& verification_time,
+ bool crl_required,
+ net::TrustStore* cast_trust_store,
+ net::TrustStore* crl_trust_store) {
+ AuthResponse response;
+
+ if (certificate_chain.size() > 0) {
+ response.set_client_auth_certificate(certificate_chain[0]);
+ for (size_t i = 1; i < certificate_chain.size(); ++i)
+ response.add_intermediate_certificate(certificate_chain[i]);
+ }
+
+ response.set_crl(crl_bundle);
+
+ cast_certificate::CRLPolicy crl_policy =
+ cast_certificate::CRLPolicy::CRL_REQUIRED;
+ if (!crl_required && crl_bundle.empty())
+ crl_policy = cast_certificate::CRLPolicy::CRL_OPTIONAL;
+ AuthResult result =
+ VerifyCredentialsForTest(response, "", crl_policy, cast_trust_store,
+ crl_trust_store, verification_time);
+ // This test doesn't set the signature so it will just fail there.
+ EXPECT_FALSE(result.success());
+ return result;
+}
+
+// Runs a single test case.
+bool RunTest(const cast_certificate::DeviceCertTest& test_case) {
+ std::unique_ptr<net::TrustStore> crl_trust_store;
+ std::unique_ptr<net::TrustStore> cast_trust_store;
+ if (test_case.use_test_trust_anchors()) {
+ crl_trust_store = cast_certificate::testing::CreateTrustStoreFromFile(
+ "certificates/cast_crl_test_root_ca.pem");
+ cast_trust_store = cast_certificate::testing::CreateTrustStoreFromFile(
+ "certificates/cast_test_root_ca.pem");
+
+ EXPECT_TRUE(crl_trust_store.get());
+ EXPECT_TRUE(cast_trust_store.get());
+ }
+
+ std::vector<std::string> certificate_chain;
+ for (auto const& cert : test_case.der_cert_path()) {
+ certificate_chain.push_back(cert);
+ }
+
+ // CastAuthUtil verifies the CRL at the same time as the certificate.
+ base::Time verification_time;
+ uint64_t cert_verify_time = test_case.cert_verification_time_seconds();
+ if (cert_verify_time) {
+ verification_time = cast_certificate::testing::ConvertUnixTimestampSeconds(
+ cert_verify_time);
+ } else {
+ verification_time = cast_certificate::testing::ConvertUnixTimestampSeconds(
+ test_case.crl_verification_time_seconds());
+ }
+
+ std::string crl_bundle = test_case.crl_bundle();
+ AuthResult result;
+ switch (test_case.expected_result()) {
+ case cast_certificate::PATH_VERIFICATION_FAILED:
+ result = TestVerifyRevocation(
+ certificate_chain, crl_bundle, verification_time, false,
+ cast_trust_store.get(), crl_trust_store.get());
+ EXPECT_EQ(result.error_type,
+ AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA);
+ return result.error_type ==
+ AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA;
+ case cast_certificate::CRL_VERIFICATION_FAILED:
+ // Fall-through intended.
+ case cast_certificate::REVOCATION_CHECK_FAILED_WITHOUT_CRL:
+ result = TestVerifyRevocation(
+ certificate_chain, crl_bundle, verification_time, true,
+ cast_trust_store.get(), crl_trust_store.get());
+ EXPECT_EQ(result.error_type, AuthResult::ERROR_CRL_INVALID);
+ return result.error_type == AuthResult::ERROR_CRL_INVALID;
+ case cast_certificate::CRL_EXPIRED_AFTER_INITIAL_VERIFICATION:
+ // By-pass this test because CRL is always verified at the time the
+ // certificate is verified.
+ return true;
+ case cast_certificate::REVOCATION_CHECK_FAILED:
+ result = TestVerifyRevocation(
+ certificate_chain, crl_bundle, verification_time, true,
+ cast_trust_store.get(), crl_trust_store.get());
+ EXPECT_EQ(result.error_type, AuthResult::ERROR_CERT_REVOKED);
+ return result.error_type == AuthResult::ERROR_CERT_REVOKED;
+ case cast_certificate::SUCCESS:
+ result = TestVerifyRevocation(
+ certificate_chain, crl_bundle, verification_time, false,
+ cast_trust_store.get(), crl_trust_store.get());
+ EXPECT_EQ(result.error_type, AuthResult::ERROR_SIGNED_BLOBS_MISMATCH);
+ return result.error_type == AuthResult::ERROR_SIGNED_BLOBS_MISMATCH;
+ case UNSPECIFIED:
+ return false;
+ }
+ 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);
+ cast_certificate::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_F(CastAuthUtilTest, CRLTestSuite) {
+ RunTestSuite("testsuite/testsuite1.pb");
+}
+
} // namespace
} // namespace cast_channel
} // namespace api

Powered by Google App Engine
This is Rietveld 408576698