xref: /aosp_15_r20/external/cronet/net/cert/internal/system_trust_store.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cert/internal/system_trust_store.h"
6 
7 #include <memory>
8 #include <optional>
9 #include <vector>
10 
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/logging.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/no_destructor.h"
16 #include "base/task/task_traits.h"
17 #include "base/task/thread_pool.h"
18 #include "base/threading/thread_restrictions.h"
19 #include "build/build_config.h"
20 #include "crypto/crypto_buildflags.h"
21 #include "net/cert/x509_certificate.h"
22 #include "net/cert/x509_util.h"
23 #include "third_party/boringssl/src/pki/cert_errors.h"
24 #include "third_party/boringssl/src/pki/parsed_certificate.h"
25 #include "third_party/boringssl/src/pki/trust_store_collection.h"
26 #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
27 
28 #if BUILDFLAG(USE_NSS_CERTS)
29 #include "net/cert/internal/system_trust_store_nss.h"
30 #include "net/cert/internal/trust_store_nss.h"
31 #elif BUILDFLAG(IS_MAC)
32 #include <Security/Security.h>
33 
34 #include "net/base/features.h"
35 #include "net/cert/internal/trust_store_mac.h"
36 #include "net/cert/x509_util_apple.h"
37 #elif BUILDFLAG(IS_FUCHSIA)
38 #include "base/lazy_instance.h"
39 #include "third_party/boringssl/src/include/openssl/pool.h"
40 #elif BUILDFLAG(IS_WIN)
41 #include "net/cert/internal/trust_store_win.h"
42 #elif BUILDFLAG(IS_ANDROID)
43 #include "net/cert/internal/trust_store_android.h"
44 #endif
45 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
46 #include "net/cert/internal/trust_store_chrome.h"
47 #endif  // CHROME_ROOT_STORE_SUPPORTED
48 
49 namespace net {
50 
51 #if BUILDFLAG(IS_CHROMEOS)
52 namespace internal {
53 class PemFileCertStore {
54  public:
PemFileCertStore(std::string_view file_name)55   explicit PemFileCertStore(std::string_view file_name) {
56     // This will block on the cert verifier service thread, so the effect will
57     // just be to block any cert verifications (interactions with the cert
58     // verifier service are async mojo calls, so it shouldn't block the browser
59     // UI). There would be no benefit to moving this to a worker thread, since
60     // all cert verifications would still need to block on loading of the roots
61     // to complete.
62     base::ScopedAllowBlocking allow_blocking;
63     std::optional<std::vector<uint8_t>> certs_file =
64         base::ReadFileToBytes(base::FilePath(file_name));
65     if (!certs_file) {
66       return;
67     }
68 
69     trust_store_ = std::make_unique<bssl::TrustStoreInMemory>();
70 
71     CertificateList certs = X509Certificate::CreateCertificateListFromBytes(
72         *certs_file, X509Certificate::FORMAT_AUTO);
73 
74     for (const auto& cert : certs) {
75       bssl::CertErrors errors;
76       auto parsed = bssl::ParsedCertificate::Create(
77           bssl::UpRef(cert->cert_buffer()),
78           x509_util::DefaultParseCertificateOptions(), &errors);
79       if (!parsed) {
80         LOG(ERROR) << file_name << ": " << errors.ToDebugString();
81         continue;
82       }
83       trust_store_->AddTrustAnchor(std::move(parsed));
84     }
85   }
86 
trust_store()87   bssl::TrustStoreInMemory* trust_store() { return trust_store_.get(); }
88 
89  private:
90   std::unique_ptr<bssl::TrustStoreInMemory> trust_store_;
91 };
92 }  // namespace internal
93 
94 namespace {
95 
96 // On ChromeOS look for a PEM file of root CA certs to trust which may be
97 // present on test images.
GetChromeOSTestTrustStore()98 bssl::TrustStoreInMemory* GetChromeOSTestTrustStore() {
99   constexpr char kCrosTestRootCertsFile[] = "/etc/fake_root_ca_certs.pem";
100   static base::NoDestructor<internal::PemFileCertStore> cros_test_roots{
101       kCrosTestRootCertsFile};
102   return cros_test_roots->trust_store();
103 }
104 
105 }  // namespace
106 #endif
107 
108 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
109 class SystemTrustStoreChromeOnly : public SystemTrustStore {
110  public:
111   // Creates a SystemTrustStore that gets publicly trusted roots from
112   // |trust_store_chrome|.
SystemTrustStoreChromeOnly(std::unique_ptr<TrustStoreChrome> trust_store_chrome)113   explicit SystemTrustStoreChromeOnly(
114       std::unique_ptr<TrustStoreChrome> trust_store_chrome)
115       : trust_store_chrome_(std::move(trust_store_chrome)) {}
116 
GetTrustStore()117   bssl::TrustStore* GetTrustStore() override {
118     return trust_store_chrome_.get();
119   }
120 
121   // IsKnownRoot returns true if the given trust anchor is a standard one (as
122   // opposed to a user-installed root)
IsKnownRoot(const bssl::ParsedCertificate * trust_anchor) const123   bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
124     return trust_store_chrome_->Contains(trust_anchor);
125   }
126 
chrome_root_store_version() const127   int64_t chrome_root_store_version() const override {
128     return trust_store_chrome_->version();
129   }
130 
GetChromeRootConstraints(const bssl::ParsedCertificate * cert) const131   base::span<const ChromeRootCertConstraints> GetChromeRootConstraints(
132       const bssl::ParsedCertificate* cert) const override {
133     return trust_store_chrome_->GetConstraintsForCert(cert);
134   }
135 
136  private:
137   std::unique_ptr<TrustStoreChrome> trust_store_chrome_;
138 };
139 
CreateChromeOnlySystemTrustStore(std::unique_ptr<TrustStoreChrome> chrome_root)140 std::unique_ptr<SystemTrustStore> CreateChromeOnlySystemTrustStore(
141     std::unique_ptr<TrustStoreChrome> chrome_root) {
142   return std::make_unique<SystemTrustStoreChromeOnly>(std::move(chrome_root));
143 }
144 
145 class SystemTrustStoreChromeWithUnOwnedSystemStore : public SystemTrustStore {
146  public:
147   // Creates a SystemTrustStore that gets publicly trusted roots from
148   // |trust_store_chrome| and local trust settings from |trust_store_system|.
149   // Does not take ownership of |trust_store_system|, which must outlive this
150   // object.
SystemTrustStoreChromeWithUnOwnedSystemStore(std::unique_ptr<TrustStoreChrome> trust_store_chrome,bssl::TrustStore * trust_store_system)151   explicit SystemTrustStoreChromeWithUnOwnedSystemStore(
152       std::unique_ptr<TrustStoreChrome> trust_store_chrome,
153       bssl::TrustStore* trust_store_system)
154       : trust_store_chrome_(std::move(trust_store_chrome)) {
155 #if BUILDFLAG(IS_CHROMEOS)
156     if (GetChromeOSTestTrustStore()) {
157       trust_store_collection_.AddTrustStore(GetChromeOSTestTrustStore());
158     }
159 #endif
160     trust_store_collection_.AddTrustStore(trust_store_system);
161     trust_store_collection_.AddTrustStore(trust_store_chrome_.get());
162   }
163 
GetTrustStore()164   bssl::TrustStore* GetTrustStore() override {
165     return &trust_store_collection_;
166   }
167 
168   // IsKnownRoot returns true if the given trust anchor is a standard one (as
169   // opposed to a user-installed root)
IsKnownRoot(const bssl::ParsedCertificate * trust_anchor) const170   bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
171     return trust_store_chrome_->Contains(trust_anchor);
172   }
173 
chrome_root_store_version() const174   int64_t chrome_root_store_version() const override {
175     return trust_store_chrome_->version();
176   }
177 
GetChromeRootConstraints(const bssl::ParsedCertificate * cert) const178   base::span<const ChromeRootCertConstraints> GetChromeRootConstraints(
179       const bssl::ParsedCertificate* cert) const override {
180     return trust_store_chrome_->GetConstraintsForCert(cert);
181   }
182 
183  private:
184   std::unique_ptr<TrustStoreChrome> trust_store_chrome_;
185   bssl::TrustStoreCollection trust_store_collection_;
186 };
187 
188 class SystemTrustStoreChrome
189     : public SystemTrustStoreChromeWithUnOwnedSystemStore {
190  public:
191   // Creates a SystemTrustStore that gets publicly trusted roots from
192   // |trust_store_chrome| and local trust settings from |trust_store_system|.
SystemTrustStoreChrome(std::unique_ptr<TrustStoreChrome> trust_store_chrome,std::unique_ptr<bssl::TrustStore> trust_store_system)193   explicit SystemTrustStoreChrome(
194       std::unique_ptr<TrustStoreChrome> trust_store_chrome,
195       std::unique_ptr<bssl::TrustStore> trust_store_system)
196       : SystemTrustStoreChromeWithUnOwnedSystemStore(
197             std::move(trust_store_chrome),
198             trust_store_system.get()),
199         trust_store_system_(std::move(trust_store_system)) {}
200 
201  private:
202   std::unique_ptr<bssl::TrustStore> trust_store_system_;
203 };
204 
CreateSystemTrustStoreChromeForTesting(std::unique_ptr<TrustStoreChrome> trust_store_chrome,std::unique_ptr<bssl::TrustStore> trust_store_system)205 std::unique_ptr<SystemTrustStore> CreateSystemTrustStoreChromeForTesting(
206     std::unique_ptr<TrustStoreChrome> trust_store_chrome,
207     std::unique_ptr<bssl::TrustStore> trust_store_system) {
208   return std::make_unique<SystemTrustStoreChrome>(
209       std::move(trust_store_chrome), std::move(trust_store_system));
210 }
211 #endif  // CHROME_ROOT_STORE_SUPPORTED
212 
213 #if BUILDFLAG(USE_NSS_CERTS)
214 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)215 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
216     std::unique_ptr<TrustStoreChrome> chrome_root) {
217   return std::make_unique<SystemTrustStoreChrome>(
218       std::move(chrome_root), std::make_unique<TrustStoreNSS>(
219                                   TrustStoreNSS::UseTrustFromAllUserSlots()));
220 }
221 
222 std::unique_ptr<SystemTrustStore>
CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction(std::unique_ptr<TrustStoreChrome> chrome_root,crypto::ScopedPK11Slot user_slot_restriction)223 CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction(
224     std::unique_ptr<TrustStoreChrome> chrome_root,
225     crypto::ScopedPK11Slot user_slot_restriction) {
226   return std::make_unique<SystemTrustStoreChrome>(
227       std::move(chrome_root),
228       std::make_unique<TrustStoreNSS>(std::move(user_slot_restriction)));
229 }
230 
231 #elif BUILDFLAG(IS_MAC)
232 
233 namespace {
234 
GetGlobalTrustStoreMacForCRS()235 TrustStoreMac* GetGlobalTrustStoreMacForCRS() {
236   constexpr TrustStoreMac::TrustImplType kDefaultMacTrustImplForCRS =
237       TrustStoreMac::TrustImplType::kDomainCacheFullCerts;
238   static base::NoDestructor<TrustStoreMac> static_trust_store_mac(
239       kSecPolicyAppleSSL, kDefaultMacTrustImplForCRS);
240   return static_trust_store_mac.get();
241 }
242 
InitializeTrustCacheForCRSOnWorkerThread()243 void InitializeTrustCacheForCRSOnWorkerThread() {
244   GetGlobalTrustStoreMacForCRS()->InitializeTrustCache();
245 }
246 
247 }  // namespace
248 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)249 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
250     std::unique_ptr<TrustStoreChrome> chrome_root) {
251   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
252       std::move(chrome_root), GetGlobalTrustStoreMacForCRS());
253 }
254 
InitializeTrustStoreMacCache()255 void InitializeTrustStoreMacCache() {
256   base::ThreadPool::PostTask(
257       FROM_HERE,
258       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
259       base::BindOnce(&InitializeTrustCacheForCRSOnWorkerThread));
260 }
261 
262 #elif BUILDFLAG(IS_FUCHSIA)
263 
264 namespace {
265 
266 constexpr char kRootCertsFileFuchsia[] = "/config/ssl/cert.pem";
267 
268 class FuchsiaSystemCerts {
269  public:
FuchsiaSystemCerts()270   FuchsiaSystemCerts() {
271     base::FilePath filename(kRootCertsFileFuchsia);
272     std::string certs_file;
273     if (!base::ReadFileToString(filename, &certs_file)) {
274       LOG(ERROR) << "Can't load root certificates from " << filename;
275       return;
276     }
277 
278     CertificateList certs = X509Certificate::CreateCertificateListFromBytes(
279         base::as_byte_span(certs_file), X509Certificate::FORMAT_AUTO);
280 
281     for (const auto& cert : certs) {
282       bssl::CertErrors errors;
283       auto parsed = bssl::ParsedCertificate::Create(
284           bssl::UpRef(cert->cert_buffer()),
285           x509_util::DefaultParseCertificateOptions(), &errors);
286       CHECK(parsed) << errors.ToDebugString();
287       system_trust_store_.AddTrustAnchor(std::move(parsed));
288     }
289   }
290 
system_trust_store()291   bssl::TrustStoreInMemory* system_trust_store() {
292     return &system_trust_store_;
293   }
294 
295  private:
296   bssl::TrustStoreInMemory system_trust_store_;
297 };
298 
299 base::LazyInstance<FuchsiaSystemCerts>::Leaky g_root_certs_fuchsia =
300     LAZY_INSTANCE_INITIALIZER;
301 
302 }  // namespace
303 
304 class SystemTrustStoreFuchsia : public SystemTrustStore {
305  public:
306   SystemTrustStoreFuchsia() = default;
307 
GetTrustStore()308   bssl::TrustStore* GetTrustStore() override {
309     return g_root_certs_fuchsia.Get().system_trust_store();
310   }
311 
IsKnownRoot(const bssl::ParsedCertificate * trust_anchor) const312   bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
313     return g_root_certs_fuchsia.Get().system_trust_store()->Contains(
314         trust_anchor);
315   }
316 };
317 
CreateSslSystemTrustStore()318 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
319   return std::make_unique<SystemTrustStoreFuchsia>();
320 }
321 
322 #elif BUILDFLAG(IS_WIN)
323 
324 namespace {
GetGlobalTrustStoreWinForCRS()325 TrustStoreWin* GetGlobalTrustStoreWinForCRS() {
326   static base::NoDestructor<TrustStoreWin> static_trust_store_win;
327   return static_trust_store_win.get();
328 }
329 
InitializeTrustStoreForCRSOnWorkerThread()330 void InitializeTrustStoreForCRSOnWorkerThread() {
331   GetGlobalTrustStoreWinForCRS()->InitializeStores();
332 }
333 }  // namespace
334 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)335 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
336     std::unique_ptr<TrustStoreChrome> chrome_root) {
337   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
338       std::move(chrome_root), GetGlobalTrustStoreWinForCRS());
339 }
340 
341 // We do this in a separate thread as loading the Windows Cert Stores can cause
342 // quite a bit of I/O. See crbug.com/1399974 for more context.
InitializeTrustStoreWinSystem()343 void InitializeTrustStoreWinSystem() {
344   base::ThreadPool::PostTask(
345       FROM_HERE,
346       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
347       base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
348 }
349 
350 #elif BUILDFLAG(IS_ANDROID)
351 
352 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
353 
354 namespace {
GetGlobalTrustStoreAndroidForCRS()355 TrustStoreAndroid* GetGlobalTrustStoreAndroidForCRS() {
356   static base::NoDestructor<TrustStoreAndroid> static_trust_store_android;
357   return static_trust_store_android.get();
358 }
359 
InitializeTrustStoreForCRSOnWorkerThread()360 void InitializeTrustStoreForCRSOnWorkerThread() {
361   GetGlobalTrustStoreAndroidForCRS()->Initialize();
362 }
363 }  // namespace
364 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)365 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
366     std::unique_ptr<TrustStoreChrome> chrome_root) {
367   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
368       std::move(chrome_root), GetGlobalTrustStoreAndroidForCRS());
369 }
370 
InitializeTrustStoreAndroid()371 void InitializeTrustStoreAndroid() {
372   // Start observing DB change before the Trust Store is initialized so we don't
373   // accidentally miss any changes. See https://crrev.com/c/4226436 for context.
374   //
375   // This call is safe here because we're the only callers of
376   // ObserveCertDBChanges on the singleton TrustStoreAndroid.
377   GetGlobalTrustStoreAndroidForCRS()->ObserveCertDBChanges();
378 
379   base::ThreadPool::PostTask(
380       FROM_HERE,
381       {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
382       base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
383 }
384 
385 #else
386 
InitializeTrustStoreAndroid()387 void InitializeTrustStoreAndroid() {}
388 
389 #endif  // CHROME_ROOT_STORE_SUPPORTED
390 
391 #endif
392 
393 }  // namespace net
394