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