Home | History | Annotate | Download | only in net
      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