Botan 3.6.1
Crypto and TLS for C&
Botan::TLS::Channel_Impl_12 Class Referenceabstract

#include <tls_channel_impl_12.h>

Inheritance diagram for Botan::TLS::Channel_Impl_12:
Botan::TLS::Channel_Impl Botan::TLS::Client_Impl_12 Botan::TLS::Server_Impl_12

Public Types

typedef std::function< void(Alert, const uint8_t[], size_t)> alert_cb
 
typedef std::function< void(const uint8_t[], size_t)> data_cb
 
typedef std::function< bool(const Session &)> handshake_cb
 
typedef std::function< void(const Handshake_Message &)> handshake_msg_cb
 
typedef std::function< void(const uint8_t[], size_t)> output_fn
 

Public Member Functions

virtual std::string application_protocol () const =0
 
 Channel_Impl_12 (const Channel_Impl_12 &)=delete
 
 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)
 
void close ()
 
bool expects_downgrade () const
 
std::optional< std::string > external_psk_identity () const override
 
std::unique_ptr< Downgrade_Informationextract_downgrade_info ()
 
size_t from_peer (std::span< const uint8_t > data) override
 
bool is_active () const override
 
bool is_closed () const override
 
bool is_closed_for_reading () const override
 
bool is_closed_for_writing () const override
 
bool is_downgrading () const
 
bool is_handshake_complete () const override
 
SymmetricKey key_material_export (std::string_view label, std::string_view context, size_t length) const override
 
virtual bool new_session_ticket_supported () const
 
Channel_Impl_12operator= (const Channel_Impl_12 &)=delete
 
std::vector< X509_Certificatepeer_cert_chain () const override
 
std::shared_ptr< const Public_Keypeer_raw_public_key () const override
 
void renegotiate (bool force_full_renegotiation=false) override
 
bool secure_renegotiation_supported () const override
 
void send_alert (const Alert &alert) override
 
void send_fatal_alert (Alert::Type type)
 
virtual size_t send_new_session_tickets (const size_t)
 
void send_warning_alert (Alert::Type type)
 
bool timeout_check () override
 
void to_peer (std::span< const uint8_t > data) override
 
void update_traffic_keys (bool request_peer_update=false) override
 
 ~Channel_Impl_12 () override
 

Protected Member Functions

void activate_session ()
 
Callbackscallbacks () const
 
void change_cipher_spec_reader (Connection_Side side)
 
void change_cipher_spec_writer (Connection_Side side)
 
Handshake_Statecreate_handshake_state (Protocol_Version version)
 
virtual std::vector< X509_Certificateget_peer_cert_chain (const Handshake_State &state) const =0
 
virtual void initiate_handshake (Handshake_State &state, bool force_full_renegotiation)=0
 
void inspect_handshake_message (const Handshake_Message &msg)
 
virtual std::unique_ptr< Handshake_Statenew_handshake_state (std::unique_ptr< class Handshake_IO > io)=0
 
const Policypolicy () const
 
void preserve_client_hello (std::span< const uint8_t > msg)
 
void preserve_peer_transcript (std::span< const uint8_t > input)
 
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
 
void request_downgrade ()
 
void request_downgrade_for_resumption (Session_with_Handle session)
 
void reset_active_association_state ()
 
RandomNumberGeneratorrng ()
 
void secure_renegotiation_check (const Client_Hello_12 *client_hello)
 
void secure_renegotiation_check (const Server_Hello_12 *server_hello)
 
std::vector< uint8_t > secure_renegotiation_data_for_client_hello () const
 
std::vector< uint8_t > secure_renegotiation_data_for_server_hello () const
 
Session_Managersession_manager ()
 
void set_io_buffer_size (size_t io_buf_sz)
 

Protected Attributes

std::unique_ptr< Downgrade_Informationm_downgrade_info
 

Detailed Description

Generic interface for TLSv.12 endpoint

Definition at line 40 of file tls_channel_impl_12.h.

Member Typedef Documentation

◆ alert_cb

std::function<void(Alert, const uint8_t[], size_t)> Botan::TLS::Channel_Impl_12::alert_cb

Definition at line 44 of file tls_channel_impl_12.h.

◆ data_cb

std::function<void(const uint8_t[], size_t)> Botan::TLS::Channel_Impl_12::data_cb

Definition at line 43 of file tls_channel_impl_12.h.

◆ handshake_cb

Definition at line 45 of file tls_channel_impl_12.h.

◆ handshake_msg_cb

Definition at line 46 of file tls_channel_impl_12.h.

◆ output_fn

std::function<void(const uint8_t[], size_t)> Botan::TLS::Channel_Impl_12::output_fn

Definition at line 42 of file tls_channel_impl_12.h.

Constructor & Destructor Documentation

◆ Channel_Impl_12() [1/2]

Botan::TLS::Channel_Impl_12::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 )
explicit

Set up a new TLS session

Parameters
callbackscontains a set of callback function references required by the TLS endpoint.
session_managermanages session state
rnga random number generator
policyspecifies other connection policy information
is_serverwhether this is a server session or not
is_datagramwhether this is a DTLS session
io_buf_szThis many bytes of memory will be preallocated for the read and write buffers. Smaller values just mean reallocations and copies are more likely.

