1 // Copyright 2024 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 #ifndef NET_DEVICE_BOUND_SESSIONS_SESSION_H_ 6 #define NET_DEVICE_BOUND_SESSIONS_SESSION_H_ 7 8 #include <memory> 9 #include <optional> 10 #include <string> 11 12 #include "components/unexportable_keys/service_error.h" 13 #include "components/unexportable_keys/unexportable_key_id.h" 14 #include "net/base/net_export.h" 15 #include "net/device_bound_sessions/cookie_craving.h" 16 #include "net/device_bound_sessions/session_inclusion_rules.h" 17 #include "net/device_bound_sessions/session_key.h" 18 #include "net/device_bound_sessions/session_params.h" 19 #include "url/gurl.h" 20 21 namespace net { 22 class URLRequest; 23 } 24 25 namespace net::device_bound_sessions { 26 27 namespace proto { 28 class Session; 29 } 30 31 // This class represents a DBSC (Device Bound Session Credentials) session. 32 class NET_EXPORT Session { 33 public: 34 using Id = SessionKey::Id; 35 using KeyIdOrError = 36 unexportable_keys::ServiceErrorOr<unexportable_keys::UnexportableKeyId>; 37 38 Session(const Session& other) = delete; 39 Session& operator=(const Session& other) = delete; 40 Session(Session&& other) noexcept = delete; 41 Session& operator=(Session&& other) noexcept = delete; 42 43 ~Session(); 44 45 static std::unique_ptr<Session> CreateIfValid(const SessionParams& params, 46 GURL url); 47 static std::unique_ptr<Session> CreateFromProto(const proto::Session& proto); 48 proto::Session ToProto() const; 49 50 // Used to set the unexportable session binding key associated with this 51 // session. This method can be called when a session is first bound with 52 // a brand new key. It can also be called when restoring a session after 53 // browser restart. set_unexportable_key_id(KeyIdOrError key_id_or_error)54 void set_unexportable_key_id(KeyIdOrError key_id_or_error) { 55 key_id_or_error_ = std::move(key_id_or_error); 56 } 57 unexportable_key_id()58 const KeyIdOrError& unexportable_key_id() const { return key_id_or_error_; } 59 60 // this bool could also be an enum for UMA, eventually devtools, etc. 61 bool ShouldDeferRequest(URLRequest* request) const; 62 id()63 const Id& id() const { return id_; } 64 refresh_url()65 const GURL& refresh_url() const { return refresh_url_; } 66 cached_challenge()67 const std::optional<std::string>& cached_challenge() const { 68 return cached_challenge_; 69 } 70 creation_date()71 const base::Time& creation_date() const { return creation_date_; } 72 expiry_date()73 const base::Time& expiry_date() const { return expiry_date_; } 74 should_defer_when_expired()75 bool should_defer_when_expired() const { return should_defer_when_expired_; } 76 77 bool IsEqualForTesting(const Session& other) const; 78 set_cached_challenge(std::string challenge)79 void set_cached_challenge(std::string challenge) { 80 cached_challenge_ = std::move(challenge); 81 } 82 set_creation_date(base::Time creation_date)83 void set_creation_date(base::Time creation_date) { 84 creation_date_ = creation_date; 85 } 86 set_expiry_date(base::Time expiry_date)87 void set_expiry_date(base::Time expiry_date) { expiry_date_ = expiry_date; } 88 89 // On use of a session, extend the TTL. 90 void RecordAccess(); 91 92 private: 93 Session(Id id, url::Origin origin, GURL refresh); 94 Session(Id id, 95 GURL refresh, 96 SessionInclusionRules inclusion_rules, 97 std::vector<CookieCraving> cookie_cravings, 98 bool should_defer_when_expired, 99 base::Time creation_date, 100 base::Time expiry_date); 101 102 // The unique server-issued identifier of the session. 103 const Id id_; 104 // The URL to use for refresh requests made on behalf of this session. 105 // Note: This probably also needs to store its IsolationInfo, so that the 106 // correct IsolationInfo can be used when sending refresh requests. 107 // If requests are not deferred when missing a craving, this should still 108 // be set as this URL must be able to set all cravings. 109 const GURL refresh_url_; 110 // Determines which requests are potentially subject to deferral on behalf of 111 // this session. 112 SessionInclusionRules inclusion_rules_; 113 // The set of credentials required by this session. Derived from the 114 // "credentials" array in the session config. 115 std::vector<CookieCraving> cookie_cravings_; 116 // If this session should defer requests when cookies are not present. 117 // Default is true, and strongly recommended. 118 // If this is false, requests will still be sent when cookies are not present, 119 // and will be signed using the cached challenge if present, if not signed 120 // using a default value for challenge. 121 bool should_defer_when_expired_ = true; 122 // Date the session was created. 123 base::Time creation_date_; 124 // Expiry date for session, 400 days from last refresh similar to cookies. 125 base::Time expiry_date_; 126 // Unexportable key for this session. 127 // NOTE: The key may not be available for sometime after a browser restart. 128 // This is because the key needs to be restored from a corresponding 129 // "wrapped" value that is persisted to disk. This restoration takes time 130 // and can be done lazily. The "wrapped" key and the restore process are 131 // transparent to this class. Once restored, the key can be set using 132 // `set_unexportable_key_id` 133 KeyIdOrError key_id_or_error_ = 134 base::unexpected(unexportable_keys::ServiceError::kKeyNotReady); 135 // Precached challenge, if any. Should not be persisted. 136 std::optional<std::string> cached_challenge_; 137 }; 138 139 } // namespace net::device_bound_sessions 140 141 #endif // NET_DEVICE_BOUND_SESSIONS_SESSION_H_ 142