9#include <botan/tls_policy.h>
10#include <botan/tls_messages.h>
12#include <botan/internal/tls_channel_impl_12.h>
13#include <botan/internal/tls_handshake_state.h>
14#include <botan/internal/tls_record.h>
15#include <botan/internal/tls_seq_numbers.h>
16#include <botan/internal/stl_util.h>
17#include <botan/internal/loadstor.h>
18#include <botan/x509cert.h>
28 size_t reserved_io_buffer_size) :
29 m_is_server(is_server),
30 m_is_datagram(is_datagram),
31 m_callbacks(callbacks),
32 m_session_manager(session_manager),
35 m_has_been_closed(false)
38 m_write_cipher_states[0] =
nullptr;
39 m_read_cipher_states[0] =
nullptr;
41 m_writebuf.reserve(reserved_io_buffer_size);
42 m_readbuf.reserve(reserved_io_buffer_size);
45void Channel_Impl_12::reset_state()
47 m_active_state.reset();
48 m_pending_state.reset();
50 m_write_cipher_states.clear();
51 m_read_cipher_states.clear();
58 m_active_state.reset();
59 m_read_cipher_states.clear();
60 m_write_cipher_states.clear();
62 m_write_cipher_states[0] =
nullptr;
63 m_read_cipher_states[0] =
nullptr;
65 if(m_sequence_numbers)
66 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
82 auto i = m_read_cipher_states.find(epoch);
83 if(i == m_read_cipher_states.end())
88std::shared_ptr<Connection_Cipher_State> Channel_Impl_12::write_cipher_state_epoch(uint16_t epoch)
const
90 auto i = m_write_cipher_states.find(epoch);
91 if(i == m_write_cipher_states.end())
98 if(
auto active = active_state())
100 return std::vector<X509_Certificate>();
111 throw Internal_Error(
"create_handshake_state called during handshake");
113 if(
auto active = active_state())
120 "Active state using version " + active_version.
to_string() +
121 " cannot change to " + version.
to_string() +
" in pending");
125 if(!m_sequence_numbers)
133 using namespace std::placeholders;
135 std::unique_ptr<Handshake_IO> io;
139 std::bind(&Channel_Impl_12::send_record_under_epoch,
this, _1, _2, _3),
152 if(
auto active = active_state())
153 m_pending_state->set_version(active->version());
155 return *m_pending_state.get();
161 return m_pending_state->handshake_io().timeout_check();
172 if(
auto active = active_state())
174 if(force_full_renegotiation ==
false)
178 force_full_renegotiation);
181 throw Invalid_State(
"Cannot renegotiate on inactive connection");
191 auto pending = pending_state();
194 "Have received server hello");
196 if(pending->server_hello()->compression_method() != 0)
204 "No read cipher state currently set for next epoch");
207 std::shared_ptr<Connection_Cipher_State> read_state(
211 pending->ciphersuite(),
212 pending->session_keys(),
213 pending->server_hello()->supports_encrypt_then_mac()));
215 m_read_cipher_states[epoch] = read_state;
220 auto pending = pending_state();
223 "Have received server hello");
225 if(pending->server_hello()->compression_method() != 0)
233 "No write cipher state currently set for next epoch");
235 std::shared_ptr<Connection_Cipher_State> write_state(
239 pending->ciphersuite(),
240 pending->session_keys(),
241 pending->server_hello()->supports_encrypt_then_mac()));
243 m_write_cipher_states[epoch] = write_state;
250 return (active_state() !=
nullptr);
255 return m_has_been_closed;
260 std::swap(m_active_state, m_pending_state);
261 m_pending_state.reset();
263 if(!m_active_state->version().is_datagram_protocol())
268 const auto not_current_epoch =
269 [current_epoch](uint16_t epoch) {
return (epoch != current_epoch); };
288 auto get_epoch = [
this](uint16_t epoch) {
return read_cipher_state_epoch(epoch); };
297 m_sequence_numbers.get(),
299 allow_epoch0_restart);
301 const size_t needed = record.
needed();
306 "Record reader consumed sane amount");
309 input_size -= consumed;
312 "Got a full record or consumed all input");
314 if(input_size == 0 && needed != 0)
325 "TLS plaintext record is larger than allowed maximum");
328 const bool epoch0_restart = m_is_datagram && record.
epoch() == 0 && active_state();
331 const bool initial_record = epoch0_restart || (!pending_state() && !active_state());
342 "Received unexpected record version in initial record");
345 else if(
auto pending = pending_state())
347 if(pending->server_hello() !=
nullptr && record.
version() != pending->version())
350 "Received unexpected record version");
353 else if(
auto active = active_state())
355 if(record.
version() != active->version())
358 "Received unexpected record version");
365 if(m_has_been_closed)
367 process_handshake_ccs(m_record_buf, record.
sequence(), record.
type(), record.
version(), epoch0_restart);
371 if(m_has_been_closed)
373 if(pending_state() !=
nullptr)
375 process_application_data(record.
sequence(), m_record_buf);
379 process_alert(m_record_buf);
384 " from counterparty");
412 uint64_t record_sequence,
422 if(m_sequence_numbers)
430 const uint16_t epoch = record_sequence >> 48;
432 if(epoch == sequence_numbers().current_read_epoch())
436 else if(epoch == sequence_numbers().current_read_epoch() - 1)
439 m_active_state->handshake_io().add_record(record.data(),
459 m_pending_state->handshake_io().add_record(record.data(),
464 while(
auto pending = m_pending_state.get())
466 auto msg = pending->get_next_handshake_msg();
472 msg.first, msg.second, epoch0_restart);
480void Channel_Impl_12::process_application_data(uint64_t seq_no,
const secure_vector<uint8_t>& record)
483 throw Unexpected_Message(
"Application data before handshake done");
488void Channel_Impl_12::process_alert(
const secure_vector<uint8_t>& record)
490 Alert alert_msg(record);
493 m_pending_state.reset();
497 if(alert_msg.is_fatal())
499 if(
auto active = active_state())
500 m_session_manager.
remove_entry(active->server_hello()->session_id());
508 m_has_been_closed =
true;
512void Channel_Impl_12::write_record(Connection_Cipher_State* cipher_state, uint16_t epoch,
513 uint8_t record_type,
const uint8_t input[],
size_t length)
515 BOTAN_ASSERT(m_pending_state || m_active_state,
"Some connection state exists");
517 const Protocol_Version record_version =
518 (m_pending_state) ? (m_pending_state->version()) : (m_active_state->version());
522 if(cipher_state ==
nullptr)
530 input, length, *cipher_state, m_rng);
536void Channel_Impl_12::send_record_array(uint16_t epoch, uint8_t
type,
const uint8_t input[],
size_t length)
541 auto cipher_state = write_cipher_state_epoch(epoch);
546 write_record(cipher_state.get(), epoch,
type, input, sending);
553void Channel_Impl_12::send_record(uint8_t record_type,
const std::vector<uint8_t>& record)
555 send_record_array(sequence_numbers().current_write_epoch(),
556 record_type, record.data(), record.size());
559void Channel_Impl_12::send_record_under_epoch(uint16_t epoch, uint8_t record_type,
560 const std::vector<uint8_t>& record)
562 send_record_array(epoch, record_type, record.data(), record.size());
568 throw Invalid_State(
"Data cannot be sent on inactive TLS connection");
570 send_record_array(sequence_numbers().current_write_epoch(),
576 const bool ready_to_send_anything = !
is_closed() && m_sequence_numbers;
577 if(alert.
is_valid() && ready_to_send_anything)
587 m_pending_state.reset();
591 if(
auto active = active_state())
593 m_session_manager.
remove_entry(active->server_hello()->session_id());
600 m_has_been_closed =
true;
608 if(
auto active = active_state())
610 const bool active_sr = active->client_hello()->secure_renegotiation();
612 if(active_sr != secure_renegotiation)
614 "Client changed its mind about secure renegotiation");
617 if(secure_renegotiation)
623 "Client sent bad values for secure renegotiation");
631 if(
auto active = active_state())
633 const bool active_sr = active->server_hello()->secure_renegotiation();
635 if(active_sr != secure_renegotiation)
637 "Server changed its mind about secure renegotiation");
640 if(secure_renegotiation)
646 "Server sent bad values for secure renegotiation");
652 if(
auto active = active_state())
653 return active->client_finished()->verify_data();
654 return std::vector<uint8_t>();
659 if(
auto active = active_state())
661 std::vector<uint8_t> buf = active->client_finished()->verify_data();
662 buf += active->server_finished()->verify_data();
666 return std::vector<uint8_t>();
671 if(
auto active = active_state())
672 return active->server_hello()->secure_renegotiation();
674 if(
auto pending = pending_state())
675 if(
auto hello = pending->server_hello())
676 return hello->secure_renegotiation();
682 const std::string& context,
685 if(
auto active = active_state())
687 if(pending_state() !=
nullptr)
688 {
throw Invalid_State(
"Channel_Impl_12::key_material_export cannot export during renegotiation"); }
690 auto prf = active->protocol_specific_prf();
693 active->session_keys().master_secret();
695 std::vector<uint8_t> salt;
696 salt += active->client_hello()->random();
697 salt += active->server_hello()->random();
701 size_t context_size = context.length();
702 if(context_size > 0xFFFF)
704 salt.push_back(get_byte<0>(
static_cast<uint16_t
>(context_size)));
705 salt.push_back(get_byte<1>(
static_cast<uint16_t
>(context_size)));
709 return prf->derive_key(length, master_secret, salt,
to_byte_vector(label));
713 throw Invalid_State(
"Channel_Impl_12::key_material_export connection not active");
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
#define BOTAN_ASSERT(expr, assertion_made)
std::vector< uint8_t > serialize() const
virtual void tls_emit_data(const uint8_t data[], size_t size)=0
virtual void tls_session_activated()
virtual bool tls_session_established(const Session &session)=0
virtual void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size)=0
virtual void tls_alert(Alert alert)=0
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)
Channel_Impl_12(Callbacks &callbacks, Session_Manager &session_manager, RandomNumberGenerator &rng, const Policy &policy, bool is_server, bool is_datagram, size_t io_buf_sz=Botan::TLS::Channel::IO_BUF_DEFAULT_SIZE)
void send(const uint8_t buf[], size_t buf_size) override
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
void secure_renegotiation_check(const Client_Hello_12 *client_hello)
bool timeout_check() override
bool is_active() const override
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 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
size_t received_data(const uint8_t buf[], size_t buf_size) override
void reset_active_association_state()
bool save_session(const Session &session)
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
SymmetricKey key_material_export(const std::string &label, const std::string &context, size_t length) const override
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 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
bool is_datagram_protocol() const
std::vector< uint8_t > renegotiation_info() const
bool secure_renegotiation() const
virtual void remove_entry(const std::vector< uint8_t > &session_id)=0
std::string to_string(const BER_Object &obj)
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_record(secure_vector< uint8_t > &output, uint8_t record_type, Protocol_Version version, uint64_t record_sequence, const uint8_t *message, size_t message_len, Connection_Cipher_State &cs, RandomNumberGenerator &rng)
void write_unencrypted_record(secure_vector< uint8_t > &output, uint8_t record_type, Protocol_Version version, uint64_t record_sequence, const uint8_t *message, size_t message_len)
void map_remove_if(Pred pred, T &assoc)
std::vector< uint8_t > to_byte_vector(const std::string &s)
std::vector< T, secure_allocator< T > > secure_vector