Definition at line 23 of file tls_channel_impl_12.cpp.

29 :
30 m_is_server(is_server),
31 m_is_datagram(is_datagram),
32 m_callbacks(callbacks),
33 m_session_manager(session_manager),
34 m_policy(policy),
35 m_rng(rng),
36 m_has_been_closed(false) {
37 BOTAN_ASSERT_NONNULL(m_callbacks);
38 BOTAN_ASSERT_NONNULL(m_session_manager);
40 BOTAN_ASSERT_NONNULL(m_policy);
41
42 /* epoch 0 is plaintext, thus null cipher state */
43 m_write_cipher_states[0] = nullptr;
44 m_read_cipher_states[0] = nullptr;
45
46 m_writebuf.reserve(reserved_io_buffer_size);
47 m_readbuf.reserve(reserved_io_buffer_size);
48}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86
RandomNumberGenerator & rng()
Session_Manager & session_manager()
const Policy & policy() const

References BOTAN_ASSERT_NONNULL.

◆ Channel_Impl_12() [2/2]

Botan::TLS::Channel_Impl_12::Channel_Impl_12 ( const Channel_Impl_12 & )
explicitdelete

◆ ~Channel_Impl_12()

Botan::TLS::Channel_Impl_12::~Channel_Impl_12 ( )
overridedefault

Member Function Documentation

◆ activate_session()

void Botan::TLS::Channel_Impl_12::activate_session ( )
protected

Definition at line 252 of file tls_channel_impl_12.cpp.

252 {
253 std::swap(m_active_state, m_pending_state);
254 m_pending_state.reset();
255
256 if(!m_active_state->version().is_datagram_protocol()) {
257 // TLS is easy just remove all but the current state
258 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
259
260 const auto not_current_epoch = [current_epoch](uint16_t epoch) { return (epoch != current_epoch); };
261
262 map_remove_if(not_current_epoch, m_write_cipher_states);
263 map_remove_if(not_current_epoch, m_read_cipher_states);
264 }
265
267}
virtual void tls_session_activated()
virtual uint16_t current_write_epoch() const =0
void map_remove_if(Pred pred, T &assoc)
Definition stl_util.h:70

References callbacks(), Botan::TLS::Connection_Sequence_Numbers::current_write_epoch(), Botan::map_remove_if(), and Botan::TLS::Callbacks::tls_session_activated().

◆ application_protocol()

virtual std::string Botan::TLS::Channel_Impl::application_protocol ( ) const
pure virtualinherited

Return the protocol notification set for this connection, if any (ALPN). This value is not tied to the session and a later renegotiation of the same session can choose a new protocol.

Implemented in Botan::TLS::Client_Impl_12, Botan::TLS::Client_Impl_13, and Botan::TLS::Server_Impl_13.

◆ callbacks()

Callbacks & Botan::TLS::Channel_Impl_12::callbacks ( ) const
inlineprotected

Definition at line 190 of file tls_channel_impl_12.h.

190{ return *m_callbacks; }

Referenced by activate_session().

◆ change_cipher_spec_reader()

void Botan::TLS::Channel_Impl_12::change_cipher_spec_reader ( Connection_Side side)
protected

Definition at line 187 of file tls_channel_impl_12.cpp.

187 {
188 auto pending = pending_state();
189
190 BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello");
191
192 if(pending->server_hello()->compression_method() != 0) {
193 throw Internal_Error("Negotiated unknown compression algorithm");
194 }
195
196 sequence_numbers().new_read_cipher_state();
197
198 const uint16_t epoch = sequence_numbers().current_read_epoch();
199
200 BOTAN_ASSERT(!m_read_cipher_states.contains(epoch), "No read cipher state currently set for next epoch");
201
202 // flip side as we are reading
203 std::shared_ptr<Connection_Cipher_State> read_state(
204 new Connection_Cipher_State(pending->version(),
206 false,
207 pending->ciphersuite(),
208 pending->session_keys(),
209 pending->server_hello()->supports_encrypt_then_mac()));
210
211 m_read_cipher_states[epoch] = read_state;
212}
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:50
virtual uint16_t current_read_epoch() const =0

References BOTAN_ASSERT, Botan::TLS::Client, Botan::TLS::Connection_Sequence_Numbers::current_read_epoch(), Botan::TLS::Connection_Sequence_Numbers::new_read_cipher_state(), and Botan::TLS::Server.

◆ change_cipher_spec_writer()

void Botan::TLS::Channel_Impl_12::change_cipher_spec_writer ( Connection_Side side)
protected

Definition at line 214 of file tls_channel_impl_12.cpp.

214 {
215 auto pending = pending_state();
216
217 BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello");
218
219 if(pending->server_hello()->compression_method() != 0) {
220 throw Internal_Error("Negotiated unknown compression algorithm");
221 }
222
223 sequence_numbers().new_write_cipher_state();
224
225 const uint16_t epoch = sequence_numbers().current_write_epoch();
226
227 BOTAN_ASSERT(!m_write_cipher_states.contains(epoch), "No write cipher state currently set for next epoch");
228
229 std::shared_ptr<Connection_Cipher_State> write_state(
230 new Connection_Cipher_State(pending->version(),
231 side,
232 true,
233 pending->ciphersuite(),
234 pending->session_keys(),
235 pending->server_hello()->supports_encrypt_then_mac()));
236
237 m_write_cipher_states[epoch] = write_state;
238}

