• 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(IS_MAC)
16 #include <Security/Security.h>
17 #endif
18 
19 #include <memory>
20 
21 #include "base/files/file_path.h"
22 #include "base/files/file_util.h"
23 #include "base/logging.h"
24 #include "base/no_destructor.h"
25 #include "base/task/task_traits.h"
26 #include "base/task/thread_pool.h"
27 #include "build/build_config.h"
28 #include "net/cert/x509_certificate.h"
29 #include "net/cert/x509_util.h"
30 #include "third_party/boringssl/src/pki/cert_errors.h"
31 #include "third_party/boringssl/src/pki/parsed_certificate.h"
32 #include "third_party/boringssl/src/pki/trust_store_collection.h"
33 #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
34 
35 #if BUILDFLAG(USE_NSS_CERTS)
36 #include "net/cert/internal/trust_store_nss.h"
37 #elif BUILDFLAG(IS_MAC)
38 #include "net/base/features.h"
39 #include "net/cert/internal/trust_store_mac.h"
40 #include "net/cert/x509_util_apple.h"
41 #elif BUILDFLAG(IS_FUCHSIA)
42 #include "base/lazy_instance.h"
43 #include "third_party/boringssl/src/include/openssl/pool.h"
44 #elif BUILDFLAG(IS_WIN)
45 #include "net/cert/internal/trust_store_win.h"
46 #elif BUILDFLAG(IS_ANDROID)
47 #include "net/cert/internal/trust_store_android.h"
48 #endif
49 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
50 #include "net/cert/internal/trust_store_chrome.h"
51 #endif  // CHROME_ROOT_STORE_SUPPORTED
52 
53 namespace net {
54 
55 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
56 class SystemTrustStoreChromeWithUnOwnedSystemStore : public SystemTrustStore {
57  public:
58   // Creates a SystemTrustStore that gets publicly trusted roots from
59   // |trust_store_chrome| and local trust settings from |trust_store_system|.
60   // Does not take ownership of |trust_store_system|, which must outlive this
61   // object.
SystemTrustStoreChromeWithUnOwnedSystemStore(std::unique_ptr<TrustStoreChrome> trust_store_chrome,bssl::TrustStore * trust_store_system)62   explicit SystemTrustStoreChromeWithUnOwnedSystemStore(
63       std::unique_ptr<TrustStoreChrome> trust_store_chrome,
64       bssl::TrustStore* trust_store_system)
65       : trust_store_chrome_(std::move(trust_store_chrome)) {
66     trust_store_collection_.AddTrustStore(trust_store_system);
67     trust_store_collection_.AddTrustStore(trust_store_chrome_.get());
68   }
69 
GetTrustStore()70   bssl::TrustStore* GetTrustStore() override {
71     return &trust_store_collection_;
72   }
73 
74   // IsKnownRoot returns true if the given trust anchor is a standard one (as
75   // opposed to a user-installed root)
IsKnownRoot(const bssl::ParsedCertificate * trust_anchor) const76   bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
77     return trust_store_chrome_->Contains(trust_anchor);
78   }
79 
chrome_root_store_version() const80   int64_t chrome_root_store_version() const override {
81     return trust_store_chrome_->version();
82   }
83 
84  private:
85   std::unique_ptr<TrustStoreChrome> trust_store_chrome_;
86   bssl::TrustStoreCollection trust_store_collection_;
87 };
88 
89 class SystemTrustStoreChrome
90     : public SystemTrustStoreChromeWithUnOwnedSystemStore {
91  public:
92   // Creates a SystemTrustStore that gets publicly trusted roots from
93   // |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)94   explicit SystemTrustStoreChrome(
95       std::unique_ptr<TrustStoreChrome> trust_store_chrome,
96       std::unique_ptr<bssl::TrustStore> trust_store_system)
97       : SystemTrustStoreChromeWithUnOwnedSystemStore(
98             std::move(trust_store_chrome),
99             trust_store_system.get()),
100         trust_store_system_(std::move(trust_store_system)) {}
101 
102  private:
103   std::unique_ptr<bssl::TrustStore> trust_store_system_;
104 };
105 
CreateSystemTrustStoreChromeForTesting(std::unique_ptr<TrustStoreChrome> trust_store_chrome,std::unique_ptr<bssl::TrustStore> trust_store_system)106 std::unique_ptr<SystemTrustStore> CreateSystemTrustStoreChromeForTesting(
107     std::unique_ptr<TrustStoreChrome> trust_store_chrome,
108     std::unique_ptr<bssl::TrustStore> trust_store_system) {
109   return std::make_unique<SystemTrustStoreChrome>(
110       std::move(trust_store_chrome), std::move(trust_store_system));
111 }
112 #endif  // CHROME_ROOT_STORE_SUPPORTED
113 
114 #if BUILDFLAG(USE_NSS_CERTS)
115 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)116 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
117     std::unique_ptr<TrustStoreChrome> chrome_root) {
118   return std::make_unique<SystemTrustStoreChrome>(
119       std::move(chrome_root), std::make_unique<TrustStoreNSS>(
120                                   TrustStoreNSS::UseTrustFromAllUserSlots()));
121 }
122 
123 std::unique_ptr<SystemTrustStore>
CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction(std::unique_ptr<TrustStoreChrome> chrome_root,crypto::ScopedPK11Slot user_slot_restriction)124 CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction(
125     std::unique_ptr<TrustStoreChrome> chrome_root,
126     crypto::ScopedPK11Slot user_slot_restriction) {
127   return std::make_unique<SystemTrustStoreChrome>(
128       std::move(chrome_root),
129       std::make_unique<TrustStoreNSS>(std::move(user_slot_restriction)));
130 }
131 
132 #elif BUILDFLAG(IS_MAC)
133 
134 namespace {
135 
GetGlobalTrustStoreMacForCRS()136 TrustStoreMac* GetGlobalTrustStoreMacForCRS() {
137   constexpr TrustStoreMac::TrustImplType kDefaultMacTrustImplForCRS =
138       TrustStoreMac::TrustImplType::kDomainCacheFullCerts;
139   static base::NoDestructor<TrustStoreMac> static_trust_store_mac(
140       kSecPolicyAppleSSL, kDefaultMacTrustImplForCRS);
141   return static_trust_store_mac.get();
142 }
143 
InitializeTrustCacheForCRSOnWorkerThread()144 void InitializeTrustCacheForCRSOnWorkerThread() {
145   GetGlobalTrustStoreMacForCRS()->InitializeTrustCache();
146 }
147 
148 }  // namespace
149 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)150 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
151     std::unique_ptr<TrustStoreChrome> chrome_root) {
152   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
153       std::move(chrome_root), GetGlobalTrustStoreMacForCRS());
154 }
155 
InitializeTrustStoreMacCache()156 void InitializeTrustStoreMacCache() {
157   base::ThreadPool::PostTask(
158       FROM_HERE,
159       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
160       base::BindOnce(&InitializeTrustCacheForCRSOnWorkerThread));
161 }
162 
163 #elif BUILDFLAG(IS_FUCHSIA)
164 
165 namespace {
166 
167 constexpr char kRootCertsFileFuchsia[] = "/config/ssl/cert.pem";
168 
169 class FuchsiaSystemCerts {
170  public:
FuchsiaSystemCerts()171   FuchsiaSystemCerts() {
172     base::FilePath filename(kRootCertsFileFuchsia);
173     std::string certs_file;
174     if (!base::ReadFileToString(filename, &certs_file)) {
175       LOG(ERROR) << "Can't load root certificates from " << filename;
176       return;
177     }
178 
179     CertificateList certs = X509Certificate::CreateCertificateListFromBytes(
180         base::as_bytes(base::make_span(certs_file)),
181         X509Certificate::FORMAT_AUTO);
182 
183     for (const auto& cert : certs) {
184       bssl::CertErrors errors;
185       auto parsed = bssl::ParsedCertificate::Create(
186           bssl::UpRef(cert->cert_buffer()),
187           x509_util::DefaultParseCertificateOptions(), &errors);
188       CHECK(parsed) << errors.ToDebugString();
189       system_trust_store_.AddTrustAnchor(std::move(parsed));
190     }
191   }
192 
system_trust_store()193   bssl::TrustStoreInMemory* system_trust_store() {
194     return &system_trust_store_;
195   }
196 
197  private:
198   bssl::TrustStoreInMemory system_trust_store_;
199 };
200 
201 base::LazyInstance<FuchsiaSystemCerts>::Leaky g_root_certs_fuchsia =
202     LAZY_INSTANCE_INITIALIZER;
203 
204 }  // namespace
205 
206 class SystemTrustStoreFuchsia : public SystemTrustStore {
207  public:
208   SystemTrustStoreFuchsia() = default;
209 
GetTrustStore()210   bssl::TrustStore* GetTrustStore() override {
211     return g_root_certs_fuchsia.Get().system_trust_store();
212   }
213 
IsKnownRoot(const bssl::ParsedCertificate * trust_anchor) const214   bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
215     return g_root_certs_fuchsia.Get().system_trust_store()->Contains(
216         trust_anchor);
217   }
218 };
219 
CreateSslSystemTrustStore()220 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
221   return std::make_unique<SystemTrustStoreFuchsia>();
222 }
223 
224 #elif BUILDFLAG(IS_WIN)
225 
226 namespace {
GetGlobalTrustStoreWinForCRS()227 TrustStoreWin* GetGlobalTrustStoreWinForCRS() {
228   static base::NoDestructor<TrustStoreWin> static_trust_store_win;
229   return static_trust_store_win.get();
230 }
231 
InitializeTrustStoreForCRSOnWorkerThread()232 void InitializeTrustStoreForCRSOnWorkerThread() {
233   GetGlobalTrustStoreWinForCRS()->InitializeStores();
234 }
235 }  // namespace
236 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)237 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
238     std::unique_ptr<TrustStoreChrome> chrome_root) {
239   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
240       std::move(chrome_root), GetGlobalTrustStoreWinForCRS());
241 }
242 
243 // We do this in a separate thread as loading the Windows Cert Stores can cause
244 // quite a bit of I/O. See crbug.com/1399974 for more context.
InitializeTrustStoreWinSystem()245 void InitializeTrustStoreWinSystem() {
246   base::ThreadPool::PostTask(
247       FROM_HERE,
248       {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
249       base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
250 }
251 
252 #elif BUILDFLAG(IS_ANDROID)
253 
254 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
255 
256 namespace {
GetGlobalTrustStoreAndroidForCRS()257 TrustStoreAndroid* GetGlobalTrustStoreAndroidForCRS() {
258   static base::NoDestructor<TrustStoreAndroid> static_trust_store_android;
259   return static_trust_store_android.get();
260 }
261 
InitializeTrustStoreForCRSOnWorkerThread()262 void InitializeTrustStoreForCRSOnWorkerThread() {
263   GetGlobalTrustStoreAndroidForCRS()->Initialize();
264 }
265 }  // namespace
266 
CreateSslSystemTrustStoreChromeRoot(std::unique_ptr<TrustStoreChrome> chrome_root)267 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStoreChromeRoot(
268     std::unique_ptr<TrustStoreChrome> chrome_root) {
269   return std::make_unique<SystemTrustStoreChromeWithUnOwnedSystemStore>(
270       std::move(chrome_root), GetGlobalTrustStoreAndroidForCRS());
271 }
272 
InitializeTrustStoreAndroid()273 void InitializeTrustStoreAndroid() {
274   // Start observing DB change before the Trust Store is initialized so we don't
275   // accidentally miss any changes. See https://crrev.com/c/4226436 for context.
276   //
277   // This call is safe here because we're the only callers of
278   // ObserveCertDBChanges on the singleton TrustStoreAndroid.
279   GetGlobalTrustStoreAndroidForCRS()->ObserveCertDBChanges();
280 
281   base::ThreadPool::PostTask(
282       FROM_HERE,
283       {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
284       base::BindOnce(&InitializeTrustStoreForCRSOnWorkerThread));
285 }
286 
287 #else
288 
InitializeTrustStoreAndroid()289 void InitializeTrustStoreAndroid() {}
290 
291 #endif  // CHROME_ROOT_STORE_SUPPORTED
292 
293 #endif
294 
295 }  // namespace net
296