Botan 2.19.0
Crypto and TLS for C&
Public Types | Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
Botan::TLS::Channel Class Referenceabstract

#include <tls_channel.h>

Inheritance diagram for Botan::TLS::Channel:
Botan::TLS::Client Botan::TLS::Server

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 (Callbacks &callbacks, Session_Manager &session_manager, RandomNumberGenerator &rng, const Policy &policy, bool is_server, bool is_datagram, size_t io_buf_sz=IO_BUF_DEFAULT_SIZE)
 
 Channel (const Channel &)=delete
 
 Channel (output_fn out, data_cb app_data_cb, alert_cb alert_cb, handshake_cb hs_cb, handshake_msg_cb hs_msg_cb, Session_Manager &session_manager, RandomNumberGenerator &rng, const Policy &policy, bool is_server, bool is_datagram, size_t io_buf_sz=IO_BUF_DEFAULT_SIZE)
 
void close ()
 
bool is_active () const
 
bool is_closed () const
 
SymmetricKey key_material_export (const std::string &label, const std::string &context, size_t length) const
 
Channeloperator= (const Channel &)=delete
 
std::vector< X509_Certificatepeer_cert_chain () const
 
size_t received_data (const std::vector< uint8_t > &buf)
 
size_t received_data (const uint8_t buf[], size_t buf_size)
 
void renegotiate (bool force_full_renegotiation=false)
 
bool secure_renegotiation_supported () const
 
void send (const std::string &val)
 
template<typename Alloc >
void send (const std::vector< unsigned char, Alloc > &val)
 
void send (const uint8_t buf[], size_t buf_size)
 
void send_alert (const Alert &alert)
 
void send_fatal_alert (Alert::Type type)
 
void send_warning_alert (Alert::Type type)
 
bool timeout_check ()
 
virtual ~Channel ()
 

Static Public Attributes

static size_t IO_BUF_DEFAULT_SIZE = 10*1024
 

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 Handshake_Statenew_handshake_state (class Handshake_IO *io)=0
 
const Policypolicy () const
 
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 reset_active_association_state ()
 
RandomNumberGeneratorrng ()
 
bool save_session (const Session &session)
 
void secure_renegotiation_check (const Client_Hello *client_hello)
 