References BOTAN_ASSERT, Botan::TLS::Connection_Sequence_Numbers::current_write_epoch(), and Botan::TLS::Connection_Sequence_Numbers::new_write_cipher_state().

◆ close()

void Botan::TLS::Channel_Impl::close ( )
inlineinherited

Send a close notification alert

Definition at line 80 of file tls_channel_impl.h.

80{ send_warning_alert(Alert::CloseNotify); }
void send_warning_alert(Alert::Type type)

References Botan::TLS::Channel_Impl::send_warning_alert().

◆ create_handshake_state()

Handshake_State & Botan::TLS::Channel_Impl_12::create_handshake_state ( Protocol_Version version)
protected

Definition at line 112 of file tls_channel_impl_12.cpp.

112 {
113 if(pending_state()) {
114 throw Internal_Error("create_handshake_state called during handshake");
115 }
116
117 if(auto active = active_state()) {
118 Protocol_Version active_version = active->version();
119
120 if(active_version.is_datagram_protocol() != version.is_datagram_protocol()) {
121 throw TLS_Exception(Alert::ProtocolVersion,
122 "Active state using version " + active_version.to_string() + " cannot change to " +
123 version.to_string() + " in pending");
124 }
125 }
126
127 if(!m_sequence_numbers) {
128 if(version.is_datagram_protocol()) {
129 m_sequence_numbers = std::make_unique<Datagram_Sequence_Numbers>();
130 } else {
131 m_sequence_numbers = std::make_unique<Stream_Sequence_Numbers>();
132 }
133 }
134
135 using namespace std::placeholders;
136
137 std::unique_ptr<Handshake_IO> io;
138 if(version.is_datagram_protocol()) {
139 io =
140 std::make_unique<Datagram_Handshake_IO>(std::bind(&Channel_Impl_12::send_record_under_epoch, this, _1, _2, _3),
141 sequence_numbers(),
142 static_cast<uint16_t>(policy().dtls_default_mtu()),
143 policy().dtls_initial_timeout(),
144 policy().dtls_maximum_timeout());
145 } else {
146 io = std::make_unique<Stream_Handshake_IO>(std::bind(&Channel_Impl_12::send_record, this, _1, _2));
147 }
148
149 m_pending_state = new_handshake_state(std::move(io));
150
151 if(auto active = active_state()) {
152 m_pending_state->set_version(active->version());
153 }
154
155 return *m_pending_state;
156}
virtual std::unique_ptr< Handshake_State > new_handshake_state(std::unique_ptr< class Handshake_IO > io)=0

References Botan::TLS::Protocol_Version::is_datagram_protocol(), new_handshake_state(), policy(), and Botan::TLS::Protocol_Version::to_string().

Referenced by Botan::TLS::Client_Impl_12::Client_Impl_12(), Botan::TLS::Client_Impl_12::Client_Impl_12(), and renegotiate().

◆ expects_downgrade()

bool Botan::TLS::Channel_Impl::expects_downgrade ( ) const
inlineinherited

Definition at line 278 of file tls_channel_impl.h.

278{ return m_downgrade_info != nullptr; }
std::unique_ptr< Downgrade_Information > m_downgrade_info

References Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Client_Impl_13::Client_Impl_13(), and Botan::TLS::Channel_Impl_13::from_peer().

◆ external_psk_identity()

std::optional< std::string > Botan::TLS::Channel_Impl_12::external_psk_identity ( ) const
overridevirtual
Returns
identity of the PSK used for this connection or std::nullopt if no PSK was used.

Implements Botan::TLS::Channel_Impl.

Definition at line 103 of file tls_channel_impl_12.cpp.

103 {
104 const auto* state = (active_state() != nullptr) ? active_state() : pending_state();
105 if(state) {
106 return state->psk_identity();
107 } else {
108 return std::nullopt;
109 }
110}

◆ extract_downgrade_info()

std::unique_ptr< Downgrade_Information > Botan::TLS::Channel_Impl::extract_downgrade_info ( )
inlineinherited
See also
Downgrade_Information

Definition at line 276 of file tls_channel_impl.h.

276{ return std::exchange(m_downgrade_info, {}); }

References Botan::TLS::Channel_Impl::m_downgrade_info.

◆ from_peer()

size_t Botan::TLS::Channel_Impl_12::from_peer ( std::span< const uint8_t > data)
overridevirtual

Inject TLS traffic received from counterparty

Returns
a hint as the how many more bytes we need to q the current record (this may be 0 if on a record boundary)

Implements Botan::TLS::Channel_Impl.

Definition at line 269 of file tls_channel_impl_12.cpp.

