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