void secure_renegotiation_check (const Server_Hello *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 ()
 

Detailed Description

Generic interface for TLS endpoint

Definition at line 37 of file tls_channel.h.

Member Typedef Documentation

◆ alert_cb

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

Definition at line 42 of file tls_channel.h.

◆ data_cb

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

Definition at line 41 of file tls_channel.h.

◆ handshake_cb

typedef std::function<bool (const Session&)> Botan::TLS::Channel::handshake_cb

Definition at line 43 of file tls_channel.h.

◆ handshake_msg_cb

typedef std::function<void (const Handshake_Message&)> Botan::TLS::Channel::handshake_msg_cb

Definition at line 44 of file tls_channel.h.

◆ output_fn

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

Definition at line 40 of file tls_channel.h.

Constructor & Destructor Documentation

◆ Channel() [1/3]

Botan::TLS::Channel::Channel ( Callbacks callbacks,
Session_Manager session_manager,
RandomNumberGenerator rng,
const Policy policy,
bool  is_server,
bool  is_datagram,
size_t  io_buf_sz = IO_BUF_DEFAULT_SIZE 
)

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 26 of file tls_channel.cpp.

32 :
33 m_is_server(is_server),
34 m_is_datagram(is_datagram),
35 m_callbacks(callbacks),
36 m_session_manager(session_manager),
37 m_policy(policy),
38 m_rng(rng),
39 m_has_been_closed(false)
40 {
41 init(reserved_io_buffer_size);
42 }
Callbacks & callbacks() const
Definition: tls_channel.h:242
Session_Manager & session_manager()
Definition: tls_channel.h:236
const Policy & policy() const
Definition: tls_channel.h:238
RandomNumberGenerator & rng()
Definition: tls_channel.h:234

◆ Channel() [2/3]

Botan::TLS::Channel::Channel ( output_fn  out,
data_cb  app_data_cb,
alert_cb  alert_cb,
handshake_cb  hs_cb,
handshake_msg_cb  hs_msg_cb,
Session_Manager session_manager,
RandomNumberGenerator rng,
const Policy policy,
bool  is_server,
bool  is_datagram,
size_t  io_buf_sz = IO_BUF_DEFAULT_SIZE 
)

DEPRECATED. This constructor is only provided for backward compatibility and should not be used in new implementations. (Not marked deprecated since it is only called internally, by other deprecated constructors)

Definition at line 44 of file tls_channel.cpp.

54 :
55 m_is_server(is_server),
56 m_is_datagram(is_datagram),
57 m_compat_callbacks(new Compat_Callbacks(
58 /*
59 this Channel constructor is also deprecated so its ok that it
60 relies on a deprecated API
61 */
63 out, app_data_cb, recv_alert_cb, hs_cb, hs_msg_cb)),
64 m_callbacks(*m_compat_callbacks.get()),
65 m_session_manager(session_manager),
66 m_policy(policy),
67 m_rng(rng),
68 m_has_been_closed(false)
69 {
70 init(io_buf_sz);
71 }

◆ Channel() [3/3]

Botan::TLS::Channel::Channel ( const Channel )
delete

◆ ~Channel()

Botan::TLS::Channel::~Channel ( )
virtual

Definition at line 107 of file tls_channel.cpp.

108 {
109 // So unique_ptr destructors run correctly
110 }

Member Function Documentation

◆ activate_session()

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

Definition at line 291 of file tls_channel.cpp.

292 {
293 std::swap(m_active_state, m_pending_state);
294 m_pending_state.reset();
295
296 if(!m_active_state->version().is_datagram_protocol())
297 {
298 // TLS is easy just remove all but the current state
299 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
300
301 const auto not_current_epoch =
302 [current_epoch](uint16_t epoch) { return (epoch != current_epoch); };
303
304 map_remove_if(not_current_epoch, m_write_cipher_states);
305 map_remove_if(not_current_epoch, m_read_cipher_states);
306 }
307
309 }
virtual void tls_session_activated()
Definition: tls_callbacks.h:97
virtual uint16_t current_write_epoch() const =0
void map_remove_if(Pred pred, T &assoc)
Definition: stl_util.h:96

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::application_protocol ( ) const
pure virtual

Implemented in Botan::TLS::Client, and Botan::TLS::Server.

◆ callbacks()

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

Definition at line 242 of file tls_channel.h.

242{ return m_callbacks; }

Referenced by activate_session(), and save_session().

◆ change_cipher_spec_reader()

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

Definition at line 222 of file tls_channel.cpp.

223 {
224 auto pending = pending_state();
225
226 BOTAN_ASSERT(pending && pending->server_hello(),
227 "Have received server hello");
228
229 if(pending->server_hello()->compression_method() != 0)
230 throw Internal_Error("Negotiated unknown compression algorithm");
231
232 sequence_numbers().new_read_cipher_state();
233
234 const uint16_t epoch = sequence_numbers().current_read_epoch();
235
236 BOTAN_ASSERT(m_read_cipher_states.count(epoch) == 0,
237 "No read cipher state currently set for next epoch");
238
239 // flip side as we are reading
240 std::shared_ptr<Connection_Cipher_State> read_state(
241 new Connection_Cipher_State(pending->version(),
242 (side == CLIENT) ? SERVER : CLIENT,
243 false,
244 pending->ciphersuite(),
245 pending->session_keys(),
246 pending->server_hello()->supports_encrypt_then_mac()));
247
248 m_read_cipher_states[epoch] = read_state;
249 }
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
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::change_cipher_spec_writer ( Connection_Side  side)
protected

Definition at line 251 of file tls_channel.cpp.

252 {
253 auto pending = pending_state();
254
255 BOTAN_ASSERT(pending && pending->server_hello(),
256 "Have received server hello");
257
258 if(pending->server_hello()->compression_method() != 0)
259 throw Internal_Error("Negotiated unknown compression algorithm");
260
261 sequence_numbers().new_write_cipher_state();
262
263 const uint16_t epoch = sequence_numbers().current_write_epoch();
264
265 BOTAN_ASSERT(m_write_cipher_states.count(epoch) == 0,
266 "No write cipher state currently set for next epoch");
267
268 std::shared_ptr<Connection_Cipher_State> write_state(
269 new Connection_Cipher_State(pending->version(),
270 side,
271 true,
272 pending->ciphersuite(),
273 pending->session_keys(),
274 pending->server_hello()->supports_encrypt_then_mac()));
275
276 m_write_cipher_states[epoch] = write_state;
277 }

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::close ( )
inline

Send a close notification alert

Definition at line 149 of file tls_channel.h.

void send_warning_alert(Alert::Type type)
Definition: tls_channel.h:139

References Botan::TLS::Alert::CLOSE_NOTIFY.

◆ create_handshake_state()

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

Definition at line 146 of file tls_channel.cpp.

147 {
148 if(pending_state())
149 throw Internal_Error("create_handshake_state called during handshake");
150
151 if(auto active = active_state())
152 {
153 Protocol_Version active_version = active->version();
154
155 if(active_version.is_datagram_protocol() != version.is_datagram_protocol())
156 {
157 throw TLS_Exception(Alert::PROTOCOL_VERSION,
158 "Active state using version " + active_version.to_string() +
159 " cannot change to " + version.to_string() + " in pending");
160 }
161 }
162
163 if(!m_sequence_numbers)
164 {
165 if(version.is_datagram_protocol())
166 m_sequence_numbers.reset(new Datagram_Sequence_Numbers);
167 else
168 m_sequence_numbers.reset(new Stream_Sequence_Numbers);
169 }
170
171 using namespace std::placeholders;
172
173 std::unique_ptr<Handshake_IO> io;
174 if(version.is_datagram_protocol())
175 {
176 io.reset(new Datagram_Handshake_IO(
177 std::bind(&Channel::send_record_under_epoch, this, _1, _2, _3),
178 sequence_numbers(),
179 static_cast<uint16_t>(m_policy.dtls_default_mtu()),
180 m_policy.dtls_initial_timeout(),
181 m_policy.dtls_maximum_timeout()));
182 }
183 else
184 {
185 io.reset(new Stream_Handshake_IO(std::bind(&Channel::send_record, this, _1, _2)));
186 }
187
188 m_pending_state.reset(new_handshake_state(io.release()));
189
190 if(auto active = active_state())
191 m_pending_state->set_version(active->version());
192
193 return *m_pending_state.get();
194 }
virtual Handshake_State * new_handshake_state(class Handshake_IO *io)=0
virtual size_t dtls_maximum_timeout() const
Definition: tls_policy.cpp:356
virtual size_t dtls_default_mtu() const
Definition: tls_policy.cpp:358
virtual size_t dtls_initial_timeout() const
Definition: tls_policy.cpp:355

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(), Botan::TLS::Alert::PROTOCOL_VERSION, and Botan::TLS::Protocol_Version::to_string().

Referenced by renegotiate().

◆ get_peer_cert_chain()

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

Referenced by peer_cert_chain().

◆ initiate_handshake()

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

Referenced by renegotiate().

◆ inspect_handshake_message()

void Botan::TLS::Channel::inspect_handshake_message ( const Handshake_Message msg)
protected

◆ is_active()

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

Definition at line 279 of file tls_channel.cpp.

280 {
281 if(is_closed())
282 return false;
283 return (active_state() != nullptr);
284 }
bool is_closed() const

References is_closed().

Referenced by Botan::TLS::Blocking_Client::do_handshake(), and send().

◆ is_closed()

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

Definition at line 286 of file tls_channel.cpp.

287 {
288 return m_has_been_closed;
289 }

Referenced by Botan::TLS::Blocking_Client::do_handshake(), is_active(), Botan::TLS::Blocking_Client::read(), and send_alert().

◆ key_material_export()

SymmetricKey Botan::TLS::Channel::key_material_export ( const std::string &  label,
const std::string &  context,
size_t  length 
) const

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

Definition at line 757 of file tls_channel.cpp.

760 {
761 if(auto active = active_state())
762 {
763 if(pending_state() != nullptr)
764 throw Invalid_State("Channel::key_material_export cannot export during renegotiation");
765
766 std::unique_ptr<KDF> prf(active->protocol_specific_prf());
767
768 const secure_vector<uint8_t>& master_secret =
769 active->session_keys().master_secret();
770
771 std::vector<uint8_t> salt;
772 salt += active->client_hello()->random();
773 salt += active->server_hello()->random();
774
775 if(context != "")
776 {
777 size_t context_size = context.length();
778 if(context_size > 0xFFFF)
779 throw Invalid_Argument("key_material_export context is too long");
780 salt.push_back(get_byte(0, static_cast<uint16_t>(context_size)));
781 salt.push_back(get_byte(1, static_cast<uint16_t>(context_size)));
782 salt += to_byte_vector(context);
783 }
784
785 return prf->derive_key(length, master_secret, salt, to_byte_vector(label));
786 }
787 else
788 {
789 throw Invalid_State("Channel::key_material_export connection not active");
790 }
791 }
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:41
std::vector< uint8_t > to_byte_vector(const std::string &s)
Definition: stl_util.h:20

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

◆ new_handshake_state()

virtual Handshake_State * Botan::TLS::Channel::new_handshake_state ( class Handshake_IO io)
protectedpure virtual

Referenced by create_handshake_state().

◆ operator=()

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

◆ peer_cert_chain()

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

Definition at line 134 of file tls_channel.cpp.

135 {
136 if(auto active = active_state())
137 return get_peer_cert_chain(*active);
138 return std::vector<X509_Certificate>();
139 }
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::policy ( ) const
inlineprotected

Definition at line 238 of file tls_channel.h.

238{ return m_policy; }

Referenced by received_data(), and renegotiate().

◆ process_handshake_msg()

virtual void Botan::TLS::Channel::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

◆ received_data() [1/2]

size_t Botan::TLS::Channel::received_data ( const std::vector< uint8_t > &  buf)

Inject TLS traffic received from counterparty

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

Definition at line 311 of file tls_channel.cpp.

312 {
313 return this->received_data(buf.data(), buf.size());
314 }
size_t received_data(const uint8_t buf[], size_t buf_size)

References received_data().

◆ received_data() [2/2]

size_t Botan::TLS::Channel::received_data ( const uint8_t  buf[],
size_t  buf_size 
)

Inject TLS traffic received from counterparty

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

Definition at line 316 of file tls_channel.cpp.

317 {
318 const bool allow_epoch0_restart = m_is_datagram && m_is_server && policy().allow_dtls_epoch0_restart();
319
320 try
321 {
322 while(input_size)
323 {
324 size_t consumed = 0;
325
326 auto get_epoch = [this](uint16_t epoch) { return read_cipher_state_epoch(epoch); };
327
328 const Record_Header record =
329 read_record(m_is_datagram,
330 m_readbuf,
331 input,
332 input_size,
333 consumed,
334 m_record_buf,
335 m_sequence_numbers.get(),
336 get_epoch,
337 allow_epoch0_restart);
338
339 const size_t needed = record.needed();
340
341 BOTAN_ASSERT(consumed > 0, "Got to eat something");
342
343 BOTAN_ASSERT(consumed <= input_size,
344 "Record reader consumed sane amount");
345
346 input += consumed;
347 input_size -= consumed;
348
349 BOTAN_ASSERT(input_size == 0 || needed == 0,
350 "Got a full record or consumed all input");
351
352 if(input_size == 0 && needed != 0)
353 return needed; // need more data to complete record
354
355 // Ignore invalid records in DTLS
356 if(m_is_datagram && record.type() == NO_RECORD)
357 {
358 return 0;
359 }
360
361 if(m_record_buf.size() > MAX_PLAINTEXT_SIZE)
362 throw TLS_Exception(Alert::RECORD_OVERFLOW,
363 "TLS plaintext record is larger than allowed maximum");
364
365
366 const bool epoch0_restart = m_is_datagram && record.epoch() == 0 && active_state();
367 BOTAN_ASSERT_IMPLICATION(epoch0_restart, allow_epoch0_restart, "Allowed state");
368
369 const bool initial_record = epoch0_restart || (!pending_state() && !active_state());
370
371 if(record.type() != ALERT)
372 {
373 if(initial_record)
374 {
375 // For initial records just check for basic sanity
376 if(record.version().major_version() != 3 &&
377 record.version().major_version() != 0xFE)
378 {
379 throw TLS_Exception(Alert::PROTOCOL_VERSION,
380 "Received unexpected record version in initial record");
381 }
382 }
383 else if(auto pending = pending_state())
384 {
385 if(pending->server_hello() != nullptr && record.version() != pending->version())
386 {
387 if(record.version() != pending->version())
388 {
389 throw TLS_Exception(Alert::PROTOCOL_VERSION,
390 "Received unexpected record version");
391 }
392 }
393 }
394 else if(auto active = active_state())
395 {
396 if(record.version() != active->version())
397 {
398 throw TLS_Exception(Alert::PROTOCOL_VERSION,
399 "Received unexpected record version");
400 }
401 }
402 }
403
404 if(record.type() == HANDSHAKE || record.type() == CHANGE_CIPHER_SPEC)
405 {
406 if(m_has_been_closed)
407 throw TLS_Exception(Alert::UNEXPECTED_MESSAGE, "Received handshake data after connection closure");
408 process_handshake_ccs(m_record_buf, record.sequence(), record.type(), record.version(), epoch0_restart);
409 }
410 else if(record.type() == APPLICATION_DATA)
411 {
412 if(m_has_been_closed)
413 throw TLS_Exception(Alert::UNEXPECTED_MESSAGE, "Received application data after connection closure");
414 if(pending_state() != nullptr)
415 throw TLS_Exception(Alert::UNEXPECTED_MESSAGE, "Can't interleave application and handshake data");
416 process_application_data(record.sequence(), m_record_buf);
417 }
418 else if(record.type() == ALERT)
419 {
420 process_alert(m_record_buf);
421 }
422 else if(record.type() != NO_RECORD)
423 throw Unexpected_Message("Unexpected record type " +
424 std::to_string(record.type()) +
425 " from counterparty");
426 }
427
428 return 0; // on a record boundary
429 }
430 catch(TLS_Exception& e)
431 {
432 send_fatal_alert(e.type());
433 throw;
434 }
435 catch(Invalid_Authentication_Tag&)
436 {
438 throw;
439 }
440 catch(Decoding_Error&)
441 {
443 throw;
444 }
445 catch(...)
446 {
448 throw;
449 }
450 }
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
Definition: assert.h:94
void send_fatal_alert(Alert::Type type)
Definition: tls_channel.h:144
virtual bool allow_dtls_epoch0_restart() const
Definition: tls_policy.cpp:350
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
@ CHANGE_CIPHER_SPEC
Definition: tls_magic.h:36
@ APPLICATION_DATA
Definition: tls_magic.h:39
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, get_cipherstate_fn get_cipherstate, bool allow_epoch0_restart)
Definition: tls_record.cpp:514
@ MAX_PLAINTEXT_SIZE
Definition: tls_magic.h:26

