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/files/file_path.h" 40 #include "base/files/important_file_writer.h" 41 #include "base/memory/raw_ptr.h" 42 #include "base/memory/scoped_refptr.h" 43 #include "base/memory/weak_ptr.h" 44 #include "net/base/net_export.h" 45 #include "net/http/transport_security_state.h" 46 47 namespace base { 48 class SequencedTaskRunner; 49 } 50 51 namespace net { 52 53 // Reads and updates on-disk TransportSecurity state. Clients of this class 54 // should create, destroy, and call into it from one thread. 55 // 56 // background_runner is the task runner this class should use internally to 57 // perform file IO, and can optionally be associated with a different thread. 58 class NET_EXPORT TransportSecurityPersister 59 : public TransportSecurityState::Delegate, 60 public base::ImportantFileWriter::DataSerializer { 61 public: 62 // Create a TransportSecurityPersister with state |state| on background runner 63 // |background_runner|. |data_path| points to the file to hold the transport 64 // security state data on disk. 65 TransportSecurityPersister( 66 TransportSecurityState* state, 67 const scoped_refptr<base::SequencedTaskRunner>& background_runner, 68 const base::FilePath& data_path); 69 70 TransportSecurityPersister(const TransportSecurityPersister&) = delete; 71 TransportSecurityPersister& operator=(const TransportSecurityPersister&) = 72 delete; 73 74 ~TransportSecurityPersister() override; 75 76 // Called by the TransportSecurityState when it changes its state. 77 void StateIsDirty(TransportSecurityState*) override; 78 // Called when the TransportSecurityState should be written immediately. 79 // |callback| is called after data is persisted. 80 void WriteNow(TransportSecurityState* state, 81 base::OnceClosure callback) override; 82 83 // ImportantFileWriter::DataSerializer: 84 // 85 // Serializes |transport_security_state_| into |*output|. Returns true if 86 // all STS states were serialized correctly. 87 // 88 // The serialization format is JSON; the JSON represents a dictionary of 89 // host:DomainState pairs (host is a string). The DomainState contains the STS 90 // states and is represented as a dictionary containing the following keys and 91 // value types (not all keys will always be present): 92 // 93 // "sts_include_subdomains": true|false 94 // "created": double 95 // "expiry": double 96 // "mode": "default"|"force-https" 97 // legacy value synonyms "strict" = "force-https" 98 // "pinning-only" = "default" 99 // legacy value "spdy-only" is unused and ignored 100 // "report-uri": string 101 // "sts_observed": double 102 // 103 // Legacy data (see https://crbug.com/1232560) may also contain a top-level 104 // "expect_ct" key, which will be deleted when read: 105 // "expect_ct": dictionary with keys: 106 // "expect_ct_expiry": double 107 // "expect_ct_observed": double 108 // "expect_ct_enforce": true|false 109 // "expect_ct_report_uri": string 110 // 111 // The JSON dictionary keys are strings containing 112 // Base64(SHA256(TransportSecurityState::CanonicalizeHost(domain))). 113 // The reason for hashing them is so that the stored state does not 114 // trivially reveal a user's browsing history to an attacker reading the 115 // serialized state on disk. 116 std::optional<std::string> SerializeData() override; 117 118 // Clears any existing non-static entries, and then re-populates 119 // |transport_security_state_|. 120 void LoadEntries(const std::string& serialized); 121 122 private: 123 // Populates |state| from the JSON string |serialized|. 124 static void Deserialize(const std::string& serialized, 125 TransportSecurityState* state, 126 bool& contains_legacy_expect_ct_data); 127 128 void CompleteLoad(const std::string& state); 129 void OnWriteFinished(base::OnceClosure callback); 130 131 raw_ptr<TransportSecurityState> transport_security_state_; 132 133 // Helper for safely writing the data. 134 base::ImportantFileWriter writer_; 135 136 scoped_refptr<base::SequencedTaskRunner> foreground_runner_; 137 scoped_refptr<base::SequencedTaskRunner> background_runner_; 138 139 base::WeakPtrFactory<TransportSecurityPersister> weak_ptr_factory_{this}; 140 }; 141 142 } // namespace net 143 144 #endif // NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_ 145