File: transport_security_persister.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (144 lines) | stat: -rw-r--r-- 5,700 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TransportSecurityState maintains an in memory database containing the
// list of hosts that currently have transport security enabled. This
// singleton object deals with writing that data out to disk as needed and
// loading it at startup.

// At startup we need to load the transport security state from the
// disk. For the moment, we don't want to delay startup for this load, so we
// let the TransportSecurityState run for a while without being loaded.
// This means that it's possible for pages opened very quickly not to get the
// correct transport security information.
//
// To load the state, we schedule a Task on background_runner, which
// deserializes and configures the TransportSecurityState.
//
// The TransportSecurityState object supports running a callback function
// when it changes. This object registers the callback, pointing at itself.
//
// TransportSecurityState calls...
// TransportSecurityPersister::StateIsDirty
//   since the callback isn't allowed to block or reenter, we schedule a Task
//   on the file task runner after some small amount of time
//
// ...
//
// TransportSecurityPersister::SerializeState
//   copies the current state of the TransportSecurityState, serializes
//   and writes to disk.

#ifndef NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_
#define NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_

#include <optional>
#include <string>

#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/important_file_writer.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/http/transport_security_state.h"

namespace base {
class SequencedTaskRunner;
}

namespace net {

// Exists only to hold a "commit-interval" param. If disabled, the default
// ImportantFileWriter commit interval is used.
NET_EXPORT BASE_DECLARE_FEATURE(kTransportSecurityFileWriterSchedule);

// Reads and updates on-disk TransportSecurity state. Clients of this class
// should create, destroy, and call into it from one thread.
//
// background_runner is the task runner this class should use internally to
// perform file IO, and can optionally be associated with a different thread.
class NET_EXPORT TransportSecurityPersister
    : public TransportSecurityState::Delegate,
      public base::ImportantFileWriter::DataSerializer {
 public:
  // Create a TransportSecurityPersister with state |state| on background runner
  // |background_runner|. |data_path| points to the file to hold the transport
  // security state data on disk.
  TransportSecurityPersister(
      TransportSecurityState* state,
      const scoped_refptr<base::SequencedTaskRunner>& background_runner,
      const base::FilePath& data_path);

  TransportSecurityPersister(const TransportSecurityPersister&) = delete;
  TransportSecurityPersister& operator=(const TransportSecurityPersister&) =
      delete;

  ~TransportSecurityPersister() override;

  // Called by the TransportSecurityState when it changes its state.
  void StateIsDirty(TransportSecurityState*) override;
  // Called when the TransportSecurityState should be written immediately.
  // |callback| is called after data is persisted.
  void WriteNow(TransportSecurityState* state,
                base::OnceClosure callback) override;

  // ImportantFileWriter::DataSerializer:
  //
  // Serializes |transport_security_state_| into |*output|. Returns true if
  // all STS states were serialized correctly.
  //
  // The serialization format is JSON; the JSON represents a dictionary of
  // host:DomainState pairs (host is a string). The DomainState contains the STS
  // states and is represented as a dictionary containing the following keys and
  // value types (not all keys will always be present):
  //
  //     "sts_include_subdomains": true|false
  //     "created": double
  //     "expiry": double
  //     "mode": "default"|"force-https"
  //             legacy value synonyms "strict" = "force-https"
  //                                   "pinning-only" = "default"
  //             legacy value "spdy-only" is unused and ignored
  //     "report-uri": string
  //     "sts_observed": double
  //
  // The JSON dictionary keys are strings containing
  // Base64(SHA256(TransportSecurityState::CanonicalizeHost(domain))).
  // The reason for hashing them is so that the stored state does not
  // trivially reveal a user's browsing history to an attacker reading the
  // serialized state on disk.
  std::optional<std::string> SerializeData() override;

  // Clears any existing non-static entries, and then re-populates
  // |transport_security_state_|.
  void LoadEntries(const std::string& serialized);

  // Returns the commit interval used by the ImportantFileWriter.
  static base::TimeDelta GetCommitInterval();

 private:
  // Populates |state| from the JSON string |serialized|.
  static void Deserialize(const std::string& serialized,
                          TransportSecurityState* state);

  void CompleteLoad(const std::string& state);
  void OnWriteFinished(base::OnceClosure callback);

  raw_ptr<TransportSecurityState> transport_security_state_;

  // Helper for safely writing the data.
  base::ImportantFileWriter writer_;

  scoped_refptr<base::SequencedTaskRunner> foreground_runner_;
  scoped_refptr<base::SequencedTaskRunner> background_runner_;

  base::WeakPtrFactory<TransportSecurityPersister> weak_ptr_factory_{this};
};

}  // namespace net

#endif  // NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_