Botan 3.9.0
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 (Channel_Impl_12 &&other)=delete
 Channel_Impl_12 (const Channel_Impl_12 &other)=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= (Channel_Impl_12 &&other)=delete
Channel_Impl_12operator= (const Channel_Impl_12 &other)=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

typedef 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

typedef 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

typedef std::function<bool(const Session&)> Botan::TLS::Channel_Impl_12::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

typedef 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/3]

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 24 of file tls_channel_impl_12.cpp.

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

References BOTAN_ASSERT_NONNULL, callbacks(), policy(), rng(), and session_manager().

Referenced by Channel_Impl_12(), Channel_Impl_12(), Botan::TLS::Client_Impl_12::Client_Impl_12(), Botan::TLS::Client_Impl_12::Client_Impl_12(), operator=(), operator=(), Botan::TLS::Server_Impl_12::Server_Impl_12(), and Botan::TLS::Server_Impl_12::Server_Impl_12().

◆ Channel_Impl_12() [2/3]

Botan::TLS::Channel_Impl_12::Channel_Impl_12 ( const Channel_Impl_12 & other)
delete

References Channel_Impl_12().

◆ Channel_Impl_12() [3/3]

Botan::TLS::Channel_Impl_12::Channel_Impl_12 ( Channel_Impl_12 && other)
delete

References Channel_Impl_12().

◆ ~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 259 of file tls_channel_impl_12.cpp.

259 {
260 std::swap(m_active_state, m_pending_state);
261 m_pending_state.reset();
262
263 if(!m_active_state->version().is_datagram_protocol()) {
264 // TLS is easy just remove all but the current state
265 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
266
267 const auto not_current_epoch = [current_epoch](uint16_t epoch) { return (epoch != current_epoch); };
268
269 map_remove_if(not_current_epoch, m_write_cipher_states);
270 map_remove_if(not_current_epoch, m_read_cipher_states);
271 }
272
274}
virtual void tls_session_activated()
void map_remove_if(Pred pred, T &assoc)
Definition stl_util.h:62

References callbacks(), 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()

◆ change_cipher_spec_reader()

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

Definition at line 194 of file tls_channel_impl_12.cpp.

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

References BOTAN_ASSERT, Botan::TLS::Client, 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 221 of file tls_channel_impl_12.cpp.

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

References BOTAN_ASSERT.

◆ close()

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

Send a close notification alert

Definition at line 86 of file tls_channel_impl.h.

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

References send_warning_alert().

◆ create_handshake_state()

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

Definition at line 113 of file tls_channel_impl_12.cpp.

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

References Botan::TLS::Policy::dtls_default_mtu(), Botan::TLS::Policy::dtls_initial_timeout(), Botan::TLS::Policy::dtls_maximum_timeout(), 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 286 of file tls_channel_impl.h.

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

References 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 104 of file tls_channel_impl_12.cpp.

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

◆ extract_downgrade_info()

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

Definition at line 284 of file tls_channel_impl.h.

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

References 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 276 of file tls_channel_impl_12.cpp.

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

251 {
252 return !is_closed() && is_handshake_complete();
253}
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 255 of file tls_channel_impl_12.cpp.

255 {
256 return m_has_been_closed;
257}

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 102 of file tls_channel_impl_12.h.

