| 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
|
| deleted file mode 100644
|
| index b658068558b4e3f9daeb7218df6c955f73aa24be..0000000000000000000000000000000000000000
|
| --- a/extensions/browser/api/cast_channel/cast_auth_util_unittest.cc
|
| +++ /dev/null
|
| @@ -1,339 +0,0 @@
|
| -// Copyright 2014 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 "extensions/browser/api/cast_channel/cast_auth_util.h"
|
| -
|
| -#include <string>
|
| -
|
| -#include "base/macros.h"
|
| -#include "base/test/scoped_feature_list.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 "net/cert/x509_certificate.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -namespace extensions {
|
| -namespace api {
|
| -namespace cast_channel {
|
| -namespace {
|
| -
|
| -class CastAuthUtilTest : public testing::Test {
|
| - public:
|
| - CastAuthUtilTest() {}
|
| - ~CastAuthUtilTest() override {}
|
| -
|
| - void SetUp() override {}
|
| -
|
| - protected:
|
| - static AuthResponse CreateAuthResponse(std::string* signed_data) {
|
| - auto chain = cast_certificate::testing::ReadCertificateChainFromFile(
|
| - "certificates/chromecast_gen1.pem");
|
| - CHECK(!chain.empty());
|
| -
|
| - auto signature_data = cast_certificate::testing::ReadSignatureTestData(
|
| - "signeddata/2ZZBG9_FA8FCA3EF91A.pem");
|
| -
|
| - AuthResponse response;
|
| -
|
| - response.set_client_auth_certificate(chain[0]);
|
| - for (size_t i = 1; i < chain.size(); ++i)
|
| - response.add_intermediate_certificate(chain[i]);
|
| -
|
| - response.set_signature(signature_data.signature_sha1);
|
| - *signed_data = signature_data.message;
|
| -
|
| - return response;
|
| - }
|
| -
|
| - // Mangles a string by inverting the first byte.
|
| - static void MangleString(std::string* str) { (*str)[0] = ~(*str)[0]; }
|
| -};
|
| -
|
| -// Note on expiration: VerifyCredentials() depends on the system clock. In
|
| -// practice this shouldn't be a problem though since the certificate chain
|
| -// being verified doesn't expire until 2032!
|
| -TEST_F(CastAuthUtilTest, VerifySuccess) {
|
| - std::string signed_data;
|
| - AuthResponse auth_response = CreateAuthResponse(&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);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifyBadCA) {
|
| - std::string signed_data;
|
| - AuthResponse auth_response = CreateAuthResponse(&signed_data);
|
| - MangleString(auth_response.mutable_intermediate_certificate(0));
|
| - AuthResult result = VerifyCredentials(auth_response, signed_data);
|
| - EXPECT_FALSE(result.success());
|
| - EXPECT_EQ(AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA, result.error_type);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifyBadClientAuthCert) {
|
| - std::string signed_data;
|
| - AuthResponse auth_response = CreateAuthResponse(&signed_data);
|
| - MangleString(auth_response.mutable_client_auth_certificate());
|
| - AuthResult result = VerifyCredentials(auth_response, signed_data);
|
| - EXPECT_FALSE(result.success());
|
| - // TODO(eroman): Not quite right of an error.
|
| - EXPECT_EQ(AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA, result.error_type);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifyBadSignature) {
|
| - std::string signed_data;
|
| - AuthResponse auth_response = CreateAuthResponse(&signed_data);
|
| - MangleString(auth_response.mutable_signature());
|
| - AuthResult result = VerifyCredentials(auth_response, signed_data);
|
| - EXPECT_FALSE(result.success());
|
| - EXPECT_EQ(AuthResult::ERROR_SIGNED_BLOBS_MISMATCH, result.error_type);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifyBadPeerCert) {
|
| - std::string signed_data;
|
| - AuthResponse auth_response = CreateAuthResponse(&signed_data);
|
| - MangleString(&signed_data);
|
| - AuthResult result = VerifyCredentials(auth_response, signed_data);
|
| - EXPECT_FALSE(result.success());
|
| - EXPECT_EQ(AuthResult::ERROR_SIGNED_BLOBS_MISMATCH, result.error_type);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifySenderNonceMatch) {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndEnableFeature(
|
| - base::Feature{"CastNonceEnforced", base::FEATURE_DISABLED_BY_DEFAULT});
|
| - AuthContext context = AuthContext::Create();
|
| - AuthResult result = context.VerifySenderNonce(context.nonce());
|
| - EXPECT_TRUE(result.success());
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifySenderNonceMismatch) {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndEnableFeature(
|
| - base::Feature{"CastNonceEnforced", base::FEATURE_DISABLED_BY_DEFAULT});
|
| - AuthContext context = AuthContext::Create();
|
| - std::string received_nonce = "test2";
|
| - EXPECT_NE(received_nonce, context.nonce());
|
| - AuthResult result = context.VerifySenderNonce(received_nonce);
|
| - EXPECT_FALSE(result.success());
|
| - EXPECT_EQ(AuthResult::ERROR_SENDER_NONCE_MISMATCH, result.error_type);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifySenderNonceMissing) {
|
| - base::test::ScopedFeatureList scoped_feature_list;
|
| - scoped_feature_list.InitAndEnableFeature(
|
| - base::Feature{"CastNonceEnforced", base::FEATURE_DISABLED_BY_DEFAULT});
|
| - AuthContext context = AuthContext::Create();
|
| - std::string received_nonce = "";
|
| - EXPECT_FALSE(context.nonce().empty());
|
| - AuthResult result = context.VerifySenderNonce(received_nonce);
|
| - EXPECT_FALSE(result.success());
|
| - EXPECT_EQ(AuthResult::ERROR_SENDER_NONCE_MISMATCH, result.error_type);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifyTLSCertificateSuccess) {
|
| - auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile(
|
| - "certificates/test_tls_cert.pem");
|
| -
|
| - scoped_refptr<net::X509Certificate> tls_cert =
|
| - net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
|
| - tls_cert_der[0].size());
|
| - std::string peer_cert_der;
|
| - AuthResult result =
|
| - VerifyTLSCertificate(*tls_cert, &peer_cert_der, tls_cert->valid_start());
|
| - EXPECT_TRUE(result.success());
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooEarly) {
|
| - auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile(
|
| - "certificates/test_tls_cert.pem");
|
| -
|
| - scoped_refptr<net::X509Certificate> tls_cert =
|
| - net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
|
| - tls_cert_der[0].size());
|
| - std::string peer_cert_der;
|
| - AuthResult result = VerifyTLSCertificate(
|
| - *tls_cert, &peer_cert_der,
|
| - tls_cert->valid_start() - base::TimeDelta::FromSeconds(1));
|
| - EXPECT_FALSE(result.success());
|
| - EXPECT_EQ(AuthResult::ERROR_TLS_CERT_VALID_START_DATE_IN_FUTURE,
|
| - result.error_type);
|
| -}
|
| -
|
| -TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooLate) {
|
| - auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile(
|
| - "certificates/test_tls_cert.pem");
|
| -
|
| - scoped_refptr<net::X509Certificate> tls_cert =
|
| - net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
|
| - tls_cert_der[0].size());
|
| - std::string peer_cert_der;
|
| - AuthResult result = VerifyTLSCertificate(
|
| - *tls_cert, &peer_cert_der,
|
| - tls_cert->valid_expiry() + base::TimeDelta::FromSeconds(2));
|
| - EXPECT_FALSE(result.success());
|
| - EXPECT_EQ(AuthResult::ERROR_TLS_CERT_EXPIRED, 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
|
| -} // namespace extensions
|
|
|