10#include <botan/internal/tls_channel_impl_13.h>
12#include <botan/tls_callbacks.h>
13#include <botan/tls_exceptn.h>
14#include <botan/tls_messages_13.h>
15#include <botan/tls_policy.h>
16#include <botan/internal/concat_util.h>
17#include <botan/internal/tls_cipher_state.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);
43 const std::shared_ptr<RandomNumberGenerator>&
rng,
44 const std::shared_ptr<const Policy>&
policy,
56 m_opportunistic_key_update(false),
57 m_first_message_sent(false),
58 m_first_message_received(false) {
82 m_record_layer.copy_data(data);
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);
132 m_handshake_layer.has_pending_data()) {
133 throw Unexpected_Message(
"Unexpected additional handshake message data found in record");
155 if(!m_first_message_received) {
156 m_record_layer.disable_receiving_compat_mode();
157 m_first_message_received =
true;
161 while(
auto handshake_msg = m_handshake_layer.next_post_handshake_message(
policy())) {
176 if(!record.seq_no.has_value()) {
181 process_alert(record.fragment);
183 throw Unexpected_Message(
"Unexpected record type " + std::to_string(
static_cast<size_t>(record.type)) +
184 " from counterparty");
207 if(m_handshake_layer.has_pending_data()) {
208 throw Unexpected_Message(
"Unexpected additional post-handshake message data found in record");
211 if(
const uint64_t min_interval =
policy().minimum_key_update_interval_ms(); min_interval > 0) {
213 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch())
216 if(m_last_key_update_ms != 0 && (now - m_last_key_update_ms) < min_interval) {
217 throw TLS_Exception(Alert::UnexpectedMessage,
"Peer is requesting KeyUpdates too frequently");
220 m_last_key_update_ms = now;
250 std::visit([&](
const auto msg) {
m_channel.callbacks().tls_inspect_handshake_msg(msg.get()); }, message);
257 std::visit([&](
const auto& msg) {
m_channel.callbacks().tls_inspect_handshake_msg(msg); }, message);
280 throw Invalid_State(
"Data cannot be sent on inactive TLS connection");
291 if(m_opportunistic_key_update) {
293 m_opportunistic_key_update =
false;
300 if(alert.
is_valid() && m_can_write) {
312 if(is_close_notify_alert(alert) && m_can_write) {
319 if(is_error_alert(alert)) {
330 std::string_view context,
331 size_t length)
const {
344void Channel_Impl_13::send_record(
Record_Type type,
const std::vector<uint8_t>& record) {
356 m_first_message_sent =
true;
362 std::array<uint8_t, 1> ccs_content = {0x01};
364 to_write =
concat(ccs, to_write);
371 const Alert alert(record);
373 if(is_close_notify_alert(alert)) {
378 m_record_layer.clear_read_buffer();
388 if(is_error_alert(alert) && !alert.
is_fatal()) {
396 throw TLS_Exception(Alert::DecodeError,
"Error alert not marked fatal");
407 if(is_close_notify_alert(alert) &&
callbacks().tls_peer_closed_connection()) {
412void Channel_Impl_13::shutdown() {
423 const std::vector<std::string>& next_protocols) {
433 m_credentials_manager,
443 m_record_layer.set_record_size_limits(outgoing_limit, incoming_limit);
447 m_handshake_layer.set_selected_certificate_type(cert_type);
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT_NONNULL(ptr)
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()
bool contains_messages() const
std::vector< uint8_t > m_message_buffer
AggregatedMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer)
Handshake_Layer & m_handshake_layer
Channel_Impl_13 & m_channel
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)
Credentials_Manager & credentials_manager()
void send_dummy_change_cipher_spec()
RandomNumberGenerator & rng()
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
std::optional< Active_Connection_State_13 > m_active_state
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
Session_Manager & session_manager()
std::unique_ptr< Cipher_State > m_cipher_state
const Connection_Side m_side
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 expects_reciprocation() const
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
detail::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