References Botan::TLS::ALERT, Botan::TLS::Policy::allow_dtls_epoch0_restart(), Botan::TLS::APPLICATION_DATA, Botan::TLS::Alert::BAD_RECORD_MAC, BOTAN_ASSERT, BOTAN_ASSERT_IMPLICATION, Botan::TLS::CHANGE_CIPHER_SPEC, Botan::TLS::Alert::DECODE_ERROR, Botan::TLS::Record_Header::epoch(), Botan::TLS::HANDSHAKE, Botan::TLS::Alert::INTERNAL_ERROR, Botan::TLS::Protocol_Version::major_version(), Botan::TLS::MAX_PLAINTEXT_SIZE, Botan::TLS::Record_Header::needed(), Botan::TLS::NO_RECORD, policy(), Botan::TLS::Alert::PROTOCOL_VERSION, Botan::TLS::read_record(), Botan::TLS::Alert::RECORD_OVERFLOW, send_fatal_alert(), Botan::TLS::Record_Header::sequence(), Botan::ASN1::to_string(), Botan::TLS::TLS_Exception::type(), Botan::TLS::Record_Header::type(), Botan::TLS::Alert::UNEXPECTED_MESSAGE, and Botan::TLS::Record_Header::version().

Referenced by Botan::TLS::Blocking_Client::do_handshake(), Botan::TLS::Blocking_Client::read(), and received_data().

