blob: c28eba8e0e68bbf51c79ad35ad3b50fe2654ffd3 [file]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/cert_verifier/cert_verifier_creation.h"
#include "base/memory/scoped_refptr.h"
#include "base/types/optional_util.h"
#include "build/build_config.h"
#include "components/network_time/time_tracker/time_tracker.h"
#include "net/base/features.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/crl_set.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_verifier.h"
#include "net/cert/do_nothing_ct_verifier.h"
#include "net/cert/multi_threaded_cert_verifier.h"
#include "net/cert/x509_util.h"
#include "net/net_buildflags.h"
#include "services/network/public/cpp/network_service_buildflags.h"
#include "services/network/public/mojom/cert_verifier_service_updater.mojom.h"
#if BUILDFLAG(IS_CT_SUPPORTED)
#include "net/cert/multi_log_ct_verifier.h"
#endif
#if BUILDFLAG(IS_FUCHSIA)
#include "net/cert/cert_verify_proc_builtin.h"
#include "net/cert/internal/system_trust_store.h"
#endif
#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
#include "net/cert/cert_verify_proc_builtin.h"
#include "net/cert/internal/system_trust_store.h"
#include "net/cert/internal/trust_store_chrome.h"
#endif
namespace cert_verifier {
namespace {
class CertVerifyProcFactoryImpl : public net::CertVerifyProcFactory {
public:
scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc(
scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
const net::CertVerifyProc::ImplParams& impl_params,
const net::CertVerifyProc::InstanceParams& instance_params) override {
std::unique_ptr<net::CTVerifier> ct_verifier;
scoped_refptr<net::CTPolicyEnforcer> ct_policy_enforcer;
#if BUILDFLAG(IS_CT_SUPPORTED)
if (!impl_params.ct_logs.empty()) {
ct_verifier =
std::make_unique<net::MultiLogCTVerifier>(impl_params.ct_logs);
}
ct_policy_enforcer = impl_params.ct_policy_enforcer;
#endif
if (!ct_verifier) {
ct_verifier = std::make_unique<net::DoNothingCTVerifier>();
}
if (!ct_policy_enforcer) {
ct_policy_enforcer = base::MakeRefCounted<net::DefaultCTPolicyEnforcer>();
}
#if BUILDFLAG(CHROME_ROOT_STORE_ONLY)
return CreateNewCertVerifyProc(
cert_net_fetcher, impl_params.crl_set, std::move(ct_verifier),
std::move(ct_policy_enforcer),
base::OptionalToPtr(impl_params.root_store_data),
base::OptionalToPtr(impl_params.root_store_mtc_metadata),
instance_params, impl_params.time_tracker);
#else
#if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL)
if (impl_params.use_chrome_root_store) {
return CreateNewCertVerifyProc(
cert_net_fetcher, impl_params.crl_set, std::move(ct_verifier),
std::move(ct_policy_enforcer),
base::OptionalToPtr(impl_params.root_store_data),
base::OptionalToPtr(impl_params.root_store_mtc_metadata),
instance_params, impl_params.time_tracker);
}
#endif
return CreateOldCertVerifyProc(cert_net_fetcher, impl_params.crl_set,
std::move(ct_verifier),
std::move(ct_policy_enforcer),
instance_params, impl_params.time_tracker);
#endif
}
protected:
~CertVerifyProcFactoryImpl() override = default;
#if !BUILDFLAG(CHROME_ROOT_STORE_ONLY)
// Factory function that returns a CertVerifyProc that supports the old
// configuration for platforms where we are transitioning from one cert
// configuration to another. If the platform only supports one configuration,
// return a CertVerifyProc that supports that configuration.
scoped_refptr<net::CertVerifyProc> CreateOldCertVerifyProc(
scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
scoped_refptr<net::CRLSet> crl_set,
std::unique_ptr<net::CTVerifier> ct_verifier,
scoped_refptr<net::CTPolicyEnforcer> ct_policy_enforcer,
const net::CertVerifyProc::InstanceParams& instance_params,
std::optional<network_time::TimeTracker> time_tracker) {
#if BUILDFLAG(IS_FUCHSIA)
return net::CreateCertVerifyProcBuiltin(
std::move(cert_net_fetcher), std::move(crl_set), std::move(ct_verifier),
std::move(ct_policy_enforcer), net::CreateSslSystemTrustStore(),
instance_params, std::move(time_tracker));
#else
return net::CertVerifyProc::CreateSystemVerifyProc(
std::move(cert_net_fetcher), std::move(crl_set));
#endif
}
#endif // !BUILDFLAG(CHROME_ROOT_STORE_ONLY)
#if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
// CertVerifyProcFactory that returns a CertVerifyProc that uses the
// Chrome Cert Verifier with the Chrome Root Store.
scoped_refptr<net::CertVerifyProc> CreateNewCertVerifyProc(
scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
scoped_refptr<net::CRLSet> crl_set,
std::unique_ptr<net::CTVerifier> ct_verifier,
scoped_refptr<net::CTPolicyEnforcer> ct_policy_enforcer,
const net::ChromeRootStoreData* root_store_data,
const net::ChromeRootStoreMtcMetadata* root_store_mtc_metadata,
const net::CertVerifyProc::InstanceParams& instance_params,
std::optional<network_time::TimeTracker> time_tracker) {
std::unique_ptr<net::TrustStoreChrome> chrome_root =
std::make_unique<net::TrustStoreChrome>(root_store_data,
root_store_mtc_metadata);
std::unique_ptr<net::SystemTrustStore> trust_store;
#if BUILDFLAG(IS_CHROMEOS)
trust_store = net::CreateChromeOnlySystemTrustStore(std::move(chrome_root));
#else
if (instance_params.include_system_trust_store) {
trust_store =
net::CreateSslSystemTrustStoreChromeRoot(std::move(chrome_root));
} else {
trust_store =
net::CreateChromeOnlySystemTrustStore(std::move(chrome_root));
}
#endif
#if BUILDFLAG(IS_WIN)
// Start initialization of TrustStoreWin on a separate thread if it hasn't
// been done already. We do this here instead of in the TrustStoreWin
// constructor to avoid any unnecessary threading in unit tests that don't
// use threads otherwise.
net::InitializeTrustStoreWinSystem();
#endif
#if BUILDFLAG(IS_ANDROID)
// Start initialization of TrustStoreAndroid on a separate thread if it
// hasn't been done already. We do this here instead of in the
// TrustStoreAndroid constructor to avoid any unnecessary threading in unit
// tests that don't use threads otherwise.
net::InitializeTrustStoreAndroid();
#endif
return net::CreateCertVerifyProcBuiltin(
std::move(cert_net_fetcher), std::move(crl_set), std::move(ct_verifier),
std::move(ct_policy_enforcer), std::move(trust_store), instance_params,
std::move(time_tracker));
}
#endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
};
std::vector<net::CertVerifyProc::CertificateWithConstraints>
ConvertMojoListToInternalList(
const std::vector<mojom::CertWithConstraintsPtr>& mojo_cert_list) {
std::vector<net::CertVerifyProc::CertificateWithConstraints> cert_list;
for (const auto& cert_with_constraints_mojo : mojo_cert_list) {
bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer =
net::x509_util::CreateCryptoBuffer(
cert_with_constraints_mojo->certificate);
std::shared_ptr<const bssl::ParsedCertificate> cert =
bssl::ParsedCertificate::Create(
std::move(cert_buffer),
net::x509_util::DefaultParseCertificateOptions(), nullptr);
if (!cert) {
continue;
}
net::CertVerifyProc::CertificateWithConstraints cert_with_constraints;
cert_with_constraints.certificate = std::move(cert);
cert_with_constraints.permitted_dns_names =
cert_with_constraints_mojo->permitted_dns_names;
for (const auto& cidr : cert_with_constraints_mojo->permitted_cidrs) {
cert_with_constraints.permitted_cidrs.push_back({cidr->ip, cidr->mask});
}
cert_list.push_back(std::move(cert_with_constraints));
}
return cert_list;
}
} // namespace
bool IsUsingCertNetFetcher() {
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) || \
BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
return true;
#else
return false;
#endif
}
std::unique_ptr<net::CertVerifierWithUpdatableProc> CreateCertVerifier(
scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
const net::CertVerifyProc::ImplParams& impl_params,
const net::CertVerifyProc::InstanceParams& instance_params) {
DCHECK(cert_net_fetcher || !IsUsingCertNetFetcher());
scoped_refptr<net::CertVerifyProcFactory> proc_factory =
base::MakeRefCounted<CertVerifyProcFactoryImpl>();
return std::make_unique<net::MultiThreadedCertVerifier>(
proc_factory->CreateCertVerifyProc(cert_net_fetcher, impl_params,
instance_params),
proc_factory);
}
void UpdateCertVerifierInstanceParams(
const mojom::AdditionalCertificatesPtr& additional_certificates,
net::CertVerifyProc::InstanceParams* instance_params) {
instance_params->additional_trust_anchors =
net::x509_util::ParseAllValidCerts(
net::x509_util::ConvertToX509CertificatesIgnoreErrors(
additional_certificates->trust_anchors));
instance_params->additional_untrusted_authorities =
net::x509_util::ParseAllValidCerts(
net::x509_util::ConvertToX509CertificatesIgnoreErrors(
additional_certificates->all_certificates));
instance_params->additional_trust_anchors_with_enforced_constraints =
net::x509_util::ParseAllValidCerts(
net::x509_util::ConvertToX509CertificatesIgnoreErrors(
additional_certificates
->trust_anchors_with_enforced_constraints));
instance_params->additional_distrusted_spkis =
additional_certificates->distrusted_spkis;
#if !BUILDFLAG(IS_CHROMEOS)
instance_params->include_system_trust_store =
additional_certificates->include_system_trust_store;
#endif
instance_params->additional_trust_anchors_with_constraints =
ConvertMojoListToInternalList(
additional_certificates->trust_anchors_with_additional_constraints);
instance_params->additional_trust_anchors_and_leafs =
ConvertMojoListToInternalList(
additional_certificates->trust_anchors_and_leafs);
instance_params->additional_trust_leafs =
ConvertMojoListToInternalList(additional_certificates->trust_leafs);
}
} // namespace cert_verifier