Home | History | Annotate | Download | only in http
      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 
     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 // 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.
     56 class 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