◆ renegotiate()

void Botan::TLS::Channel::renegotiate ( bool  force_full_renegotiation = false)

Attempt to renegotiate the session

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

Definition at line 205 of file tls_channel.cpp.

206 {
207 if(pending_state()) // currently in handshake?
208 return;
209
210 if(auto active = active_state())
211 {
212 if(force_full_renegotiation == false)
213 force_full_renegotiation = !policy().allow_resumption_for_renegotiation();
214
216 force_full_renegotiation);
217 }
218 else
219 throw Invalid_State("Cannot renegotiate on inactive connection");
220 }
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:345

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

◆ reset_active_association_state()

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

Definition at line 92 of file tls_channel.cpp.

93 {
94 // This operation only makes sense for DTLS
95 BOTAN_ASSERT_NOMSG(m_is_datagram);
96 m_active_state.reset();
97 m_read_cipher_states.clear();
98 m_write_cipher_states.clear();
99
100 m_write_cipher_states[0] = nullptr;
101 m_read_cipher_states[0] = nullptr;
102
103 if(m_sequence_numbers)
104 m_sequence_numbers->reset();
105 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68

References BOTAN_ASSERT_NOMSG.

◆ rng()

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

Definition at line 234 of file tls_channel.h.

234{ return m_rng; }

◆ save_session()

bool Botan::TLS::Channel::save_session ( const Session session)
protected

Definition at line 141 of file tls_channel.cpp.

142 {
143 return callbacks().tls_session_established(session);
144 }
virtual bool tls_session_established(const Session &session)=0

References callbacks(), and Botan::TLS::Callbacks::tls_session_established().

◆ secure_renegotiation_check() [1/2]

void Botan::TLS::Channel::secure_renegotiation_check ( const Client_Hello client_hello)
protected

Definition at line 680 of file tls_channel.cpp.

681 {
682 const bool secure_renegotiation = client_hello->secure_renegotiation();
683
684 if(auto active = active_state())
685 {
686 const bool active_sr = active->client_hello()->secure_renegotiation();
687
688 if(active_sr != secure_renegotiation)
689 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
690 "Client changed its mind about secure renegotiation");
691 }
692
693 if(secure_renegotiation)
694 {
695 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
696
698 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
699 "Client sent bad values for secure renegotiation");
700 }
701 }
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const

