9#include <botan/internal/tls_channel_impl_12.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>
24 const std::shared_ptr<Session_Manager>& session_manager,
25 const std::shared_ptr<RandomNumberGenerator>& rng,
26 const std::shared_ptr<const Policy>& policy,
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),
36 m_has_been_closed(false) {
43 m_write_cipher_states[0] =
nullptr;
44 m_read_cipher_states[0] =
nullptr;
46 m_writebuf.reserve(reserved_io_buffer_size);
47 m_readbuf.reserve(reserved_io_buffer_size);
50void Channel_Impl_12::reset_state() {
51 m_active_state.reset();
52 m_pending_state.reset();
54 m_write_cipher_states.clear();
55 m_read_cipher_states.clear();
61 m_active_state.reset();
62 m_read_cipher_states.clear();
63 m_write_cipher_states.clear();
65 m_write_cipher_states[0] =
nullptr;
66 m_read_cipher_states[0] =
nullptr;
68 if(m_sequence_numbers) {
69 m_sequence_numbers->reset();
76 BOTAN_ASSERT(m_sequence_numbers,
"Have a sequence numbers object");
77 return *m_sequence_numbers;
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));
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));
97 if(
auto active = active_state()) {
100 return std::vector<X509_Certificate>();
104 if(pending_state()) {
105 throw Internal_Error(
"create_handshake_state called during handshake");
108 if(
auto active = active_state()) {
113 "Active state using version " + active_version.
to_string() +
" cannot change to " +
118 if(!m_sequence_numbers) {
120 m_sequence_numbers = std::make_unique<Datagram_Sequence_Numbers>();
122 m_sequence_numbers = std::make_unique<Stream_Sequence_Numbers>();
126 using namespace std::placeholders;
128 std::unique_ptr<Handshake_IO> io;
131 std::make_unique<Datagram_Handshake_IO>(std::bind(&Channel_Impl_12::send_record_under_epoch,
this, _1, _2, _3),
133 static_cast<uint16_t
>(
policy().dtls_default_mtu()),
134 policy().dtls_initial_timeout(),
135 policy().dtls_maximum_timeout());
137 io = std::make_unique<Stream_Handshake_IO>(std::bind(&Channel_Impl_12::send_record,
this, _1, _2));
142 if(
auto active = active_state()) {
143 m_pending_state->set_version(active->version());
146 return *m_pending_state;
150 if(m_pending_state) {
151 return m_pending_state->handshake_io().timeout_check();
159 if(pending_state()) {
163 if(
auto active = active_state()) {
164 if(force_full_renegotiation ==
false) {
170 throw Invalid_State(
"Cannot renegotiate on inactive connection");
179 auto pending = pending_state();
181 BOTAN_ASSERT(pending && pending->server_hello(),
"Have received server hello");
183 if(pending->server_hello()->compression_method() != 0) {
191 BOTAN_ASSERT(!m_read_cipher_states.contains(epoch),
"No read cipher state currently set for next epoch");
194 std::shared_ptr<Connection_Cipher_State> read_state(
198 pending->ciphersuite(),
199 pending->session_keys(),
200 pending->server_hello()->supports_encrypt_then_mac()));
202 m_read_cipher_states[epoch] = read_state;
206 auto pending = pending_state();
208 BOTAN_ASSERT(pending && pending->server_hello(),
"Have received server hello");
210 if(pending->server_hello()->compression_method() != 0) {
218 BOTAN_ASSERT(!m_write_cipher_states.contains(epoch),
"No write cipher state currently set for next epoch");
220 std::shared_ptr<Connection_Cipher_State> write_state(
224 pending->ciphersuite(),
225 pending->session_keys(),
226 pending->server_hello()->supports_encrypt_then_mac()));
228 m_write_cipher_states[epoch] = write_state;
235 return (active_state() !=
nullptr);
239 return m_has_been_closed;
243 std::swap(m_active_state, m_pending_state);
244 m_pending_state.reset();
246 if(!m_active_state->version().is_datagram_protocol()) {
250 const auto not_current_epoch = [current_epoch](uint16_t epoch) {
return (epoch != current_epoch); };
262 auto input = data.data();
263 auto input_size = data.size();
269 auto get_epoch = [
this](uint16_t epoch) {
return read_cipher_state_epoch(epoch); };
277 m_sequence_numbers.get(),
279 allow_epoch0_restart);
281 const size_t needed = record.
needed();
285 BOTAN_ASSERT(consumed <= input_size,
"Record reader consumed sane amount");
288 input_size -= consumed;
290 BOTAN_ASSERT(input_size == 0 || needed == 0,
"Got a full record or consumed all input");
292 if(input_size == 0 && needed != 0) {
302 throw TLS_Exception(Alert::RecordOverflow,
"TLS plaintext record is larger than allowed maximum");
305 const bool epoch0_restart = m_is_datagram && record.
epoch() == 0 && active_state();
308 const bool initial_record = epoch0_restart || (!pending_state() && !active_state());
314 throw TLS_Exception(Alert::ProtocolVersion,
"Received unexpected record version in initial record");
316 }
else if(
auto pending = pending_state()) {
317 if(pending->server_hello() !=
nullptr && record.
version() != pending->version()) {
318 throw TLS_Exception(Alert::ProtocolVersion,
"Received unexpected record version");
320 }
else if(
auto active = active_state()) {
321 if(record.
version() != active->version()) {
322 throw TLS_Exception(Alert::ProtocolVersion,
"Received unexpected record version");
328 if(m_has_been_closed) {
329 throw TLS_Exception(Alert::UnexpectedMessage,
"Received handshake data after connection closure");
331 process_handshake_ccs(m_record_buf, record.
sequence(), record.
type(), record.
version(), epoch0_restart);
333 if(m_has_been_closed) {
334 throw TLS_Exception(Alert::UnexpectedMessage,
"Received application data after connection closure");
336 if(pending_state() !=
nullptr) {
337 throw TLS_Exception(Alert::UnexpectedMessage,
"Can't interleave application and handshake data");
339 process_application_data(record.
sequence(), m_record_buf);
341 process_alert(m_record_buf);
344 " from counterparty");
365 uint64_t record_sequence,
368 bool epoch0_restart) {
369 if(!m_pending_state) {
372 if(m_sequence_numbers) {
379 const uint16_t epoch = record_sequence >> 48;
381 if(epoch == sequence_numbers().current_read_epoch()) {
383 }
else if(epoch == sequence_numbers().current_read_epoch() - 1) {
385 m_active_state->handshake_io().add_record(record.data(), record.size(), record_type, record_sequence);
396 if(m_pending_state) {
397 m_pending_state->handshake_io().add_record(record.data(), record.size(), record_type, record_sequence);
399 while(
auto pending = m_pending_state.get()) {
400 auto msg = pending->get_next_handshake_msg();
408 if(!m_pending_state) {
415void Channel_Impl_12::process_application_data(uint64_t seq_no,
const secure_vector<uint8_t>& record) {
416 if(!active_state()) {
417 throw Unexpected_Message(
"Application data before handshake done");
423void Channel_Impl_12::process_alert(
const secure_vector<uint8_t>& record) {
424 Alert alert_msg(record);
426 if(alert_msg.type() == Alert::NoRenegotiation) {
427 m_pending_state.reset();
432 if(alert_msg.is_fatal()) {
433 if(
auto active = active_state()) {
434 const auto& session_id = active->server_hello()->session_id();
435 if(!session_id.empty()) {
441 if(alert_msg.type() == Alert::CloseNotify) {
448 if(alert_msg.type() == Alert::CloseNotify || alert_msg.is_fatal()) {
449 m_has_been_closed =
true;
453void Channel_Impl_12::write_record(Connection_Cipher_State* cipher_state,
456 const uint8_t input[],
458 BOTAN_ASSERT(m_pending_state || m_active_state,
"Some connection state exists");
460 const Protocol_Version record_version =
461 (m_pending_state) ? (m_pending_state->version()) : (m_active_state->version());
465 if(cipher_state ==
nullptr) {
468 TLS::write_record(m_writebuf, record_type, record_version, next_seq, input, length, *cipher_state,
rng());
474void Channel_Impl_12::send_record_array(uint16_t epoch,
Record_Type type,
const uint8_t input[],
size_t length) {
479 auto cipher_state = write_cipher_state_epoch(epoch);
483 write_record(cipher_state.get(), epoch, type, input, sending);
490void Channel_Impl_12::send_record(
Record_Type record_type,
const std::vector<uint8_t>& record) {
491 send_record_array(sequence_numbers().current_write_epoch(), record_type, record.data(), record.size());
494void Channel_Impl_12::send_record_under_epoch(uint16_t epoch,
496 const std::vector<uint8_t>& record) {
497 send_record_array(epoch, record_type, record.data(), record.size());
502 throw Invalid_State(
"Data cannot be sent on inactive TLS connection");
509 const bool ready_to_send_anything = !
is_closed() && m_sequence_numbers;
510 if(alert.
is_valid() && ready_to_send_anything) {
517 if(alert.
type() == Alert::NoRenegotiation) {
518 m_pending_state.reset();
522 if(
auto active = active_state()) {
523 const auto& session_id = active->server_hello()->session_id();
524 if(!session_id.empty()) {
531 if(alert.
type() == Alert::CloseNotify || alert.
is_fatal()) {
532 m_has_been_closed =
true;
539 if(
auto active = active_state()) {
540 const bool active_sr = active->client_hello()->secure_renegotiation();
542 if(active_sr != secure_renegotiation) {
543 throw TLS_Exception(Alert::HandshakeFailure,
"Client changed its mind about secure renegotiation");
547 if(secure_renegotiation) {
551 throw TLS_Exception(Alert::HandshakeFailure,
"Client sent bad values for secure renegotiation");
559 if(
auto active = active_state()) {
560 const bool active_sr = active->server_hello()->secure_renegotiation();
562 if(active_sr != secure_renegotiation) {
563 throw TLS_Exception(Alert::HandshakeFailure,
"Server changed its mind about secure renegotiation");
567 if(secure_renegotiation) {
571 throw TLS_Exception(Alert::HandshakeFailure,
"Server sent bad values for secure renegotiation");
577 if(
auto active = active_state()) {
578 return active->client_finished()->verify_data();
580 return std::vector<uint8_t>();
584 if(
auto active = active_state()) {
585 std::vector<uint8_t> buf = active->client_finished()->verify_data();
586 buf += active->server_finished()->verify_data();
590 return std::vector<uint8_t>();
594 if(
auto active = active_state()) {
595 return active->server_hello()->secure_renegotiation();
598 if(
auto pending = pending_state()) {
599 if(
auto hello = pending->server_hello()) {
600 return hello->secure_renegotiation();
608 std::string_view context,
609 size_t length)
const {
610 if(
auto active = active_state()) {
611 if(pending_state() !=
nullptr) {
612 throw Invalid_State(
"Channel_Impl_12::key_material_export cannot export during renegotiation");
615 auto prf = active->protocol_specific_prf();
619 std::vector<uint8_t> salt;
620 salt += active->client_hello()->random();
621 salt += active->server_hello()->random();
623 if(!context.empty()) {
624 size_t context_size = context.length();
625 if(context_size > 0xFFFF) {
628 salt.push_back(get_byte<0>(
static_cast<uint16_t
>(context_size)));
629 salt.push_back(get_byte<1>(
static_cast<uint16_t
>(context_size)));
635 throw Invalid_State(
"Channel_Impl_12::key_material_export connection not active");
#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 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
bool is_closed() const override
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
Callbacks & callbacks() const
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 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
void reset_active_association_state()
virtual ~Channel_Impl_12()
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
bool secure_renegotiation() 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 void new_read_cipher_state()=0
virtual void new_write_cipher_state()=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
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
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)
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
void map_remove_if(Pred pred, T &assoc)
std::vector< uint8_t > to_byte_vector(std::string_view s)
std::vector< T, secure_allocator< T > > secure_vector