269 {
270 const bool allow_epoch0_restart = m_is_datagram && m_is_server && policy().allow_dtls_epoch0_restart();
271
272 auto input = data.data();
273 auto input_size = data.size();
274
275 try {
276 while(input_size) {
277 size_t consumed = 0;
278
279 auto get_epoch = [this](uint16_t epoch) { return read_cipher_state_epoch(epoch); };
280
281 const Record_Header record = read_record(m_is_datagram,
282 m_readbuf,
283 input,
284 input_size,
285 consumed,
286 m_record_buf,
287 m_sequence_numbers.get(),
288 get_epoch,
289 allow_epoch0_restart);
290
291 const size_t needed = record.needed();
292
293 BOTAN_ASSERT(consumed > 0, "Got to eat something");
294
295 BOTAN_ASSERT(consumed <= input_size, "Record reader consumed sane amount");
296
297 input += consumed;
298 input_size -= consumed;
299
300 BOTAN_ASSERT(input_size == 0 || needed == 0, "Got a full record or consumed all input");
301
302 if(input_size == 0 && needed != 0) {
303 return needed; // need more data to complete record
304 }
305
306 // Ignore invalid records in DTLS
307 if(m_is_datagram && record.type() == Record_Type::Invalid) {
308 return 0;
309 }
310
311 if(m_record_buf.size() > MAX_PLAINTEXT_SIZE) {
312 throw TLS_Exception(Alert::RecordOverflow, "TLS plaintext record is larger than allowed maximum");
313 }
314
315 const bool epoch0_restart = m_is_datagram && record.epoch() == 0 && active_state();
316 BOTAN_ASSERT_IMPLICATION(epoch0_restart, allow_epoch0_restart, "Allowed state");
317
318 const bool initial_record = epoch0_restart || (!pending_state() && !active_state());
319 bool initial_handshake_message = false;
320 if(record.type() == Record_Type::Handshake && !m_record_buf.empty()) {
321 Handshake_Type type = static_cast<Handshake_Type>(m_record_buf[0]);
322 initial_handshake_message = (type == Handshake_Type::ClientHello);
323 }
324
325 if(record.type() != Record_Type::Alert) {
326 if(initial_record) {
327 // For initial records just check for basic sanity
328 if(record.version().major_version() != 3 && record.version().major_version() != 0xFE) {
329 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version in initial record");
330 }
331 } else if(auto pending = pending_state()) {
332 if(pending->server_hello() != nullptr && !initial_handshake_message &&
333 record.version() != pending->version()) {
334 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version");
335 }
336 } else if(auto active = active_state()) {
337 if(record.version() != active->version() && !initial_handshake_message) {
338 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version");
339 }
340 }
341 }
342
343 if(record.type() == Record_Type::Handshake || record.type() == Record_Type::ChangeCipherSpec) {
344 if(m_has_been_closed) {
345 throw TLS_Exception(Alert::UnexpectedMessage, "Received handshake data after connection closure");
346 }
347 process_handshake_ccs(m_record_buf, record.sequence(), record.type(), record.version(), epoch0_restart);
348 } else if(record.type() == Record_Type::ApplicationData) {
349 if(m_has_been_closed) {
350 throw TLS_Exception(Alert::UnexpectedMessage, "Received application data after connection closure");
351 }
352 if(pending_state() != nullptr) {
353 throw TLS_Exception(Alert::UnexpectedMessage, "Can't interleave application and handshake data");
354 }
355 process_application_data(record.sequence(), m_record_buf);
356 } else if(record.type() == Record_Type::Alert) {
357 process_alert(m_record_buf);
358 } else if(record.type() != Record_Type::Invalid) {
359 throw Unexpected_Message("Unexpected record type " + std::to_string(static_cast<size_t>(record.type())) +
360 " from counterparty");
361 }
362 }
363
364 return 0; // on a record boundary
365 } catch(TLS_Exception& e) {
366 send_fatal_alert(e.type());
367 throw;
368 } catch(Invalid_Authentication_Tag&) {
369 send_fatal_alert(Alert::BadRecordMac);
370 throw;
371 } catch(Decoding_Error&) {
372 send_fatal_alert(Alert::DecodeError);
373 throw;
374 } catch(...) {
375 send_fatal_alert(Alert::InternalError);
376 throw;
377 }
378}
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
Definition assert.h:77
void send_fatal_alert(Alert::Type type)
virtual bool allow_dtls_epoch0_restart() const
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)
@ MAX_PLAINTEXT_SIZE
Definition tls_magic.h:30

References Botan::TLS::Alert, Botan::TLS::Policy::allow_dtls_epoch0_restart(), Botan::TLS::ApplicationData, BOTAN_ASSERT, BOTAN_ASSERT_IMPLICATION, Botan::TLS::ChangeCipherSpec, Botan::TLS::ClientHello, Botan::TLS::Record_Header::epoch(), Botan::TLS::Handshake, Botan::TLS::Invalid, Botan::TLS::Protocol_Version::major_version(), Botan::TLS::MAX_PLAINTEXT_SIZE, Botan::TLS::Record_Header::needed(), policy(), Botan::TLS::read_record(), Botan::TLS::Channel_Impl::send_fatal_alert(), Botan::TLS::Record_Header::sequence(), Botan::TLS::Record_Header::type(), Botan::TLS::TLS_Exception::type(), and Botan::TLS::Record_Header::version().

◆ get_peer_cert_chain()

virtual std::vector< X509_Certificate > Botan::TLS::Channel_Impl_12::get_peer_cert_chain ( const Handshake_State & state) const
protectedpure virtual