References Botan::TLS::Alert::HANDSHAKE_FAILURE, Botan::TLS::Client_Hello::renegotiation_info(), Botan::TLS::Client_Hello::secure_renegotiation(), and secure_renegotiation_data_for_client_hello().

◆ secure_renegotiation_check() [2/2]

void Botan::TLS::Channel::secure_renegotiation_check ( const Server_Hello server_hello)
protected

Definition at line 703 of file tls_channel.cpp.

704 {
705 const bool secure_renegotiation = server_hello->secure_renegotiation();
706
707 if(auto active = active_state())
708 {
709 const bool active_sr = active->server_hello()->secure_renegotiation();
710
711 if(active_sr != secure_renegotiation)
712 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
713 "Server changed its mind about secure renegotiation");
714 }
715
716 if(secure_renegotiation)
717 {
718 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
719
721 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
722 "Server sent bad values for secure renegotiation");
723 }
724 }
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const

References Botan::TLS::Alert::HANDSHAKE_FAILURE, Botan::TLS::Server_Hello::renegotiation_info(), Botan::TLS::Server_Hello::secure_renegotiation(), and secure_renegotiation_data_for_server_hello().

◆ secure_renegotiation_data_for_client_hello()

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

Definition at line 726 of file tls_channel.cpp.

727 {
728 if(auto active = active_state())
729 return active->client_finished()->verify_data();
730 return std::vector<uint8_t>();
731 }

