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