• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cookies/cookie_partition_key.h"
6 
7 #include <ostream>
8 #include <tuple>
9 
10 #include "base/feature_list.h"
11 #include "base/logging.h"
12 #include "base/types/optional_util.h"
13 #include "net/base/features.h"
14 #include "net/cookies/cookie_constants.h"
15 
16 namespace net {
17 
18 CookiePartitionKey::CookiePartitionKey() = default;
19 
CookiePartitionKey(const SchemefulSite & site,absl::optional<base::UnguessableToken> nonce)20 CookiePartitionKey::CookiePartitionKey(
21     const SchemefulSite& site,
22     absl::optional<base::UnguessableToken> nonce)
23     : site_(site), nonce_(nonce) {}
24 
CookiePartitionKey(const GURL & url)25 CookiePartitionKey::CookiePartitionKey(const GURL& url)
26     : site_(SchemefulSite(url)) {}
27 
CookiePartitionKey(bool from_script)28 CookiePartitionKey::CookiePartitionKey(bool from_script)
29     : from_script_(from_script) {}
30 
31 CookiePartitionKey::CookiePartitionKey(const CookiePartitionKey& other) =
32     default;
33 
34 CookiePartitionKey::CookiePartitionKey(CookiePartitionKey&& other) = default;
35 
36 CookiePartitionKey& CookiePartitionKey::operator=(
37     const CookiePartitionKey& other) = default;
38 
39 CookiePartitionKey& CookiePartitionKey::operator=(CookiePartitionKey&& other) =
40     default;
41 
42 CookiePartitionKey::~CookiePartitionKey() = default;
43 
operator ==(const CookiePartitionKey & other) const44 bool CookiePartitionKey::operator==(const CookiePartitionKey& other) const {
45   return site_ == other.site_ && nonce_ == other.nonce_;
46 }
47 
operator !=(const CookiePartitionKey & other) const48 bool CookiePartitionKey::operator!=(const CookiePartitionKey& other) const {
49   return site_ != other.site_ || nonce_ != other.nonce_;
50 }
51 
operator <(const CookiePartitionKey & other) const52 bool CookiePartitionKey::operator<(const CookiePartitionKey& other) const {
53   return std::tie(site_, nonce_) < std::tie(other.site_, other.nonce_);
54 }
55 
56 // static
Serialize(const absl::optional<CookiePartitionKey> & in,std::string & out)57 bool CookiePartitionKey::Serialize(const absl::optional<CookiePartitionKey>& in,
58                                    std::string& out) {
59   if (!in) {
60     out = kEmptyCookiePartitionKey;
61     return true;
62   }
63   if (!in->IsSerializeable()) {
64     DLOG(WARNING) << "CookiePartitionKey is not serializeable";
65     return false;
66   }
67   out = in->site_.GetURL().SchemeIsFile()
68             ? in->site_.SerializeFileSiteWithHost()
69             : in->site_.Serialize();
70   return true;
71 }
72 
73 // static
Deserialize(const std::string & in,absl::optional<CookiePartitionKey> & out)74 bool CookiePartitionKey::Deserialize(const std::string& in,
75                                      absl::optional<CookiePartitionKey>& out) {
76   if (in == kEmptyCookiePartitionKey) {
77     out = absl::nullopt;
78     return true;
79   }
80   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
81     DLOG(WARNING) << "Attempting to deserialize CookiePartitionKey when "
82                      "PartitionedCookies is disabled";
83     return false;
84   }
85   auto schemeful_site = SchemefulSite::Deserialize(in);
86   // SchemfulSite is opaque if the input is invalid.
87   if (schemeful_site.opaque()) {
88     DLOG(WARNING) << "Cannot deserialize opaque origin to CookiePartitionKey";
89     return false;
90   }
91   out = absl::make_optional(CookiePartitionKey(schemeful_site, absl::nullopt));
92   return true;
93 }
94 
FromNetworkIsolationKey(const NetworkIsolationKey & network_isolation_key)95 absl::optional<CookiePartitionKey> CookiePartitionKey::FromNetworkIsolationKey(
96     const NetworkIsolationKey& network_isolation_key) {
97   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
98     return absl::nullopt;
99   }
100 
101   const absl::optional<base::UnguessableToken>& nonce =
102       network_isolation_key.GetNonce();
103 
104   // Use frame site for nonced partitions. Since the nonce is unique, this still
105   // creates a unique partition key. The reason we use the frame site is to
106   // align CookiePartitionKey's implementation of nonced partitions with
107   // StorageKey's. See https://crbug.com/1440765.
108   const absl::optional<SchemefulSite>& partition_key_site =
109       nonce ? network_isolation_key.GetFrameSiteForCookiePartitionKey(
110                   NetworkIsolationKey::CookiePartitionKeyPassKey())
111             : network_isolation_key.GetTopFrameSite();
112   if (!partition_key_site)
113     return absl::nullopt;
114 
115   return net::CookiePartitionKey(*partition_key_site, nonce);
116 }
117 
118 // static
119 absl::optional<net::CookiePartitionKey>
FromStorageKeyComponents(const SchemefulSite & site,const absl::optional<base::UnguessableToken> & nonce)120 CookiePartitionKey::FromStorageKeyComponents(
121     const SchemefulSite& site,
122     const absl::optional<base::UnguessableToken>& nonce) {
123   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
124     return absl::nullopt;
125   }
126   return CookiePartitionKey::FromWire(site, nonce);
127 }
128 
IsSerializeable() const129 bool CookiePartitionKey::IsSerializeable() const {
130   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
131     DLOG(WARNING) << "Attempting to serialize CookiePartitionKey when "
132                      "PartitionedCookies feature is disabled";
133     return false;
134   }
135   // We should not try to serialize a partition key created by a renderer.
136   DCHECK(!from_script_);
137   return !site_.opaque() && !nonce_.has_value();
138 }
139 
operator <<(std::ostream & os,const CookiePartitionKey & cpk)140 std::ostream& operator<<(std::ostream& os, const CookiePartitionKey& cpk) {
141   os << cpk.site();
142   if (cpk.nonce().has_value()) {
143     os << ",nonced";
144   }
145   return os;
146 }
147 
148 }  // namespace net
149