Botan 3.12.0
Crypto and TLS for C&
tls_session.h
Go to the documentation of this file.
1/*
2* TLS Session
3* (C) 2011-2012,2015 Jack Lloyd
4* (C) 2022 René Meusel - Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_TLS_SESSION_STATE_H_
10#define BOTAN_TLS_SESSION_STATE_H_
11
12#include <botan/secmem.h>
13#include <botan/strong_type.h>
14#include <botan/symkey.h>
15#include <botan/tls_ciphersuite.h>
16#include <botan/tls_magic.h>
17#include <botan/tls_server_info.h>
18#include <botan/tls_session_id.h>
19#include <botan/tls_version.h>
20#include <chrono>
21#include <memory>
22#include <span>
23
24namespace Botan {
25
26class Public_Key;
28
29} // namespace Botan
30
31namespace Botan::TLS {
32
33class Server_Hello_13;
34class Callbacks;
35
36/**
37 * Represents basic information about a session that can be both
38 * persisted for resumption and presented to the application as
39 * a summary of a specific just-established TLS session.
40 */
42 public:
43 Session_Base(std::chrono::system_clock::time_point start_time,
45 uint16_t ciphersuite,
46 Connection_Side connection_side,
47 uint16_t srtp_profile,
48 bool extended_master_secret,
49 bool encrypt_then_mac,
50 const std::vector<X509_Certificate>& peer_certs,
51 std::shared_ptr<const Public_Key> peer_raw_public_key,
53
56
57 Session_Base(Session_Base&& other) noexcept;
59
61
62 protected:
64
65 public:
66 /**
67 * Get the wall clock time this session began
68 */
69 std::chrono::system_clock::time_point start_time() const { return m_start_time; }
70
71 /**
72 * Get the negotiated protocol version of the TLS session
73 */
75
76 /**
77 * Get the ciphersuite code of the negotiated TLS session
78 */
79 uint16_t ciphersuite_code() const { return m_ciphersuite; }
80
81 /**
82 * Get the ciphersuite info of the negotiated TLS session
83 */
84 Ciphersuite ciphersuite() const;
85
86 /**
87 * Get which side of the connection we are/were acting as.
88 */
90
91 /**
92 * Get the negotiated DTLS-SRTP algorithm (RFC 5764)
93 */
94 uint16_t dtls_srtp_profile() const { return m_srtp_profile; }
95
96 /**
97 * Returns true if a TLS 1.2 session negotiated "encrypt then MAC";
98 * TLS 1.3 sessions will always return false as they always use an AEAD.
99 */
101
102 /**
103 * Returns true if a TLS 1.2 session negotiated "extended master secret";
104 * TLS 1.3 sessions will always return true (see RFC 8446 Appendix D).
105 */
107
108 /**
109 * Return the certificate chain of the peer (possibly empty)
110 */
111 const std::vector<X509_Certificate>& peer_certs() const { return m_peer_certs; }
112
113 /**
114 * Return the raw public key of the peer (possibly empty)
115 */
116 std::shared_ptr<const Public_Key> peer_raw_public_key() const { return m_peer_raw_public_key; }
117
118 /**
119 * Get information about the TLS server
120 *
121 * Returns information that identifies the server side of the connection.
122 * This is useful for the client in that it identifies what was originally
123 * passed to the constructor. For the server, it includes the name the
124 * client specified in the server name indicator extension.
125 */
127
128 protected:
129 std::chrono::system_clock::time_point m_start_time; // NOLINT(*non-private-member-variable*)
130
131 Protocol_Version m_version; // NOLINT(*non-private-member-variable*)
132 uint16_t m_ciphersuite = 0; // NOLINT(*non-private-member-variable*)
133 Connection_Side m_connection_side = Connection_Side::Client; // NOLINT(*non-private-member-variable*)
134 uint16_t m_srtp_profile = 0; // NOLINT(*non-private-member-variable*)
135
136 bool m_extended_master_secret = false; // NOLINT(*non-private-member-variable*)
137 bool m_encrypt_then_mac = false; // NOLINT(*non-private-member-variable*)
138
139 std::vector<X509_Certificate> m_peer_certs; // NOLINT(*non-private-member-variable*)
140 std::shared_ptr<const Public_Key> m_peer_raw_public_key; // NOLINT(*non-private-member-variable*)
141 Server_Information m_server_info; // NOLINT(*non-private-member-variable*)
142};
143
144/**
145 * Summarizes the negotiated features after a TLS handshake. Applications may
146 * query those in Callbacks::tls_session_established().
147 */
148class BOTAN_PUBLIC_API(3, 0) Session_Summary final : public Session_Base {
149 public:
150 /**
151 * The Session_ID negotiated during the handshake.
152 * Note that this does not carry any meaning in TLS 1.3 and might even
153 * be empty.
154 */
155 const Session_ID& session_id() const { return m_session_id; }
156
157 /**
158 * The session ticket a TLS 1.2 server issued for this session.
159 * Note that this may be set in TLS 1.2 clients only. It is _not_ the
160 * ticket used to establish this session.
161 */
162 const std::optional<Session_Ticket>& session_ticket() const { return m_session_ticket; }
163
164 /**
165 * The negotiated identity of an externally provided preshared key used to
166 * establish this session. For TLS 1.3 this may be any of the externally
167 * provided PSKs offered by the client. PSK identities used as session
168 * tickets for TLS 1.3 session resumption won't be shown here.
169 */
170 const std::optional<std::string>& external_psk_identity() const { return m_external_psk_identity; }
171
172 /**
173 * Indicates that the session was established using an externally provided
174 * PSK. Session resumptions in TLS 1.3 (while technically implemented
175 * using a PSK) are not considered here. @sa was_resumption()
176 *
177 * @note Botan 3.0 and 3.1 did incorrectly report true for session resumption.
178 *
179 * @returns true if the session was established using an externally
180 * provided PSK.
181 */
182 bool psk_used() const { return m_external_psk_identity.has_value(); }
183
184 /**
185 * Indicates that the session was resumed from a previous handshake state.
186 *
187 * @returns true if this session is a resumption, otherwise false
188 */
189 bool was_resumption() const { return m_was_resumption; }
190
191 std::string kex_algo() const { return m_kex_algo; }
192
193 std::optional<std::string> kex_parameters() const { return m_kex_parameters; }
194
195 std::string cipher_algo() const { return ciphersuite().cipher_algo(); }
196
197 std::string mac_algo() const { return ciphersuite().mac_algo(); }
198
199 std::string prf_algo() const { return ciphersuite().prf_algo(); }
200
201 private:
202 friend class Server_Impl_12;
203 friend class Server_Impl_13;
204 friend class Client_Impl_12;
205 friend class Client_Impl_13;
206
207 Session_Summary(const Session_Base& base, bool was_resumption, std::optional<std::string> psk_identity);
208
209#if defined(BOTAN_HAS_TLS_13)
210 Session_Summary(const Server_Hello_13& server_hello,
212 const std::vector<X509_Certificate>& peer_certs,
213 std::shared_ptr<const Public_Key> peer_raw_public_key,
214 std::optional<std::string> psk_identity,
215 bool session_was_resumed,
217 std::chrono::system_clock::time_point current_timestamp);
218#endif
219
220 void set_session_id(Session_ID id) { m_session_id = std::move(id); }
221
222 void set_session_ticket(Session_Ticket ticket) { m_session_ticket = std::move(ticket); }
223
224 private:
225 Session_ID m_session_id;
226 std::optional<Session_Ticket> m_session_ticket;
227 std::optional<std::string> m_external_psk_identity;
228
229 bool m_was_resumption;
230 std::string m_kex_algo;
231 std::optional<std::string> m_kex_parameters;
232};
233
234/**
235 * Represents a session's negotiated features along with all resumption
236 * information to re-establish a TLS connection later on.
237 */
238class BOTAN_PUBLIC_API(3, 0) Session final : public Session_Base {
239 public:
240 /**
241 * New TLS 1.2 session (sets session start time)
242 */
245 uint16_t ciphersuite,
249 const std::vector<X509_Certificate>& peer_certs,
251 uint16_t srtp_profile,
252 std::chrono::system_clock::time_point current_timestamp,
253 std::chrono::seconds lifetime_hint = std::chrono::seconds::max());
254
255#if defined(BOTAN_HAS_TLS_13)
256
257 /**
258 * New TLS 1.3 session (sets session start time)
259 */
260 Session(const secure_vector<uint8_t>& session_psk,
261 const std::optional<uint32_t>& max_early_data_bytes,
262 uint32_t ticket_age_add,
263 std::chrono::seconds lifetime_hint,
265 uint16_t ciphersuite,
267 const std::vector<X509_Certificate>& peer_certs,
268 std::shared_ptr<const Public_Key> peer_raw_public_key,
270 std::chrono::system_clock::time_point current_timestamp);
271
272#endif
273
274 /**
275 * Load a session from DER representation (created by DER_encode)
276 * @param ber_data DER representation buffer
277 */
278 BOTAN_FUTURE_EXPLICIT Session(std::span<const uint8_t> ber_data);
279
280 /**
281 * Load a session from PEM representation (created by PEM_encode)
282 * @param pem PEM representation
283 */
284 explicit Session(std::string_view pem);
285
286 /**
287 * Encode this session data for storage
288 * @warning if the master secret is compromised so is the
289 * session traffic
290 */
292
293 /**
294 * Encrypt a session (useful for serialization or session tickets)
295 */
296 std::vector<uint8_t> encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const;
297
298 /**
299 * Decrypt a session created by encrypt
300 * @param ctext the ciphertext returned by encrypt
301 * @param ctext_size the size of ctext in bytes
302 * @param key the same key used by the encrypting side
303 */
304 static inline Session decrypt(const uint8_t ctext[], size_t ctext_size, const SymmetricKey& key) {
305 return Session::decrypt(std::span(ctext, ctext_size), key);
306 }
307
308 /**
309 * Decrypt a session created by encrypt
310 * @param ctext the ciphertext returned by encrypt
311 * @param key the same key used by the encrypting side
312 */
313 static Session decrypt(std::span<const uint8_t> ctext, const SymmetricKey& key);
314
315 /**
316 * Encode this session data for storage
317 * @warning if the master secret is compromised so is the
318 * session traffic
319 */
320 std::string PEM_encode() const;
321
322 /**
323 * Get a reference to the contained master secret
324 */
325 const secure_vector<uint8_t>& master_secret() const { return m_master_secret; }
326
327 /**
328 * Get the contained master secret as a moved-out object
329 */
330 secure_vector<uint8_t> extract_master_secret();
331
332 /**
333 * Get whether the saved session supports sending/receiving of early data
334 */
335 bool supports_early_data() const { return m_early_data_allowed; }
336
337 /**
338 * Return the ticket obfuscation adder
339 */
340 uint32_t session_age_add() const { return m_ticket_age_add; }
341
342 /**
343 * Return the number of bytes allowed for 0-RTT early data
344 */
345 uint32_t max_early_data_bytes() const { return m_max_early_data_bytes; }
346
347 /**
348 * @return the lifetime of the ticket as defined by the TLS server
349 */
350 std::chrono::seconds lifetime_hint() const { return m_lifetime_hint; }
351
352 private:
353 /*
354 * Struct Version history
355 *
356 * 20160812 - Pre TLS 1.3
357 * 20220505 - Introduction of TLS 1.3 sessions
358 * - added fields:
359 * - m_early_data_allowed
360 * - m_max_early_data_bytes
361 * - m_ticket_age_add
362 * - m_lifetime_hint
363 * 20230112 - Remove Session_ID and Session_Ticket from this object
364 * (association is now in the hands of the Session_Manager)
365 * - Peer certificates are now stored as a SEQUENCE
366 * 20230222 - Remove deprecated and unused fields
367 * - compression method (always 0)
368 * - fragment size (always 0)
369 * - SRP identifier (always "")
370 * 20231031 - Allow storage of peer's raw public key
371 */
372 static constexpr size_t TLS_SESSION_PARAM_STRUCT_VERSION = 20231031;
373
374 secure_vector<uint8_t> m_master_secret;
375
376 bool m_early_data_allowed;
377 uint32_t m_max_early_data_bytes;
378 uint32_t m_ticket_age_add;
379 std::chrono::seconds m_lifetime_hint;
380};
381
382/**
383 * Helper struct to conveniently pass a Session and its Session_Handle around
384 */
390
391} // namespace Botan::TLS
392
393#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
std::vector< X509_Certificate > m_peer_certs
Session_Base(std::chrono::system_clock::time_point start_time, Protocol_Version version, uint16_t ciphersuite, Connection_Side connection_side, uint16_t srtp_profile, bool extended_master_secret, bool encrypt_then_mac, const std::vector< X509_Certificate > &peer_certs, std::shared_ptr< const Public_Key > peer_raw_public_key, Server_Information server_info)
std::shared_ptr< const Public_Key > peer_raw_public_key() const
Session_Base & operator=(Session_Base &&other) noexcept
Session_Base(const Session_Base &other)
uint16_t dtls_srtp_profile() const
Definition tls_session.h:94
Protocol_Version version() const
Definition tls_session.h:74
Connection_Side side() const
Definition tls_session.h:89
bool supports_encrypt_then_mac() const
Protocol_Version m_version
std::chrono::system_clock::time_point m_start_time
Server_Information m_server_info
std::chrono::system_clock::time_point start_time() const
Definition tls_session.h:69
uint16_t ciphersuite_code() const
Definition tls_session.h:79
bool supports_extended_master_secret() const
Session_Base(Session_Base &&other) noexcept
Session_Base & operator=(const Session_Base &other)
Ciphersuite ciphersuite() const
const std::vector< X509_Certificate > & peer_certs() const
const Server_Information & server_info() const
std::shared_ptr< const Public_Key > m_peer_raw_public_key
Connection_Side m_connection_side
Helper class to embody a session handle in all protocol versions.
std::string cipher_algo() const
std::string mac_algo() const
std::string kex_algo() const
const std::optional< Session_Ticket > & session_ticket() const
const std::optional< std::string > & external_psk_identity() const
const Session_ID & session_id() const
std::string prf_algo() const
std::optional< std::string > kex_parameters() const
secure_vector< uint8_t > DER_encode() const
std::vector< uint8_t > encrypt(const SymmetricKey &key, RandomNumberGenerator &rng) const
std::chrono::seconds lifetime_hint() const
static Session decrypt(const uint8_t ctext[], size_t ctext_size, const SymmetricKey &key)
bool supports_early_data() const
uint32_t session_age_add() const
Session(const secure_vector< uint8_t > &master_secret, Protocol_Version version, uint16_t ciphersuite, Connection_Side side, bool supports_extended_master_secret, bool supports_encrypt_then_mac, const std::vector< X509_Certificate > &peer_certs, const Server_Information &server_info, uint16_t srtp_profile, std::chrono::system_clock::time_point current_timestamp, std::chrono::seconds lifetime_hint=std::chrono::seconds::max())
const secure_vector< uint8_t > & master_secret() const
uint32_t max_early_data_bytes() const
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
Strong< std::vector< uint8_t >, struct Session_Ticket_ > Session_Ticket
holds a TLS 1.2 session ticket for stateless resumption
OctetString SymmetricKey
Definition symkey.h:140
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68