Botan 3.0.0
Crypto and TLS for C&
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
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::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
 
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
 
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
 
virtual ~Channel_Impl_12 ()
 

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 45 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 44 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 46 of file tls_channel_impl_12.h.

◆ handshake_msg_cb

Definition at line 47 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 43 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 22 of file tls_channel_impl_12.cpp.

28 :
29 m_is_server(is_server),
30 m_is_datagram(is_datagram),
31 m_callbacks(callbacks),
32 m_session_manager(session_manager),
33 m_policy(policy),
34 m_rng(rng),
35 m_has_been_closed(false)
36 {
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:106
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 ( )
virtualdefault

Member Function Documentation

◆ activate_session()

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

Definition at line 255 of file tls_channel_impl_12.cpp.

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

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

177{ 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 186 of file tls_channel_impl_12.cpp.

187 {
188 auto pending = pending_state();
189
190 BOTAN_ASSERT(pending && pending->server_hello(),
191 "Have received server hello");
192
193 if(pending->server_hello()->compression_method() != 0)
194 throw Internal_Error("Negotiated unknown compression algorithm");
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),
201 "No read cipher state currently set for next epoch");
202
203 // flip side as we are reading
204 std::shared_ptr<Connection_Cipher_State> read_state(
205 new Connection_Cipher_State(pending->version(),
207 false,
208 pending->ciphersuite(),
209 pending->session_keys(),
210 pending->server_hello()->supports_encrypt_then_mac()));
211
212 m_read_cipher_states[epoch] = read_state;
213 }
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:54
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 215 of file tls_channel_impl_12.cpp.

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

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

