• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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/trust_store_chrome.h"
6 #include "base/containers/span.h"
7 #include "base/logging.h"
8 #include "base/memory/ptr_util.h"
9 #include "net/cert/pki/cert_errors.h"
10 #include "net/cert/pki/parsed_certificate.h"
11 #include "net/cert/root_store_proto_lite/root_store.pb.h"
12 #include "net/cert/x509_certificate.h"
13 #include "net/cert/x509_util.h"
14 #include "third_party/abseil-cpp/absl/types/optional.h"
15 #include "third_party/boringssl/src/include/openssl/pool.h"
16 
17 namespace net {
18 
19 namespace {
20 #include "net/data/ssl/chrome_root_store/chrome-root-store-inc.cc"
21 }  // namespace
22 
23 ChromeRootStoreData::ChromeRootStoreData() = default;
24 
25 ChromeRootStoreData::~ChromeRootStoreData() = default;
26 
27 ChromeRootStoreData::ChromeRootStoreData(const ChromeRootStoreData& other) =
28     default;
29 ChromeRootStoreData::ChromeRootStoreData(ChromeRootStoreData&& other) = default;
30 ChromeRootStoreData& ChromeRootStoreData::operator=(
31     const ChromeRootStoreData& other) = default;
32 ChromeRootStoreData& ChromeRootStoreData::operator=(
33     ChromeRootStoreData&& other) = default;
34 
35 absl::optional<ChromeRootStoreData>
CreateChromeRootStoreData(const chrome_root_store::RootStore & proto)36 ChromeRootStoreData::CreateChromeRootStoreData(
37     const chrome_root_store::RootStore& proto) {
38   ChromeRootStoreData root_store_data;
39 
40   for (auto& anchor : proto.trust_anchors()) {
41     if (anchor.der().empty()) {
42       LOG(ERROR) << "Error anchor with empty DER in update";
43       return absl::nullopt;
44     }
45 
46     auto parsed = net::ParsedCertificate::Create(
47         net::x509_util::CreateCryptoBuffer(anchor.der()),
48         net::x509_util::DefaultParseCertificateOptions(), nullptr);
49     if (!parsed) {
50       LOG(ERROR) << "Error parsing cert for update";
51       return absl::nullopt;
52     }
53     root_store_data.anchors_.push_back(std::move(parsed));
54   }
55 
56   root_store_data.version_ = proto.version_major();
57 
58   return root_store_data;
59 }
60 
TrustStoreChrome()61 TrustStoreChrome::TrustStoreChrome()
62     : TrustStoreChrome(kChromeRootCertList,
63                        /*certs_are_static=*/true,
64                        /*version=*/CompiledChromeRootStoreVersion()) {}
65 
TrustStoreChrome(base::span<const ChromeRootCertInfo> certs,bool certs_are_static,int64_t version)66 TrustStoreChrome::TrustStoreChrome(base::span<const ChromeRootCertInfo> certs,
67                                    bool certs_are_static,
68                                    int64_t version) {
69   // TODO(hchao, sleevi): Explore keeping a CRYPTO_BUFFER of just the DER
70   // certificate and subject name. This would hopefully save memory compared
71   // to keeping the full parsed representation in memory, especially when
72   // there are multiple instances of TrustStoreChrome.
73   for (const auto& cert_info : certs) {
74     bssl::UniquePtr<CRYPTO_BUFFER> cert;
75     if (certs_are_static) {
76       // TODO(mattm,hchao): Ensure the static data crypto_buffers for the
77       // compiled-in roots are kept alive, so that roots from the component
78       // updater data will de-dupe against them. This currently works if the
79       // new components roots are the same as the compiled in roots, but
80       // fails if a component update drops a root and then the next component
81       // update readds the root without a restart.
82       cert = x509_util::CreateCryptoBufferFromStaticDataUnsafe(
83           cert_info.root_cert_der);
84     } else {
85       cert = x509_util::CreateCryptoBuffer(cert_info.root_cert_der);
86     }
87     CertErrors errors;
88     auto parsed = ParsedCertificate::Create(
89         std::move(cert), x509_util::DefaultParseCertificateOptions(), &errors);
90     DCHECK(parsed);
91     trust_store_.AddTrustAnchor(parsed);
92   }
93   version_ = version;
94 }
95 
TrustStoreChrome(const ChromeRootStoreData & root_store_data)96 TrustStoreChrome::TrustStoreChrome(const ChromeRootStoreData& root_store_data) {
97   for (const auto& anchor : root_store_data.anchors()) {
98     trust_store_.AddTrustAnchor(anchor);
99   }
100   version_ = root_store_data.version();
101 }
102 
103 TrustStoreChrome::~TrustStoreChrome() = default;
104 
SyncGetIssuersOf(const ParsedCertificate * cert,ParsedCertificateList * issuers)105 void TrustStoreChrome::SyncGetIssuersOf(const ParsedCertificate* cert,
106                                         ParsedCertificateList* issuers) {
107   trust_store_.SyncGetIssuersOf(cert, issuers);
108 }
109 
GetTrust(const ParsedCertificate * cert,base::SupportsUserData * debug_data)110 CertificateTrust TrustStoreChrome::GetTrust(
111     const ParsedCertificate* cert,
112     base::SupportsUserData* debug_data) {
113   return trust_store_.GetTrust(cert, debug_data);
114 }
115 
Contains(const ParsedCertificate * cert) const116 bool TrustStoreChrome::Contains(const ParsedCertificate* cert) const {
117   return trust_store_.Contains(cert);
118 }
119 
120 // static
CreateTrustStoreForTesting(base::span<const ChromeRootCertInfo> certs,int64_t version)121 std::unique_ptr<TrustStoreChrome> TrustStoreChrome::CreateTrustStoreForTesting(
122     base::span<const ChromeRootCertInfo> certs,
123     int64_t version) {
124   // Note: wrap_unique is used because the constructor is private.
125   return base::WrapUnique(new TrustStoreChrome(
126       certs, /*certs_are_static=*/false, /*version=*/version));
127 }
128 
CompiledChromeRootStoreVersion()129 int64_t CompiledChromeRootStoreVersion() {
130   return kRootStoreVersion;
131 }
132 
CompiledChromeRootStoreAnchors()133 ParsedCertificateList CompiledChromeRootStoreAnchors() {
134   ParsedCertificateList parsed_cert_list;
135   for (const auto& cert_info : kChromeRootCertList) {
136     bssl::UniquePtr<CRYPTO_BUFFER> cert =
137         x509_util::CreateCryptoBufferFromStaticDataUnsafe(
138             cert_info.root_cert_der);
139     CertErrors errors;
140     auto parsed = ParsedCertificate::Create(
141         std::move(cert), x509_util::DefaultParseCertificateOptions(), &errors);
142     DCHECK(parsed);
143     parsed_cert_list.push_back(parsed);
144   }
145 
146   return parsed_cert_list;
147 }
148 
149 }  // namespace net
150