Botan 3.12.0
Crypto and TLS for C&
tls_session.cpp
Go to the documentation of this file.
1/*
2* TLS Session State
3* (C) 2011-2012,2015,2019 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/tls_session.h>
9
10#include <botan/aead.h>
11#include <botan/asn1_obj.h>
12#include <botan/ber_dec.h>
13#include <botan/der_enc.h>
14#include <botan/mac.h>
15#include <botan/pem.h>
16#include <botan/rng.h>
17#include <botan/tls_callbacks.h>
18#include <botan/x509_key.h>
19#include <botan/x509cert.h>
20#include <botan/internal/buffer_slicer.h>
21#include <botan/internal/ct_utils.h>
22#include <botan/internal/loadstor.h>
23#include <botan/internal/stl_util.h>
24
25#if defined(BOTAN_HAS_TLS_13)
26 #include <botan/tls_extensions_13.h>
27 #include <botan/tls_messages_13.h>
28#endif
29
30#include <utility>
31
32namespace Botan::TLS {
33
34void Session_Handle::validate_constraints() const {
35 std::visit(overloaded{
36 [](const Session_ID& id) {
37 // RFC 5246 7.4.1.2
38 // opaque SessionID<0..32>;
39 BOTAN_ARG_CHECK(!id.empty(), "Session ID must not be empty");
40 BOTAN_ARG_CHECK(id.size() <= 32, "Session ID cannot be longer than 32 bytes");
41 },
42 [](const Session_Ticket& ticket) {
43 BOTAN_ARG_CHECK(!ticket.empty(), "Ticket most not be empty");
44 BOTAN_ARG_CHECK(ticket.size() <= std::numeric_limits<uint16_t>::max(),
45 "Ticket cannot be longer than 64kB");
46 },
47 [](const Opaque_Session_Handle& handle) {
48 // RFC 8446 4.6.1
49 // opaque ticket<1..2^16-1>;
50 BOTAN_ARG_CHECK(!handle.empty(), "Opaque session handle must not be empty");
51 BOTAN_ARG_CHECK(handle.size() <= std::numeric_limits<uint16_t>::max(),
52 "Opaque session handle cannot be longer than 64kB");
53 },
54 },
55 m_handle);
56}
57
59 // both a Session_ID and a Session_Ticket could be an Opaque_Session_Handle
60 return Opaque_Session_Handle(std::visit([](const auto& handle) { return handle.get(); }, m_handle));
61}
62
63std::optional<Session_ID> Session_Handle::id() const {
64 if(is_id()) {
65 return std::get<Session_ID>(m_handle);
66 }
67
68 // Opaque handles can mimic as a Session_ID if they are short enough
69 if(is_opaque_handle()) {
70 const auto& handle = std::get<Opaque_Session_Handle>(m_handle);
71 if(handle.size() <= 32) {
72 return Session_ID(handle.get());
73 }
74 }
75
76 return std::nullopt;
77}
78
79std::optional<Session_Ticket> Session_Handle::ticket() const {
80 if(is_ticket()) {
81 return std::get<Session_Ticket>(m_handle);
82 }
83
84 // Opaque handles can mimic 'normal' Session_Tickets at any time
85 if(is_opaque_handle()) {
86 return Session_Ticket(std::get<Opaque_Session_Handle>(m_handle).get());
87 }
88
89 return std::nullopt;
90}
91
93
95
96Session_Base::Session_Base(const Session_Base& other) = default;
98
99Session_Base::Session_Base(Session_Base&& other) noexcept = default;
100Session_Base& Session_Base::operator=(Session_Base&& other) noexcept = default;
101
102Session_Base::Session_Base(std::chrono::system_clock::time_point start_time,
104 uint16_t ciphersuite,
105 Connection_Side connection_side,
106 uint16_t srtp_profile,
107 bool extended_master_secret,
108 bool encrypt_then_mac,
109 const std::vector<X509_Certificate>& peer_certs,
110 std::shared_ptr<const Public_Key> peer_raw_public_key,
115 m_connection_side(connection_side),
116 m_srtp_profile(srtp_profile),
117 m_extended_master_secret(extended_master_secret),
118 m_encrypt_then_mac(encrypt_then_mac),
121 m_server_info(std::move(server_info)) {}
122
124 auto suite = Ciphersuite::by_id(m_ciphersuite);
125 if(!suite.has_value()) {
126 throw Decoding_Error("Failed to find cipher suite for ID " + std::to_string(m_ciphersuite));
127 }
128 return suite.value();
129}
130
131Session_Summary::Session_Summary(const Session_Base& base,
132 bool was_resumption,
133 std::optional<std::string> psk_identity) :
134 Session_Base(base), m_external_psk_identity(std::move(psk_identity)), m_was_resumption(was_resumption) {
135 BOTAN_ARG_CHECK(version().is_pre_tls_13(), "Instantiated a TLS 1.2 session summary with an newer TLS version");
136
137 const auto cs = ciphersuite();
138 m_kex_algo = cs.kex_algo();
139}
140
141#if defined(BOTAN_HAS_TLS_13)
142
143namespace {
144
145std::string tls13_kex_to_string(bool psk, std::optional<Named_Group> group) {
146 if(psk && group) {
147 if(group->is_dh_named_group()) {
149 } else if(group->is_ecdh_named_curve() || group->is_x25519() || group->is_x448()) {
151 } else if(group->is_pure_ml_kem() || group->is_pure_frodokem()) {
153 } else if(group->is_pqc_hybrid()) {
155 } else if(auto s = group->to_string()) {
156 return *s;
157 }
158 } else if(psk) {
160 } else {
161 BOTAN_ASSERT_NOMSG(group.has_value());
162 if(group->is_dh_named_group()) {
164 } else if(group->is_ecdh_named_curve() || group->is_x25519() || group->is_x448()) {
166 } else if(group->is_pure_ml_kem() || group->is_pure_frodokem()) {
168 } else if(group->is_pqc_hybrid()) {
170 } else if(auto s = group->to_string()) {
171 return *s;
172 }
173 }
174
176}
177
178} // namespace
179
180Session_Summary::Session_Summary(const Server_Hello_13& server_hello,
181 Connection_Side side,
182 const std::vector<X509_Certificate>& peer_certs,
183 std::shared_ptr<const Public_Key> peer_raw_public_key,
184 std::optional<std::string> psk_identity,
185 bool session_was_resumed,
186 Server_Information server_info,
187 std::chrono::system_clock::time_point current_timestamp) :
188 Session_Base(current_timestamp,
189 server_hello.selected_version(),
190 server_hello.ciphersuite(),
191 side,
192
193 // TODO: SRTP might become necessary when DTLS 1.3 is being implemented
194 0,
195
196 // RFC 8446 Appendix D
197 // Because TLS 1.3 always hashes in the transcript up to the server
198 // Finished, implementations which support both TLS 1.3 and earlier
199 // versions SHOULD indicate the use of the Extended Master Secret
200 // extension in their APIs whenever TLS 1.3 is used.
201 true,
202
203 // TLS 1.3 uses AEADs, so technically encrypt-then-MAC is not applicable.
204 false,
205 peer_certs,
206 std::move(peer_raw_public_key),
207 std::move(server_info)),
208 m_external_psk_identity(std::move(psk_identity)),
209 m_was_resumption(session_was_resumed) {
210 BOTAN_ARG_CHECK(version().is_tls_13_or_later(), "Instantiated a TLS 1.3 session summary with an older TLS version");
211 set_session_id(server_hello.session_id());
212
213 // In TLS 1.3 the key exchange algorithm is not negotiated in the ciphersuite
214 // anymore. This provides a compatible identifier for applications to use.
215
216 std::optional<Named_Group> group = [&]() -> std::optional<Named_Group> {
217 if(psk_used() || was_resumption()) {
218 if(auto* const keyshare = server_hello.extensions().get<Key_Share>()) {
219 return keyshare->selected_group();
220 } else {
221 return {};
222 }
223 } else {
224 auto* const keyshare = server_hello.extensions().get<Key_Share>();
225 BOTAN_ASSERT_NONNULL(keyshare);
226 return keyshare->selected_group();
227 }
228 }();
229
230 if(group.has_value()) {
231 m_kex_parameters = group->to_string();
232 }
233
234 m_kex_algo = tls13_kex_to_string(psk_used() || was_resumption(), group);
235}
236
237#endif
238
241 uint16_t ciphersuite,
243 bool extended_master_secret,
244 bool encrypt_then_mac,
245 const std::vector<X509_Certificate>& certs,
247 uint16_t srtp_profile,
248 std::chrono::system_clock::time_point current_timestamp,
249 std::chrono::seconds lifetime_hint) :
250 Session_Base(current_timestamp,
251 version,
253 side,
254 srtp_profile,
255 extended_master_secret,
256 encrypt_then_mac,
257 certs,
258 nullptr, // RFC 7250 (raw public keys) is NYI for TLS 1.2
260 m_master_secret(master_secret),
261 m_early_data_allowed(false),
262 m_max_early_data_bytes(0),
263 m_ticket_age_add(0),
264 m_lifetime_hint(lifetime_hint) {
265 BOTAN_ARG_CHECK(version.is_pre_tls_13(), "Instantiated a TLS 1.2 session object with a TLS version newer than 1.2");
266}
267
268#if defined(BOTAN_HAS_TLS_13)
269
271 const std::optional<uint32_t>& max_early_data_bytes,
272 uint32_t ticket_age_add,
273 std::chrono::seconds lifetime_hint,
275 uint16_t ciphersuite,
277 const std::vector<X509_Certificate>& peer_certs,
278 std::shared_ptr<const Public_Key> peer_raw_public_key,
280 std::chrono::system_clock::time_point current_timestamp) :
281 Session_Base(current_timestamp,
282 version,
284 side,
285
286 // TODO: SRTP might become necessary when DTLS 1.3 is being implemented
287 0,
288
289 // RFC 8446 Appendix D
290 // Because TLS 1.3 always hashes in the transcript up to the server
291 // Finished, implementations which support both TLS 1.3 and earlier
292 // versions SHOULD indicate the use of the Extended Master Secret
293 // extension in their APIs whenever TLS 1.3 is used.
294 true,
295
296 // TLS 1.3 uses AEADs, so technically encrypt-then-MAC is not applicable.
297 false,
299 std::move(peer_raw_public_key),
301 m_master_secret(session_psk),
302 m_early_data_allowed(max_early_data_bytes.has_value()),
303 m_max_early_data_bytes(max_early_data_bytes.value_or(0)),
304 m_ticket_age_add(ticket_age_add),
305 m_lifetime_hint(lifetime_hint) {
306 BOTAN_ARG_CHECK(!version.is_pre_tls_13(), "Instantiated a TLS 1.3 session object with a TLS version older than 1.3");
307}
308
309#endif
310
311Session::Session(std::string_view pem) : Session(PEM_Code::decode_check_label(pem, "TLS SESSION")) {}
312
313Session::Session(std::span<const uint8_t> ber_data) /* NOLINT(*-member-init) */ {
314 uint8_t side_code = 0;
315
316 std::vector<uint8_t> raw_pubkey_or_empty;
317
318 ASN1_String server_hostname;
319 ASN1_String server_service;
320 size_t server_port = 0;
321
322 uint8_t major_version = 0;
323 uint8_t minor_version = 0;
324
325 size_t start_time = 0;
326 size_t srtp_profile = 0;
327 uint16_t ciphersuite_code = 0;
328 uint64_t lifetime_hint = 0;
329
332 .decode_and_check(TLS_SESSION_PARAM_STRUCT_VERSION, "Unknown version in serialized TLS session")
334 .decode_integer_type(major_version)
335 .decode_integer_type(minor_version)
337 .decode_integer_type(side_code)
340 .decode(m_master_secret, ASN1_Type::OctetString)
342 .decode(raw_pubkey_or_empty, ASN1_Type::OctetString)
343 .decode(server_hostname)
344 .decode(server_service)
345 .decode(server_port)
346 .decode(srtp_profile)
347 .decode(m_early_data_allowed)
348 .decode_integer_type(m_max_early_data_bytes)
349 .decode_integer_type(m_ticket_age_add)
350 .decode_integer_type(lifetime_hint)
351 .end_cons()
352 .verify_end();
353
355 throw Decoding_Error(
356 "Serialized TLS session contains unknown cipher suite "
357 "(" +
358 std::to_string(ciphersuite_code) + ")");
359 }
360
362 m_version = Protocol_Version(major_version, minor_version);
363 m_start_time = std::chrono::system_clock::from_time_t(start_time);
364 if(side_code != static_cast<uint8_t>(Connection_Side::Client) &&
365 side_code != static_cast<uint8_t>(Connection_Side::Server)) {
366 throw Decoding_Error("Serialized TLS session contains unknown connection side " + std::to_string(side_code));
367 }
368 m_connection_side = static_cast<Connection_Side>(side_code);
369
370 const bool valid_secret_size = m_version.is_pre_tls_13()
371 ? (m_master_secret.size() == 48)
372 : (m_master_secret.size() == 32 || m_master_secret.size() == 48);
373 if(!valid_secret_size) {
374 throw Decoding_Error("Serialized TLS session has master_secret of unexpected length");
375 }
376 m_srtp_profile = static_cast<uint16_t>(srtp_profile);
377
379 Server_Information(server_hostname.value(), server_service.value(), static_cast<uint16_t>(server_port));
380
381 if(!raw_pubkey_or_empty.empty()) {
382 m_peer_raw_public_key = X509::load_key(raw_pubkey_or_empty);
383 }
384
385 m_lifetime_hint = std::chrono::seconds(lifetime_hint);
386}
387
389 const auto raw_pubkey_or_empty =
390 m_peer_raw_public_key ? m_peer_raw_public_key->subject_public_key() : std::vector<uint8_t>{};
391
392 return DER_Encoder()
394 .encode(TLS_SESSION_PARAM_STRUCT_VERSION)
395 .encode(static_cast<size_t>(std::chrono::system_clock::to_time_t(m_start_time)))
396 .encode(static_cast<size_t>(m_version.major_version()))
397 .encode(static_cast<size_t>(m_version.minor_version()))
398 .encode(static_cast<size_t>(m_ciphersuite))
399 .encode(static_cast<size_t>(m_connection_side))
402 .encode(m_master_secret, ASN1_Type::OctetString)
405 .end_cons()
406 .encode(raw_pubkey_or_empty, ASN1_Type::OctetString)
409 .encode(static_cast<size_t>(m_server_info.port()))
410 .encode(static_cast<size_t>(m_srtp_profile))
411
412 // the fields below were introduced for TLS 1.3 session tickets
413 .encode(m_early_data_allowed)
414 .encode(static_cast<size_t>(m_max_early_data_bytes))
415 .encode(static_cast<size_t>(m_ticket_age_add))
416 .encode(static_cast<size_t>(m_lifetime_hint.count()))
417 .end_cons()
418 .get_contents();
419}
420
421std::string Session::PEM_encode() const {
422 return PEM_Code::encode(this->DER_encode(), "TLS SESSION");
423}
424
426 BOTAN_STATE_CHECK(!m_master_secret.empty());
427 return std::exchange(m_master_secret, {});
428}
429
430namespace {
431
432// The output length of the HMAC must be a valid keylength for the AEAD
433const char* const TLS_SESSION_CRYPT_HMAC = "HMAC(SHA-512-256)";
434// SIV would be better, but we can't assume it is available
435const char* const TLS_SESSION_CRYPT_AEAD = "AES-256/GCM";
436const char* const TLS_SESSION_CRYPT_KEY_NAME = "BOTAN TLS SESSION KEY NAME";
437const uint64_t TLS_SESSION_CRYPT_MAGIC = 0x068B5A9D396C0000;
438const size_t TLS_SESSION_CRYPT_MAGIC_LEN = 8;
439const size_t TLS_SESSION_CRYPT_KEY_NAME_LEN = 4;
440const size_t TLS_SESSION_CRYPT_AEAD_NONCE_LEN = 12;
441const size_t TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN = 16;
442const size_t TLS_SESSION_CRYPT_AEAD_TAG_SIZE = 16;
443
444const size_t TLS_SESSION_CRYPT_HDR_LEN = TLS_SESSION_CRYPT_MAGIC_LEN + TLS_SESSION_CRYPT_KEY_NAME_LEN +
445 TLS_SESSION_CRYPT_AEAD_NONCE_LEN + TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN;
446
447const size_t TLS_SESSION_CRYPT_OVERHEAD = TLS_SESSION_CRYPT_HDR_LEN + TLS_SESSION_CRYPT_AEAD_TAG_SIZE;
448
449} // namespace
450
451std::vector<uint8_t> Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const {
452 auto hmac = MessageAuthenticationCode::create_or_throw(TLS_SESSION_CRYPT_HMAC);
453 hmac->set_key(key);
454
455 // First derive the "key name"
456 std::vector<uint8_t> key_name(hmac->output_length());
457 hmac->update(TLS_SESSION_CRYPT_KEY_NAME);
458 hmac->final(key_name.data());
459 key_name.resize(TLS_SESSION_CRYPT_KEY_NAME_LEN);
460
461 std::vector<uint8_t> aead_nonce;
462 std::vector<uint8_t> key_seed;
463
464 rng.random_vec(aead_nonce, TLS_SESSION_CRYPT_AEAD_NONCE_LEN);
465 rng.random_vec(key_seed, TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN);
466
467 hmac->update(key_seed);
468 const secure_vector<uint8_t> aead_key = hmac->final();
469
470 secure_vector<uint8_t> bits = this->DER_encode();
471
472 // create the header
473 std::vector<uint8_t> buf;
474 buf.reserve(TLS_SESSION_CRYPT_OVERHEAD + bits.size());
475 buf.resize(TLS_SESSION_CRYPT_MAGIC_LEN);
476 store_be(TLS_SESSION_CRYPT_MAGIC, &buf[0]); // NOLINT(*container-data-pointer)
477 buf += key_name;
478 buf += key_seed;
479 buf += aead_nonce;
480
481 auto aead = AEAD_Mode::create_or_throw(TLS_SESSION_CRYPT_AEAD, Cipher_Dir::Encryption);
482 BOTAN_ASSERT_NOMSG(aead->valid_nonce_length(TLS_SESSION_CRYPT_AEAD_NONCE_LEN));
483 BOTAN_ASSERT_NOMSG(aead->tag_size() == TLS_SESSION_CRYPT_AEAD_TAG_SIZE);
484 aead->set_key(aead_key);
485 aead->set_associated_data(buf);
486 aead->start(aead_nonce);
487 aead->finish(bits, 0);
488
489 // append the ciphertext
490 buf += bits;
491 return buf;
492}
493
494Session Session::decrypt(std::span<const uint8_t> in, const SymmetricKey& key) {
495 try {
496 const size_t min_session_size = 48 + 4; // serious under-estimate
497 if(in.size() < TLS_SESSION_CRYPT_OVERHEAD + min_session_size) {
498 throw Decoding_Error("Encrypted session too short to be valid");
499 }
500
501 BufferSlicer sub(in);
502 const auto* const magic = sub.take(TLS_SESSION_CRYPT_MAGIC_LEN).data();
503 const auto* const key_name = sub.take(TLS_SESSION_CRYPT_KEY_NAME_LEN).data();
504 const auto* const key_seed = sub.take(TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN).data();
505 const auto* const aead_nonce = sub.take(TLS_SESSION_CRYPT_AEAD_NONCE_LEN).data();
506 auto ctext = sub.copy_as_secure_vector(sub.remaining());
507
508 if(load_be<uint64_t>(magic, 0) != TLS_SESSION_CRYPT_MAGIC) {
509 throw Decoding_Error("Missing expected magic numbers");
510 }
511
512 auto hmac = MessageAuthenticationCode::create_or_throw(TLS_SESSION_CRYPT_HMAC);
513 hmac->set_key(key);
514
515 // First derive and check the "key name"
516 std::vector<uint8_t> cmp_key_name(hmac->output_length());
517 hmac->update(TLS_SESSION_CRYPT_KEY_NAME);
518 hmac->final(cmp_key_name.data());
519
520 if(CT::is_equal(cmp_key_name.data(), key_name, TLS_SESSION_CRYPT_KEY_NAME_LEN).as_bool() == false) {
521 throw Decoding_Error("Wrong key name for encrypted session");
522 }
523
524 hmac->update(key_seed, TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN);
525 const secure_vector<uint8_t> aead_key = hmac->final();
526
527 auto aead = AEAD_Mode::create_or_throw(TLS_SESSION_CRYPT_AEAD, Cipher_Dir::Decryption);
528 aead->set_key(aead_key);
529 aead->set_associated_data(in.data(), TLS_SESSION_CRYPT_HDR_LEN);
530 aead->start(aead_nonce, TLS_SESSION_CRYPT_AEAD_NONCE_LEN);
531 aead->finish(ctext, 0);
532 return Session(ctext);
533 } catch(std::exception& e) {
534 throw Decoding_Error("Failed to decrypt serialized TLS session: " + std::string(e.what()));
535 }
536}
537
538} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
static std::unique_ptr< AEAD_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition aead.cpp:49
const std::string & value() const
Definition asn1_obj.h:365
static Limits DER()
Definition ber_dec.h:35
BER_Decoder & decode(bool &out)
Definition ber_dec.h:220
BER_Decoder & decode_list(std::vector< T > &out, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:430
BER_Decoder start_sequence()
Definition ber_dec.h:160
BER_Decoder & decode_and_check(const T &expected, std::string_view error_msg)
Definition ber_dec.h:314
BER_Decoder & decode_integer_type(T &out)
Definition ber_dec.h:274
size_t remaining() const
auto copy_as_secure_vector(const size_t count)
std::span< const uint8_t > take(const size_t count)
secure_vector< uint8_t > get_contents()
Definition der_enc.cpp:134
DER_Encoder & encode_list(const std::vector< T > &values)
Definition der_enc.h:140
DER_Encoder & start_sequence()
Definition der_enc.h:67
DER_Encoder & end_cons()
Definition der_enc.cpp:173
DER_Encoder & encode(bool b)
Definition der_enc.cpp:245
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition mac.cpp:147
void random_vec(std::span< uint8_t > v)
Definition rng.h:204
static std::optional< Ciphersuite > by_id(uint16_t suite)
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
Protocol_Version version() const
Definition tls_session.h:74
Connection_Side side() const
Definition tls_session.h:89
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
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
std::optional< Session_Ticket > ticket() const
decltype(auto) get() const
Opaque_Session_Handle opaque_handle() const
std::optional< Session_ID > id() 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)
std::string PEM_encode() 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
secure_vector< uint8_t > extract_master_secret()
uint32_t max_early_data_bytes() const
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
Definition ct_utils.h:798
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
Definition pem.cpp:39
std::string kex_method_to_string(Kex_Algo method)
Definition tls_algos.cpp:30
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
Strong< std::vector< uint8_t >, struct Opaque_Session_Handle_ > Opaque_Session_Handle
holds an opaque session handle as used in TLS 1.3 that could be either a ticket for stateless resumpt...
std::unique_ptr< Public_Key > load_key(DataSource &source)
Definition x509_key.cpp:28
OctetString SymmetricKey
Definition symkey.h:140
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:745
overloaded(Ts...) -> overloaded< Ts... >
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504