Botan 3.4.0
Crypto and TLS for C&
tls_channel_impl_12.cpp
Go to the documentation of this file.
1/*
2* TLS Channels
3* (C) 2011,2012,2014,2015,2016 Jack Lloyd
4* 2016 Matthias Gierlings
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/internal/tls_channel_impl_12.h>
10
11#include <botan/kdf.h>
12#include <botan/tls_messages.h>
13#include <botan/tls_policy.h>
14#include <botan/x509cert.h>
15#include <botan/internal/loadstor.h>
16#include <botan/internal/stl_util.h>
17#include <botan/internal/tls_handshake_state.h>
18#include <botan/internal/tls_record.h>
19#include <botan/internal/tls_seq_numbers.h>
20
21namespace Botan::TLS {
22
23Channel_Impl_12::Channel_Impl_12(const std::shared_ptr<Callbacks>& callbacks,
24 const std::shared_ptr<Session_Manager>& session_manager,
25 const std::shared_ptr<RandomNumberGenerator>& rng,
26 const std::shared_ptr<const Policy>& policy,
27 bool is_server,
28 bool is_datagram,
29 size_t reserved_io_buffer_size) :
30 m_is_server(is_server),
31 m_is_datagram(is_datagram),
32 m_callbacks(callbacks),
33 m_session_manager(session_manager),
34 m_policy(policy),
35 m_rng(rng),
36 m_has_been_closed(false) {
37 BOTAN_ASSERT_NONNULL(m_callbacks);
38 BOTAN_ASSERT_NONNULL(m_session_manager);
40 BOTAN_ASSERT_NONNULL(m_policy);
41
42 /* epoch 0 is plaintext, thus null cipher state */
43 m_write_cipher_states[0] = nullptr;
44 m_read_cipher_states[0] = nullptr;
45
46 m_writebuf.reserve(reserved_io_buffer_size);
47 m_readbuf.reserve(reserved_io_buffer_size);
48}
49
50void Channel_Impl_12::reset_state() {
51 m_active_state.reset();
52 m_pending_state.reset();
53 m_readbuf.clear();
54 m_write_cipher_states.clear();
55 m_read_cipher_states.clear();
56}
57
59 // This operation only makes sense for DTLS
60 BOTAN_ASSERT_NOMSG(m_is_datagram);
61 m_active_state.reset();
62 m_read_cipher_states.clear();
63 m_write_cipher_states.clear();
64
65 m_write_cipher_states[0] = nullptr;
66 m_read_cipher_states[0] = nullptr;
67
68 if(m_sequence_numbers) {
69 m_sequence_numbers->reset();
70 }
71}
72
74
75Connection_Sequence_Numbers& Channel_Impl_12::sequence_numbers() const {
76 BOTAN_ASSERT(m_sequence_numbers, "Have a sequence numbers object");
77 return *m_sequence_numbers;
78}
79
80std::shared_ptr<Connection_Cipher_State> Channel_Impl_12::read_cipher_state_epoch(uint16_t epoch) const {
81 auto i = m_read_cipher_states.find(epoch);
82 if(i == m_read_cipher_states.end()) {
83 throw Internal_Error("TLS::Channel_Impl_12 No read cipherstate for epoch " + std::to_string(epoch));
84 }
85 return i->second;
86}
87
88std::shared_ptr<Connection_Cipher_State> Channel_Impl_12::write_cipher_state_epoch(uint16_t epoch) const {
89 auto i = m_write_cipher_states.find(epoch);
90 if(i == m_write_cipher_states.end()) {
91 throw Internal_Error("TLS::Channel_Impl_12 No write cipherstate for epoch " + std::to_string(epoch));
92 }
93 return i->second;
94}
95
96std::vector<X509_Certificate> Channel_Impl_12::peer_cert_chain() const {
97 if(auto active = active_state()) {
98 return get_peer_cert_chain(*active);
99 }
100 return std::vector<X509_Certificate>();
101}
102
103std::optional<std::string> Channel_Impl_12::external_psk_identity() const {
104 const auto* state = (active_state() != nullptr) ? active_state() : pending_state();
105 if(state) {
106 return state->psk_identity();
107 } else {
108 return std::nullopt;
109 }
110}
111
113 if(pending_state()) {
114 throw Internal_Error("create_handshake_state called during handshake");
115 }
116
117 if(auto active = active_state()) {
118 Protocol_Version active_version = active->version();
119
120 if(active_version.is_datagram_protocol() != version.is_datagram_protocol()) {
121 throw TLS_Exception(Alert::ProtocolVersion,
122 "Active state using version " + active_version.to_string() + " cannot change to " +
123 version.to_string() + " in pending");
124 }
125 }
126
127 if(!m_sequence_numbers) {
128 if(version.is_datagram_protocol()) {
129 m_sequence_numbers = std::make_unique<Datagram_Sequence_Numbers>();
130 } else {
131 m_sequence_numbers = std::make_unique<Stream_Sequence_Numbers>();
132 }
133 }
134
135 using namespace std::placeholders;
136
137 std::unique_ptr<Handshake_IO> io;
138 if(version.is_datagram_protocol()) {
139 io =
140 std::make_unique<Datagram_Handshake_IO>(std::bind(&Channel_Impl_12::send_record_under_epoch, this, _1, _2, _3),
141 sequence_numbers(),
142 static_cast<uint16_t>(policy().dtls_default_mtu()),
143 policy().dtls_initial_timeout(),
144 policy().dtls_maximum_timeout());
145 } else {
146 io = std::make_unique<Stream_Handshake_IO>(std::bind(&Channel_Impl_12::send_record, this, _1, _2));
147 }
148
149 m_pending_state = new_handshake_state(std::move(io));
150
151 if(auto active = active_state()) {
152 m_pending_state->set_version(active->version());
153 }
154
155 return *m_pending_state;
156}
157
159 if(m_pending_state) {
160 return m_pending_state->handshake_io().timeout_check();
161 }
162
163 //FIXME: scan cipher suites and remove epochs older than 2*MSL
164 return false;
165}
166
167void Channel_Impl_12::renegotiate(bool force_full_renegotiation) {
168 if(pending_state()) { // currently in handshake?
169 return;
170 }
171
172 if(auto active = active_state()) {
173 if(force_full_renegotiation == false) {
174 force_full_renegotiation = !policy().allow_resumption_for_renegotiation();
175 }
176
177 initiate_handshake(create_handshake_state(active->version()), force_full_renegotiation);
178 } else {
179 throw Invalid_State("Cannot renegotiate on inactive connection");
180 }
181}
182
184 throw Invalid_Argument("cannot update traffic keys on a TLS 1.2 channel");
185}
186
188 auto pending = pending_state();
189
190 BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello");
191
192 if(pending->server_hello()->compression_method() != 0) {
193 throw Internal_Error("Negotiated unknown compression algorithm");
194 }
195
196 sequence_numbers().new_read_cipher_state();
197
198 const uint16_t epoch = sequence_numbers().current_read_epoch();
199
200 BOTAN_ASSERT(!m_read_cipher_states.contains(epoch), "No read cipher state currently set for next epoch");
201
202 // flip side as we are reading
203 std::shared_ptr<Connection_Cipher_State> read_state(
204 new Connection_Cipher_State(pending->version(),
206 false,
207 pending->ciphersuite(),
208 pending->session_keys(),
209 pending->server_hello()->supports_encrypt_then_mac()));
210
211 m_read_cipher_states[epoch] = read_state;
212}
213
215 auto pending = pending_state();
216
217 BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello");
218
219 if(pending->server_hello()->compression_method() != 0) {
220 throw Internal_Error("Negotiated unknown compression algorithm");
221 }
222
223 sequence_numbers().new_write_cipher_state();
224
225 const uint16_t epoch = sequence_numbers().current_write_epoch();
226
227 BOTAN_ASSERT(!m_write_cipher_states.contains(epoch), "No write cipher state currently set for next epoch");
228
229 std::shared_ptr<Connection_Cipher_State> write_state(
230 new Connection_Cipher_State(pending->version(),
231 side,
232 true,
233 pending->ciphersuite(),
234 pending->session_keys(),
235 pending->server_hello()->supports_encrypt_then_mac()));
236
237 m_write_cipher_states[epoch] = write_state;
238}
239
241 return (active_state() != nullptr);
242}
243
245 return !is_closed() && is_handshake_complete();
246}
247
249 return m_has_been_closed;
250}
251
253 std::swap(m_active_state, m_pending_state);
254 m_pending_state.reset();
255
256 if(!m_active_state->version().is_datagram_protocol()) {
257 // TLS is easy just remove all but the current state
258 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
259
260 const auto not_current_epoch = [current_epoch](uint16_t epoch) { return (epoch != current_epoch); };
261
262 map_remove_if(not_current_epoch, m_write_cipher_states);
263 map_remove_if(not_current_epoch, m_read_cipher_states);
264 }
265
267}
268
269size_t Channel_Impl_12::from_peer(std::span<const uint8_t> data) {
270 const bool allow_epoch0_restart = m_is_datagram && m_is_server && policy().allow_dtls_epoch0_restart();
271
272 auto input = data.data();
273 auto input_size = data.size();
274
275 try {
276 while(input_size) {
277 size_t consumed = 0;
278
279 auto get_epoch = [this](uint16_t epoch) { return read_cipher_state_epoch(epoch); };
280
281 const Record_Header record = read_record(m_is_datagram,
282 m_readbuf,
283 input,
284 input_size,
285 consumed,
286 m_record_buf,
287 m_sequence_numbers.get(),
288 get_epoch,
289 allow_epoch0_restart);
290
291 const size_t needed = record.needed();
292
293 BOTAN_ASSERT(consumed > 0, "Got to eat something");
294
295 BOTAN_ASSERT(consumed <= input_size, "Record reader consumed sane amount");
296
297 input += consumed;
298 input_size -= consumed;
299
300 BOTAN_ASSERT(input_size == 0 || needed == 0, "Got a full record or consumed all input");
301
302 if(input_size == 0 && needed != 0) {
303 return needed; // need more data to complete record
304 }
305
306 // Ignore invalid records in DTLS
307 if(m_is_datagram && record.type() == Record_Type::Invalid) {
308 return 0;
309 }
310
311 if(m_record_buf.size() > MAX_PLAINTEXT_SIZE) {
312 throw TLS_Exception(Alert::RecordOverflow, "TLS plaintext record is larger than allowed maximum");
313 }
314
315 const bool epoch0_restart = m_is_datagram && record.epoch() == 0 && active_state();
316 BOTAN_ASSERT_IMPLICATION(epoch0_restart, allow_epoch0_restart, "Allowed state");
317
318 const bool initial_record = epoch0_restart || (!pending_state() && !active_state());
319
320 if(record.type() != Record_Type::Alert) {
321 if(initial_record) {
322 // For initial records just check for basic sanity
323 if(record.version().major_version() != 3 && record.version().major_version() != 0xFE) {
324 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version in initial record");
325 }
326 } else if(auto pending = pending_state()) {
327 if(pending->server_hello() != nullptr && record.version() != pending->version()) {
328 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version");
329 }
330 } else if(auto active = active_state()) {
331 if(record.version() != active->version()) {
332 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version");
333 }
334 }
335 }
336
337 if(record.type() == Record_Type::Handshake || record.type() == Record_Type::ChangeCipherSpec) {
338 if(m_has_been_closed) {
339 throw TLS_Exception(Alert::UnexpectedMessage, "Received handshake data after connection closure");
340 }
341 process_handshake_ccs(m_record_buf, record.sequence(), record.type(), record.version(), epoch0_restart);
342 } else if(record.type() == Record_Type::ApplicationData) {
343 if(m_has_been_closed) {
344 throw TLS_Exception(Alert::UnexpectedMessage, "Received application data after connection closure");
345 }
346 if(pending_state() != nullptr) {
347 throw TLS_Exception(Alert::UnexpectedMessage, "Can't interleave application and handshake data");
348 }
349 process_application_data(record.sequence(), m_record_buf);
350 } else if(record.type() == Record_Type::Alert) {
351 process_alert(m_record_buf);
352 } else if(record.type() != Record_Type::Invalid) {
353 throw Unexpected_Message("Unexpected record type " + std::to_string(static_cast<size_t>(record.type())) +
354 " from counterparty");
355 }
356 }
357
358 return 0; // on a record boundary
359 } catch(TLS_Exception& e) {
361 throw;
363 send_fatal_alert(Alert::BadRecordMac);
364 throw;
365 } catch(Decoding_Error&) {
366 send_fatal_alert(Alert::DecodeError);
367 throw;
368 } catch(...) {
369 send_fatal_alert(Alert::InternalError);
370 throw;
371 }
372}
373
374void Channel_Impl_12::process_handshake_ccs(const secure_vector<uint8_t>& record,
375 uint64_t record_sequence,
376 Record_Type record_type,
377 Protocol_Version record_version,
378 bool epoch0_restart) {
379 if(!m_pending_state) {
380 // No pending handshake, possibly new:
381 if(record_version.is_datagram_protocol() && !epoch0_restart) {
382 if(m_sequence_numbers) {
383 /*
384 * Might be a peer retransmit under epoch - 1 in which
385 * case we must retransmit last flight
386 */
387 sequence_numbers().read_accept(record_sequence);
388
389 const uint16_t epoch = record_sequence >> 48;
390
391 if(epoch == sequence_numbers().current_read_epoch()) {
392 create_handshake_state(record_version);
393 } else if(epoch == sequence_numbers().current_read_epoch() - 1) {
394 BOTAN_ASSERT(m_active_state, "Have active state here");
395 m_active_state->handshake_io().add_record(record.data(), record.size(), record_type, record_sequence);
396 }
397 } else {
398 create_handshake_state(record_version);
399 }
400 } else {
401 create_handshake_state(record_version);
402 }
403 }
404
405 // May have been created in above conditional
406 if(m_pending_state) {
407 m_pending_state->handshake_io().add_record(record.data(), record.size(), record_type, record_sequence);
408
409 while(auto pending = m_pending_state.get()) {
410 auto msg = pending->get_next_handshake_msg();
411
412 if(msg.first == Handshake_Type::None) { // no full handshake yet
413 break;
414 }
415
416 process_handshake_msg(active_state(), *pending, msg.first, msg.second, epoch0_restart);
417
418 if(!m_pending_state) {
419 break;
420 }
421 }
422 }
423}
424
425void Channel_Impl_12::process_application_data(uint64_t seq_no, const secure_vector<uint8_t>& record) {
426 if(!active_state()) {
427 throw Unexpected_Message("Application data before handshake done");
428 }
429
430 callbacks().tls_record_received(seq_no, record);
431}
432
433void Channel_Impl_12::process_alert(const secure_vector<uint8_t>& record) {
434 Alert alert_msg(record);
435
436 if(alert_msg.type() == Alert::NoRenegotiation) {
437 m_pending_state.reset();
438 }
439
440 callbacks().tls_alert(alert_msg);
441
442 if(alert_msg.is_fatal()) {
443 if(auto active = active_state()) {
444 const auto& session_id = active->server_hello()->session_id();
445 if(!session_id.empty()) {
446 session_manager().remove(session_id);
447 }
448 }
449 }
450
451 if(alert_msg.type() == Alert::CloseNotify) {
452 // TLS 1.2 requires us to immediately react with our "close_notify",
453 // the return value of the application's callback has no effect on that.
455 send_warning_alert(Alert::CloseNotify); // reply in kind
456 }
457
458 if(alert_msg.type() == Alert::CloseNotify || alert_msg.is_fatal()) {
459 m_has_been_closed = true;
460 }
461}
462
463void Channel_Impl_12::write_record(Connection_Cipher_State* cipher_state,
464 uint16_t epoch,
465 Record_Type record_type,
466 const uint8_t input[],
467 size_t length) {
468 BOTAN_ASSERT(m_pending_state || m_active_state, "Some connection state exists");
469
470 const Protocol_Version record_version =
471 (m_pending_state) ? (m_pending_state->version()) : (m_active_state->version());
472
473 const uint64_t next_seq = sequence_numbers().next_write_sequence(epoch);
474
475 if(cipher_state == nullptr) {
476 TLS::write_unencrypted_record(m_writebuf, record_type, record_version, next_seq, input, length);
477 } else {
478 TLS::write_record(m_writebuf, record_type, record_version, next_seq, input, length, *cipher_state, rng());
479 }
480
481 callbacks().tls_emit_data(m_writebuf);
482}
483
484void Channel_Impl_12::send_record_array(uint16_t epoch, Record_Type type, const uint8_t input[], size_t length) {
485 if(length == 0) {
486 return;
487 }
488
489 auto cipher_state = write_cipher_state_epoch(epoch);
490
491 while(length) {
492 const size_t sending = std::min<size_t>(length, MAX_PLAINTEXT_SIZE);
493 write_record(cipher_state.get(), epoch, type, input, sending);
494
495 input += sending;
496 length -= sending;
497 }
498}
499
500void Channel_Impl_12::send_record(Record_Type record_type, const std::vector<uint8_t>& record) {
501 send_record_array(sequence_numbers().current_write_epoch(), record_type, record.data(), record.size());
502}
503
504void Channel_Impl_12::send_record_under_epoch(uint16_t epoch,
505 Record_Type record_type,
506 const std::vector<uint8_t>& record) {
507 send_record_array(epoch, record_type, record.data(), record.size());
508}
509
510void Channel_Impl_12::to_peer(std::span<const uint8_t> data) {
511 if(!is_active()) {
512 throw Invalid_State("Data cannot be sent on inactive TLS connection");
513 }
514
515 send_record_array(sequence_numbers().current_write_epoch(), Record_Type::ApplicationData, data.data(), data.size());
516}
517
519 const bool ready_to_send_anything = !is_closed() && m_sequence_numbers;
520 if(alert.is_valid() && ready_to_send_anything) {
521 try {
522 send_record(Record_Type::Alert, alert.serialize());
523 } catch(...) { /* swallow it */
524 }
525 }
526
527 if(alert.type() == Alert::NoRenegotiation) {
528 m_pending_state.reset();
529 }
530
531 if(alert.is_fatal()) {
532 if(auto active = active_state()) {
533 const auto& session_id = active->server_hello()->session_id();
534 if(!session_id.empty()) {
535 session_manager().remove(Session_ID(session_id));
536 }
537 }
538 reset_state();
539 }
540
541 if(alert.type() == Alert::CloseNotify || alert.is_fatal()) {
542 m_has_been_closed = true;
543 }
544}
545
547 const bool secure_renegotiation = client_hello->secure_renegotiation();
548
549 if(auto active = active_state()) {
550 const bool active_sr = active->client_hello()->secure_renegotiation();
551
552 if(active_sr != secure_renegotiation) {
553 throw TLS_Exception(Alert::HandshakeFailure, "Client changed its mind about secure renegotiation");
554 }
555 }
556
557 if(secure_renegotiation) {
558 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
559
561 throw TLS_Exception(Alert::HandshakeFailure, "Client sent bad values for secure renegotiation");
562 }
563 }
564}
565
567 const bool secure_renegotiation = server_hello->secure_renegotiation();
568
569 if(auto active = active_state()) {
570 const bool active_sr = active->server_hello()->secure_renegotiation();
571
572 if(active_sr != secure_renegotiation) {
573 throw TLS_Exception(Alert::HandshakeFailure, "Server changed its mind about secure renegotiation");
574 }
575 }
576
577 if(secure_renegotiation) {
578 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
579
581 throw TLS_Exception(Alert::HandshakeFailure, "Server sent bad values for secure renegotiation");
582 }
583 }
584}
585
587 if(auto active = active_state()) {
588 return active->client_finished()->verify_data();
589 }
590 return std::vector<uint8_t>();
591}
592
594 if(auto active = active_state()) {
595 std::vector<uint8_t> buf = active->client_finished()->verify_data();
596 buf += active->server_finished()->verify_data();
597 return buf;
598 }
599
600 return std::vector<uint8_t>();
601}
602
604 if(auto active = active_state()) {
605 return active->server_hello()->secure_renegotiation();
606 }
607
608 if(auto pending = pending_state()) {
609 if(auto hello = pending->server_hello()) {
610 return hello->secure_renegotiation();
611 }
612 }
613
614 return false;
615}
616
618 std::string_view context,
619 size_t length) const {
620 if(auto active = active_state()) {
621 if(pending_state() != nullptr) {
622 throw Invalid_State("Channel_Impl_12::key_material_export cannot export during renegotiation");
623 }
624
625 auto prf = active->protocol_specific_prf();
626
627 const secure_vector<uint8_t>& master_secret = active->session_keys().master_secret();
628
629 std::vector<uint8_t> salt;
630 salt += active->client_hello()->random();
631 salt += active->server_hello()->random();
632
633 if(!context.empty()) {
634 size_t context_size = context.length();
635 if(context_size > 0xFFFF) {
636 throw Invalid_Argument("key_material_export context is too long");
637 }
638 salt.push_back(get_byte<0>(static_cast<uint16_t>(context_size)));
639 salt.push_back(get_byte<1>(static_cast<uint16_t>(context_size)));
640 salt += to_byte_vector(context);
641 }
642
643 return SymmetricKey(prf->derive_key(length, master_secret, salt, to_byte_vector(label)));
644 } else {
645 throw Invalid_State("Channel_Impl_12::key_material_export connection not active");
646 }
647}
648
649} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
Definition assert.h:77
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:50
bool is_valid() const
Definition tls_alert.h:77
std::vector< uint8_t > serialize() const
Definition tls_alert.cpp:32
bool is_fatal() const
Definition tls_alert.h:88
Type type() const
Definition tls_alert.h:93
virtual void tls_session_activated()
virtual void tls_record_received(uint64_t seq_no, std::span< const uint8_t > data)=0
virtual void tls_alert(Alert alert)=0
virtual bool tls_peer_closed_connection()
virtual void tls_emit_data(std::span< const uint8_t > data)=0
RandomNumberGenerator & rng()
virtual std::vector< X509_Certificate > get_peer_cert_chain(const Handshake_State &state) const =0
void change_cipher_spec_reader(Connection_Side side)
void update_traffic_keys(bool request_peer_update=false) override
Handshake_State & create_handshake_state(Protocol_Version version)
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const
bool is_handshake_complete() const override
size_t from_peer(std::span< const uint8_t > data) override
void secure_renegotiation_check(const Client_Hello_12 *client_hello)
Session_Manager & session_manager()
const Policy & policy() const
void send_alert(const Alert &alert) override
virtual void initiate_handshake(Handshake_State &state, bool force_full_renegotiation)=0
std::vector< X509_Certificate > peer_cert_chain() const override
void to_peer(std::span< const uint8_t > data) override
void change_cipher_spec_writer(Connection_Side side)
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const
virtual std::unique_ptr< Handshake_State > new_handshake_state(std::unique_ptr< class Handshake_IO > io)=0
Channel_Impl_12(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< RandomNumberGenerator > &rng, const std::shared_ptr< const Policy > &policy, bool is_server, bool is_datagram, size_t io_buf_sz=TLS::Channel::IO_BUF_DEFAULT_SIZE)
SymmetricKey key_material_export(std::string_view label, std::string_view context, size_t length) const override
std::optional< std::string > external_psk_identity() const override
virtual void process_handshake_msg(const Handshake_State *active_state, Handshake_State &pending_state, Handshake_Type type, const std::vector< uint8_t > &contents, bool epoch0_restart)=0
bool secure_renegotiation_supported() const override
void renegotiate(bool force_full_renegotiation=false) override
void send_warning_alert(Alert::Type type)
void send_fatal_alert(Alert::Type type)
std::vector< uint8_t > renegotiation_info() const
virtual uint16_t current_read_epoch() const =0
virtual void read_accept(uint64_t seq)=0
virtual uint16_t current_write_epoch() const =0
virtual uint64_t next_write_sequence(uint16_t)=0
virtual bool allow_dtls_epoch0_restart() const
virtual bool allow_resumption_for_renegotiation() const
std::string to_string() const
uint8_t major_version() const
Definition tls_version.h:78
Protocol_Version version() const
Definition tls_record.h:80
Record_Type type() const
Definition tls_record.h:92
uint64_t sequence() const
Definition tls_record.h:85
size_t needed() const
Definition tls_record.h:78
uint16_t epoch() const
Definition tls_record.h:90
std::vector< uint8_t > renegotiation_info() const
virtual size_t remove(const Session_Handle &handle)=0
Alert::Type type() const
Definition tls_exceptn.h:21
Record_Header read_record(bool is_datagram, secure_vector< uint8_t > &readbuf, const uint8_t input[], size_t input_len, size_t &consumed, secure_vector< uint8_t > &recbuf, Connection_Sequence_Numbers *sequence_numbers, const get_cipherstate_fn &get_cipherstate, bool allow_epoch0_restart)
@ MAX_PLAINTEXT_SIZE
Definition tls_magic.h:30
void write_unencrypted_record(secure_vector< uint8_t > &output, Record_Type record_type, Protocol_Version version, uint64_t record_sequence, const uint8_t *message, size_t message_len)
void write_record(secure_vector< uint8_t > &output, Record_Type record_type, Protocol_Version version, uint64_t record_sequence, const uint8_t *message, size_t message_len, Connection_Cipher_State &cs, RandomNumberGenerator &rng)
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
Definition tls_session.h:32
void map_remove_if(Pred pred, T &assoc)
Definition stl_util.h:128
T to_byte_vector(std::string_view s)
Definition stl_util.h:30
OctetString SymmetricKey
Definition symkey.h:141
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61