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