Commit 8bc8fbcf authored by Jordan Bayles's avatar Jordan Bayles Committed by Commit Bot

[Cast Streaming] add developer cert argument

This patch adds a build flag, CAST_ALLOW_DEVELOPER_CERTIFICATE, and a
new command line switch ("--cast-developer-certificate-path") that allows
developers to pass in a PEM file containing a root cast certificate that
can be used for authentication.

Example usage:

-> % ./out/Default/Chromium.app/Contents/MacOS/Chromium --vmodule="*cert*=2" --cast-developer-certificate-path="generated_root_cast_receiver.crt"

Note that the certificate path MUST be in the same directory or nested below
the location of the Chrome executable. Referencing parent ("..") or using
an absolute path (e.g.
/usr/local/src/openscreen/generated_root_cast_receiver.crt)
will cause Chrome to refuse to load the certificate.

Bug: b/153079261
Change-Id: I8a8420547aeafb3535ce445ea72d13d9c3b18ddc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2472919
Commit-Queue: Jordan Bayles <jophba@chromium.org>
Reviewed-by: default avatarJordan Bayles <jophba@chromium.org>
Reviewed-by: default avatarDoug Steedman <dougsteed@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826650}
parent b8ea43e5
...@@ -2,6 +2,29 @@ ...@@ -2,6 +2,29 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
declare_args() {
# Allow use of custom Cast root certificate for authentication.
cast_allow_developer_certificate = false
}
config("certificate_config") {
defines = []
if (cast_allow_developer_certificate) {
defines += [ "CAST_ALLOW_DEVELOPER_CERTIFICATE" ]
}
}
source_set("cast_certificate_reader") {
sources = [
"cast_cert_reader.cc",
"cast_cert_reader.h",
]
deps = [
"//base",
"//net",
]
}
static_library("cast_certificate") { static_library("cast_certificate") {
sources = [ sources = [
"cast_cert_validator.cc", "cast_cert_validator.cc",
...@@ -11,21 +34,34 @@ static_library("cast_certificate") { ...@@ -11,21 +34,34 @@ static_library("cast_certificate") {
"cast_root_ca_cert_der-inc.h", "cast_root_ca_cert_der-inc.h",
"eureka_root_ca_der-inc.h", "eureka_root_ca_der-inc.h",
] ]
configs += [ ":certificate_config" ]
deps = [ deps = [
"//base", "//base",
"//net", "//net",
"//third_party/openscreen/src/cast/common/certificate/proto:certificate_proto", "//third_party/openscreen/src/cast/common/certificate/proto:certificate_proto",
# Although we won't use the reader unless cast_allow_developer_certificate
# is enabled, the buildfiles generation step requires the inclusion
# anyway since it doesn't check preprocesser macros.
":cast_certificate_reader",
] ]
if (cast_allow_developer_certificate) {
sources += [
"switches.cc",
"switches.h",
]
}
} }
static_library("test_support") { static_library("test_support") {
testonly = true testonly = true
sources = [ sources = [
"cast_cert_validator_test_helpers.cc", "cast_cert_test_helpers.cc",
"cast_cert_validator_test_helpers.h", "cast_cert_test_helpers.h",
] ]
deps = [ deps = [
":cast_certificate", ":cast_certificate",
":cast_certificate_reader",
"//base", "//base",
"//net", "//net",
"//testing/gtest", "//testing/gtest",
...@@ -41,8 +77,10 @@ source_set("unit_tests") { ...@@ -41,8 +77,10 @@ source_set("unit_tests") {
] ]
deps = [ deps = [
":cast_certificate", ":cast_certificate",
":cast_certificate_reader",
":test_support", ":test_support",
"//base", "//base",
"//base/test:test_support",
"//net", "//net",
"//testing/gtest", "//testing/gtest",
"//third_party/openscreen/src/cast/common/certificate/proto:certificate_unittest_proto", "//third_party/openscreen/src/cast/common/certificate/proto:certificate_unittest_proto",
......
...@@ -2,4 +2,4 @@ include_rules = [ ...@@ -2,4 +2,4 @@ include_rules = [
"+crypto", "+crypto",
"+net", "+net",
"+third_party/openscreen/src/cast/common/certificate/proto", "+third_party/openscreen/src/cast/common/certificate/proto",
] ]
\ No newline at end of file
// Copyright 2020 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 "components/cast_certificate/cast_cert_reader.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "net/cert/internal/common_cert_errors.h"
#include "net/cert/pem.h"
#include "net/cert/x509_util.h"
namespace cast_certificate {
bool PopulateStoreWithCertsFromPath(net::TrustStoreInMemory* store,
const base::FilePath& path) {
const std::vector<std::string> trusted_roots =
ReadCertificateChainFromFile(path);
for (const auto& trusted_root : trusted_roots) {
net::CertErrors errors;
scoped_refptr<net::ParsedCertificate> cert(net::ParsedCertificate::Create(
net::x509_util::CreateCryptoBuffer(trusted_root), {}, &errors));
if (errors.ContainsAnyErrorWithSeverity(
net::CertError::Severity::SEVERITY_HIGH)) {
LOG(ERROR) << "Failed to load cert due to following error(s): "
<< errors.ToDebugString();
return false;
}
store->AddTrustAnchorWithConstraints(cert);
}
return true;
}
std::vector<std::string> ReadCertificateChainFromFile(
const base::FilePath& path) {
std::string file_data;
if (!base::ReadFileToString(path, &file_data)) {
LOG(ERROR) << "Failed to read certificate chain from file: " << path;
return {};
}
std::vector<std::string> pem_headers;
pem_headers.push_back("CERTIFICATE");
std::vector<std::string> certs;
net::PEMTokenizer pem_tokenizer(file_data, pem_headers);
while (pem_tokenizer.GetNext())
certs.push_back(pem_tokenizer.data());
return certs;
}
} // namespace cast_certificate
// Copyright 2020 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.
#ifndef COMPONENTS_CAST_CERTIFICATE_CAST_CERT_READER_H_
#define COMPONENTS_CAST_CERTIFICATE_CAST_CERT_READER_H_
#include <memory>
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "net/cert/internal/trust_store_in_memory.h"
namespace cast_certificate {
// Creates a trust store using the test roots encoded in the PEM file at |path|.
bool PopulateStoreWithCertsFromPath(net::TrustStoreInMemory* store,
const base::FilePath& path);
// Reads a PEM file located at |path|, containing certificates to a vector of
// their DER data.
std::vector<std::string> ReadCertificateChainFromFile(
const base::FilePath& path);
} // namespace cast_certificate
#endif // COMPONENTS_CAST_CERTIFICATE_CAST_CERT_READER_H_
// Copyright 2016 The Chromium Authors. All rights reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "components/cast_certificate/cast_cert_validator_test_helpers.h" #include "components/cast_certificate/cast_cert_test_helpers.h"
#include "base/base_paths.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/threading/thread_restrictions.h"
#include "components/cast_certificate/cast_cert_reader.h"
#include "net/cert/internal/cert_errors.h" #include "net/cert/internal/cert_errors.h"
#include "net/cert/pem.h" #include "net/cert/pem.h"
#include "net/cert/x509_util.h" #include "net/cert/x509_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cast_certificate { namespace cast_certificate {
namespace testing { namespace testing {
std::string ReadTestFileToString(const base::StringPiece& file_name) { namespace {
base::FilePath filepath;
base::PathService::Get(base::DIR_SOURCE_ROOT, &filepath);
filepath = filepath.Append(FILE_PATH_LITERAL("components"));
filepath = filepath.Append(FILE_PATH_LITERAL("test"));
filepath = filepath.Append(FILE_PATH_LITERAL("data"));
filepath = filepath.Append(FILE_PATH_LITERAL("cast_certificate"));
filepath = filepath.AppendASCII(file_name);
// Read the full contents of the file.
std::string file_data;
if (!base::ReadFileToString(filepath, &file_data)) {
ADD_FAILURE() << "Couldn't read file: " << filepath.value();
return std::string();
}
return file_data; // Test cast certificate directory, relative to source root.
} constexpr base::FilePath::CharType kCastCertsRelativePath[] =
FILE_PATH_LITERAL("components/test/data/cast_certificate");
std::vector<std::string> ReadCertificateChainFromFile( } // namespace
const base::StringPiece& file_name) {
std::string file_data = ReadTestFileToString(file_name);
std::vector<std::string> pem_headers; base::FilePath GetCastTestCertsDirectory() {
pem_headers.push_back("CERTIFICATE"); base::FilePath src_root;
{
base::ScopedAllowBlockingForTesting allow_blocking;
base::PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
}
std::vector<std::string> certs; return src_root.Append(kCastCertsRelativePath);
net::PEMTokenizer pem_tokenizer(file_data, pem_headers); }
while (pem_tokenizer.GetNext())
certs.push_back(pem_tokenizer.data());
EXPECT_FALSE(certs.empty()); base::FilePath GetCastTestCertsCertsDirectory() {
return certs; return GetCastTestCertsDirectory().AppendASCII("certificates");
} }
SignatureTestData ReadSignatureTestData(const base::StringPiece& file_name) { SignatureTestData ReadSignatureTestData(const base::StringPiece& file_name) {
SignatureTestData result; SignatureTestData result;
std::string file_data = ReadTestFileToString(file_name); std::string file_data;
EXPECT_FALSE(file_data.empty()); base::ReadFileToString(GetCastTestCertsDirectory().AppendASCII(file_name),
&file_data);
CHECK(!file_data.empty());
std::vector<std::string> pem_headers; std::vector<std::string> pem_headers;
pem_headers.push_back("MESSAGE"); pem_headers.push_back("MESSAGE");
...@@ -75,33 +65,25 @@ SignatureTestData ReadSignatureTestData(const base::StringPiece& file_name) { ...@@ -75,33 +65,25 @@ SignatureTestData ReadSignatureTestData(const base::StringPiece& file_name) {
} }
} }
EXPECT_FALSE(result.message.empty()); CHECK(!result.message.empty());
EXPECT_FALSE(result.signature_sha1.empty()); CHECK(!result.signature_sha1.empty());
EXPECT_FALSE(result.signature_sha256.empty()); CHECK(!result.signature_sha256.empty());
return result; return result;
} }
std::unique_ptr<net::TrustStoreInMemory> CreateTrustStoreFromFile(
const std::string& path) {
std::unique_ptr<net::TrustStoreInMemory> trust_store(
new net::TrustStoreInMemory());
const auto trusted_test_roots =
cast_certificate::testing::ReadCertificateChainFromFile(path);
for (const auto& trusted_root : trusted_test_roots) {
net::CertErrors errors;
scoped_refptr<net::ParsedCertificate> cert(net::ParsedCertificate::Create(
net::x509_util::CreateCryptoBuffer(trusted_root), {}, &errors));
EXPECT_TRUE(cert) << errors.ToDebugString();
trust_store->AddTrustAnchorWithConstraints(cert);
}
return trust_store;
}
base::Time ConvertUnixTimestampSeconds(uint64_t time) { base::Time ConvertUnixTimestampSeconds(uint64_t time) {
return base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(time); return base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(time);
} }
std::unique_ptr<net::TrustStoreInMemory> LoadTestCert(
const base::StringPiece& cert_file_name) {
auto store = std::make_unique<net::TrustStoreInMemory>();
CHECK(PopulateStoreWithCertsFromPath(
store.get(),
testing::GetCastTestCertsCertsDirectory().AppendASCII(cert_file_name)));
CHECK(store);
return store;
}
} // namespace testing } // namespace testing
} // namespace cast_certificate } // namespace cast_certificate
// Copyright 2016 The Chromium Authors. All rights reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef COMPONENTS_CAST_CERTIFICATE_CAST_CERT_VALIDATOR_TEST_HELPERS_H_ #ifndef COMPONENTS_CAST_CERTIFICATE_CAST_CERT_TEST_HELPERS_H_
#define COMPONENTS_CAST_CERTIFICATE_CAST_CERT_VALIDATOR_TEST_HELPERS_H_ #define COMPONENTS_CAST_CERTIFICATE_CAST_CERT_TEST_HELPERS_H_
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/files/file_path.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "net/cert/internal/trust_store_in_memory.h" #include "net/cert/internal/trust_store_in_memory.h"
namespace net {
class TrustStoreInMemory;
}
namespace cast_certificate { namespace cast_certificate {
namespace testing { namespace testing {
// Reads a PEM file containing certificates to a vector of their DER data. // Returns components/test/data/cast_certificates
// |file_name| should be relative to //components/test/data/cast_certificate base::FilePath GetCastTestCertsDirectory();
std::vector<std::string> ReadCertificateChainFromFile(
const base::StringPiece& file_name); // Returns components/test/data/cast_certificates/certificates
base::FilePath GetCastTestCertsCertsDirectory();
// Helper structure that describes a message and its various signatures. // Helper structure that describes a message and its various signatures.
struct SignatureTestData { struct SignatureTestData {
...@@ -42,19 +39,15 @@ struct SignatureTestData { ...@@ -42,19 +39,15 @@ struct SignatureTestData {
// |file_name| should be relative to //components/test/data/cast_certificate // |file_name| should be relative to //components/test/data/cast_certificate
SignatureTestData ReadSignatureTestData(const base::StringPiece& file_name); SignatureTestData ReadSignatureTestData(const base::StringPiece& file_name);
// Reads a file from the test data directory
// (//src/components/test/data/cast_certificate)
std::string ReadTestFileToString(const base::StringPiece& file_name);
// Creates a trust store using the test roots encoded in the PEM file at |path|.
std::unique_ptr<net::TrustStoreInMemory> CreateTrustStoreFromFile(
const std::string& path);
// Converts uint64_t unix timestamp in seconds to base::Time. // Converts uint64_t unix timestamp in seconds to base::Time.
base::Time ConvertUnixTimestampSeconds(uint64_t time); base::Time ConvertUnixTimestampSeconds(uint64_t time);
} // namespace testing // Helper method that loads a certificate from the test certificates folder and
// places it in an heap allocated trust store.
std::unique_ptr<net::TrustStoreInMemory> LoadTestCert(
const base::StringPiece& cert_file_name);
} // namespace testing
} // namespace cast_certificate } // namespace cast_certificate
#endif // COMPONENTS_CAST_CERTIFICATE_CAST_CERT_VALIDATOR_TEST_HELPERS_H_ #endif // COMPONENTS_CAST_CERTIFICATE_CAST_CERT_TEST_HELPERS_H_
...@@ -11,8 +11,12 @@ ...@@ -11,8 +11,12 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "base/memory/singleton.h" #include "base/logging.h"
#include "base/no_destructor.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "components/cast_certificate/cast_crl.h" #include "components/cast_certificate/cast_crl.h"
#include "net/cert/internal/cert_issuer_source_static.h" #include "net/cert/internal/cert_issuer_source_static.h"
#include "net/cert/internal/certificate_policies.h" #include "net/cert/internal/certificate_policies.h"
...@@ -26,10 +30,18 @@ ...@@ -26,10 +30,18 @@
#include "net/cert/internal/simple_path_builder_delegate.h" #include "net/cert/internal/simple_path_builder_delegate.h"
#include "net/cert/internal/trust_store_in_memory.h" #include "net/cert/internal/trust_store_in_memory.h"
#include "net/cert/internal/verify_signed_data.h" #include "net/cert/internal/verify_signed_data.h"
#include "net/cert/pem.h"
#include "net/cert/x509_util.h" #include "net/cert/x509_util.h"
#include "net/der/encode_values.h" #include "net/der/encode_values.h"
#include "net/der/input.h" #include "net/der/input.h"
// Used specifically when CAST_ALLOW_DEVELOPER_CERTIFICATE is true:
#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "components/cast_certificate/cast_cert_reader.h"
#include "components/cast_certificate/switches.h"
namespace cast_certificate { namespace cast_certificate {
namespace { namespace {
...@@ -51,22 +63,57 @@ namespace { ...@@ -51,22 +63,57 @@ namespace {
#include "components/cast_certificate/cast_root_ca_cert_der-inc.h" #include "components/cast_certificate/cast_root_ca_cert_der-inc.h"
#include "components/cast_certificate/eureka_root_ca_der-inc.h" #include "components/cast_certificate/eureka_root_ca_der-inc.h"
// Singleton for the Cast trust store.
class CastTrustStore { class CastTrustStore {
public: public:
static CastTrustStore* GetInstance() { using AccessCallback = base::OnceCallback<void(net::TrustStore*)>;
return base::Singleton<CastTrustStore, static void AccessInstance(AccessCallback callback) {
base::LeakySingletonTraits<CastTrustStore>>::get(); CastTrustStore* instance = GetInstance();
const base::AutoLock guard(instance->lock_);
std::move(callback).Run(&instance->store_);
} }
static net::TrustStore& Get() { return GetInstance()->store_; }
private: private:
friend struct base::DefaultSingletonTraits<CastTrustStore>; friend class base::NoDestructor<CastTrustStore>;
static CastTrustStore* GetInstance() {
static base::NoDestructor<CastTrustStore> instance;
return instance.get();
}
CastTrustStore() { CastTrustStore() {
AddAnchor(kCastRootCaDer); AddAnchor(kCastRootCaDer);
AddAnchor(kEurekaRootCaDer); AddAnchor(kEurekaRootCaDer);
// Adding developer certificates must be done off of the IO thread due
// to blocking file access.
#if defined(CAST_ALLOW_DEVELOPER_CERTIFICATE)
base::ThreadPool::PostTask(
FROM_HERE, {base::MayBlock()},
// NOTE: the singleton instance is never destroyed, so we can use
// Unretained here instead of a weak pointer.
base::BindOnce(&CastTrustStore::AddDeveloperCertificates,
base::Unretained(this)));
}
// Check for custom root developer certificate and create a trust store
// from it if present and enabled.
void AddDeveloperCertificates() {
base::AutoLock guard(lock_);
auto* command_line = base::CommandLine::ForCurrentProcess();
std::string cert_path = command_line->GetSwitchValueASCII(
switches::kCastDeveloperCertificatePath);
if (!cert_path.empty()) {
base::FilePath path;
base::PathService::Get(base::DIR_CURRENT, &path);
path = path.Append(cert_path);
VLOG(1) << "Using cast developer certificate path=" << cert_path
<< ", processed as: " << path;
if (!PopulateStoreWithCertsFromPath(&store_, path)) {
LOG(WARNING) << "No developer certs added to store, only official"
"Google root CA certificates will work.";
}
}
#endif
} }
// Adds a trust anchor given a DER-encoded certificate from static // Adds a trust anchor given a DER-encoded certificate from static
...@@ -79,10 +126,12 @@ class CastTrustStore { ...@@ -79,10 +126,12 @@ class CastTrustStore {
&errors); &errors);
CHECK(cert) << errors.ToDebugString(); CHECK(cert) << errors.ToDebugString();
// Enforce pathlen constraints and policies defined on the root certificate. // Enforce pathlen constraints and policies defined on the root certificate.
base::AutoLock guard(lock_);
store_.AddTrustAnchorWithConstraints(std::move(cert)); store_.AddTrustAnchorWithConstraints(std::move(cert));
} }
net::TrustStoreInMemory store_; base::Lock lock_;
net::TrustStoreInMemory store_ GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(CastTrustStore); DISALLOW_COPY_AND_ASSIGN(CastTrustStore);
}; };
...@@ -258,8 +307,17 @@ CastCertError VerifyDeviceCert( ...@@ -258,8 +307,17 @@ CastCertError VerifyDeviceCert(
CastDeviceCertPolicy* policy, CastDeviceCertPolicy* policy,
const CastCRL* crl, const CastCRL* crl,
CRLPolicy crl_policy) { CRLPolicy crl_policy) {
return VerifyDeviceCertUsingCustomTrustStore( CastCertError verification_result;
certs, time, context, policy, crl, crl_policy, &CastTrustStore::Get()); CastTrustStore::AccessInstance(base::BindOnce(
[](const std::vector<std::string>& certs, const base::Time& time,
std::unique_ptr<CertVerificationContext>* context,
CastDeviceCertPolicy* policy, const CastCRL* crl, CRLPolicy crl_policy,
CastCertError* result, net::TrustStore* store) {
*result = VerifyDeviceCertUsingCustomTrustStore(
certs, time, context, policy, crl, crl_policy, store);
},
certs, time, context, policy, crl, crl_policy, &verification_result));
return verification_result;
} }
CastCertError VerifyDeviceCertUsingCustomTrustStore( CastCertError VerifyDeviceCertUsingCustomTrustStore(
......
...@@ -3,10 +3,12 @@ ...@@ -3,10 +3,12 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "components/cast_certificate/cast_crl.h" #include "components/cast_certificate/cast_crl.h"
#include "base/files/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "components/cast_certificate/cast_cert_reader.h"
#include "components/cast_certificate/cast_cert_test_helpers.h"
#include "components/cast_certificate/cast_cert_validator.h" #include "components/cast_certificate/cast_cert_validator.h"
#include "components/cast_certificate/cast_cert_validator_test_helpers.h"
#include "net/cert/internal/cert_errors.h" #include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/trust_store_in_memory.h" #include "net/cert/internal/trust_store_in_memory.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -95,17 +97,14 @@ bool TestVerifyRevocation(CastCertError expected_result, ...@@ -95,17 +97,14 @@ bool TestVerifyRevocation(CastCertError expected_result,
// Runs a single test case. // Runs a single test case.
bool RunTest(const DeviceCertTest& test_case) { bool RunTest(const DeviceCertTest& test_case) {
std::unique_ptr<net::TrustStoreInMemory> crl_trust_store; std::unique_ptr<net::TrustStoreInMemory> cast_trust_store =
std::unique_ptr<net::TrustStoreInMemory> cast_trust_store; test_case.use_test_trust_anchors()
if (test_case.use_test_trust_anchors()) { ? cast_certificate::testing::LoadTestCert("cast_test_root_ca.pem")
crl_trust_store = testing::CreateTrustStoreFromFile( : nullptr;
"certificates/cast_crl_test_root_ca.pem"); std::unique_ptr<net::TrustStoreInMemory> crl_trust_store =
cast_trust_store = test_case.use_test_trust_anchors()
testing::CreateTrustStoreFromFile("certificates/cast_test_root_ca.pem"); ? cast_certificate::testing::LoadTestCert("cast_crl_test_root_ca.pem")
: nullptr;
EXPECT_TRUE(crl_trust_store.get());
EXPECT_TRUE(cast_trust_store.get());
}
std::vector<std::string> certificate_chain; std::vector<std::string> certificate_chain;
for (auto const& cert : test_case.der_cert_path()) { for (auto const& cert : test_case.der_cert_path()) {
...@@ -175,8 +174,11 @@ bool RunTest(const DeviceCertTest& test_case) { ...@@ -175,8 +174,11 @@ bool RunTest(const DeviceCertTest& test_case) {
// To see the description of the test, execute the test. // To see the description of the test, execute the test.
// These tests are generated by a test generator in google3. // These tests are generated by a test generator in google3.
void RunTestSuite(const std::string& test_suite_file_name) { void RunTestSuite(const std::string& test_suite_file_name) {
std::string testsuite_raw = std::string testsuite_raw;
cast_certificate::testing::ReadTestFileToString(test_suite_file_name); base::ReadFileToString(
testing::GetCastTestCertsDirectory().AppendASCII(test_suite_file_name),
&testsuite_raw);
DeviceCertTestSuite test_suite; DeviceCertTestSuite test_suite;
EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw)); EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw));
uint16_t success = 0; uint16_t success = 0;
......
// Copyright 2020 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 "components/cast_certificate/switches.h"
namespace cast_certificate {
namespace switches {
// When enabled by build flags, passing this argument allows the Cast
// authentication utils to use a custom root developer certificate in the trust
// store instead of the root Google-signed cert.
const char kCastDeveloperCertificatePath[] = "cast-developer-certificate-path";
} // namespace switches
} // namespace cast_certificate
// Copyright 2020 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.
#ifndef COMPONENTS_CAST_CERTIFICATE_SWITCHES_H_
#define COMPONENTS_CAST_CERTIFICATE_SWITCHES_H_
namespace cast_certificate {
namespace switches {
extern const char kCastDeveloperCertificatePath[];
} // namespace switches
} // namespace cast_certificate
#endif // COMPONENTS_CAST_CERTIFICATE_SWITCHES_H_
...@@ -43,7 +43,6 @@ static_library("cast_channel") { ...@@ -43,7 +43,6 @@ static_library("cast_channel") {
"//components/prefs", "//components/prefs",
"//components/version_info", "//components/version_info",
"//content/public/browser", "//content/public/browser",
"//content/public/common",
"//crypto", "//crypto",
"//net", "//net",
"//third_party/openscreen/src/cast/common/channel/proto:channel_proto", "//third_party/openscreen/src/cast/common/channel/proto:channel_proto",
...@@ -91,6 +90,7 @@ source_set("unit_tests") { ...@@ -91,6 +90,7 @@ source_set("unit_tests") {
":test_support", ":test_support",
"//base/test:test_support", "//base/test:test_support",
"//components/cast_certificate", "//components/cast_certificate",
"//components/cast_certificate:cast_certificate_reader",
"//components/cast_certificate:test_support", "//components/cast_certificate:test_support",
"//components/prefs", "//components/prefs",
"//components/prefs:test_support", "//components/prefs:test_support",
...@@ -144,6 +144,7 @@ fuzzer_test("cast_auth_util_fuzzer") { ...@@ -144,6 +144,7 @@ fuzzer_test("cast_auth_util_fuzzer") {
":cast_channel", ":cast_channel",
":cast_channel_fuzzer_inputs", ":cast_channel_fuzzer_inputs",
"//components/cast_certificate", "//components/cast_certificate",
"//components/cast_certificate:cast_certificate_reader",
"//components/cast_certificate:test_support", "//components/cast_certificate:test_support",
"//net:test_support", "//net:test_support",
"//net/data/ssl/certificates:generate_fuzzer_cert_includes", "//net/data/ssl/certificates:generate_fuzzer_cert_includes",
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "base/notreached.h" #include "base/notreached.h"
#include "base/time/time_override.h" #include "base/time/time_override.h"
#include "components/cast_certificate/cast_cert_validator_test_helpers.h" #include "components/cast_certificate/cast_cert_reader.h"
#include "components/cast_certificate/cast_cert_test_helpers.h"
#include "components/cast_channel/cast_auth_util.h" #include "components/cast_channel/cast_auth_util.h"
#include "components/cast_channel/fuzz_proto/fuzzer_inputs.pb.h" #include "components/cast_channel/fuzz_proto/fuzzer_inputs.pb.h"
#include "net/cert/x509_certificate.h" #include "net/cert/x509_certificate.h"
...@@ -30,8 +31,9 @@ const char kCertData[] = { ...@@ -30,8 +31,9 @@ const char kCertData[] = {
base::NoDestructor<std::vector<std::string>> certs; base::NoDestructor<std::vector<std::string>> certs;
static bool InitializeOnce() { static bool InitializeOnce() {
*certs = cast_certificate::testing::ReadCertificateChainFromFile( *certs = cast_certificate::ReadCertificateChainFromFile(
"certificates/chromecast_gen1.pem"); cast_certificate::testing::GetCastTestCertsCertsDirectory().AppendASCII(
"chromecast_gen1.pem"));
DCHECK(certs->size() >= 1); DCHECK(certs->size() >= 1);
return true; return true;
} }
......
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
#include <string> #include <string>
#include "base/files/file_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "components/cast_certificate/cast_cert_reader.h"
#include "components/cast_certificate/cast_cert_test_helpers.h"
#include "components/cast_certificate/cast_cert_validator.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/cast_crl.h"
#include "net/cert/internal/trust_store_in_memory.h" #include "net/cert/internal/trust_store_in_memory.h"
#include "net/cert/x509_certificate.h" #include "net/cert/x509_certificate.h"
...@@ -36,8 +38,9 @@ class CastAuthUtilTest : public testing::Test { ...@@ -36,8 +38,9 @@ class CastAuthUtilTest : public testing::Test {
static AuthResponse CreateAuthResponse( static AuthResponse CreateAuthResponse(
std::string* signed_data, std::string* signed_data,
cast::channel::HashAlgorithm digest_algorithm) { cast::channel::HashAlgorithm digest_algorithm) {
auto chain = cast_certificate::testing::ReadCertificateChainFromFile( auto chain = cast_certificate::ReadCertificateChainFromFile(
"certificates/chromecast_gen1.pem"); cast_certificate::testing::GetCastTestCertsCertsDirectory().AppendASCII(
"chromecast_gen1.pem"));
CHECK(!chain.empty()); CHECK(!chain.empty());
auto signature_data = cast_certificate::testing::ReadSignatureTestData( auto signature_data = cast_certificate::testing::ReadSignatureTestData(
...@@ -186,8 +189,9 @@ TEST_F(CastAuthUtilTest, VerifySenderNonceMissing) { ...@@ -186,8 +189,9 @@ TEST_F(CastAuthUtilTest, VerifySenderNonceMissing) {
} }
TEST_F(CastAuthUtilTest, VerifyTLSCertificateSuccess) { TEST_F(CastAuthUtilTest, VerifyTLSCertificateSuccess) {
auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile( auto tls_cert_der = cast_certificate::ReadCertificateChainFromFile(
"certificates/test_tls_cert.pem"); cast_certificate::testing::GetCastTestCertsCertsDirectory().AppendASCII(
"test_tls_cert.pem"));
scoped_refptr<net::X509Certificate> tls_cert = scoped_refptr<net::X509Certificate> tls_cert =
net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(), net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
...@@ -199,8 +203,9 @@ TEST_F(CastAuthUtilTest, VerifyTLSCertificateSuccess) { ...@@ -199,8 +203,9 @@ TEST_F(CastAuthUtilTest, VerifyTLSCertificateSuccess) {
} }
TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooEarly) { TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooEarly) {
auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile( auto tls_cert_der = cast_certificate::ReadCertificateChainFromFile(
"certificates/test_tls_cert.pem"); cast_certificate::testing::GetCastTestCertsCertsDirectory().AppendASCII(
"test_tls_cert.pem"));
scoped_refptr<net::X509Certificate> tls_cert = scoped_refptr<net::X509Certificate> tls_cert =
net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(), net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
...@@ -215,8 +220,9 @@ TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooEarly) { ...@@ -215,8 +220,9 @@ TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooEarly) {
} }
TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooLate) { TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooLate) {
auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile( auto tls_cert_der = cast_certificate::ReadCertificateChainFromFile(
"certificates/test_tls_cert.pem"); cast_certificate::testing::GetCastTestCertsCertsDirectory().AppendASCII(
"test_tls_cert.pem"));
scoped_refptr<net::X509Certificate> tls_cert = scoped_refptr<net::X509Certificate> tls_cert =
net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(), net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
...@@ -271,17 +277,14 @@ AuthResult TestVerifyRevocation( ...@@ -271,17 +277,14 @@ AuthResult TestVerifyRevocation(
// Runs a single test case. // Runs a single test case.
bool RunTest(const cast::certificate::DeviceCertTest& test_case) { bool RunTest(const cast::certificate::DeviceCertTest& test_case) {
std::unique_ptr<net::TrustStore> crl_trust_store; std::unique_ptr<net::TrustStoreInMemory> cast_trust_store =
std::unique_ptr<net::TrustStore> cast_trust_store; test_case.use_test_trust_anchors()
if (test_case.use_test_trust_anchors()) { ? cast_certificate::testing::LoadTestCert("cast_test_root_ca.pem")
crl_trust_store = cast_certificate::testing::CreateTrustStoreFromFile( : nullptr;
"certificates/cast_crl_test_root_ca.pem"); std::unique_ptr<net::TrustStoreInMemory> crl_trust_store =
cast_trust_store = cast_certificate::testing::CreateTrustStoreFromFile( test_case.use_test_trust_anchors()
"certificates/cast_test_root_ca.pem"); ? cast_certificate::testing::LoadTestCert("cast_crl_test_root_ca.pem")
: nullptr;
EXPECT_TRUE(crl_trust_store.get());
EXPECT_TRUE(cast_trust_store.get());
}
std::vector<std::string> certificate_chain; std::vector<std::string> certificate_chain;
for (auto const& cert : test_case.der_cert_path()) { for (auto const& cert : test_case.der_cert_path()) {
...@@ -345,8 +348,12 @@ bool RunTest(const cast::certificate::DeviceCertTest& test_case) { ...@@ -345,8 +348,12 @@ bool RunTest(const cast::certificate::DeviceCertTest& test_case) {
// To see the description of the test, execute the test. // To see the description of the test, execute the test.
// These tests are generated by a test generator in google3. // These tests are generated by a test generator in google3.
void RunTestSuite(const std::string& test_suite_file_name) { void RunTestSuite(const std::string& test_suite_file_name) {
std::string testsuite_raw = std::string testsuite_raw;
cast_certificate::testing::ReadTestFileToString(test_suite_file_name); base::ReadFileToString(
cast_certificate::testing::GetCastTestCertsDirectory().AppendASCII(
test_suite_file_name),
&testsuite_raw);
cast::certificate::DeviceCertTestSuite test_suite; cast::certificate::DeviceCertTestSuite test_suite;
EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw)); EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw));
uint16_t success = 0; uint16_t success = 0;
......
...@@ -534,11 +534,12 @@ class SslCastSocketTest : public CastSocketTestBase { ...@@ -534,11 +534,12 @@ class SslCastSocketTest : public CastSocketTestBase {
std::unique_ptr<crypto::RSAPrivateKey> ReadTestKeyFromPEM( std::unique_ptr<crypto::RSAPrivateKey> ReadTestKeyFromPEM(
const base::StringPiece& name) { const base::StringPiece& name) {
base::FilePath key_path = GetTestCertsDirectory().AppendASCII(name); base::FilePath key_path = GetTestCertsDirectory().AppendASCII(name);
std::vector<std::string> headers({"PRIVATE KEY"});
std::string pem_data; std::string pem_data;
if (!base::ReadFileToString(key_path, &pem_data)) { if (!base::ReadFileToString(key_path, &pem_data)) {
return nullptr; return nullptr;
} }
const std::vector<std::string> headers({"PRIVATE KEY"});
net::PEMTokenizer pem_tokenizer(pem_data, headers); net::PEMTokenizer pem_tokenizer(pem_data, headers);
if (!pem_tokenizer.GetNext()) { if (!pem_tokenizer.GetNext()) {
return nullptr; return nullptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment