xref: /aosp_15_r20/external/cronet/net/cert/internal/trust_store_chrome.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #ifndef NET_CERT_INTERNAL_TRUST_STORE_CHROME_H_
6 #define NET_CERT_INTERNAL_TRUST_STORE_CHROME_H_
7 
8 #include <optional>
9 #include <vector>
10 
11 #include "base/containers/flat_map.h"
12 #include "base/containers/span.h"
13 #include "base/time/time.h"
14 #include "base/version.h"
15 #include "net/base/net_export.h"
16 #include "net/cert/root_store_proto_lite/root_store.pb.h"
17 #include "third_party/boringssl/src/pki/trust_store.h"
18 #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
19 
20 namespace net {
21 
22 // Represents a ConstraintSet for compiled-in version of the root store.
23 // This is a separate struct from ChromeRootCertConstraints since the in-memory
24 // representation parses the version constraints into a base::Version.
25 // (base::Version can't be used in the compiled-in version since it isn't
26 // constexpr.)
27 struct StaticChromeRootCertConstraints {
28   std::optional<base::Time> sct_not_after;
29   std::optional<base::Time> sct_all_after;
30 
31   std::optional<std::string_view> min_version;
32   std::optional<std::string_view> max_version_exclusive;
33 };
34 
35 struct ChromeRootCertInfo {
36   base::span<const uint8_t> root_cert_der;
37   base::span<const StaticChromeRootCertConstraints> constraints;
38 };
39 
40 struct NET_EXPORT ChromeRootCertConstraints {
41   ChromeRootCertConstraints(std::optional<base::Time> sct_not_after,
42                             std::optional<base::Time> sct_all_after,
43                             std::optional<base::Version> min_version,
44                             std::optional<base::Version> max_version_exclusive);
45   explicit ChromeRootCertConstraints(
46       const StaticChromeRootCertConstraints& constraints);
47   ~ChromeRootCertConstraints();
48   ChromeRootCertConstraints(const ChromeRootCertConstraints& other);
49   ChromeRootCertConstraints(ChromeRootCertConstraints&& other);
50   ChromeRootCertConstraints& operator=(const ChromeRootCertConstraints& other);
51   ChromeRootCertConstraints& operator=(ChromeRootCertConstraints&& other);
52 
53   std::optional<base::Time> sct_not_after;
54   std::optional<base::Time> sct_all_after;
55 
56   std::optional<base::Version> min_version;
57   std::optional<base::Version> max_version_exclusive;
58 };
59 
60 // ChromeRootStoreData is a container class that stores all of the Chrome Root
61 // Store data in a single class.
62 class NET_EXPORT ChromeRootStoreData {
63  public:
64   struct NET_EXPORT Anchor {
65     Anchor(std::shared_ptr<const bssl::ParsedCertificate> certificate,
66            std::vector<ChromeRootCertConstraints> constraints);
67     ~Anchor();
68 
69     Anchor(const Anchor& other);
70     Anchor(Anchor&& other);
71     Anchor& operator=(const Anchor& other);
72     Anchor& operator=(Anchor&& other);
73 
74     std::shared_ptr<const bssl::ParsedCertificate> certificate;
75     std::vector<ChromeRootCertConstraints> constraints;
76   };
77   // CreateChromeRootStoreData converts |proto| into a usable
78   // ChromeRootStoreData object. Returns std::nullopt if the passed in
79   // proto has errors in it (e.g. an unparsable DER-encoded certificate).
80   static std::optional<ChromeRootStoreData> CreateChromeRootStoreData(
81       const chrome_root_store::RootStore& proto);
82   ~ChromeRootStoreData();
83 
84   ChromeRootStoreData(const ChromeRootStoreData& other);
85   ChromeRootStoreData(ChromeRootStoreData&& other);
86   ChromeRootStoreData& operator=(const ChromeRootStoreData& other);
87   ChromeRootStoreData& operator=(ChromeRootStoreData&& other);
88 
anchors()89   const std::vector<Anchor>& anchors() const { return anchors_; }
version()90   int64_t version() const { return version_; }
91 
92  private:
93   ChromeRootStoreData();
94 
95   std::vector<Anchor> anchors_;
96   int64_t version_;
97 };
98 
99 // TrustStoreChrome contains the Chrome Root Store, as described at
100 // https://g.co/chrome/root-policy
101 class NET_EXPORT TrustStoreChrome : public bssl::TrustStore {
102  public:
103   // Creates a TrustStoreChrome that uses a copy of `certs`, instead of the
104   // default Chrome Root Store.
105   static std::unique_ptr<TrustStoreChrome> CreateTrustStoreForTesting(
106       base::span<const ChromeRootCertInfo> certs,
107       int64_t version);
108 
109   // Creates a TrustStoreChrome that uses the compiled in Chrome Root Store.
110   TrustStoreChrome();
111 
112   // Creates a TrustStoreChrome that uses the passed in anchors as
113   // the contents of the Chrome Root Store.
114   TrustStoreChrome(const ChromeRootStoreData& anchors);
115   ~TrustStoreChrome() override;
116 
117   TrustStoreChrome(const TrustStoreChrome& other) = delete;
118   TrustStoreChrome& operator=(const TrustStoreChrome& other) = delete;
119 
120   // bssl::TrustStore implementation:
121   void SyncGetIssuersOf(const bssl::ParsedCertificate* cert,
122                         bssl::ParsedCertificateList* issuers) override;
123   bssl::CertificateTrust GetTrust(const bssl::ParsedCertificate* cert) override;
124 
125   // Returns true if the trust store contains the given bssl::ParsedCertificate
126   // (matches by DER).
127   bool Contains(const bssl::ParsedCertificate* cert) const;
128 
129   // Returns the root store constraints for `cert`, or an empty span if the
130   // certificate is not constrained.
131   base::span<const ChromeRootCertConstraints> GetConstraintsForCert(
132       const bssl::ParsedCertificate* cert) const;
133 
version()134   int64_t version() const { return version_; }
135 
136  private:
137   TrustStoreChrome(base::span<const ChromeRootCertInfo> certs,
138                    bool certs_are_static,
139                    int64_t version);
140   bssl::TrustStoreInMemory trust_store_;
141   // Map from certificate DER bytes to additional constraints (if any) for that
142   // certificate. The DER bytes of the key are owned by the ParsedCertificate
143   // stored in `trust_store_`, so this must be below `trust_store_` in the
144   // member list.
145   base::flat_map<std::string_view, std::vector<ChromeRootCertConstraints>>
146       constraints_;
147   int64_t version_;
148 };
149 
150 // Returns the version # of the Chrome Root Store that was compiled into the
151 // binary.
152 NET_EXPORT int64_t CompiledChromeRootStoreVersion();
153 
154 // Returns the anchors of the Chrome Root Store that were compiled into the
155 // binary.
156 NET_EXPORT std::vector<ChromeRootStoreData::Anchor>
157 CompiledChromeRootStoreAnchors();
158 
159 }  // namespace net
160 
161 #endif  // NET_CERT_INTERNAL_TRUST_STORE_CHROME_H_
162