Referenced by secure_renegotiation_check().

◆ secure_renegotiation_data_for_server_hello()

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

Definition at line 733 of file tls_channel.cpp.

734 {
735 if(auto active = active_state())
736 {
737 std::vector<uint8_t> buf = active->client_finished()->verify_data();
738 buf += active->server_finished()->verify_data();
739 return buf;
740 }
741
742 return std::vector<uint8_t>();
743 }

Referenced by secure_renegotiation_check().

◆ secure_renegotiation_supported()

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

Definition at line 745 of file tls_channel.cpp.

746 {
747 if(auto active = active_state())
748 return active->server_hello()->secure_renegotiation();
749
750 if(auto pending = pending_state())
751 if(auto hello = pending->server_hello())
752 return hello->secure_renegotiation();
753
754 return false;
755 }

◆ send() [1/3]

void Botan::TLS::Channel::send ( const std::string &  val)

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

Definition at line 646 of file tls_channel.cpp.

647 {
648 this->send(cast_char_ptr_to_uint8(string.data()), string.size());
649 }
void send(const uint8_t buf[], size_t buf_size)
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:190

References Botan::cast_char_ptr_to_uint8(), and send().

◆ send() [2/3]

template<typename Alloc >
void Botan::TLS::Channel::send ( const std::vector< unsigned char, Alloc > &  val)
inline

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

