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