| // 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 |