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