1 // Copyright 2012 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 // TransportSecurityState maintains an in memory database containing the 6 // list of hosts that currently have transport security enabled. This 7 // singleton object deals with writing that data out to disk as needed and 8 // loading it at startup. 9 10 // At startup we need to load the transport security state from the 11 // disk. For the moment, we don't want to delay startup for this load, so we 12 // let the TransportSecurityState run for a while without being loaded. 13 // This means that it's possible for pages opened very quickly not to get the 14 // correct transport security information. 15 // 16 // To load the state, we schedule a Task on background_runner, which 17 // deserializes and configures the TransportSecurityState. 18 // 19 // The TransportSecurityState object supports running a callback function 20 // when it changes. This object registers the callback, pointing at itself. 21 // 22 // TransportSecurityState calls... 23 // TransportSecurityPersister::StateIsDirty 24 // since the callback isn't allowed to block or reenter, we schedule a Task 25 // on the file task runner after some small amount of time 26 // 27 // ... 28 // 29 // TransportSecurityPersister::SerializeState 30 // copies the current state of the TransportSecurityState, serializes 31 // and writes to disk. 32 33 #ifndef NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_ 34 #define NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_ 35 36 #include <optional> 37 #include <string> 38 39 #include "base/feature_list.h" 40 #include "base/files/file_path.h" 41 #include "base/files/important_file_writer.h" 42 #include "base/memory/raw_ptr.h" 43 #include "base/memory/scoped_refptr.h" 44 #include "base/memory/weak_ptr.h" 45 #include "base/time/time.h" 46 #include "net/base/net_export.h" 47 #include "net/http/transport_security_state.h" 48 49 namespace base { 50 class SequencedTaskRunner; 51 } 52 53 namespace net { 54 55 // Exists only to hold a "commit-interval" param. If disabled, the default 56 // ImportantFileWriter commit interval is used. 57 NET_EXPORT BASE_DECLARE_FEATURE(kTransportSecurityFileWriterSchedule); 58 59 // Reads and updates on-disk TransportSecurity state. Clients of this class 60 // should create, destroy, and call into it from one thread. 61 // 62 // background_runner is the task runner this class should use internally to 63 // perform file IO, and can optionally be associated with a different thread. 64 class NET_EXPORT TransportSecurityPersister 65 : public TransportSecurityState::Delegate, 66 public base::ImportantFileWriter::DataSerializer { 67 public: 68 // Create a TransportSecurityPersister with state |state| on background runner 69 // |background_runner|. |data_path| points to the file to hold the transport 70 // security state data on disk. 71 TransportSecurityPersister( 72 TransportSecurityState* state, 73 const scoped_refptr<base::SequencedTaskRunner>& background_runner, 74 const base::FilePath& data_path); 75 76 TransportSecurityPersister(const TransportSecurityPersister&) = delete; 77 TransportSecurityPersister& operator=(const TransportSecurityPersister&) = 78 delete; 79 80 ~TransportSecurityPersister() override; 81 82 // Called by the TransportSecurityState when it changes its state. 83 void StateIsDirty(TransportSecurityState*) override; 84 // Called when the TransportSecurityState should be written immediately. 85 // |callback| is called after data is persisted. 86 void WriteNow(TransportSecurityState* state, 87 base::OnceClosure callback) override; 88 89 // ImportantFileWriter::DataSerializer: 90 // 91 // Serializes |transport_security_state_| into |*output|. Returns true if 92 // all STS states were serialized correctly. 93 // 94 // The serialization format is JSON; the JSON represents a dictionary of 95 // host:DomainState pairs (host is a string). The DomainState contains the STS 96 // states and is represented as a dictionary containing the following keys and 97 // value types (not all keys will always be present): 98 // 99 // "sts_include_subdomains": true|false 100 // "created": double 101 // "expiry": double 102 // "mode": "default"|"force-https" 103 // legacy value synonyms "strict" = "force-https" 104 // "pinning-only" = "default" 105 // legacy value "spdy-only" is unused and ignored 106 // "report-uri": string 107 // "sts_observed": double 108 // 109 // Legacy data (see https://crbug.com/1232560) may also contain a top-level 110 // "expect_ct" key, which will be deleted when read: 111 // "expect_ct": dictionary with keys: 112 // "expect_ct_expiry": double 113 // "expect_ct_observed": double 114 // "expect_ct_enforce": true|false 115 // "expect_ct_report_uri": string 116 // 117 // The JSON dictionary keys are strings containing 118 // Base64(SHA256(TransportSecurityState::CanonicalizeHost(domain))). 119 // The reason for hashing them is so that the stored state does not 120 // trivially reveal a user's browsing history to an attacker reading the 121 // serialized state on disk. 122 std::optional<std::string> SerializeData() override; 123 124 // Clears any existing non-static entries, and then re-populates 125 // |transport_security_state_|. 126 void LoadEntries(const std::string& serialized); 127 128 // Returns the commit interval used by the ImportantFileWriter. 129 static base::TimeDelta GetCommitInterval(); 130 131 private: 132 // Populates |state| from the JSON string |serialized|. 133 static void Deserialize(const std::string& serialized, 134 TransportSecurityState* state, 135 bool& contains_legacy_expect_ct_data); 136 137 void CompleteLoad(const std::string& state); 138 void OnWriteFinished(base::OnceClosure callback); 139 140 raw_ptr<TransportSecurityState> transport_security_state_; 141 142 // Helper for safely writing the data. 143 base::ImportantFileWriter writer_; 144 145 scoped_refptr<base::SequencedTaskRunner> foreground_runner_; 146 scoped_refptr<base::SequencedTaskRunner> background_runner_; 147 148 base::WeakPtrFactory<TransportSecurityPersister> weak_ptr_factory_{this}; 149 }; 150 151 } // namespace net 152 153 #endif // NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_ 154