1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 file_task_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 <string> 37 38 #include "base/files/file_path.h" 39 #include "base/files/important_file_writer.h" 40 #include "base/memory/ref_counted.h" 41 #include "base/memory/weak_ptr.h" 42 #include "net/base/net_export.h" 43 #include "net/http/transport_security_state.h" 44 45 namespace base { 46 class SequencedTaskRunner; 47 } 48 49 namespace net { 50 51 // Reads and updates on-disk TransportSecurity state. Clients of this class 52 // should create, destroy, and call into it from one thread. 53 // 54 // file_task_runner is the task runner this class should use internally to 55 // perform file IO, and can optionally be associated with a different thread. 56 class NET_EXPORT TransportSecurityPersister 57 : public TransportSecurityState::Delegate, 58 public base::ImportantFileWriter::DataSerializer { 59 public: 60 TransportSecurityPersister(TransportSecurityState* state, 61 const base::FilePath& profile_path, 62 base::SequencedTaskRunner* file_task_runner, 63 bool readonly); 64 virtual ~TransportSecurityPersister(); 65 66 // Called by the TransportSecurityState when it changes its state. 67 virtual void StateIsDirty(TransportSecurityState*) OVERRIDE; 68 69 // ImportantFileWriter::DataSerializer: 70 // 71 // Serializes |transport_security_state_| into |*output|. Returns true if 72 // all DomainStates were serialized correctly. 73 // 74 // The serialization format is JSON; the JSON represents a dictionary of 75 // host:DomainState pairs (host is a string). The DomainState is 76 // represented as a dictionary containing the following keys and value 77 // types (not all keys will always be present): 78 // 79 // "sts_include_subdomains": true|false 80 // "pkp_include_subdomains": true|false 81 // "created": double 82 // "expiry": double 83 // "dynamic_spki_hashes_expiry": double 84 // "mode": "default"|"force-https" 85 // legacy value synonyms "strict" = "force-https" 86 // "pinning-only" = "default" 87 // legacy value "spdy-only" is unused and ignored 88 // "static_spki_hashes": list of strings 89 // legacy key synonym "preloaded_spki_hashes" 90 // "bad_static_spki_hashes": list of strings 91 // legacy key synonym "bad_preloaded_spki_hashes" 92 // "dynamic_spki_hashes": list of strings 93 // 94 // The JSON dictionary keys are strings containing 95 // Base64(SHA256(TransportSecurityState::CanonicalizeHost(domain))). 96 // The reason for hashing them is so that the stored state does not 97 // trivially reveal a user's browsing history to an attacker reading the 98 // serialized state on disk. 99 virtual bool SerializeData(std::string* data) OVERRIDE; 100 101 // Clears any existing non-static entries, and then re-populates 102 // |transport_security_state_|. 103 // 104 // Sets |*dirty| to true if the new state differs from the persisted 105 // state; false otherwise. 106 bool LoadEntries(const std::string& serialized, bool* dirty); 107 108 private: 109 // Populates |state| from the JSON string |serialized|. Returns true if 110 // all entries were parsed and deserialized correctly. 111 // 112 // Sets |*dirty| to true if the new state differs from the persisted 113 // state; false otherwise. 114 static bool Deserialize(const std::string& serialized, 115 bool* dirty, 116 TransportSecurityState* state); 117 118 void CompleteLoad(const std::string& state); 119 120 TransportSecurityState* transport_security_state_; 121 122 // Helper for safely writing the data. 123 base::ImportantFileWriter writer_; 124 125 scoped_refptr<base::SequencedTaskRunner> foreground_runner_; 126 scoped_refptr<base::SequencedTaskRunner> background_runner_; 127 128 // Whether or not we're in read-only mode. 129 const bool readonly_; 130 131 base::WeakPtrFactory<TransportSecurityPersister> weak_ptr_factory_; 132 133 DISALLOW_COPY_AND_ASSIGN(TransportSecurityPersister); 134 }; 135 136 } // namespace net 137 138 #endif // NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_ 139