10#include <botan/internal/tls_channel_impl_13.h>
12#include <botan/hash.h>
13#include <botan/tls_messages.h>
14#include <botan/internal/stl_util.h>
15#include <botan/internal/tls_cipher_state.h>
16#include <botan/internal/tls_handshake_state.h>
17#include <botan/internal/tls_record.h>
18#include <botan/internal/tls_seq_numbers.h>
24 return alert.
type() == Botan::TLS::Alert::UserCanceled;
28 return alert.
type() == Botan::TLS::Alert::CloseNotify;
34 return !is_close_notify_alert(alert) && !is_user_canceled_alert(alert);
41 const std::shared_ptr<Session_Manager>& session_manager,
42 const std::shared_ptr<Credentials_Manager>& credentials_manager,
43 const std::shared_ptr<RandomNumberGenerator>& rng,
44 const std::shared_ptr<const Policy>& policy,
47 m_callbacks(callbacks),
48 m_session_manager(session_manager),
49 m_credentials_manager(credentials_manager),
52 m_record_layer(m_side),
53 m_handshake_layer(m_side),
56 m_opportunistic_key_update(false),
57 m_first_message_sent(false),
58 m_first_message_received(false) {
95 if(std::holds_alternative<BytesNeeded>(result)) {
96 return std::get<BytesNeeded>(result);
99 const auto& record = std::get<Record>(result);
108 m_handshake_layer.
copy_data(record.fragment);
133 throw Unexpected_Message(
"Unexpected additional handshake message data found in record");
155 if(!m_first_message_received) {
157 m_first_message_received =
true;
168 BOTAN_ASSERT(record.seq_no.has_value(),
"decrypted application traffic had a sequence number");
171 process_alert(record.fragment);
173 throw Unexpected_Message(
"Unexpected record type " + std::to_string(
static_cast<size_t>(record.type)) +
174 " from counterparty");
198 throw Unexpected_Message(
"Unexpected additional post-handshake message data found in record");
221 m_channel(channel), m_handshake_layer(handshake_layer) {}
230 std::visit([&](
const auto msg) { m_channel.callbacks().tls_inspect_handshake_msg(msg.get()); }, message);
237 std::visit([&](
const auto& msg) { m_channel.callbacks().tls_inspect_handshake_msg(msg); }, message);
245 return std::exchange(m_message_buffer, {});
260 throw Invalid_State(
"Data cannot be sent on inactive TLS connection");
271 if(m_opportunistic_key_update) {
273 m_opportunistic_key_update =
false;
280 if(alert.
is_valid() && m_can_write) {
292 if(is_close_notify_alert(alert) && m_can_write) {
299 if(is_error_alert(alert)) {
310 std::string_view context,
311 size_t length)
const {
325void Channel_Impl_13::send_record(
Record_Type type,
const std::vector<uint8_t>& record) {
337 m_first_message_sent =
true;
343 std::array<uint8_t, 1> ccs_content = {0x01};
345 to_write =
concat(ccs, to_write);
354 if(is_close_notify_alert(alert)) {
369 if(is_error_alert(alert) && !alert.
is_fatal()) {
377 throw TLS_Exception(Alert::DecodeError,
"Error alert not marked fatal");
388 if(is_close_notify_alert(alert) &&
callbacks().tls_peer_closed_connection()) {
393void Channel_Impl_13::shutdown() {
403 const std::vector<std::string>& next_protocols) {
413 m_credentials_manager,
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ASSERT(expr, assertion_made)
std::vector< uint8_t > serialize() 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 void tls_emit_data(std::span< const uint8_t > data)=0
AggregatedHandshakeMessages & add(Handshake_Message_13_Ref message)
AggregatedHandshakeMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer, Transcript_Hash_State &transcript_hash)
std::vector< uint8_t > send()
AggregatedMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer)
AggregatedPostHandshakeMessages & add(Post_Handshake_Message_13 message)
~Channel_Impl_13() override
const Policy & policy() const
void expect_downgrade(const Server_Information &server_info, const std::vector< std::string > &next_protocols)
SymmetricKey key_material_export(std::string_view label, std::string_view context, size_t length) const override
void handle(const Key_Update &key_update)
std::vector< uint8_t > send_post_handshake_message(Post_Handshake_Message_13 message)
void send_dummy_change_cipher_spec()
void opportunistically_update_traffic_keys()
virtual bool prepend_ccs()
void to_peer(std::span< const uint8_t > data) override
Transcript_Hash_State m_transcript_hash
virtual void process_post_handshake_msg(Post_Handshake_Message_13 msg)=0
virtual void process_handshake_msg(Handshake_Message_13 msg)=0
Channel_Impl_13(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< RandomNumberGenerator > &rng, const std::shared_ptr< const Policy > &policy, bool is_server)
void send_alert(const Alert &alert) override
size_t from_peer(std::span< const uint8_t > data) override
void update_traffic_keys(bool request_peer_update=false) override
virtual void process_dummy_change_cipher_spec()=0
std::unique_ptr< Cipher_State > m_cipher_state
bool is_active() const override
Callbacks & callbacks() const
void set_selected_certificate_type(Certificate_Type cert_type)
void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit)
void preserve_peer_transcript(std::span< const uint8_t > input)
bool is_downgrading() const
bool expects_downgrade() const
void send_fatal_alert(Alert::Type type)
std::unique_ptr< Downgrade_Information > m_downgrade_info
virtual bool is_handshake_complete() const =0
static constexpr size_t IO_BUF_DEFAULT_SIZE
bool has_pending_data() const
static std::vector< uint8_t > prepare_message(Handshake_Message_13_Ref message, Transcript_Hash_State &transcript_hash)
std::optional< Handshake_Message_13 > next_message(const Policy &policy, Transcript_Hash_State &transcript_hash)
std::optional< Post_Handshake_Message_13 > next_post_handshake_message(const Policy &policy)
static std::vector< uint8_t > prepare_post_handshake_message(const Post_Handshake_Message_13 &message)
void copy_data(std::span< const uint8_t > data_from_peer)
void set_selected_certificate_type(Certificate_Type cert_type)
bool expects_reciprocation() const
void copy_data(std::span< const uint8_t > data_from_peer)
void disable_sending_compat_mode()
std::vector< uint8_t > prepare_records(Record_Type type, std::span< const uint8_t > data, Cipher_State *cipher_state=nullptr) const
void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit)
ReadResult< Record > next_record(Cipher_State *cipher_state=nullptr)
void disable_receiving_compat_mode()
as_wrapped_references_t< Handshake_Message_13 > Handshake_Message_13_Ref
std::variant< New_Session_Ticket_13, Key_Update > Post_Handshake_Message_13
constexpr bool holds_any_of(const std::variant< Ts... > &v) noexcept
constexpr auto concat(Rs &&... ranges)
std::vector< T, secure_allocator< T > > secure_vector