#include "net/cert/internal/system_trust_store.h"
#include <memory>
#include <optional>
#include <vector>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "crypto/crypto_buildflags.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
#include "third_party/boringssl/src/pki/cert_errors.h"
#include "third_party/boringssl/src/pki/parsed_certificate.h"
#include "third_party/boringssl/src/pki/trust_store_collection.h"
#include "third_party/boringssl/src/pki/trust_store_in_memory.h"
#if BUILDFLAG(USE_NSS_CERTS)
#include "net/cert/internal/trust_store_nss.h"
#elif BUILDFLAG(IS_MAC)
#include <Security/Security.h>
#include "net/base/features.h"
#include "net/cert/internal/trust_store_mac.h"
#include "net/cert/x509_util_apple.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include "third_party/boringssl/src/include/openssl/pool.h"
#elif BUILDFLAG(IS_WIN)
#include "net/cert/internal/trust_store_win.h"
#elif BUILDFLAG(IS_ANDROID)
#include "net/cert/internal/trust_store_android.h"
#endif
#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
#include "net/cert/internal/trust_store_chrome.h"
#endif
#if BUILDFLAG(IS_CHROMEOS)
#include "base/system/sys_info.h"
#endif
namespace net {
#if BUILDFLAG(IS_CHROMEOS)
namespace internal {
class PemFileCertStore {
public:
explicit PemFileCertStore(std::string_view file_name) {
base::ScopedAllowBlocking allow_blocking;
std::optional<std::vector<uint8_t>> certs_file =
base::ReadFileToBytes(base::FilePath(file_name));
if (!certs_file) {
return;
}
trust_store_ = std::make_unique<bssl::TrustStoreInMemory>();
CertificateList certs = X509Certificate::CreateCertificateListFromBytes(
*certs_file, X509Certificate::FORMAT_AUTO);
for (const auto& cert : certs) {
bssl::CertErrors errors;
auto parsed = bssl::ParsedCertificate::Create(
bssl::UpRef(cert->cert_buffer()),
x509_util::DefaultParseCertificateOptions(), &errors);
if (!parsed) {
LOG(ERROR) << file_name << ": " << errors.ToDebugString();
continue;
}
trust_store_->AddTrustAnchor(std::move(parsed));
}
}
bssl::TrustStoreInMemory* trust_store() { return trust_store_.get(); }
private:
std::unique_ptr<bssl::TrustStoreInMemory> trust_store_;
};
}
namespace {
bssl::TrustStoreInMemory* GetChromeOSTestTrustStore() {
constexpr char kCrosTestRootCertsFile[] = "/etc/fake_root_ca_certs.pem";
static base::NoDestructor<internal::PemFileCertStore> cros_test_roots{
kCrosTestRootCertsFile};
return cros_test_roots->trust_store();
}
}
#endif
#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
class SystemTrustStoreChromeWithUnOwnedSystemStore : public SystemTrustStore {
public:
explicit SystemTrustStoreChromeWithUnOwnedSystemStore(
std::unique_ptr<TrustStoreChrome> trust_store_chrome,
net::PlatformTrustStore* trust_store_system)
: trust_store_chrome_(std::move(trust_store_chrome)),
platform_trust_store_(trust_store_system) {
#if BUILDFLAG(IS_CHROMEOS)
if (GetChromeOSTestTrustStore()) {
base::SysInfo::CrashIfChromeOSNonTestImage();
trust_store_collection_.AddTrustStore(GetChromeOSTestTrustStore());
non_crs_trust_store_collection_.AddTrustStore(
GetChromeOSTestTrustStore());
}
#endif
if (trust_store_system) {
trust_store_collection_.AddTrustStore(trust_store_system);
non_crs_trust_store_collection_.AddTrustStore(trust_store_system);
}
trust_store_collection_.AddTrustStore(trust_store_chrome_.get());
}
bssl::TrustStore* GetTrustStore() override {
return &trust_store_collection_;
}
bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
return trust_store_chrome_->Contains(trust_anchor);
}
bool IsLocallyTrustedRoot(
const bssl::ParsedCertificate* trust_anchor) override {
return non_crs_trust_store_collection_.GetTrust(trust_anchor)
.IsTrustAnchor();
}
int64_t chrome_root_store_version() const override {
return trust_store_chrome_->version();
}
base::span<const ChromeRootCertConstraints> GetChromeRootConstraints(
const bssl::ParsedCertificate* cert) const override {
return trust_store_chrome_->GetConstraintsForCert(cert);
}
bssl::TrustStore* eutl_trust_store() override {
return trust_store_chrome_->eutl_trust_store();
}
net::PlatformTrustStore* GetPlatformTrustStore() override {
return platform_trust_store_;
}
private:
std::unique_ptr<TrustStoreChrome> trust_store_chrome_;
bssl::TrustStoreCollection trust_store_collection_;
bssl::TrustStoreCollection non_crs_trust_store_collection_;
net::PlatformTrustStore* platform_trust_store_;
};
std::unique_ptr<SystemTrustStore> CreateChromeOnlySystemTrustStore(
std::unique_ptr<TrustStoreChrome> chrome_root) {
return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
std::move(chrome_root), nullptr);
}
class SystemTrustStoreChrome
: public SystemTrustStoreChromeWithUnOwnedSystemStore {
public:
explicit SystemTrustStoreChrome(
std::unique_ptr<TrustStoreChrome> trust_store_chrome,
std::unique_ptr<net::PlatformTrustStore> trust_store_system)
: SystemTrustStoreChromeWithUnOwnedSystemStore(
std::move(trust_store_chrome),
trust_store_system.get()),
trust_store_system_(std::move(trust_store_system)) {}
private:
std::unique_ptr<net::PlatformTrustStore> trust_store_system_;
};
std::unique_ptr<SystemTrustStore> CreateSystemTrustStoreChromeForTesting(
std::unique_ptr<TrustStoreChrome> trust_store_chrome,
std::unique_ptr<net::PlatformTrustStore> trust_store_system) {
return std::make_unique<SystemTrustStoreChrome>(
std::move(trust_store_chrome), std::move(trust_store_system));
}
#endif
#if BUILDFLAG(USE_NSS_CERTS)
std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
std::unique_ptr<TrustStoreChrome> chrome_root) {
return std::make_unique<SystemTrustStoreChrome>(
std::move(chrome_root), std::make_unique<TrustStoreNSS>(
TrustStoreNSS::UseTrustFromAllUserSlots()));
}
#elif BUILDFLAG(IS_MAC)
namespace {
TrustStoreMac* GetGlobalTrustStoreMacForCRS() {
constexpr TrustStoreMac::TrustImplType kDefaultMacTrustImplForCRS =
TrustStoreMac::TrustImplType::kDomainCacheFullCerts;
static base::NoDestructor<TrustStoreMac> static_trust_store_mac(
kSecPolicyAppleSSL, kDefaultMacTrustImplForCRS);
return static_trust_store_mac.get();
}
void InitializeTrustCacheForCRSOnWorkerThread() {
GetGlobalTrustStoreMacForCRS()->InitializeTrustCache();
}
}
std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
std::unique_ptr<TrustStoreChrome> chrome_root) {
return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
std::move(chrome_root), GetGlobalTrustStoreMacForCRS());
}
void InitializeTrustStoreMacCache() {
base::ThreadPool::PostTask(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&InitializeTrustCacheForCRSOnWorkerThread));
}
#elif BUILDFLAG(IS_FUCHSIA)
namespace {
constexpr char kRootCertsFileFuchsia[] = "/config/ssl/cert.pem";
class FuchsiaSystemCerts {
public:
FuchsiaSystemCerts() {
base::FilePath filename(kRootCertsFileFuchsia);
std::string certs_file;
if (!base::ReadFileToString(filename, &certs_file)) {
LOG(ERROR) << "Can't load root certificates from " << filename;
return;
}
CertificateList certs = X509Certificate::CreateCertificateListFromBytes(
base::as_byte_span(certs_file), X509Certificate::FORMAT_AUTO);
for (const auto& cert : certs) {
bssl::CertErrors errors;
auto parsed = bssl::ParsedCertificate::Create(
bssl::UpRef(cert->cert_buffer()),
x509_util::DefaultParseCertificateOptions(), &errors);
CHECK(parsed) << errors.ToDebugString();
system_trust_store_.AddTrustAnchor(std::move(parsed));
}
}
bssl::TrustStoreInMemory* system_trust_store() {
return &system_trust_store_;
}
private:
bssl::TrustStoreInMemory system_trust_store_;
};
FuchsiaSystemCerts& GetFuchsiaRootCerts() {
static base::NoDestructor<FuchsiaSystemCerts> certs;
return *certs;
}
}
class SystemTrustStoreFuchsia : public SystemTrustStore {
public:
SystemTrustStoreFuchsia() = default;
bssl::TrustStore* GetTrustStore() override {
return GetFuchsiaRootCerts().system_trust_store();
}
bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
return GetFuchsiaRootCerts().system_trust_store()->Contains(trust_anchor);
}
};
std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
return std::make_unique<SystemTrustStoreFuchsia>();
}
#elif BUILDFLAG(IS_WIN)
namespace {
TrustStoreWin* GetGlobalTrustStoreWinForCRS() {
static base::NoDestructor<TrustStoreWin> static_trust_store_win;
return static_trust_store_win.get();
}
void InitializeTrustStoreForCRSOnWorkerThread() {
GetGlobalTrustStoreWinForCRS()->InitializeStores();
}
}
std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
std::unique_ptr<TrustStoreChrome> chrome_root) {
return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
std::move(chrome_root), GetGlobalTrustStoreWinForCRS());
}
void InitializeTrustStoreWinSystem() {
base::ThreadPool::PostTask(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
}
#elif BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
namespace {
TrustStoreAndroid* GetGlobalTrustStoreAndroidForCRS() {
static base::NoDestructor<TrustStoreAndroid> static_trust_store_android;
return static_trust_store_android.get();
}
void InitializeTrustStoreForCRSOnWorkerThread() {
GetGlobalTrustStoreAndroidForCRS()->Initialize();
}
}
std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
std::unique_ptr<TrustStoreChrome> chrome_root) {
return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
std::move(chrome_root), GetGlobalTrustStoreAndroidForCRS());
}
void InitializeTrustStoreAndroid() {
GetGlobalTrustStoreAndroidForCRS()->ObserveCertDBChanges();
base::ThreadPool::PostTask(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
}
#else
void InitializeTrustStoreAndroid() {}
#endif
#endif
}