blob: c8ddaa8d392f2002eb67137c079d6984810c7898 [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2022 The Chromium Authors
Brianna Goldsteinbd14ec62022-07-21 06:48:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_BASE_NETWORK_ANONYMIZATION_KEY_H_
6#define NET_BASE_NETWORK_ANONYMIZATION_KEY_H_
7
Brianna Goldsteineb07f5b2022-09-22 23:35:338#include <cstddef>
Brianna Goldsteinbd14ec62022-07-21 06:48:539#include <string>
10#include <tuple>
11
12#include "base/unguessable_token.h"
13#include "net/base/net_export.h"
Brianna Goldstein64891e742022-09-20 01:10:2414#include "net/base/network_isolation_key.h"
Brianna Goldsteinbd14ec62022-07-21 06:48:5315#include "net/base/schemeful_site.h"
16#include "third_party/abseil-cpp/absl/types/optional.h"
17
Brianna Goldstein62aeced2022-09-29 01:23:3118namespace base {
19class Value;
20}
21
Brianna Goldsteinbd14ec62022-07-21 06:48:5322namespace net {
23
24// NetworkAnonymizationKey will be used to partition shared network state based
25// on the context on which they were made. This class is an expiremental key
26// that contains properties that will be changed via feature flags.
27
28// NetworkAnonymizationKey contains the following properties:
29
30// `top_frame_site` represents the SchemefulSite of the pages top level frame.
31// In order to separate first and third party context from each other this field
32// will always be populated.
33
Dustin J. Mitchell1d774ea2023-03-03 00:54:4634// `is_cross_site` indicates whether the key is cross-site or same-site. A
35// same-site key indicates that he schemeful site of the top frame and the frame
36// are the same. Intermediary frames between the two may be cross-site to them.
37// The effect of this property is to partition first-party and third-party
38// resources within a given `top_frame_site`.
Brianna Goldsteinbd14ec62022-07-21 06:48:5339
40// The following show how the `is_cross_site` boolean is populated for the
41// innermost frame in the chain.
Brianna Goldsteind4ec1ec02023-01-19 21:11:5442// a->a => is_cross_site = false
43// a->b => is_cross_site = true
Brianna Goldsteinbd14ec62022-07-21 06:48:5344// a->b->a => is_cross_site = false
45// a->(sandboxed a [has nonce]) => is_cross_site = true
46
47// The `nonce` value creates a key for anonymous iframes by giving them a
48// temporary `nonce` value which changes per top level navigation. For now, any
49// NetworkAnonymizationKey with a nonce will be considered transient. This is
50// being considered to possibly change in the future in an effort to allow
51// anonymous iframes with the same partition key access to shared resources.
52// The nonce value will be empty except for anonymous iframes.
53
54// TODO @brgoldstein, add link to public documentation of key scheme naming
55// conventions.
56
57class NET_EXPORT NetworkAnonymizationKey {
58 public:
Brianna Goldsteinbd14ec62022-07-21 06:48:5359 // Construct an empty key.
60 NetworkAnonymizationKey();
61
62 NetworkAnonymizationKey(
63 const NetworkAnonymizationKey& network_anonymization_key);
64 NetworkAnonymizationKey(NetworkAnonymizationKey&& network_anonymization_key);
65
66 ~NetworkAnonymizationKey();
67
68 NetworkAnonymizationKey& operator=(
69 const NetworkAnonymizationKey& network_anonymization_key);
70 NetworkAnonymizationKey& operator=(
71 NetworkAnonymizationKey&& network_anonymization_key);
72
73 // Compare keys for equality, true if all enabled fields are equal.
74 bool operator==(const NetworkAnonymizationKey& other) const {
Dustin J. Mitchellc9d15402023-02-07 14:49:3675 return std::tie(top_frame_site_, is_cross_site_, nonce_) ==
76 std::tie(other.top_frame_site_, other.is_cross_site_, other.nonce_);
Brianna Goldsteinbd14ec62022-07-21 06:48:5377 }
78
79 // Compare keys for inequality, true if any enabled field varies.
80 bool operator!=(const NetworkAnonymizationKey& other) const {
81 return !(*this == other);
82 }
83
84 // Provide an ordering for keys based on all enabled fields.
85 bool operator<(const NetworkAnonymizationKey& other) const {
Dustin J. Mitchellc9d15402023-02-07 14:49:3686 return std::tie(top_frame_site_, is_cross_site_, nonce_) <
87 std::tie(other.top_frame_site_, other.is_cross_site_, other.nonce_);
Brianna Goldsteinbd14ec62022-07-21 06:48:5388 }
89
Dustin J. Mitchell1d774ea2023-03-03 00:54:4690 // Create a `NetworkAnonymizationKey` from a `top_frame_site`, assuming it is
91 // same-site (see comment on the class, above) and has no nonce.
92 static NetworkAnonymizationKey CreateSameSite(
93 const SchemefulSite& top_frame_site) {
94 return NetworkAnonymizationKey(top_frame_site, false, absl::nullopt);
95 }
96
97 // Create a `NetworkAnonymizationKey` from a `top_frame_site`, assuming it is
98 // cross-site (see comment on the class, above) and has no nonce.
99 static NetworkAnonymizationKey CreateCrossSite(
100 const SchemefulSite& top_frame_site) {
101 return NetworkAnonymizationKey(top_frame_site, true, absl::nullopt);
102 }
103
104 // Create a `NetworkAnonymizationKey` from a `top_frame_site` and
105 // `frame_site`. This calculates is_cross_site on the basis of those two
106 // sites.
107 static NetworkAnonymizationKey CreateFromFrameSite(
108 const SchemefulSite& top_frame_site,
109 const SchemefulSite& frame_site,
110 absl::optional<base::UnguessableToken> nonce = absl::nullopt);
111
112 // Creates a `NetworkAnonymizationKey` from a `NetworkIsolationKey`. This is
113 // possible because a `NetworkIsolationKey` must always be more granular
114 // than a `NetworkAnonymizationKey`.
Brianna Goldstein64891e742022-09-20 01:10:24115 static NetworkAnonymizationKey CreateFromNetworkIsolationKey(
116 const net::NetworkIsolationKey& network_isolation_key);
117
Dustin J. Mitchell1d774ea2023-03-03 00:54:46118 // Creates a `NetworkAnonymizationKey` from its constituent parts. This
119 // is intended to be used to build a NAK from Mojo, and for tests.
120 static NetworkAnonymizationKey CreateFromParts(
121 const SchemefulSite& top_frame_site,
122 bool is_cross_site,
123 absl::optional<base::UnguessableToken> nonce = absl::nullopt) {
124 return NetworkAnonymizationKey(top_frame_site, is_cross_site, nonce);
125 }
126
Brianna Goldsteind22b0642022-10-11 16:30:50127 // Creates a transient non-empty NetworkAnonymizationKey by creating an opaque
128 // origin. This prevents the NetworkAnonymizationKey from sharing data with
129 // other NetworkAnonymizationKey.
Brianna Goldsteind372b232022-09-25 17:24:17130 static NetworkAnonymizationKey CreateTransient();
131
Brianna Goldsteinbd14ec62022-07-21 06:48:53132 // Returns the string representation of the key.
133 std::string ToDebugString() const;
134
135 // Returns true if all parts of the key are empty.
136 bool IsEmpty() const;
137
Dustin J. Mitchellc9d15402023-02-07 14:49:36138 // Returns true if `top_frame_site_` is non-empty.
Brianna Goldsteinbd14ec62022-07-21 06:48:53139 bool IsFullyPopulated() const;
140
141 // Returns true if this key's lifetime is short-lived. It may not make sense
142 // to persist state to disk related to it (e.g., disk cache).
Dustin J. Mitchellc9d15402023-02-07 14:49:36143 // A NetworkAnonymizationKey will be considered transient if
144 // `top_frame_site_` is empty or opaque or if the key has a `nonce_`.
Brianna Goldsteinbd14ec62022-07-21 06:48:53145 bool IsTransient() const;
146
147 // Getters for the top frame, frame site, nonce and is cross site flag.
Brianna Goldsteinbd14ec62022-07-21 06:48:53148 const absl::optional<SchemefulSite>& GetTopFrameSite() const {
149 return top_frame_site_;
150 }
151
Dustin J. Mitchell1d774ea2023-03-03 00:54:46152 bool IsCrossSite() const { return is_cross_site_; }
153
154 bool IsSameSite() const { return !IsCrossSite(); }
Brianna Goldsteinbd14ec62022-07-21 06:48:53155
156 const absl::optional<base::UnguessableToken>& GetNonce() const {
157 return nonce_;
158 }
159
Brianna Goldstein62aeced2022-09-29 01:23:31160 // Returns a representation of |this| as a base::Value. Returns false on
161 // failure. Succeeds if either IsEmpty() or !IsTransient().
162 [[nodiscard]] bool ToValue(base::Value* out_value) const;
163
164 // Inverse of ToValue(). Writes the result to |network_anonymization_key|.
165 // Returns false on failure. Fails on values that could not have been produced
166 // by ToValue(), like transient origins.
167 [[nodiscard]] static bool FromValue(
168 const base::Value& value,
169 NetworkAnonymizationKey* out_network_anonymization_key);
170
Dustin J. Mitchell5624da42023-04-20 18:26:17171 // Determine whether network state partitioning is enabled. This is true if
172 // any of the features
173 //
174 // * `SplitHostCacheByNetworkIsolationKey`
175 // * `PartitionConnectionsByNetworkIsolationKey`
176 // * `PartitionHttpServerPropertiesByNetworkIsolationKey`
177 // * `PartitionSSLSessionsByNetworkIsolationKey`
178 // * `PartitionNelAndReportingByNetworkIsolationKey`
179 //
180 // is enabled, or if `PartitionByDefault()` has been called.
181 static bool IsPartitioningEnabled();
182
183 // Default partitioning to enabled, regardless of feature settings. This must
184 // be called before any calls to `IsPartitioningEnabled()`.
185 static void PartitionByDefault();
186
187 // Clear partitioning-related globals.
188 static void ClearGlobalsForTesting();
189
Brianna Goldsteinbd14ec62022-07-21 06:48:53190 private:
Dustin J. Mitchell1d774ea2023-03-03 00:54:46191 NetworkAnonymizationKey(
192 const SchemefulSite& top_frame_site,
193 bool is_cross_site,
194 absl::optional<base::UnguessableToken> nonce = absl::nullopt);
195
Brianna Goldsteinbd14ec62022-07-21 06:48:53196 std::string GetSiteDebugString(
197 const absl::optional<SchemefulSite>& site) const;
Brianna Goldstein62aeced2022-09-29 01:23:31198
199 static absl::optional<std::string> SerializeSiteWithNonce(
200 const SchemefulSite& site);
201
Brianna Goldsteinbd14ec62022-07-21 06:48:53202 // The origin/etld+1 of the top frame of the page making the request. This
203 // will always be populated unless all other fields are also nullopt.
204 absl::optional<SchemefulSite> top_frame_site_;
205
Brianna Goldsteinbd14ec62022-07-21 06:48:53206 // True if the frame site is cross site when compared to the top frame site.
Dustin J. Mitchell1d774ea2023-03-03 00:54:46207 // This is always false for a non-fully-populated NAK.
208 bool is_cross_site_;
Brianna Goldsteinbd14ec62022-07-21 06:48:53209
210 // for non-opaque origins.
211 absl::optional<base::UnguessableToken> nonce_;
212};
213
214} // namespace net
215
Dustin J. Mitchellc9d15402023-02-07 14:49:36216#endif // NET_BASE_NETWORK_ANONYMIZATION_KEY_H_