81{ 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 105 of file tls_channel_impl_12.cpp.

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

◆ expects_downgrade()

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

Definition at line 271 of file tls_channel_impl.h.

271{ 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().

◆ extract_downgrade_info()

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

Definition at line 269 of file tls_channel_impl.h.

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

References Botan::TLS::Alert, Botan::TLS::Policy::allow_dtls_epoch0_restart(), Botan::TLS::ApplicationData, BOTAN_ASSERT, BOTAN_ASSERT_IMPLICATION, Botan::TLS::ChangeCipherSpec, 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 243 of file tls_channel_impl_12.cpp.

244 {
245 if(is_closed())
246 return false;
247 return (active_state() != nullptr);
248 }

References is_closed().

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

251 {
252 return m_has_been_closed;
253 }

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

97{ 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 98 of file tls_channel_impl_12.h.

98{ 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 264 of file tls_channel_impl.h.

264{ 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().

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

704 {
705 if(auto active = active_state())
706 {
707 if(pending_state() != nullptr)
708 { throw Invalid_State("Channel_Impl_12::key_material_export cannot export during renegotiation"); }
709
710 auto prf = active->protocol_specific_prf();
711
712 const secure_vector<uint8_t>& master_secret =
713 active->session_keys().master_secret();
714
715 std::vector<uint8_t> salt;
716 salt += active->client_hello()->random();
717 salt += active->server_hello()->random();
718
719 if(!context.empty())
720 {
721 size_t context_size = context.length();
722 if(context_size > 0xFFFF)
723 throw Invalid_Argument("key_material_export context is too long");
724 salt.push_back(get_byte<0>(static_cast<uint16_t>(context_size)));
725 salt.push_back(get_byte<1>(static_cast<uint16_t>(context_size)));
726 salt += to_byte_vector(context);
727 }
728
729 return SymmetricKey(prf->derive_key(length, master_secret, salt, to_byte_vector(label)));
730 }
731 else
732 {
733 throw Invalid_State("Channel_Impl_12::key_material_export connection not active");
734 }
735 }
std::vector< uint8_t > to_byte_vector(std::string_view s)
Definition: stl_util.h:24
OctetString SymmetricKey
Definition: symkey.h:145

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

129{ 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 98 of file tls_channel_impl_12.cpp.

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

References get_peer_cert_chain().

◆ policy()

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

Definition at line 175 of file tls_channel_impl_12.h.

175{ 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 219 of file tls_channel_impl.h.

220 {
222 m_downgrade_info->client_hello_message.assign(msg.begin(), msg.end());
223 }
#define BOTAN_STATE_CHECK(expr)
Definition: assert.h:48

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

213 {
215 m_downgrade_info->peer_transcript.insert(m_downgrade_info->peer_transcript.end(),
216 input.begin(), input.end());
217 }

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

165 {
166 if(pending_state()) // currently in handshake?
167 return;
168
169 if(auto active = active_state())
170 {
171 if(force_full_renegotiation == false)
172 force_full_renegotiation = !policy().allow_resumption_for_renegotiation();
173
175 force_full_renegotiation);
176 }
177 else
178 throw Invalid_State("Cannot renegotiate on inactive connection");
179 }
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
Definition: tls_policy.cpp:375

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

242 {
244 m_downgrade_info->will_downgrade = true;
245 }

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

248 {
250 m_downgrade_info->client_hello_message.empty() &&
251 m_downgrade_info->peer_transcript.empty() &&
252 !m_downgrade_info->tls12_session.has_value());
253 BOTAN_ASSERT_NOMSG(session.session.version().is_pre_tls_13());
254 m_downgrade_info->tls12_session = std::move(session);
256 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:67

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

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

References BOTAN_ASSERT_NOMSG.

◆ rng()

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

Definition at line 171 of file tls_channel_impl_12.h.

171{ 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 624 of file tls_channel_impl_12.cpp.

625 {
626 const bool secure_renegotiation = client_hello->secure_renegotiation();
627
628 if(auto active = active_state())
629 {
630 const bool active_sr = active->client_hello()->secure_renegotiation();
631
632 if(active_sr != secure_renegotiation)
633 throw TLS_Exception(Alert::HandshakeFailure,
634 "Client changed its mind about secure renegotiation");
635 }
636
637 if(secure_renegotiation)
638 {
639 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
640
642 throw TLS_Exception(Alert::HandshakeFailure,
643 "Client sent bad values for secure renegotiation");
644 }
645 }
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 647 of file tls_channel_impl_12.cpp.

648 {
649 const bool secure_renegotiation = server_hello->secure_renegotiation();
650
651 if(auto active = active_state())
652 {
653 const bool active_sr = active->server_hello()->secure_renegotiation();
654
655 if(active_sr != secure_renegotiation)
656 throw TLS_Exception(Alert::HandshakeFailure,
657 "Server changed its mind about secure renegotiation");
658 }
659
660 if(secure_renegotiation)
661 {
662 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
663
665 throw TLS_Exception(Alert::HandshakeFailure,
666 "Server sent bad values for secure renegotiation");
667 }
668 }
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 670 of file tls_channel_impl_12.cpp.

671 {
672 if(auto active = active_state())
673 return active->client_finished()->verify_data();
674 return std::vector<uint8_t>();
675 }

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

678 {
679 if(auto active = active_state())
680 {
681 std::vector<uint8_t> buf = active->client_finished()->verify_data();
682 buf += active->server_finished()->verify_data();
683 return buf;
684 }
685
686 return std::vector<uint8_t>();
687 }

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

690 {
691 if(auto active = active_state())
692 return active->server_hello()->secure_renegotiation();
693
694 if(auto pending = pending_state())
695 if(auto hello = pending->server_hello())
696 return hello->secure_renegotiation();
697
698 return false;
699 }

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

591 {
592 const bool ready_to_send_anything = !is_closed() && m_sequence_numbers;
593 if(alert.is_valid() && ready_to_send_anything)
594 {
595 try
596 {
597 send_record(Record_Type::Alert, alert.serialize());
598 }
599 catch(...) { /* swallow it */ }
600 }
601
602 if(alert.type() == Alert::NoRenegotiation)
603 m_pending_state.reset();
604
605 if(alert.is_fatal())
606 {
607 if(auto active = active_state())
608 {
609 const auto& session_id = active->server_hello()->session_id();
610 if(!session_id.empty())
611 {
612 session_manager().remove(Session_ID(session_id));
613 }
614 }
615 reset_state();
616 }
617
618 if(alert.type() == Alert::CloseNotify || alert.is_fatal())
619 {
620 m_has_been_closed = true;
621 }
622 }
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:34

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

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

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

142{ return 0; }

◆ send_warning_alert()

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

Send a warning alert

Definition at line 71 of file tls_channel_impl.h.

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

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

173{ 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 227 of file tls_channel_impl.h.

228 {
230 m_downgrade_info->io_buffer_size = io_buf_sz;
231 }

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

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

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

582 {
583 if(!is_active())
584 throw Invalid_State("Data cannot be sent on inactive TLS connection");
585
586 send_record_array(sequence_numbers().current_write_epoch(),
587 Record_Type::ApplicationData, data.data(), data.size());
588 }

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

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

Member Data Documentation

◆ m_downgrade_info

std::unique_ptr<Downgrade_Information> Botan::TLS::Channel_Impl::m_downgrade_info
protectedinherited

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