• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/memory/ptr_util.h"
8 #include "build/build_config.h"
9 #include "crypto/crypto_buildflags.h"
10 
11 #if BUILDFLAG(USE_NSS_CERTS)
12 #include "net/cert/internal/system_trust_store_nss.h"
13 #endif  // BUILDFLAG(USE_NSS_CERTS)
14 
15 #if BUILDFLAG(USE_NSS_CERTS)
16 #include <cert.h>
17 #include <pk11pub.h>
18 #elif BUILDFLAG(IS_MAC)
19 #include <Security/Security.h>
20 #endif
21 
22 #include <memory>
23 
24 #include "base/files/file_path.h"
25 #include "base/files/file_util.h"
26 #include "base/logging.h"
27 #include "base/no_destructor.h"
28 #include "base/task/task_traits.h"
29 #include "base/task/thread_pool.h"
30 #include "build/build_config.h"
31 #include "net/cert/pki/cert_errors.h"
32 #include "net/cert/pki/parsed_certificate.h"
33 #include "net/cert/pki/trust_store_collection.h"
34 #include "net/cert/pki/trust_store_in_memory.h"
35 #include "net/cert/x509_certificate.h"
36 #include "net/cert/x509_util.h"
37 
38 #if BUILDFLAG(USE_NSS_CERTS)
39 #include "crypto/nss_util.h"
40 #include "net/cert/internal/trust_store_nss.h"
41 #include "net/cert/known_roots_nss.h"
42 #include "net/cert/scoped_nss_types.h"
43 #elif BUILDFLAG(IS_MAC)
44 #include "net/base/features.h"
45 #include "net/cert/internal/trust_store_mac.h"
46 #include "net/cert/x509_util_apple.h"
47 #elif BUILDFLAG(IS_FUCHSIA)
48 #include "base/lazy_instance.h"
49 #include "third_party/boringssl/src/include/openssl/pool.h"
50 #elif BUILDFLAG(IS_WIN)
51 #include "net/cert/internal/trust_store_win.h"
52 #elif BUILDFLAG(IS_ANDROID)
53 #include "net/cert/internal/trust_store_android.h"
54 #endif
55 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
56 #include "net/cert/internal/trust_store_chrome.h"
57 #endif  // CHROME_ROOT_STORE_SUPPORTED
58 
59 namespace net {
60 
61 namespace {
62 
63 class DummySystemTrustStore : public SystemTrustStore {
64  public:
GetTrustStore()65   TrustStore* GetTrustStore() override { return &trust_store_; }
66 
UsesSystemTrustStore() const67   bool UsesSystemTrustStore() const override { return false; }
68 
IsKnownRoot(const ParsedCertificate * trust_anchor) const69   bool IsKnownRoot(const ParsedCertificate* trust_anchor) const override {
70     return false;
71   }
72 
73 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
chrome_root_store_version()74   int64_t chrome_root_store_version() override { return 0; }
75 #endif
76 
77  private:
78   TrustStoreCollection trust_store_;
79 };
80 
81 }  // namespace
82 
83 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
84 class SystemTrustStoreChromeWithUnOwnedSystemStore : public SystemTrustStore {
85  public:
86   // Creates a SystemTrustStore that gets publicly trusted roots from
87   // |trust_store_chrome| and local trust settings from |trust_store_system|.
88   // Does not take ownership of |trust_store_system|, which must outlive this
89   // object.
SystemTrustStoreChromeWithUnOwnedSystemStore(std::unique_ptr<TrustStoreChrome> trust_store_chrome,TrustStore * trust_store_system)90   explicit SystemTrustStoreChromeWithUnOwnedSystemStore(
91       std::unique_ptr<TrustStoreChrome> trust_store_chrome,
92       TrustStore* trust_store_system)
93       : trust_store_chrome_(std::move(trust_store_chrome)) {
94     trust_store_collection_.AddTrustStore(trust_store_system);
95     trust_store_collection_.AddTrustStore(trust_store_chrome_.get());
96   }
97 
GetTrustStore()98   TrustStore* GetTrustStore() override { return &trust_store_collection_; }
99 
UsesSystemTrustStore() const100   bool UsesSystemTrustStore() const override { return true; }
101 
102   // IsKnownRoot returns true if the given trust anchor is a standard one (as
103   // opposed to a user-installed root)
IsKnownRoot(const ParsedCertificate * trust_anchor) const104   bool IsKnownRoot(const ParsedCertificate* trust_anchor) const override {
105     return trust_store_chrome_->Contains(trust_anchor);
106   }
107 
chrome_root_store_version()108   int64_t chrome_root_store_version() override {
109     return trust_store_chrome_->version();
110   }
111 
112  private:
113   std::unique_ptr<TrustStoreChrome> trust_store_chrome_;
114   TrustStoreCollection trust_store_collection_;
115 };
116 
117 class SystemTrustStoreChrome
118     : public SystemTrustStoreChromeWithUnOwnedSystemStore {
119  public:
120   // Creates a SystemTrustStore that gets publicly trusted roots from
121   // |trust_store_chrome| and local trust settings from |trust_store_system|.
SystemTrustStoreChrome(std::unique_ptr<TrustStoreChrome> trust_store_chrome,std::unique_ptr<TrustStore> trust_store_system)122   explicit SystemTrustStoreChrome(
123       std::unique_ptr<TrustStoreChrome> trust_store_chrome,
124       std::unique_ptr<TrustStore> trust_store_system)
125       : SystemTrustStoreChromeWithUnOwnedSystemStore(
126             std::move(trust_store_chrome),
127             trust_store_system.get()),
128         trust_store_system_(std::move(trust_store_system)) {}
129 
130  private:
131   std::unique_ptr<TrustStore> trust_store_system_;
132 };
133 
CreateSystemTrustStoreChromeForTesting(std::unique_ptr<TrustStoreChrome> trust_store_chrome,std::unique_ptr<TrustStore> trust_store_system)134 std::unique_ptr<SystemTrustStore> CreateSystemTrustStoreChromeForTesting(
135     std::unique_ptr<TrustStoreChrome> trust_store_chrome,
136     std::unique_ptr<TrustStore> trust_store_system) {
137   return std::make_unique<SystemTrustStoreChrome>(
138       std::move(trust_store_chrome), std::move(trust_store_system));
139 }
140 #endif  // CHROME_ROOT_STORE_SUPPORTED
141 
142 #if BUILDFLAG(USE_NSS_CERTS)
143 namespace {
144 
145 class SystemTrustStoreNSS : public SystemTrustStore {
146  public:
SystemTrustStoreNSS(std::unique_ptr<TrustStoreNSS> trust_store_nss)147   explicit SystemTrustStoreNSS(std::unique_ptr<TrustStoreNSS> trust_store_nss)
148       : trust_store_nss_(std::move(trust_store_nss)) {}
149 
GetTrustStore()150   TrustStore* GetTrustStore() override { return trust_store_nss_.get(); }
151 
UsesSystemTrustStore() const152   bool UsesSystemTrustStore() const override { return true; }
153 
154   // IsKnownRoot returns true if the given trust anchor is a standard one (as
155   // opposed to a user-installed root)
IsKnownRoot(const ParsedCertificate * trust_anchor) const156   bool IsKnownRoot(const ParsedCertificate* trust_anchor) const override {
157     // TODO(eroman): The overall approach of IsKnownRoot() is inefficient -- it
158     // requires searching for the trust anchor by DER in NSS, however path
159     // building already had a handle to it.
160     SECItem der_cert;
161     der_cert.data = const_cast<uint8_t*>(trust_anchor->der_cert().UnsafeData());
162     der_cert.len = trust_anchor->der_cert().Length();
163     der_cert.type = siDERCertBuffer;
164     ScopedCERTCertificate nss_cert(
165         CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
166     if (!nss_cert)
167       return false;
168 
169     if (!net::IsKnownRoot(nss_cert.get()))
170       return false;
171 
172     return trust_anchor->der_cert() ==
173            der::Input(nss_cert->derCert.data, nss_cert->derCert.len);
174   }
175 
176 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
chrome_root_store_version()177   int64_t chrome_root_store_version() override { return 0; }
178 #endif
179 
180  private:
181   std::unique_ptr<TrustStoreNSS> trust_store_nss_;
182 };
183 
184 }  // namespace
185 
CreateSslSystemTrustStore()186 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
187   return std::make_unique<SystemTrustStoreNSS>(std::make_unique<TrustStoreNSS>(
188       TrustStoreNSS::kUseSystemTrust,
189       TrustStoreNSS::UseTrustFromAllUserSlots()));
190 }
191 
192 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)193 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
194     std::unique_ptr<TrustStoreChrome> chrome_root) {
195   return std::make_unique<SystemTrustStoreChrome>(
196       std::move(chrome_root), std::make_unique<TrustStoreNSS>(
197                                   TrustStoreNSS::kIgnoreSystemTrust,
198                                   TrustStoreNSS::UseTrustFromAllUserSlots()));
199 }
200 
201 std::unique_ptr<SystemTrustStore>
CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction(std::unique_ptr<TrustStoreChrome> chrome_root,crypto::ScopedPK11Slot user_slot_restriction)202 CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction(
203     std::unique_ptr<TrustStoreChrome> chrome_root,
204     crypto::ScopedPK11Slot user_slot_restriction) {
205   return std::make_unique<SystemTrustStoreChrome>(
206       std::move(chrome_root),
207       std::make_unique<TrustStoreNSS>(TrustStoreNSS::kIgnoreSystemTrust,
208                                       std::move(user_slot_restriction)));
209 }
210 
211 #endif  // CHROME_ROOT_STORE_SUPPORTED
212 
213 std::unique_ptr<SystemTrustStore>
CreateSslSystemTrustStoreNSSWithUserSlotRestriction(crypto::ScopedPK11Slot user_slot_restriction)214 CreateSslSystemTrustStoreNSSWithUserSlotRestriction(
215     crypto::ScopedPK11Slot user_slot_restriction) {
216   return std::make_unique<SystemTrustStoreNSS>(std::make_unique<TrustStoreNSS>(
217       TrustStoreNSS::kUseSystemTrust, std::move(user_slot_restriction)));
218 }
219 
220 #elif BUILDFLAG(IS_MAC)
221 
222 // Using the Builtin Verifier w/o the Chrome Root Store is unsupported on
223 // Mac.
CreateSslSystemTrustStore()224 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
225   return std::make_unique<DummySystemTrustStore>();
226 }
227 
228 namespace {
229 
GetGlobalTrustStoreMacForCRS()230 TrustStoreMac* GetGlobalTrustStoreMacForCRS() {
231   constexpr TrustStoreMac::TrustImplType kDefaultMacTrustImplForCRS =
232       TrustStoreMac::TrustImplType::kDomainCacheFullCerts;
233   static base::NoDestructor<TrustStoreMac> static_trust_store_mac(
234       kSecPolicyAppleSSL, kDefaultMacTrustImplForCRS);
235   return static_trust_store_mac.get();
236 }
237 
InitializeTrustCacheForCRSOnWorkerThread()238 void InitializeTrustCacheForCRSOnWorkerThread() {
239   GetGlobalTrustStoreMacForCRS()->InitializeTrustCache();
240 }
241 
242 }  // namespace
243 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)244 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
245     std::unique_ptr<TrustStoreChrome> chrome_root) {
246   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
247       std::move(chrome_root), GetGlobalTrustStoreMacForCRS());
248 }
249 
InitializeTrustStoreMacCache()250 void InitializeTrustStoreMacCache() {
251   base::ThreadPool::PostTask(
252       FROM_HERE,
253       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
254       base::BindOnce(&InitializeTrustCacheForCRSOnWorkerThread));
255 }
256 
257 #elif BUILDFLAG(IS_FUCHSIA)
258 
259 namespace {
260 
261 constexpr char kRootCertsFileFuchsia[] = "/config/ssl/cert.pem";
262 
263 class FuchsiaSystemCerts {
264  public:
FuchsiaSystemCerts()265   FuchsiaSystemCerts() {
266     base::FilePath filename(kRootCertsFileFuchsia);
267     std::string certs_file;
268     if (!base::ReadFileToString(filename, &certs_file)) {
269       LOG(ERROR) << "Can't load root certificates from " << filename;
270       return;
271     }
272 
273     CertificateList certs = X509Certificate::CreateCertificateListFromBytes(
274         base::as_bytes(base::make_span(certs_file)),
275         X509Certificate::FORMAT_AUTO);
276 
277     for (const auto& cert : certs) {
278       CertErrors errors;
279       auto parsed = ParsedCertificate::Create(
280           bssl::UpRef(cert->cert_buffer()),
281           x509_util::DefaultParseCertificateOptions(), &errors);
282       CHECK(parsed) << errors.ToDebugString();
283       system_trust_store_.AddTrustAnchor(parsed);
284     }
285   }
286 
system_trust_store()287   TrustStoreInMemory* system_trust_store() { return &system_trust_store_; }
288 
289  private:
290   TrustStoreInMemory system_trust_store_;
291 };
292 
293 base::LazyInstance<FuchsiaSystemCerts>::Leaky g_root_certs_fuchsia =
294     LAZY_INSTANCE_INITIALIZER;
295 
296 }  // namespace
297 
298 class SystemTrustStoreFuchsia : public SystemTrustStore {
299  public:
300   SystemTrustStoreFuchsia() = default;
301 
GetTrustStore()302   TrustStore* GetTrustStore() override {
303     return g_root_certs_fuchsia.Get().system_trust_store();
304   }
305 
UsesSystemTrustStore() const306   bool UsesSystemTrustStore() const override { return true; }
307 
IsKnownRoot(const ParsedCertificate * trust_anchor) const308   bool IsKnownRoot(const ParsedCertificate* trust_anchor) const override {
309     return g_root_certs_fuchsia.Get().system_trust_store()->Contains(
310         trust_anchor);
311   }
312 };
313 
CreateSslSystemTrustStore()314 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
315   return std::make_unique<SystemTrustStoreFuchsia>();
316 }
317 
318 #elif BUILDFLAG(IS_WIN)
319 
320 // Using the Builtin Verifier w/o the Chrome Root Store is unsupported on
321 // Windows.
CreateSslSystemTrustStore()322 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
323   return std::make_unique<DummySystemTrustStore>();
324 }
325 
326 namespace {
GetGlobalTrustStoreWinForCRS()327 TrustStoreWin* GetGlobalTrustStoreWinForCRS() {
328   static base::NoDestructor<TrustStoreWin> static_trust_store_win;
329   return static_trust_store_win.get();
330 }
331 
InitializeTrustStoreForCRSOnWorkerThread()332 void InitializeTrustStoreForCRSOnWorkerThread() {
333   GetGlobalTrustStoreWinForCRS()->InitializeStores();
334 }
335 }  // namespace
336 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)337 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
338     std::unique_ptr<TrustStoreChrome> chrome_root) {
339   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
340       std::move(chrome_root), GetGlobalTrustStoreWinForCRS());
341 }
342 
343 // We do this in a separate thread as loading the Windows Cert Stores can cause
344 // quite a bit of I/O. See crbug.com/1399974 for more context.
InitializeTrustStoreWinSystem()345 void InitializeTrustStoreWinSystem() {
346   base::ThreadPool::PostTask(
347       FROM_HERE,
348       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
349       base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
350 }
351 
352 #elif BUILDFLAG(IS_ANDROID)
353 
354 // Using the Builtin Verifier w/o the Chrome Root Store is unsupported on
355 // Android.
CreateSslSystemTrustStore()356 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
357   return std::make_unique<DummySystemTrustStore>();
358 }
359 
360 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
361 
362 namespace {
GetGlobalTrustStoreAndroidForCRS()363 TrustStoreAndroid* GetGlobalTrustStoreAndroidForCRS() {
364   static base::NoDestructor<TrustStoreAndroid> static_trust_store_android;
365   return static_trust_store_android.get();
366 }
367 
InitializeTrustStoreForCRSOnWorkerThread()368 void InitializeTrustStoreForCRSOnWorkerThread() {
369   GetGlobalTrustStoreAndroidForCRS()->Initialize();
370 }
371 }  // namespace
372 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)373 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
374     std::unique_ptr<TrustStoreChrome> chrome_root) {
375   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
376       std::move(chrome_root), GetGlobalTrustStoreAndroidForCRS());
377 }
378 
InitializeTrustStoreAndroid()379 void InitializeTrustStoreAndroid() {
380   // Start observing DB change before the Trust Store is initialized so we don't
381   // accidentally miss any changes. See https://crrev.com/c/4226436 for context.
382   //
383   // This call is safe here because we're the only callers of
384   // ObserveCertDBChanges on the singleton TrustStoreAndroid.
385   GetGlobalTrustStoreAndroidForCRS()->ObserveCertDBChanges();
386 
387   base::ThreadPool::PostTask(
388       FROM_HERE,
389       {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
390       base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
391 }
392 
393 #else
394 
InitializeTrustStoreAndroid()395 void InitializeTrustStoreAndroid() {}
396 
397 #endif  // CHROME_ROOT_STORE_SUPPORTED
398 
399 #else
400 
CreateSslSystemTrustStore()401 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
402   return std::make_unique<DummySystemTrustStore>();
403 }
404 
405 #endif
406 
CreateEmptySystemTrustStore()407 std::unique_ptr<SystemTrustStore> CreateEmptySystemTrustStore() {
408   return std::make_unique<DummySystemTrustStore>();
409 }
410 
411 }  // namespace net
412