Definition at line 124 of file tls_channel.h.

125 {
126 send(val.data(), val.size());
127 }

◆ send() [3/3]

void Botan::TLS::Channel::send ( const uint8_t  buf[],
size_t  buf_size 
)

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

Definition at line 637 of file tls_channel.cpp.

638 {
639 if(!is_active())
640 throw Invalid_State("Data cannot be sent on inactive TLS connection");
641
642 send_record_array(sequence_numbers().current_write_epoch(),
643 APPLICATION_DATA, buf, buf_size);
644 }
bool is_active() const

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

Referenced by send().

◆ send_alert()

void Botan::TLS::Channel::send_alert ( const Alert alert)

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

Parameters
alertthe Alert to send

Definition at line 651 of file tls_channel.cpp.

652 {
653 if(alert.is_valid() && !is_closed())
654 {
655 try
656 {
657 send_record(ALERT, alert.serialize());
658 }
659 catch(...) { /* swallow it */ }
660 }
661
662 if(alert.type() == Alert::NO_RENEGOTIATION)
663 m_pending_state.reset();
664
665 if(alert.is_fatal())
666 {
667 if(auto active = active_state())
668 {
669 m_session_manager.remove_entry(active->server_hello()->session_id());
670 }
671 reset_state();
672 }
673
674 if(alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal())
675 {
676 m_has_been_closed = true;
677 }
678 }
virtual void remove_entry(const std::vector< uint8_t > &session_id)=0

References Botan::TLS::ALERT, Botan::TLS::Alert::CLOSE_NOTIFY, is_closed(), Botan::TLS::Alert::is_fatal(), Botan::TLS::Alert::is_valid(), Botan::TLS::Alert::NO_RENEGOTIATION, Botan::TLS::Session_Manager::remove_entry(), Botan::TLS::Alert::serialize(), and Botan::TLS::Alert::type().

◆ send_fatal_alert()

void Botan::TLS::Channel::send_fatal_alert ( Alert::Type  type)
inline

Send a fatal alert

Definition at line 144 of file tls_channel.h.

144{ send_alert(Alert(type, true)); }
void send_alert(const Alert &alert)
MechanismType type

References type.

Referenced by received_data().

◆ send_warning_alert()

void Botan::TLS::Channel::send_warning_alert ( Alert::Type  type)
inline

Send a warning alert

Definition at line 139 of file tls_channel.h.

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

References type.

◆ session_manager()

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

Definition at line 236 of file tls_channel.h.

236{ return m_session_manager; }

◆ timeout_check()

bool Botan::TLS::Channel::timeout_check ( )

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.

Definition at line 196 of file tls_channel.cpp.

197 {
198 if(m_pending_state)
199 return m_pending_state->handshake_io().timeout_check();
200
201 //FIXME: scan cipher suites and remove epochs older than 2*MSL
202 return false;
203 }

Member Data Documentation

◆ IO_BUF_DEFAULT_SIZE

size_t Botan::TLS::Channel::IO_BUF_DEFAULT_SIZE = 10*1024
static

Definition at line 45 of file tls_channel.h.


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