| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_BASE_NETWORK_ISOLATION_KEY_H_ |
| #define NET_BASE_NETWORK_ISOLATION_KEY_H_ |
| |
| #include <optional> |
| #include <string> |
| |
| #include "base/types/pass_key.h" |
| #include "base/unguessable_token.h" |
| #include "net/base/net_export.h" |
| #include "net/base/network_isolation_partition.h" |
| #include "net/base/schemeful_site.h" |
| |
| namespace network::mojom { |
| class NonEmptyNetworkIsolationKeyDataView; |
| } |
| |
| namespace net { |
| class CookiePartitionKey; |
| class NetworkAnonymizationKey; |
| } |
| |
| namespace net { |
| |
| // NetworkIsolationKey (NIK) is used to partition shared network state based on |
| // the context in which the requests were made. It is used to divide the HTTP |
| // cache, while the NetworkAnonymizationKey is used for most other network |
| // state. |
| // |
| // The NetworkIsolationKey uses the "triple-key" scheme to partition the HTTP |
| // cache. The key has the following properties: |
| // `top_frame_site` -> the schemeful site of the top level page. |
| // `frame_site ` -> the schemeful site of the frame. |
| // `network_isolation_partition` -> an extra partition for the HTTP cache for |
| // special use cases. |
| class NET_EXPORT NetworkIsolationKey { |
| public: |
| // Full constructor. When a request is initiated by the top frame, it must |
| // also populate the |frame_site| parameter when calling this constructor. |
| NetworkIsolationKey( |
| const SchemefulSite& top_frame_site, |
| const SchemefulSite& frame_site, |
| const std::optional<base::UnguessableToken>& nonce = std::nullopt, |
| NetworkIsolationPartition network_isolation_partition = |
| NetworkIsolationPartition::kGeneral); |
| |
| // Alternative constructor that takes ownership of arguments, to save copies. |
| NetworkIsolationKey( |
| SchemefulSite&& top_frame_site, |
| SchemefulSite&& frame_site, |
| std::optional<base::UnguessableToken>&& nonce = std::nullopt, |
| NetworkIsolationPartition network_isolation_partition = |
| NetworkIsolationPartition::kGeneral); |
| |
| // Construct an empty key. |
| NetworkIsolationKey(); |
| |
| NetworkIsolationKey(const NetworkIsolationKey& network_isolation_key); |
| NetworkIsolationKey(NetworkIsolationKey&& network_isolation_key); |
| |
| ~NetworkIsolationKey(); |
| |
| NetworkIsolationKey& operator=( |
| const NetworkIsolationKey& network_isolation_key); |
| NetworkIsolationKey& operator=(NetworkIsolationKey&& network_isolation_key); |
| |
| // Creates a transient non-empty NetworkIsolationKey by creating an opaque |
| // origin. This prevents the NetworkIsolationKey from sharing data with other |
| // NetworkIsolationKeys. Data for transient NetworkIsolationKeys is not |
| // persisted to disk. |
| static NetworkIsolationKey CreateTransientForTesting(); |
| |
| // Creates a new key using |top_frame_site_| and |new_frame_site|. |
| NetworkIsolationKey CreateWithNewFrameSite( |
| const SchemefulSite& new_frame_site) const; |
| |
| // Compare keys for equality, true if all enabled fields are equal. |
| friend bool operator==(const NetworkIsolationKey&, |
| const NetworkIsolationKey&) = default; |
| |
| // Provide an ordering for keys based on all enabled fields. |
| friend auto operator<=>(const NetworkIsolationKey&, |
| const NetworkIsolationKey&) = default; |
| |
| // Returns the string representation of the key for use in string-keyed disk |
| // cache. This is the string representation of each piece of the key separated |
| // by spaces. Returns nullopt if the network isolation key is transient, in |
| // which case, nothing should typically be saved to disk using the key. |
| std::optional<std::string> ToCacheKeyString() const; |
| |
| // Returns string for debugging. Difference from ToString() is that transient |
| // entries may be distinguishable from each other. |
| std::string ToDebugString() const; |
| |
| // Returns true if all parts of the key are non-empty. |
| bool IsFullyPopulated() const; |
| |
| // Returns true if this key's lifetime is short-lived, or if |
| // IsFullyPopulated() returns true. It may not make sense to persist state to |
| // disk related to it (e.g., disk cache). |
| bool IsTransient() const; |
| |
| // Getters for the top frame and frame sites. These accessors are primarily |
| // intended for IPC calls, and to be able to create an IsolationInfo from a |
| // NetworkIsolationKey. |
| const std::optional<SchemefulSite>& GetTopFrameSite() const { |
| return top_frame_site_; |
| } |
| |
| // Do not use outside of testing. Returns the `frame_site_`. |
| const std::optional<SchemefulSite> GetFrameSiteForTesting() const { |
| return frame_site_; |
| } |
| |
| // When serializing a NIK for sending via mojo we want to access the frame |
| // site directly. We don't want to expose this broadly, though, hence the |
| // passkey. |
| using SerializationPassKey = base::PassKey<struct mojo::StructTraits< |
| network::mojom::NonEmptyNetworkIsolationKeyDataView, |
| NetworkIsolationKey>>; |
| const std::optional<SchemefulSite>& GetFrameSiteForSerialization( |
| SerializationPassKey) const { |
| CHECK(!IsEmpty()); |
| return frame_site_; |
| } |
| // We also need to access the frame site directly when constructing |
| // CookiePartitionKey for nonced partitions. We also use a passkey for this |
| // case. |
| using CookiePartitionKeyPassKey = base::PassKey<CookiePartitionKey>; |
| const std::optional<SchemefulSite>& GetFrameSiteForCookiePartitionKey( |
| CookiePartitionKeyPassKey) const { |
| CHECK(!IsEmpty()); |
| return frame_site_; |
| } |
| // Same as above but for constructing a `NetworkAnonymizationKey()` from this |
| // NIK. |
| using NetworkAnonymizationKeyPassKey = base::PassKey<NetworkAnonymizationKey>; |
| const std::optional<SchemefulSite>& GetFrameSiteForNetworkAnonymizationKey( |
| NetworkAnonymizationKeyPassKey) const { |
| CHECK(!IsEmpty()); |
| return frame_site_; |
| } |
| |
| // Getter for the nonce. |
| const std::optional<base::UnguessableToken>& GetNonce() const { |
| return nonce_; |
| } |
| |
| NetworkIsolationPartition GetNetworkIsolationPartition() const { |
| return network_isolation_partition_; |
| } |
| |
| // Returns true if all parts of the key are empty. |
| bool IsEmpty() const; |
| |
| private: |
| // Whether this key has opaque origins or a nonce. |
| bool IsOpaque() const; |
| |
| // The origin/etld+1 of the top frame of the page making the request. |
| std::optional<SchemefulSite> top_frame_site_; |
| |
| // The origin/etld+1 of the frame that initiates the request. |
| std::optional<SchemefulSite> frame_site_; |
| |
| // Having a nonce is a way to force a transient opaque `NetworkIsolationKey` |
| // for non-opaque origins. |
| std::optional<base::UnguessableToken> nonce_; |
| |
| // The network isolation partition for this NIK. This will be kGeneral |
| // except for specific use cases that require isolation from all other |
| // use cases. |
| NetworkIsolationPartition network_isolation_partition_ = |
| NetworkIsolationPartition::kGeneral; |
| }; |
| |
| NET_EXPORT std::ostream& operator<<(std::ostream& os, |
| const NetworkIsolationKey& nak); |
| |
| } // namespace net |
| |
| #endif // NET_BASE_NETWORK_ISOLATION_KEY_H_ |