blob: 06086e3d8c7c71927ac5e4ff2b368aa88dea83cc [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
18namespace net {
19
20// NetworkAnonymizationKey will be used to partition shared network state based
21// on the context on which they were made. This class is an expiremental key
22// that contains properties that will be changed via feature flags.
23
24// NetworkAnonymizationKey contains the following properties:
25
26// `top_frame_site` represents the SchemefulSite of the pages top level frame.
27// In order to separate first and third party context from each other this field
28// will always be populated.
29
30// `frame_site` represents the SchemefulSite of the requestor frame. This will
Brianna Goldstein3cbf48a2022-07-27 21:35:4931// be empty when kEnableDoubleKeyNetworkAnonymizationKey is enabled.
Brianna Goldsteinbd14ec62022-07-21 06:48:5332
33//`is_cross_site` is an expiremental boolean that will be used with the
34//`top_frame_site` to create a partition key that separates the
Brianna Goldstein3cbf48a2022-07-27 21:35:4935//`top_frame_site`s first party partition from any cross-site iframes. This will
36// be used only when `kEnableCrossSiteFlagNetworkAnonymizationKey` is enabled.
37// When `kEnableCrossSiteFlagNetworkAnonymizationKey` is disabled,
38// `is_cross_site_` will be an empty optional.
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.
42// a->a => is_cross_site = true
43// a->b => is_cross_site = false
44// 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:
59 NetworkAnonymizationKey(
60 const SchemefulSite& top_frame_site,
Brianna Goldstein32eacb0b2022-08-29 08:52:1961 const absl::optional<SchemefulSite>& frame_site = absl::nullopt,
Brianna Goldstein3cbf48a2022-07-27 21:35:4962 const absl::optional<bool> is_cross_site = absl::nullopt,
Brianna Goldsteinbd14ec62022-07-21 06:48:5363 const absl::optional<base::UnguessableToken> nonce = absl::nullopt);
64
65 // Construct an empty key.
66 NetworkAnonymizationKey();
67
68 NetworkAnonymizationKey(
69 const NetworkAnonymizationKey& network_anonymization_key);
70 NetworkAnonymizationKey(NetworkAnonymizationKey&& network_anonymization_key);
71
72 ~NetworkAnonymizationKey();
73
74 NetworkAnonymizationKey& operator=(
75 const NetworkAnonymizationKey& network_anonymization_key);
76 NetworkAnonymizationKey& operator=(
77 NetworkAnonymizationKey&& network_anonymization_key);
78
79 // Compare keys for equality, true if all enabled fields are equal.
80 bool operator==(const NetworkAnonymizationKey& other) const {
81 return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) ==
82 std::tie(other.top_frame_site_, other.frame_site_,
83 other.is_cross_site_, other.nonce_);
84 }
85
86 // Compare keys for inequality, true if any enabled field varies.
87 bool operator!=(const NetworkAnonymizationKey& other) const {
88 return !(*this == other);
89 }
90
91 // Provide an ordering for keys based on all enabled fields.
92 bool operator<(const NetworkAnonymizationKey& other) const {
93 return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) <
94 std::tie(other.top_frame_site_, other.frame_site_,
95 other.is_cross_site_, other.nonce_);
96 }
97
Brianna Goldsteineb07f5b2022-09-22 23:35:3398 // This is a temporary method to allow for an iterative transition from using
99 // the NetworkIsolationKey to using the NetworkAnonymizationKey to partition
100 // the network state. When the two keys are not configured to use the same
101 // scheme the results of this conversion are inaccurate.
102
103 // TODO(@brgoldstein): Remove this method once key conversion is complete and
104 // before partitioning experiments are enabled.
105 operator NetworkIsolationKey() const {
106 if (!top_frame_site_) {
107 return NetworkIsolationKey();
108 }
109 if (!frame_site_) {
110 return NetworkIsolationKey(top_frame_site_.value(),
111 top_frame_site_.value(),
112 nonce_.value() ? &nonce_.value() : nullptr);
113 }
114 return NetworkIsolationKey(top_frame_site_.value(), frame_site_.value(),
115 nonce_.value() ? &nonce_.value() : nullptr);
116 }
117
Brianna Goldstein64891e742022-09-20 01:10:24118 // Creates a NetworkAnonymizationKey from a NetworkIsolationKey. This is
119 // possible because a NetworkIsolationKey must always be more granular than a
120 // NetworkAnonymizationKey.
121 static NetworkAnonymizationKey CreateFromNetworkIsolationKey(
122 const net::NetworkIsolationKey& network_isolation_key);
123
Brianna Goldsteinbd14ec62022-07-21 06:48:53124 // Returns the string representation of the key.
125 std::string ToDebugString() const;
126
127 // Returns true if all parts of the key are empty.
128 bool IsEmpty() const;
129
130 // Returns true if `top_frame_site_` and `frame_site_` of the key are
131 // non-empty.
132 bool IsFullyPopulated() const;
133
134 // Returns true if this key's lifetime is short-lived. It may not make sense
135 // to persist state to disk related to it (e.g., disk cache).
136 // A NetworkAnonymizationKey will be considered transient if either
137 // `top_frame_site_` or `frame_site_` are empty or opaque or if the key has a
138 // `nonce_`.
139 bool IsTransient() const;
140
141 // Getters for the top frame, frame site, nonce and is cross site flag.
Brianna Goldsteinbd14ec62022-07-21 06:48:53142 const absl::optional<SchemefulSite>& GetTopFrameSite() const {
143 return top_frame_site_;
144 }
145
Brianna Goldstein9c044362022-09-08 14:56:02146 const absl::optional<SchemefulSite>& GetFrameSite() const;
147
148 // Do not use outside of testing. Returns the `frame_site_` if neither
149 // `kEnableCrossSiteFlagNetworkAnonymizationKey` or
150 // `kEnableDoubleKeyNetworkAnonymizationKey` are enabled. Else it
151 // returns nullopt.
152 const absl::optional<SchemefulSite>& GetFrameSiteForTesting() const {
Brianna Goldsteinbd14ec62022-07-21 06:48:53153 return frame_site_;
154 }
155
Brianna Goldstein3cbf48a2022-07-27 21:35:49156 bool GetIsCrossSite() const;
Brianna Goldsteinbd14ec62022-07-21 06:48:53157
158 const absl::optional<base::UnguessableToken>& GetNonce() const {
159 return nonce_;
160 }
161
Brianna Goldstein3cbf48a2022-07-27 21:35:49162 // Returns true if the NetworkAnonymizationKey has a triple keyed scheme. This
163 // means the values of the NetworkAnonymizationKey are as follows:
164 // `top_frame_site` -> the schemeful site of the top level page.
165 // `frame_site ` -> the schemeful site of the requestor frame
166 // `is_cross_site` -> nullopt
167 static bool IsFrameSiteEnabled();
168
Brianna Goldstein1ad5e962022-07-25 19:17:46169 // Returns true if the NetworkAnonymizationKey has a double keyed scheme. This
170 // means the values of the NetworkAnonymizationKey are as follows:
171 // `top_frame_site` -> the schemeful site of the top level page.
172 // `frame_site ` -> nullopt
Brianna Goldstein3cbf48a2022-07-27 21:35:49173 // `is_cross_site` -> nullopt
174 static bool IsDoubleKeySchemeEnabled();
175
176 // Returns true if the NetworkAnonymizationKey has a <double keyed +
177 // is_cross_site> scheme. This means the values of the NetworkAnonymizationKey
178 // are as follows:
179 // `top_frame_site` -> the schemeful site of the top level page.
180 // `frame_site ` -> nullopt
181 // `is_cross_site` -> a boolean indicating if the requestor frame site is
182 // cross site from the top level site.
183 static bool IsCrossSiteFlagSchemeEnabled();
Brianna Goldstein1ad5e962022-07-25 19:17:46184
Brianna Goldsteinbd14ec62022-07-21 06:48:53185 private:
186 std::string GetSiteDebugString(
187 const absl::optional<SchemefulSite>& site) const;
188 // The origin/etld+1 of the top frame of the page making the request. This
189 // will always be populated unless all other fields are also nullopt.
190 absl::optional<SchemefulSite> top_frame_site_;
191
192 // The origin/etld+1 of the frame that initiates the request.
193 absl::optional<SchemefulSite> frame_site_;
194
195 // True if the frame site is cross site when compared to the top frame site.
196 absl::optional<bool> is_cross_site_;
197
198 // for non-opaque origins.
199 absl::optional<base::UnguessableToken> nonce_;
200};
201
202} // namespace net
203
204#endif // NET_BASE_NETWORK_ANONYMIZATION_KEY_H_