blob: a9610b9a315c7efebeef86482190e5e3b4dd4eab [file] [log] [blame]
Brianna Goldsteinbd14ec62022-07-21 06:48:531// Copyright 2022 The Chromium Authors. All rights reserved.
2// 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
8#include <string>
9#include <tuple>
10
11#include "base/unguessable_token.h"
12#include "net/base/net_export.h"
13#include "net/base/schemeful_site.h"
14#include "third_party/abseil-cpp/absl/types/optional.h"
15
16namespace net {
17
18// NetworkAnonymizationKey will be used to partition shared network state based
19// on the context on which they were made. This class is an expiremental key
20// that contains properties that will be changed via feature flags.
21
22// NetworkAnonymizationKey contains the following properties:
23
24// `top_frame_site` represents the SchemefulSite of the pages top level frame.
25// In order to separate first and third party context from each other this field
26// will always be populated.
27
28// `frame_site` represents the SchemefulSite of the requestor frame. This will
29// be empty when the feature flag to enable double keyed NetworkAnonymizationKey
30// is enabled. TODO @brgoldstein create feature flag to enable double keyed
31// NetworkAnonymizationKeys.
32
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
35//`top_frame_site`s first party partition from
36// any cross-site iframes. This will be used only when the feature flag to
37// enable double keyed NetworkAnonymizationKey's is enabled and the feature flag
38// to enable cross-site subframe partitioning is enabled. TODO: brgoldstein add
39// these feature flags.
40
41// The following show how the `is_cross_site` boolean is populated for the
42// innermost frame in the chain.
43// a->a => is_cross_site = true
44// a->b => is_cross_site = false
45// a->b->a => is_cross_site = false
46// a->(sandboxed a [has nonce]) => is_cross_site = true
47
48// The `nonce` value creates a key for anonymous iframes by giving them a
49// temporary `nonce` value which changes per top level navigation. For now, any
50// NetworkAnonymizationKey with a nonce will be considered transient. This is
51// being considered to possibly change in the future in an effort to allow
52// anonymous iframes with the same partition key access to shared resources.
53// The nonce value will be empty except for anonymous iframes.
54
55// TODO @brgoldstein, add link to public documentation of key scheme naming
56// conventions.
57
58class NET_EXPORT NetworkAnonymizationKey {
59 public:
60 NetworkAnonymizationKey(
61 const SchemefulSite& top_frame_site,
62 const absl::optional<SchemefulSite>& frame_site,
63 bool is_cross_site = false,
64 const absl::optional<base::UnguessableToken> nonce = absl::nullopt);
65
66 // Construct an empty key.
67 NetworkAnonymizationKey();
68
69 NetworkAnonymizationKey(
70 const NetworkAnonymizationKey& network_anonymization_key);
71 NetworkAnonymizationKey(NetworkAnonymizationKey&& network_anonymization_key);
72
73 ~NetworkAnonymizationKey();
74
75 NetworkAnonymizationKey& operator=(
76 const NetworkAnonymizationKey& network_anonymization_key);
77 NetworkAnonymizationKey& operator=(
78 NetworkAnonymizationKey&& network_anonymization_key);
79
80 // Compare keys for equality, true if all enabled fields are equal.
81 bool operator==(const NetworkAnonymizationKey& other) const {
82 return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) ==
83 std::tie(other.top_frame_site_, other.frame_site_,
84 other.is_cross_site_, other.nonce_);
85 }
86
87 // Compare keys for inequality, true if any enabled field varies.
88 bool operator!=(const NetworkAnonymizationKey& other) const {
89 return !(*this == other);
90 }
91
92 // Provide an ordering for keys based on all enabled fields.
93 bool operator<(const NetworkAnonymizationKey& other) const {
94 return std::tie(top_frame_site_, frame_site_, is_cross_site_, nonce_) <
95 std::tie(other.top_frame_site_, other.frame_site_,
96 other.is_cross_site_, other.nonce_);
97 }
98
99 // Returns the string representation of the key.
100 std::string ToDebugString() const;
101
102 // Returns true if all parts of the key are empty.
103 bool IsEmpty() const;
104
105 // Returns true if `top_frame_site_` and `frame_site_` of the key are
106 // non-empty.
107 bool IsFullyPopulated() const;
108
109 // Returns true if this key's lifetime is short-lived. It may not make sense
110 // to persist state to disk related to it (e.g., disk cache).
111 // A NetworkAnonymizationKey will be considered transient if either
112 // `top_frame_site_` or `frame_site_` are empty or opaque or if the key has a
113 // `nonce_`.
114 bool IsTransient() const;
115
116 // Getters for the top frame, frame site, nonce and is cross site flag.
117 // TODO @brgoldstein: create feature flags to wrap these properties so that
118 // the key can be modified for experimentation.
119 const absl::optional<SchemefulSite>& GetTopFrameSite() const {
120 return top_frame_site_;
121 }
122
123 const absl::optional<SchemefulSite>& GetFrameSite() const {
124 return frame_site_;
125 }
126
127 const absl::optional<bool>& GetIsCrossSite() const { return is_cross_site_; }
128
129 const absl::optional<base::UnguessableToken>& GetNonce() const {
130 return nonce_;
131 }
132
Brianna Goldstein1ad5e962022-07-25 19:17:46133 // Returns true if the NetworkAnonymizationKey has a double keyed scheme. This
134 // means the values of the NetworkAnonymizationKey are as follows:
135 // `top_frame_site` -> the schemeful site of the top level page.
136 // `frame_site ` -> nullopt
137 static bool IsDoubleKeyingEnabled();
138
Brianna Goldsteinbd14ec62022-07-21 06:48:53139 private:
140 std::string GetSiteDebugString(
141 const absl::optional<SchemefulSite>& site) const;
142 // The origin/etld+1 of the top frame of the page making the request. This
143 // will always be populated unless all other fields are also nullopt.
144 absl::optional<SchemefulSite> top_frame_site_;
145
146 // The origin/etld+1 of the frame that initiates the request.
147 absl::optional<SchemefulSite> frame_site_;
148
149 // True if the frame site is cross site when compared to the top frame site.
150 absl::optional<bool> is_cross_site_;
151
152 // for non-opaque origins.
153 absl::optional<base::UnguessableToken> nonce_;
154};
155
156} // namespace net
157
158#endif // NET_BASE_NETWORK_ANONYMIZATION_KEY_H_