Referenced by peer_cert_chain().

◆ initiate_handshake()

virtual void Botan::TLS::Channel_Impl_12::initiate_handshake ( Handshake_State & state,
bool force_full_renegotiation )
protectedpure virtual

Referenced by renegotiate().

◆ inspect_handshake_message()

void Botan::TLS::Channel_Impl_12::inspect_handshake_message ( const Handshake_Message & msg)
protected

◆ is_active()

bool Botan::TLS::Channel_Impl_12::is_active ( ) const
overridevirtual
Returns
true iff the connection is active for sending application data

Implements Botan::TLS::Channel_Impl.

Definition at line 244 of file tls_channel_impl_12.cpp.

244 {
245 return !is_closed() && is_handshake_complete();
246}
bool is_handshake_complete() const override

References is_closed(), and is_handshake_complete().

Referenced by to_peer().

◆ is_closed()

bool Botan::TLS::Channel_Impl_12::is_closed ( ) const
overridevirtual
Returns
true iff the connection has been definitely closed

Implements Botan::TLS::Channel_Impl.

Definition at line 248 of file tls_channel_impl_12.cpp.

248 {
249 return m_has_been_closed;
250}

Referenced by is_active(), is_closed_for_reading(), is_closed_for_writing(), and send_alert().

◆ is_closed_for_reading()

bool Botan::TLS::Channel_Impl_12::is_closed_for_reading ( ) const
inlineoverridevirtual
Returns
true iff the connection is active for sending application data

Implements Botan::TLS::Channel_Impl.

Definition at line 101 of file tls_channel_impl_12.h.

101{ return is_closed(); }

References is_closed().

◆ is_closed_for_writing()

bool Botan::TLS::Channel_Impl_12::is_closed_for_writing ( ) const
inlineoverridevirtual
Returns
true iff the connection has been definitely closed

Implements Botan::TLS::Channel_Impl.

Definition at line 103 of file tls_channel_impl_12.h.

103{ return is_closed(); }

References is_closed().

◆ is_downgrading()

bool Botan::TLS::Channel_Impl::is_downgrading ( ) const
inlineinherited

Indicates whether a downgrade to TLS 1.2 or lower is in progress

See also
Downgrade_Information

Definition at line 271 of file tls_channel_impl.h.

271{ return m_downgrade_info && m_downgrade_info->will_downgrade; }

References Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Channel_Impl_13::from_peer(), Botan::TLS::Channel_Impl_13::key_material_export(), and Botan::TLS::Channel_Impl_13::update_traffic_keys().

◆ is_handshake_complete()

bool Botan::TLS::Channel_Impl_12::is_handshake_complete ( ) const
overridevirtual
Returns
true iff the TLS handshake completed successfully

Implements Botan::TLS::Channel_Impl.

Definition at line 240 of file tls_channel_impl_12.cpp.

240 {
241 return (active_state() != nullptr);
242}

Referenced by is_active().

◆ key_material_export()

SymmetricKey Botan::TLS::Channel_Impl_12::key_material_export ( std::string_view label,
std::string_view context,
size_t length ) const
overridevirtual

Key material export (RFC 5705)

Parameters
labela disambiguating label string
contexta per-association context value
lengththe length of the desired key in bytes
Returns
key of length bytes

Implements Botan::TLS::Channel_Impl.

Definition at line 623 of file tls_channel_impl_12.cpp.

625 {
626 if(auto active = active_state()) {
627 if(pending_state() != nullptr) {
628 throw Invalid_State("Channel_Impl_12::key_material_export cannot export during renegotiation");
629 }
630
631 auto prf = active->protocol_specific_prf();
632
633 const secure_vector<uint8_t>& master_secret = active->session_keys().master_secret();
634
635 std::vector<uint8_t> salt;
636 salt += active->client_hello()->random();
637 salt += active->server_hello()->random();
638
639 if(!context.empty()) {
640 size_t context_size = context.length();
641 if(context_size > 0xFFFF) {
642 throw Invalid_Argument("key_material_export context is too long");
643 }
644 salt.push_back(get_byte<0>(static_cast<uint16_t>(context_size)));
645 salt.push_back(get_byte<1>(static_cast<uint16_t>(context_size)));
646 salt += to_byte_vector(context);
647 }
648
649 return SymmetricKey(prf->derive_key(length, master_secret, salt, to_byte_vector(label)));
650 } else {
651 throw Invalid_State("Channel_Impl_12::key_material_export connection not active");
652 }
653}
constexpr uint8_t get_byte(T input)
Definition loadstor.h:75
T to_byte_vector(std::string_view s)
Definition stl_util.h:29
OctetString SymmetricKey
Definition symkey.h:140
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61

References Botan::get_byte(), and Botan::to_byte_vector().

◆ new_handshake_state()

virtual std::unique_ptr< Handshake_State > Botan::TLS::Channel_Impl_12::new_handshake_state ( std::unique_ptr< class Handshake_IO > io)
protectedpure virtual

Referenced by create_handshake_state().

◆ new_session_ticket_supported()

virtual bool Botan::TLS::Channel_Impl::new_session_ticket_supported ( ) const
inlinevirtualinherited
Returns
true if this channel can issue TLS 1.3 style session tickets.