102{ 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 104 of file tls_channel_impl_12.h.

104{ 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 279 of file tls_channel_impl.h.

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

References 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 247 of file tls_channel_impl_12.cpp.

247 {
248 return (active_state() != nullptr);
249}

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 630 of file tls_channel_impl_12.cpp.

632 {
633 if(const auto* active = active_state()) {
634 if(pending_state() != nullptr) {
635 throw Invalid_State("Channel_Impl_12::key_material_export cannot export during renegotiation");
636 }
637
638 auto prf = active->protocol_specific_prf();
639
640 const secure_vector<uint8_t>& master_secret = active->session_keys().master_secret();
641
642 std::vector<uint8_t> salt;
643 salt += active->client_hello()->random();
644 salt += active->server_hello()->random();
645
646 if(!context.empty()) {
647 size_t context_size = context.length();
648 if(context_size > 0xFFFF) {
649 throw Invalid_Argument("key_material_export context is too long");
650 }
651 salt.push_back(get_byte<0>(static_cast<uint16_t>(context_size)));
652 salt.push_back(get_byte<1>(static_cast<uint16_t>(context_size)));
653 salt += as_span_of_bytes(context);
654 }
655
656 return SymmetricKey(prf->derive_key(length, master_secret, salt, as_span_of_bytes(label)));
657 } else {
658 throw Invalid_State("Channel_Impl_12::key_material_export connection not active");
659 }
660}
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79
OctetString SymmetricKey
Definition symkey.h:140
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
Definition mem_utils.h:28
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:69

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

◆ 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 150 of file tls_channel_impl.h.

150{ return false; }

◆ operator=() [1/2]

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

References Channel_Impl_12().

◆ operator=() [2/2]

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

References Channel_Impl_12().

◆ 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 97 of file tls_channel_impl_12.cpp.

97 {
98 if(const auto* active = active_state()) {
99 return get_peer_cert_chain(*active);
100 }
101 return std::vector<X509_Certificate>();
102}
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 117 of file tls_channel_impl_12.h.

117{ return nullptr; }

◆ policy()

◆ preserve_client_hello()

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

Definition at line 239 of file tls_channel_impl.h.

239 {
241 m_downgrade_info->client_hello_message.assign(msg.begin(), msg.end());
242 }
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49

References BOTAN_STATE_CHECK, and 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 234 of file tls_channel_impl.h.

234 {
236 m_downgrade_info->peer_transcript.insert(m_downgrade_info->peer_transcript.end(), input.begin(), input.end());
237 }

References BOTAN_STATE_CHECK, and 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 174 of file tls_channel_impl_12.cpp.

174 {
175 if(pending_state() != nullptr) { // currently in handshake?
176 return;
177 }
178
179 if(const auto* active = active_state()) {
180 if(!force_full_renegotiation) {
181 force_full_renegotiation = !policy().allow_resumption_for_renegotiation();
182 }
183
184 initiate_handshake(create_handshake_state(active->version()), force_full_renegotiation);
185 } else {
186 throw Invalid_State("Cannot renegotiate on inactive connection");
187 }
188}
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 260 of file tls_channel_impl.h.

260 {
262 m_downgrade_info->will_downgrade = true;
263 }

References BOTAN_STATE_CHECK, and m_downgrade_info.

Referenced by 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 265 of file tls_channel_impl.h.

265 {
266 BOTAN_STATE_CHECK(m_downgrade_info && m_downgrade_info->client_hello_message.empty() &&
267 m_downgrade_info->peer_transcript.empty() && !m_downgrade_info->tls12_session.has_value());
268 BOTAN_ASSERT_NOMSG(session.session.version().is_pre_tls_13());
269 m_downgrade_info->tls12_session = std::move(session);
271 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::TLS::Protocol_Version::is_pre_tls_13(), m_downgrade_info, 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 59 of file tls_channel_impl_12.cpp.

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

References BOTAN_ASSERT_NOMSG.

◆ 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 559 of file tls_channel_impl_12.cpp.

559 {
560 const bool secure_renegotiation = client_hello->secure_renegotiation();
561
562 if(const auto* active = active_state()) {
563 const bool active_sr = active->client_hello()->secure_renegotiation();
564
565 if(active_sr != secure_renegotiation) {
566 throw TLS_Exception(Alert::HandshakeFailure, "Client changed its mind about secure renegotiation");
567 }
568 }
569
570 if(secure_renegotiation) {
571 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
572
574 throw TLS_Exception(Alert::HandshakeFailure, "Client sent bad values for secure renegotiation");
575 }
576 }
577}
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 579 of file tls_channel_impl_12.cpp.

579 {
580 const bool secure_renegotiation = server_hello->secure_renegotiation();
581
582 if(const auto* active = active_state()) {
583 const bool active_sr = active->server_hello()->secure_renegotiation();
584
585 if(active_sr != secure_renegotiation) {
586 throw TLS_Exception(Alert::HandshakeFailure, "Server changed its mind about secure renegotiation");
587 }
588 }
589
590 if(secure_renegotiation) {
591 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
592
594 throw TLS_Exception(Alert::HandshakeFailure, "Server sent bad values for secure renegotiation");
595 }
596 }
597}
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 599 of file tls_channel_impl_12.cpp.

599 {
600 if(const auto* active = active_state()) {
601 return active->client_finished()->verify_data();
602 }
603 return std::vector<uint8_t>();
604}

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 606 of file tls_channel_impl_12.cpp.

606 {
607 if(const auto* active = active_state()) {
608 std::vector<uint8_t> buf = active->client_finished()->verify_data();
609 buf += active->server_finished()->verify_data();
610 return buf;
611 }
612
613 return std::vector<uint8_t>();
614}

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 616 of file tls_channel_impl_12.cpp.

616 {
617 if(const auto* active = active_state()) {
618 return active->server_hello()->secure_renegotiation();
619 }
620
621 if(const auto* pending = pending_state()) {
622 if(const auto* hello = pending->server_hello()) {
623 return hello->secure_renegotiation();
624 }
625 }
626
627 return false;
628}

◆ 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 531 of file tls_channel_impl_12.cpp.

531 {
532 const bool ready_to_send_anything = !is_closed() && m_sequence_numbers;
533 if(alert.is_valid() && ready_to_send_anything) {
534 try {
535 send_record(Record_Type::Alert, alert.serialize());
536 } catch(...) { /* swallow it */
537 }
538 }
539
540 if(alert.type() == Alert::NoRenegotiation) {
541 m_pending_state.reset();
542 }
543
544 if(alert.is_fatal()) {
545 if(const auto* active = active_state()) {
546 const auto& session_id = active->server_hello()->session_id();
547 if(!session_id.empty()) {
548 session_manager().remove(Session_Handle(Session_ID(session_id)));
549 }
550 }
551 reset_state();
552 }
553
554 if(alert.type() == Alert::CloseNotify || alert.is_fatal()) {
555 m_has_been_closed = true;
556 }
557}
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:31

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 81 of file tls_channel_impl.h.

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

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

Referenced by Botan::TLS::Channel_Impl_12::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 163 of file tls_channel_impl.h.

163{ return 0; }

◆ send_warning_alert()

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

Send a warning alert

Definition at line 76 of file tls_channel_impl.h.

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

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

Referenced by close().

◆ session_manager()

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

◆ set_io_buffer_size()

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

Definition at line 247 of file tls_channel_impl.h.

247 {
249 m_downgrade_info->io_buffer_size = io_buf_sz;
250 }

References BOTAN_STATE_CHECK, and 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 165 of file tls_channel_impl_12.cpp.

165 {
166 if(m_pending_state) {
167 return m_pending_state->handshake_io().timeout_check();
168 }
169
170 //FIXME: scan cipher suites and remove epochs older than 2*MSL
171 return false;
172}

◆ 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 523 of file tls_channel_impl_12.cpp.

523 {
524 if(!is_active()) {
525 throw Invalid_State("Data cannot be sent on inactive TLS connection");
526 }
527
528 send_record_array(sequence_numbers().current_write_epoch(), Record_Type::ApplicationData, data.data(), data.size());
529}

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 190 of file tls_channel_impl_12.cpp.

190 {
191 throw Invalid_Argument("cannot update traffic keys on a TLS 1.2 channel");
192}

Member Data Documentation

◆ m_downgrade_info


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