9#include <botan/internal/tls_channel_impl_12.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>
30bool is_new_dtls_association_client_hello(std::span<const uint8_t> msg_and_header,
Record_Type record_type) {
31 constexpr size_t DTLS_HANDSHAKE_HEADER_SIZE = 12;
38 load_be(msg_and_header.subspan<4, 2>()) == 0;
48constexpr size_t TLS_RETAINED_CIPHERSTATES = 2;
52constexpr uint64_t TCP_MSL_MS = 2 * 60 * 1000;
55void prune_old_cipher_states(std::map<uint16_t, T>& states) {
59 size_t non_zero = states.size() - states.count(0);
60 auto it = states.lower_bound(1);
61 while(non_zero > TLS_RETAINED_CIPHERSTATES) {
62 it = states.erase(it);
74void absorb_malformed_input_errors(
bool absorb, F fn) {
81 }
catch(
const Decoding_Error&) {
92 const std::shared_ptr<RandomNumberGenerator>&
rng,
93 const std::shared_ptr<const Policy>&
policy,
96 size_t reserved_io_buffer_size) :
97 m_is_server(is_server),
98 m_is_datagram(is_datagram),
103 m_has_been_closed(false) {
110 m_write_cipher_states[0] =
nullptr;
111 m_read_cipher_states[0] = {};
113 m_writebuf.reserve(reserved_io_buffer_size);
114 m_readbuf.reserve(reserved_io_buffer_size);
117void Channel_Impl_12::reset_state() {
118 m_active_state.reset();
119 m_pending_state.reset();
120 m_epochs_before_latest_renegotiation.reset();
121 m_resumption_handle.reset();
123 m_write_cipher_states.clear();
124 m_read_cipher_states.clear();
128 m_resumption_handle = std::move(handle);
131std::vector<Session_Handle> Channel_Impl_12::take_sessions_to_invalidate() {
134 std::vector<Session_Handle> handles;
136 if(m_resumption_handle.has_value()) {
137 handles.push_back(m_resumption_handle.value());
138 m_resumption_handle.reset();
141 if(m_active_state.has_value()) {
142 const auto& sid = m_active_state->session_id();
144 handles.emplace_back(sid);
151void Channel_Impl_12::invalidate_sessions(
const std::vector<Session_Handle>& handles) {
162 for(
const auto& handle : handles) {
172 m_active_state.reset();
173 m_read_cipher_states.clear();
174 m_write_cipher_states.clear();
176 m_write_cipher_states[0] =
nullptr;
177 m_read_cipher_states[0] = {};
179 if(m_sequence_numbers) {
180 m_sequence_numbers->reset();
187 BOTAN_ASSERT(m_sequence_numbers,
"Have a sequence numbers object");
188 return *m_sequence_numbers;
191std::shared_ptr<Connection_Cipher_State> Channel_Impl_12::read_cipher_state_epoch(uint16_t epoch)
const {
192 auto i = m_read_cipher_states.find(epoch);
193 if(i == m_read_cipher_states.end()) {
194 throw Internal_Error(
"TLS::Channel_Impl_12 No read cipherstate for epoch " + std::to_string(epoch));
202 if(
const auto& retired_at = i->second.retired_at; retired_at.has_value()) {
204 const auto retired = retired_at.value();
206 if(now - retired > TCP_MSL_MS) {
207 throw Invalid_State(
"TLS::Channel_Impl_12 Read cipherstate for epoch " + std::to_string(epoch) +
208 " is past its retention window");
212 return i->second.state;
215std::shared_ptr<Connection_Cipher_State> Channel_Impl_12::write_cipher_state_epoch(uint16_t epoch)
const {
216 auto i = m_write_cipher_states.find(epoch);
217 if(i == m_write_cipher_states.end()) {
218 throw Internal_Error(
"TLS::Channel_Impl_12 No write cipherstate for epoch " + std::to_string(epoch));
224 if(m_active_state.has_value()) {
225 return m_active_state->peer_certs();
227 return std::vector<X509_Certificate>();
231 if(m_active_state.has_value()) {
232 return m_active_state->psk_identity();
234 if(
const auto* state = pending_state()) {
235 return state->psk_identity();
241 if(pending_state() !=
nullptr) {
242 throw Internal_Error(
"create_handshake_state called during handshake");
245 if(m_active_state.has_value()) {
250 "Active state using version " + active_version.
to_string() +
" cannot change to " +
255 if(!m_sequence_numbers) {
257 m_sequence_numbers = std::make_unique<Datagram_Sequence_Numbers>();
259 m_sequence_numbers = std::make_unique<Stream_Sequence_Numbers>();
267 m_epochs_before_latest_renegotiation = Epochs_Before_Latest_Renegotiation{sequence_numbers().current_read_epoch(),
268 sequence_numbers().current_write_epoch()};
278 const uint16_t initial_epoch = epoch0_restart ? 0 : m_epochs_before_latest_renegotiation->read_epoch;
280 using namespace std::placeholders;
282 std::unique_ptr<Handshake_IO> io;
289 auto send_record_f = [
this](uint16_t epoch,
Record_Type record_type,
const std::vector<uint8_t>& record) {
290 send_record_under_epoch(epoch, record_type, record);
293 io = std::make_unique<Datagram_Handshake_IO>(send_record_f,
300 policy().maximum_handshake_message_size(),
303 auto send_record_f = [
this](
Record_Type rec_type,
const std::vector<uint8_t>& record) {
304 send_record(rec_type, record);
306 io = std::make_unique<Stream_Handshake_IO>(send_record_f);
311 if(m_active_state.has_value()) {
312 m_pending_state->set_version(m_active_state->version());
315 return *m_pending_state;
318bool Channel_Impl_12::pending_handshake_epochs_unmoved()
const {
321 if(!m_pending_state || !m_epochs_before_latest_renegotiation.has_value()) {
327 return sequence_numbers().
current_read_epoch() == m_epochs_before_latest_renegotiation->read_epoch &&
328 sequence_numbers().
current_write_epoch() == m_epochs_before_latest_renegotiation->write_epoch;
331void Channel_Impl_12::clear_pending_handshake_state() {
332 m_pending_state.reset();
333 m_epochs_before_latest_renegotiation.reset();
342void Channel_Impl_12::abandon_timed_out_handshake() {
343 if(m_active_state.has_value() && pending_handshake_epochs_unmoved()) {
347 clear_pending_handshake_state();
353 m_has_been_closed =
true;
359 if(m_is_datagram && !m_has_been_closed && m_pending_state) {
361 return m_pending_state->handshake_io().timeout_check();
363 abandon_timed_out_handshake();
374 if(pending_state() !=
nullptr) {
378 if(m_active_state.has_value()) {
383 (sequence_numbers().current_read_epoch() == 0xFFFF || sequence_numbers().current_write_epoch() == 0xFFFF)) {
384 throw Invalid_State(
"DTLS epoch counter exhausted, a new association is required");
387 if(!force_full_renegotiation) {
393 throw Invalid_State(
"Cannot renegotiate on inactive connection");
402 const auto* pending = pending_state();
404 BOTAN_ASSERT(pending && pending->server_hello(),
"Have received server hello");
406 if(pending->server_hello()->compression_method() != 0) {
410 sequence_numbers().new_read_cipher_state();
412 const uint16_t epoch = sequence_numbers().current_read_epoch();
414 BOTAN_ASSERT(!m_read_cipher_states.contains(epoch),
"No read cipher state currently set for next epoch");
417 auto read_state = std::make_shared<Connection_Cipher_State>(
421 pending->ciphersuite(),
422 pending->session_keys(),
423 pending->server_hello()->supports_encrypt_then_mac());
428 if(m_is_datagram && epoch > 1) {
429 if(
auto prev = m_read_cipher_states.find(
static_cast<uint16_t
>(epoch - 1)); prev != m_read_cipher_states.end()) {
434 m_read_cipher_states[epoch] = Retained_Read_Cipher_State{.state = read_state, .retired_at = std::nullopt};
435 prune_old_cipher_states(m_read_cipher_states);
439 const auto* pending = pending_state();
441 BOTAN_ASSERT(pending && pending->server_hello(),
"Have received server hello");
443 if(pending->server_hello()->compression_method() != 0) {
447 sequence_numbers().new_write_cipher_state();
449 const uint16_t epoch = sequence_numbers().current_write_epoch();
451 BOTAN_ASSERT(!m_write_cipher_states.contains(epoch),
"No write cipher state currently set for next epoch");
453 auto write_state = std::make_shared<Connection_Cipher_State>(pending->version(),
456 pending->ciphersuite(),
457 pending->session_keys(),
458 pending->server_hello()->supports_encrypt_then_mac());
460 m_write_cipher_states[epoch] = write_state;
461 prune_old_cipher_states(m_write_cipher_states);
465 return m_active_state.has_value();
473 if(m_is_datagram && !m_has_been_closed && m_pending_state) {
474 return m_pending_state->handshake_io().next_retransmission_timeout();
481 return m_has_been_closed;
487 const auto& state = *m_pending_state;
489 if(!state.version().is_datagram_protocol()) {
491 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
493 const auto not_current_epoch = [current_epoch](uint16_t epoch) {
return (epoch != current_epoch); };
504 const bool sent_terminal_dtls_flight = m_is_datagram && (m_is_server == (state.server_hello_done() !=
nullptr));
508 if(
auto* dtls_io = m_active_state->dtls_handshake_io()) {
512 dtls_io->finalize_handshake(sent_terminal_dtls_flight);
518 clear_pending_handshake_state();
526 const auto* input = data.data();
527 auto input_size = data.size();
530 while(input_size > 0) {
535 if(m_had_fatal_alert) {
541 auto get_epoch = [
this](uint16_t epoch) {
return read_cipher_state_epoch(epoch); };
549 m_sequence_numbers.get(),
551 allow_epoch0_restart);
553 const size_t needed = record.
needed();
557 BOTAN_ASSERT(consumed <= input_size,
"Record reader consumed sane amount");
560 input_size -= consumed;
562 BOTAN_ASSERT(input_size == 0 || needed == 0,
"Got a full record or consumed all input");
564 if(input_size == 0 && needed != 0) {
573 const bool old_unprotected_record = m_is_datagram && record.
epoch() == 0 && m_active_state.has_value() &&
574 sequence_numbers().current_read_epoch() > 0;
585 if(old_unprotected_record) {
589 throw TLS_Exception(Alert::RecordOverflow,
"TLS plaintext record is larger than allowed maximum");
592 const bool epoch0_restart = allow_epoch0_restart && record.
epoch() == 0 && m_active_state.has_value();
595 const bool initial_record = epoch0_restart || (pending_state() ==
nullptr && !m_active_state.has_value());
596 bool initial_handshake_message =
false;
606 throw TLS_Exception(Alert::ProtocolVersion,
"Received unexpected record version in initial record");
608 }
else if(
const auto* pending = pending_state()) {
609 if(pending->server_hello() !=
nullptr && !initial_handshake_message &&
610 record.
version() != pending->version()) {
611 throw TLS_Exception(Alert::ProtocolVersion,
"Received unexpected record version");
613 }
else if(m_active_state.has_value()) {
614 if(record.
version() != m_active_state->version() && !initial_handshake_message) {
615 throw TLS_Exception(Alert::ProtocolVersion,
"Received unexpected record version");
629 if(m_has_been_closed) {
630 throw TLS_Exception(Alert::UnexpectedMessage,
"Received handshake data after connection closure");
632 process_handshake_ccs(m_record_buf, record.
sequence(), record.
type(), record.
version(), epoch0_restart);
634 if(m_has_been_closed) {
635 throw TLS_Exception(Alert::UnexpectedMessage,
"Received application data after connection closure");
637 if(pending_state() !=
nullptr) {
656 if(m_is_datagram && record.
epoch() > 0) {
657 const uint16_t active_epoch =
658 m_epochs_before_latest_renegotiation ? m_epochs_before_latest_renegotiation->read_epoch : 0;
660 if(!m_active_state.has_value() || record.
epoch() > active_epoch) {
664 throw TLS_Exception(Alert::UnexpectedMessage,
"Can't interleave application and handshake data");
667 process_application_data(record.
sequence(), m_record_buf);
669 process_alert(m_record_buf);
672 " from counterparty");
693 uint64_t record_sequence,
696 bool epoch0_restart) {
697 const auto process_retransmitted_record = [&] {
698 BOTAN_ASSERT(m_active_state.has_value(),
"Have active DTLS association for retransmission");
702 const bool unauthenticated = (record_sequence >> 48) == 0;
704 absorb_malformed_input_errors(unauthenticated, [&] {
705 m_active_state->dtls_handshake_io()->add_retransmitted_record(
706 record.data(), record.size(), record_type, record_sequence);
710 if(!m_pending_state) {
714 if(epoch0_restart && m_sequence_numbers && m_active_state.has_value()) {
715 const bool starts_new_handshake = is_new_dtls_association_client_hello(record, record_type);
717 if(!starts_new_handshake) {
718 process_retransmitted_record();
723 if(m_is_datagram && !epoch0_restart) {
724 if(m_sequence_numbers) {
725 const uint16_t epoch = record_sequence >> 48;
726 const uint16_t current_epoch = sequence_numbers().current_read_epoch();
727 if(epoch == current_epoch) {
730 const bool starts_new_handshake =
735 if(m_active_state.has_value() && !starts_new_handshake) {
736 process_retransmitted_record();
740 }
else if(current_epoch > 0 && epoch == current_epoch - 1) {
741 process_retransmitted_record();
752 if(m_pending_state) {
763 const bool unauthenticated_against_active_association =
764 m_is_datagram && (record_sequence >> 48) == 0 && m_active_state.has_value();
766 absorb_malformed_input_errors(unauthenticated_against_active_association, [&] {
767 m_pending_state->handshake_io().add_record(record.data(), record.size(), record_type, record_sequence);
769 while(
auto* pending = m_pending_state.get()) {
770 auto msg = pending->get_next_handshake_msg(
policy().maximum_handshake_message_size());
778 if(!m_pending_state) {
787 if(!m_active_state.has_value()) {
788 throw Unexpected_Message(
"Application data before handshake done");
792 const uint16_t read_epoch =
793 m_is_datagram ?
static_cast<uint16_t
>(seq_no >> 48) : sequence_numbers().current_read_epoch();
794 if(read_epoch == 0) {
795 throw Unexpected_Message(
"Application data received in unexpected read epoch");
802 const Alert alert_msg(record);
816 if(alert_msg.type() == Alert::NoRenegotiation && m_active_state.has_value()) {
817 if(!pending_handshake_epochs_unmoved()) {
818 throw TLS_Exception(Alert::UnexpectedMessage,
"Received no_renegotiation after ChangeCipherSpec");
821 clear_pending_handshake_state();
824 if(alert_msg.is_fatal()) {
831 m_has_been_closed =
true;
832 m_had_fatal_alert =
true;
833 const auto invalidated = take_sessions_to_invalidate();
835 invalidate_sessions(invalidated);
840 if(alert_msg.type() == Alert::CloseNotify) {
841 m_peer_closed_connection =
true;
849 if(alert_msg.type() == Alert::CloseNotify || alert_msg.is_fatal()) {
850 m_has_been_closed =
true;
857 const uint8_t input[],
859 BOTAN_ASSERT(m_pending_state || m_active_state.has_value(),
"Some connection state exists");
861 const Protocol_Version record_version = (m_pending_state) ? (m_pending_state->version()) : m_active_state->version();
863 const uint64_t next_seq = sequence_numbers().next_write_sequence(epoch);
865 if(cipher_state ==
nullptr) {
868 TLS::write_record(m_writebuf, record_type, record_version, next_seq, input, length, *cipher_state,
rng());
874void Channel_Impl_12::send_record_array(uint16_t epoch,
Record_Type type,
const uint8_t input[],
size_t length) {
879 auto cipher_state = write_cipher_state_epoch(epoch);
883 write_record(cipher_state.get(), epoch, type, input, sending);
890void Channel_Impl_12::send_record(
Record_Type record_type,
const std::vector<uint8_t>& record) {
891 send_record_array(sequence_numbers().current_write_epoch(), record_type, record.data(), record.size());
894void Channel_Impl_12::send_record_under_epoch(uint16_t epoch,
896 const std::vector<uint8_t>& record) {
897 send_record_array(epoch, record_type, record.data(), record.size());
902 throw Invalid_State(
"Data cannot be sent on inactive TLS connection");
909 const bool ready_to_send_anything = !
is_closed() && m_sequence_numbers;
910 if(alert.
is_valid() && ready_to_send_anything) {
927 if(alert.
type() == Alert::NoRenegotiation && m_active_state.has_value()) {
928 if(pending_handshake_epochs_unmoved()) {
929 clear_pending_handshake_state();
937 m_had_fatal_alert =
true;
938 m_has_been_closed =
true;
945 const auto invalidated =
946 (alert.
type() == Alert::None) ? std::vector<Session_Handle>() : take_sessions_to_invalidate();
949 invalidate_sessions(invalidated);
952 if(alert.
type() == Alert::CloseNotify || alert.
is_fatal()) {
953 m_has_been_closed =
true;
961 if(m_active_state && m_active_state->client_supports_secure_renegotiation() != secure_renegotiation) {
962 throw TLS_Exception(Alert::HandshakeFailure,
"Client changed its mind about secure renegotiation");
965 if(secure_renegotiation) {
970 throw TLS_Exception(Alert::HandshakeFailure,
"Client sent bad values for secure renegotiation");
979 if(m_active_state && m_active_state->server_supports_secure_renegotiation() != secure_renegotiation) {
980 throw TLS_Exception(Alert::HandshakeFailure,
"Server changed its mind about secure renegotiation");
983 if(secure_renegotiation) {
988 throw TLS_Exception(Alert::HandshakeFailure,
"Server sent bad values for secure renegotiation");
994 if(m_active_state.has_value()) {
995 return m_active_state->client_finished_verify_data();
997 return std::vector<uint8_t>();
1001 if(m_active_state.has_value()) {
1002 return concat(m_active_state->client_finished_verify_data(), m_active_state->server_finished_verify_data());
1009 if(m_active_state.has_value()) {
1010 return m_active_state->server_supports_secure_renegotiation();
1013 if(
const auto* pending = pending_state()) {
1014 if(
const auto* hello = pending->server_hello()) {
1015 return hello->secure_renegotiation();
1023 std::string_view context,
1024 size_t length)
const {
1025 if(!m_active_state.has_value()) {
1026 throw Invalid_State(
"Channel_Impl_12::key_material_export connection not active");
1032 if(pending_state() !=
nullptr) {
1033 throw Invalid_State(
"Channel_Impl_12::key_material_export cannot export during renegotiation");
1038 const auto salt = [&] {
1039 if(context.empty()) {
1040 return concat(m_active_state->client_random(), m_active_state->server_random());
1042 return concat(m_active_state->client_random(),
1043 m_active_state->server_random(),
1044 store_be(
static_cast<uint16_t
>(context.size())),
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
#define BOTAN_ASSERT(expr, assertion_made)
std::vector< uint8_t > serialize() const
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 uint64_t tls_current_monotonic_clock_ms()
virtual bool tls_peer_closed_connection()
virtual void tls_emit_data(std::span< const uint8_t > data)=0
RandomNumberGenerator & rng()
bool is_closed() const override
void change_cipher_spec_reader(Connection_Side side)
void update_traffic_keys(bool request_peer_update=false) override
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const
~Channel_Impl_12() override
bool is_handshake_complete() const override
Callbacks & callbacks() const
Handshake_State & create_handshake_state(Protocol_Version version, bool epoch0_restart=false)
size_t from_peer(std::span< const uint8_t > data) override
void secure_renegotiation_check(const Client_Hello_12 *client_hello)
bool timeout_check() override
bool is_active() const override
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 note_resumption_handle(std::optional< Session_Handle > handle)
void change_cipher_spec_writer(Connection_Side side)
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const
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
void reset_active_association_state()
virtual std::unique_ptr< Handshake_State > new_handshake_state(std::unique_ptr< Handshake_IO > io)=0
std::optional< std::chrono::milliseconds > next_retransmission_timeout() 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
bool secure_renegotiation() const
virtual uint16_t current_read_epoch() const =0
virtual uint16_t current_write_epoch() const =0
virtual size_t dtls_maximum_timeout() const
virtual size_t dtls_default_mtu() const
virtual std::optional< size_t > dtls_maximum_retransmissions() 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
bool is_datagram_protocol() const
std::vector< uint8_t > renegotiation_info() const
bool secure_renegotiation() const
virtual size_t remove(const Session_Handle &handle)=0
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
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)
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)
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
constexpr auto concat(Rs &&... ranges)
std::vector< T, secure_allocator< T > > secure_vector
constexpr auto store_be(ParamTs &&... params)
constexpr auto load_be(ParamTs &&... params)