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 the file thread which loads, 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 thread 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 CHROME_BROWSER_NET_TRANSPORT_SECURITY_PERSISTER_H_ 34 #define CHROME_BROWSER_NET_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/weak_ptr.h" 41 #include "net/http/transport_security_state.h" 42 43 // Reads and updates on-disk TransportSecurity state. 44 // Must be created, used and destroyed only on the IO thread. 45 class TransportSecurityPersister 46 : public net::TransportSecurityState::Delegate, 47 public base::ImportantFileWriter::DataSerializer { 48 public: 49 TransportSecurityPersister(net::TransportSecurityState* state, 50 const base::FilePath& profile_path, 51 bool readonly); 52 virtual ~TransportSecurityPersister(); 53 54 // Called by the TransportSecurityState when it changes its state. 55 virtual void StateIsDirty(net::TransportSecurityState*) OVERRIDE; 56 57 // ImportantFileWriter::DataSerializer: 58 // 59 // Serializes |transport_security_state_| into |*output|. Returns true if 60 // all DomainStates were serialized correctly. 61 // 62 // The serialization format is JSON; the JSON represents a dictionary of 63 // host:DomainState pairs (host is a string). The DomainState is 64 // represented as a dictionary containing the following keys and value 65 // types (not all keys will always be present): 66 // 67 // "sts_include_subdomains": true|false 68 // "pkp_include_subdomains": true|false 69 // "created": double 70 // "expiry": double 71 // "dynamic_spki_hashes_expiry": double 72 // "mode": "default"|"force-https" 73 // legacy value synonyms "strict" = "force-https" 74 // "pinning-only" = "default" 75 // legacy value "spdy-only" is unused and ignored 76 // "static_spki_hashes": list of strings 77 // legacy key synonym "preloaded_spki_hashes" 78 // "bad_static_spki_hashes": list of strings 79 // legacy key synonym "bad_preloaded_spki_hashes" 80 // "dynamic_spki_hashes": list of strings 81 // 82 // The JSON dictionary keys are strings containing 83 // Base64(SHA256(net::TransportSecurityState::CanonicalizeHost(domain))). 84 // The reason for hashing them is so that the stored state does not 85 // trivially reveal a user's browsing history to an attacker reading the 86 // serialized state on disk. 87 virtual bool SerializeData(std::string* data) OVERRIDE; 88 89 // Clears any existing non-static entries, and then re-populates 90 // |transport_security_state_|. 91 // 92 // Sets |*dirty| to true if the new state differs from the persisted 93 // state; false otherwise. 94 bool LoadEntries(const std::string& serialized, bool* dirty); 95 96 private: 97 class Loader; 98 99 // Populates |state| from the JSON string |serialized|. Returns true if 100 // all entries were parsed and deserialized correctly. 101 // 102 // Sets |*dirty| to true if the new state differs from the persisted 103 // state; false otherwise. 104 static bool Deserialize(const std::string& serialized, 105 bool* dirty, 106 net::TransportSecurityState* state); 107 108 void CompleteLoad(const std::string& state); 109 110 net::TransportSecurityState* transport_security_state_; 111 112 // Helper for safely writing the data. 113 base::ImportantFileWriter writer_; 114 115 // Whether or not we're in read-only mode. 116 const bool readonly_; 117 118 base::WeakPtrFactory<TransportSecurityPersister> weak_ptr_factory_; 119 120 DISALLOW_COPY_AND_ASSIGN(TransportSecurityPersister); 121 }; 122 123 #endif // CHROME_BROWSER_NET_TRANSPORT_SECURITY_PERSISTER_H_ 124