• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 <optional>
37 #include <string>
38 
39 #include "base/feature_list.h"
40 #include "base/files/file_path.h"
41 #include "base/files/important_file_writer.h"
42 #include "base/memory/raw_ptr.h"
43 #include "base/memory/scoped_refptr.h"
44 #include "base/memory/weak_ptr.h"
45 #include "base/time/time.h"
46 #include "net/base/net_export.h"
47 #include "net/http/transport_security_state.h"
48 
49 namespace base {
50 class SequencedTaskRunner;
51 }
52 
53 namespace net {
54 
55 // Exists only to hold a "commit-interval" param. If disabled, the default
56 // ImportantFileWriter commit interval is used.
57 NET_EXPORT BASE_DECLARE_FEATURE(kTransportSecurityFileWriterSchedule);
58 
59 // Reads and updates on-disk TransportSecurity state. Clients of this class
60 // should create, destroy, and call into it from one thread.
61 //
62 // background_runner is the task runner this class should use internally to
63 // perform file IO, and can optionally be associated with a different thread.
64 class NET_EXPORT TransportSecurityPersister
65     : public TransportSecurityState::Delegate,
66       public base::ImportantFileWriter::DataSerializer {
67  public:
68   // Create a TransportSecurityPersister with state |state| on background runner
69   // |background_runner|. |data_path| points to the file to hold the transport
70   // security state data on disk.
71   TransportSecurityPersister(
72       TransportSecurityState* state,
73       const scoped_refptr<base::SequencedTaskRunner>& background_runner,
74       const base::FilePath& data_path);
75 
76   TransportSecurityPersister(const TransportSecurityPersister&) = delete;
77   TransportSecurityPersister& operator=(const TransportSecurityPersister&) =
78       delete;
79 
80   ~TransportSecurityPersister() override;
81 
82   // Called by the TransportSecurityState when it changes its state.
83   void StateIsDirty(TransportSecurityState*) override;
84   // Called when the TransportSecurityState should be written immediately.
85   // |callback| is called after data is persisted.
86   void WriteNow(TransportSecurityState* state,
87                 base::OnceClosure callback) override;
88 
89   // ImportantFileWriter::DataSerializer:
90   //
91   // Serializes |transport_security_state_| into |*output|. Returns true if
92   // all STS states were serialized correctly.
93   //
94   // The serialization format is JSON; the JSON represents a dictionary of
95   // host:DomainState pairs (host is a string). The DomainState contains the STS
96   // states and is represented as a dictionary containing the following keys and
97   // value types (not all keys will always be present):
98   //
99   //     "sts_include_subdomains": true|false
100   //     "created": double
101   //     "expiry": double
102   //     "mode": "default"|"force-https"
103   //             legacy value synonyms "strict" = "force-https"
104   //                                   "pinning-only" = "default"
105   //             legacy value "spdy-only" is unused and ignored
106   //     "report-uri": string
107   //     "sts_observed": double
108   //
109   // Legacy data (see https://crbug.com/1232560) may also contain a top-level
110   // "expect_ct" key, which will be deleted when read:
111   //     "expect_ct": dictionary with keys:
112   //         "expect_ct_expiry": double
113   //         "expect_ct_observed": double
114   //         "expect_ct_enforce": true|false
115   //         "expect_ct_report_uri": string
116   //
117   // The JSON dictionary keys are strings containing
118   // Base64(SHA256(TransportSecurityState::CanonicalizeHost(domain))).
119   // The reason for hashing them is so that the stored state does not
120   // trivially reveal a user's browsing history to an attacker reading the
121   // serialized state on disk.
122   std::optional<std::string> SerializeData() override;
123 
124   // Clears any existing non-static entries, and then re-populates
125   // |transport_security_state_|.
126   void LoadEntries(const std::string& serialized);
127 
128   // Returns the commit interval used by the ImportantFileWriter.
129   static base::TimeDelta GetCommitInterval();
130 
131  private:
132   // Populates |state| from the JSON string |serialized|.
133   static void Deserialize(const std::string& serialized,
134                           TransportSecurityState* state,
135                           bool& contains_legacy_expect_ct_data);
136 
137   void CompleteLoad(const std::string& state);
138   void OnWriteFinished(base::OnceClosure callback);
139 
140   raw_ptr<TransportSecurityState> transport_security_state_;
141 
142   // Helper for safely writing the data.
143   base::ImportantFileWriter writer_;
144 
145   scoped_refptr<base::SequencedTaskRunner> foreground_runner_;
146   scoped_refptr<base::SequencedTaskRunner> background_runner_;
147 
148   base::WeakPtrFactory<TransportSecurityPersister> weak_ptr_factory_{this};
149 };
150 
151 }  // namespace net
152 
153 #endif  // NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_
154