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