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 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