Reimplemented in Botan::TLS::Server_Impl_13.

Definition at line 144 of file tls_channel_impl.h.

144{ return false; }

◆ operator=()

Channel_Impl_12 & Botan::TLS::Channel_Impl_12::operator= ( const Channel_Impl_12 & )
delete

◆ peer_cert_chain()

std::vector< X509_Certificate > Botan::TLS::Channel_Impl_12::peer_cert_chain ( ) const
overridevirtual
Returns
certificate chain of the peer (may be empty)

Implements Botan::TLS::Channel_Impl.

Definition at line 96 of file tls_channel_impl_12.cpp.

96 {
97 if(auto active = active_state()) {
98 return get_peer_cert_chain(*active);
99 }
100 return std::vector<X509_Certificate>();
101}
virtual std::vector< X509_Certificate > get_peer_cert_chain(const Handshake_State &state) const =0

References get_peer_cert_chain().

◆ peer_raw_public_key()

std::shared_ptr< const Public_Key > Botan::TLS::Channel_Impl_12::peer_raw_public_key ( ) const
inlineoverridevirtual

Note: Raw public key for authentication (RFC7250) is currently not implemented for TLS 1.2.

Returns
raw public key of the peer (will be nullptr)

Implements Botan::TLS::Channel_Impl.

Definition at line 116 of file tls_channel_impl_12.h.

116{ return nullptr; }

◆ policy()

const Policy & Botan::TLS::Channel_Impl_12::policy ( ) const
inlineprotected

Definition at line 188 of file tls_channel_impl_12.h.

188{ return *m_policy; }

Referenced by create_handshake_state(), from_peer(), and renegotiate().

◆ preserve_client_hello()

void Botan::TLS::Channel_Impl::preserve_client_hello ( std::span< const uint8_t > msg)
inlineprotectedinherited

Definition at line 231 of file tls_channel_impl.h.

231 {
233 m_downgrade_info->client_hello_message.assign(msg.begin(), msg.end());
234 }
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Client_Impl_13::Client_Impl_13().

◆ preserve_peer_transcript()

void Botan::TLS::Channel_Impl::preserve_peer_transcript ( std::span< const uint8_t > input)
inlineprotectedinherited

Definition at line 226 of file tls_channel_impl.h.

226 {
228 m_downgrade_info->peer_transcript.insert(m_downgrade_info->peer_transcript.end(), input.begin(), input.end());
229 }

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Channel_Impl_13::from_peer().

◆ process_handshake_msg()

virtual void Botan::TLS::Channel_Impl_12::process_handshake_msg ( const Handshake_State * active_state,
Handshake_State & pending_state,
Handshake_Type type,
const std::vector< uint8_t > & contents,
bool epoch0_restart )
protectedpure virtual

◆ renegotiate()

void Botan::TLS::Channel_Impl_12::renegotiate ( bool force_full_renegotiation = false)
overridevirtual

Attempt to renegotiate the session

Parameters
force_full_renegotiationif true, require a full renegotiation, otherwise allow session resumption

Implements Botan::TLS::Channel_Impl.

Definition at line 167 of file tls_channel_impl_12.cpp.

167 {
168 if(pending_state()) { // currently in handshake?
169 return;
170 }
171
172 if(auto active = active_state()) {
173 if(force_full_renegotiation == false) {
174 force_full_renegotiation = !policy().allow_resumption_for_renegotiation();
175 }
176
177 initiate_handshake(create_handshake_state(active->version()), force_full_renegotiation);
178 } else {
179 throw Invalid_State("Cannot renegotiate on inactive connection");
180 }
181}
Handshake_State & create_handshake_state(Protocol_Version version)
virtual void initiate_handshake(Handshake_State &state, bool force_full_renegotiation)=0
virtual bool allow_resumption_for_renegotiation() const

References Botan::TLS::Policy::allow_resumption_for_renegotiation(), create_handshake_state(), initiate_handshake(), and policy().

◆ request_downgrade()

void Botan::TLS::Channel_Impl::request_downgrade ( )
inlineprotectedinherited

Implementations use this to signal that the peer indicated a protocol version downgrade. After calling request_downgrade() no further state changes must be perfomed by the implementation. Particularly, no further handshake messages must be emitted. Instead, they must yield control flow back to the underlying Channel implementation to perform the protocol version downgrade.

Definition at line 252 of file tls_channel_impl.h.

252 {
254 m_downgrade_info->will_downgrade = true;
255 }

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Channel_Impl::request_downgrade_for_resumption().

◆ request_downgrade_for_resumption()

void Botan::TLS::Channel_Impl::request_downgrade_for_resumption ( Session_with_Handle session)
inlineprotectedinherited

Definition at line 257 of file tls_channel_impl.h.

257 {
258 BOTAN_STATE_CHECK(m_downgrade_info && m_downgrade_info->client_hello_message.empty() &&
259 m_downgrade_info->peer_transcript.empty() && !m_downgrade_info->tls12_session.has_value());
260 BOTAN_ASSERT_NOMSG(session.session.version().is_pre_tls_13());
261 m_downgrade_info->tls12_session = std::move(session);
263 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::TLS::Protocol_Version::is_pre_tls_13(), Botan::TLS::Channel_Impl::m_downgrade_info, Botan::TLS::Channel_Impl::request_downgrade(), Botan::TLS::Session_with_Handle::session, and Botan::TLS::Session_Base::version().

Referenced by Botan::TLS::Client_Impl_13::Client_Impl_13().

◆ reset_active_association_state()

void Botan::TLS::Channel_Impl_12::reset_active_association_state ( )
protected

Definition at line 58 of file tls_channel_impl_12.cpp.

58 {
59 // This operation only makes sense for DTLS
60 BOTAN_ASSERT_NOMSG(m_is_datagram);
61 m_active_state.reset();
62 m_read_cipher_states.clear();
63 m_write_cipher_states.clear();
64
65 m_write_cipher_states[0] = nullptr;
66 m_read_cipher_states[0] = nullptr;
67
68 if(m_sequence_numbers) {
69 m_sequence_numbers->reset();
70 }
71}

References BOTAN_ASSERT_NOMSG.

◆ rng()

RandomNumberGenerator & Botan::TLS::Channel_Impl_12::rng ( )
inlineprotected

Definition at line 184 of file tls_channel_impl_12.h.

184{ return *m_rng; }

◆ secure_renegotiation_check() [1/2]

void Botan::TLS::Channel_Impl_12::secure_renegotiation_check ( const Client_Hello_12 * client_hello)
protected

Definition at line 552 of file tls_channel_impl_12.cpp.

552 {
553 const bool secure_renegotiation = client_hello->secure_renegotiation();
554
555 if(auto active = active_state()) {
556 const bool active_sr = active->client_hello()->secure_renegotiation();
557
558 if(active_sr != secure_renegotiation) {
559 throw TLS_Exception(Alert::HandshakeFailure, "Client changed its mind about secure renegotiation");
560 }
561 }
562
563 if(secure_renegotiation) {
564 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
565
567 throw TLS_Exception(Alert::HandshakeFailure, "Client sent bad values for secure renegotiation");
568 }
569 }
570}
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const

References Botan::TLS::Client_Hello_12::renegotiation_info(), Botan::TLS::Client_Hello_12::secure_renegotiation(), and secure_renegotiation_data_for_client_hello().

Referenced by Botan::TLS::Client_Impl_12::Client_Impl_12().

◆ secure_renegotiation_check() [2/2]

void Botan::TLS::Channel_Impl_12::secure_renegotiation_check ( const Server_Hello_12 * server_hello)
protected

Definition at line 572 of file tls_channel_impl_12.cpp.

572 {
573 const bool secure_renegotiation = server_hello->secure_renegotiation();
574
575 if(auto active = active_state()) {
576 const bool active_sr = active->server_hello()->secure_renegotiation();
577
578 if(active_sr != secure_renegotiation) {
579 throw TLS_Exception(Alert::HandshakeFailure, "Server changed its mind about secure renegotiation");
580 }
581 }
582
583 if(secure_renegotiation) {
584 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
585
587 throw TLS_Exception(Alert::HandshakeFailure, "Server sent bad values for secure renegotiation");
588 }
589 }
590}
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const

References Botan::TLS::Server_Hello_12::renegotiation_info(), Botan::TLS::Server_Hello_12::secure_renegotiation(), and secure_renegotiation_data_for_server_hello().

◆ secure_renegotiation_data_for_client_hello()

std::vector< uint8_t > Botan::TLS::Channel_Impl_12::secure_renegotiation_data_for_client_hello ( ) const
protected

Definition at line 592 of file tls_channel_impl_12.cpp.

592 {
593 if(auto active = active_state()) {
594 return active->client_finished()->verify_data();
595 }
596 return std::vector<uint8_t>();
597}

Referenced by secure_renegotiation_check().

◆ secure_renegotiation_data_for_server_hello()

std::vector< uint8_t > Botan::TLS::Channel_Impl_12::secure_renegotiation_data_for_server_hello ( ) const
protected

Definition at line 599 of file tls_channel_impl_12.cpp.

599 {
600 if(auto active = active_state()) {
601 std::vector<uint8_t> buf = active->client_finished()->verify_data();
602 buf += active->server_finished()->verify_data();
603 return buf;
604 }
605
606 return std::vector<uint8_t>();
607}

Referenced by secure_renegotiation_check().

◆ secure_renegotiation_supported()

bool Botan::TLS::Channel_Impl_12::secure_renegotiation_supported ( ) const
overridevirtual
Returns
true iff the counterparty supports the secure renegotiation extensions.

Implements Botan::TLS::Channel_Impl.

Definition at line 609 of file tls_channel_impl_12.cpp.

609 {
610 if(auto active = active_state()) {
611 return active->server_hello()->secure_renegotiation();
612 }
613
614 if(auto pending = pending_state()) {
615 if(auto hello = pending->server_hello()) {
616 return hello->secure_renegotiation();
617 }
618 }
619
620 return false;
621}

◆ send_alert()

void Botan::TLS::Channel_Impl_12::send_alert ( const Alert & alert)
overridevirtual

Send a TLS alert message. If the alert is fatal, the internal state (keys, etc) will be reset.

Parameters
alertthe Alert to send

Implements Botan::TLS::Channel_Impl.

Definition at line 524 of file tls_channel_impl_12.cpp.

524 {
525 const bool ready_to_send_anything = !is_closed() && m_sequence_numbers;
526 if(alert.is_valid() && ready_to_send_anything) {
527 try {
528 send_record(Record_Type::Alert, alert.serialize());
529 } catch(...) { /* swallow it */
530 }
531 }
532
533 if(alert.type() == Alert::NoRenegotiation) {
534 m_pending_state.reset();
535 }
536
537 if(alert.is_fatal()) {
538 if(auto active = active_state()) {
539 const auto& session_id = active->server_hello()->session_id();
540 if(!session_id.empty()) {
541 session_manager().remove(Session_ID(session_id));
542 }
543 }
544 reset_state();
545 }
546
547 if(alert.type() == Alert::CloseNotify || alert.is_fatal()) {
548 m_has_been_closed = true;
549 }
550}
virtual size_t remove(const Session_Handle &handle)=0
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
Definition tls_session.h:32

References Botan::TLS::Alert, is_closed(), Botan::TLS::Alert::is_fatal(), Botan::TLS::Alert::is_valid(), Botan::TLS::Session_Manager::remove(), Botan::TLS::Alert::serialize(), session_manager(), and Botan::TLS::Alert::type().

◆ send_fatal_alert()

void Botan::TLS::Channel_Impl::send_fatal_alert ( Alert::Type type)
inlineinherited

Send a fatal alert

Definition at line 75 of file tls_channel_impl.h.

75{ send_alert(Alert(type, true)); }
virtual void send_alert(const Alert &alert)=0

References Botan::TLS::Alert, and Botan::TLS::Channel_Impl::send_alert().

Referenced by from_peer(), and Botan::TLS::Channel_Impl_13::from_peer().

◆ send_new_session_tickets()

virtual size_t Botan::TLS::Channel_Impl::send_new_session_tickets ( const size_t )
inlinevirtualinherited

Send tickets new session tickets to the peer. This is only supported on TLS 1.3 servers.

If the server's Session_Manager does not accept the generated Session objects, the server implementation won't be able to send new tickets. Additionally, anything but TLS 1.3 servers will return 0 (because they don't support sending such session tickets).

Returns
the number of session tickets successfully sent to the client

Reimplemented in Botan::TLS::Server_Impl_13.

Definition at line 157 of file tls_channel_impl.h.

157{ return 0; }

◆ send_warning_alert()

void Botan::TLS::Channel_Impl::send_warning_alert ( Alert::Type type)
inlineinherited

Send a warning alert

Definition at line 70 of file tls_channel_impl.h.

70{ send_alert(Alert(type, false)); }

References Botan::TLS::Alert, and Botan::TLS::Channel_Impl::send_alert().

Referenced by Botan::TLS::Channel_Impl::close().

◆ session_manager()

Session_Manager & Botan::TLS::Channel_Impl_12::session_manager ( )
inlineprotected

Definition at line 186 of file tls_channel_impl_12.h.

186{ return *m_session_manager; }

Referenced by send_alert().

◆ set_io_buffer_size()

void Botan::TLS::Channel_Impl::set_io_buffer_size ( size_t io_buf_sz)
inlineprotectedinherited

Definition at line 239 of file tls_channel_impl.h.

239 {
241 m_downgrade_info->io_buffer_size = io_buf_sz;
242 }

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

◆ timeout_check()

bool Botan::TLS::Channel_Impl_12::timeout_check ( )
overridevirtual

Perform a handshake timeout check. This does nothing unless this is a DTLS channel with a pending handshake state, in which case we check for timeout and potentially retransmit handshake packets.

Implements Botan::TLS::Channel_Impl.

Definition at line 158 of file tls_channel_impl_12.cpp.

158 {
159 if(m_pending_state) {
160 return m_pending_state->handshake_io().timeout_check();
161 }
162
163 //FIXME: scan cipher suites and remove epochs older than 2*MSL
164 return false;
165}

◆ to_peer()

void Botan::TLS::Channel_Impl_12::to_peer ( std::span< const uint8_t > data)
overridevirtual

Inject plaintext intended for counterparty Throws an exception if is_active() is false

Implements Botan::TLS::Channel_Impl.

Definition at line 516 of file tls_channel_impl_12.cpp.

516 {
517 if(!is_active()) {
518 throw Invalid_State("Data cannot be sent on inactive TLS connection");
519 }
520
521 send_record_array(sequence_numbers().current_write_epoch(), Record_Type::ApplicationData, data.data(), data.size());
522}

References Botan::TLS::ApplicationData, and is_active().

◆ update_traffic_keys()

void Botan::TLS::Channel_Impl_12::update_traffic_keys ( bool request_peer_update = false)
overridevirtual

Attempt to update the session's traffic key material Note that this is possible with a TLS 1.3 channel, only.

Parameters
request_peer_updateif true, require a reciprocal key update

Implements Botan::TLS::Channel_Impl.

Definition at line 183 of file tls_channel_impl_12.cpp.

183 {
184 throw Invalid_Argument("cannot update traffic keys on a TLS 1.2 channel");
185}

Member Data Documentation

◆ m_downgrade_info


The documentation for this class was generated from the following files: