Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

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:

## 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 (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)
| Channel (const Channel &)=delete
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
Channel & | operator= (const Channel &)=delete
std::vector< X509_Certificate > | peer_cert_chain () const
size_t | received_data (const uint8_t buf[], size_t buf_size)
size_t | received_data (const std::vector< uint8_t > &buf)
void | renegotiate (bool force_full_renegotiation=false)
bool | secure_renegotiation_supported () const
void | send (const uint8_t buf[], size_t buf_size)
void | send (const std::string &val)
template<typename Alloc >
void | send (const std::vector< unsigned char, Alloc > &val)
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 ()
Callbacks & | callbacks () const
void | change_cipher_spec_reader (Connection_Side side)
void | change_cipher_spec_writer (Connection_Side side)
Handshake_State & | create_handshake_state (Protocol_Version version)
virtual std::vector< X509_Certificate > | get_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_State * | new_handshake_state (class Handshake_IO *io)=0
const Policy & | policy () 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 ()
RandomNumberGenerator & | rng ()
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_Manager & | session_manager ()

## Detailed Description

Generic interface for TLS endpoint

Definition at line 37 of file tls_channel.h.

## Member Typedef Documentation

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

Definition at line 42 of file tls_channel.h.

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

Definition at line 41 of file tls_channel.h.

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

Definition at line 43 of file tls_channel.h.

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

Definition at line 44 of file tls_channel.h.

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

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

  callbacks | contains a set of callback function references required by the TLS endpoint.
  session_manager | manages session state
  rng | a random number generator
  policy | specifies other connection policy information
  is_server | whether this is a server session or not
  is_datagram | whether this is a DTLS session
  io_buf_sz | This 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 }
Botan::TLS::Channel::callbacks
Callbacks & callbacks() const
Definition: tls_channel.h:242
Botan::TLS::Channel::rng
RandomNumberGenerator & rng()
Definition: tls_channel.h:234
Botan::TLS::Channel::policy
const Policy & policy() const
Definition: tls_channel.h:238
Botan::TLS::Channel::session_manager
Session_Manager & session_manager()
Definition: tls_channel.h:236

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 */
62 Compat_Callbacks::SILENCE_DEPRECATION_WARNING::PLEASE,
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 }
Botan::TLS::Compat_Callbacks::SILENCE_DEPRECATION_WARNING::PLEASE
Botan::TLS::Channel::rng
RandomNumberGenerator & rng()
Definition: tls_channel.h:234
Botan::TLS::Channel::policy
const Policy & policy() const
Definition: tls_channel.h:238
Botan::TLS::Channel::session_manager
Session_Manager & session_manager()
Definition: tls_channel.h:236

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

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

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

Definition at line 291 of file tls_channel.cpp.

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

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
308 callbacks().tls_session_activated();
309 }
Botan::TLS::Channel::callbacks
Callbacks & callbacks() const
Definition: tls_channel.h:242
Botan::TLS::Callbacks::tls_session_activated
virtual void tls_session_activated()
Definition: tls_callbacks.h:97
Botan::map_remove_if
void map_remove_if(Pred pred, T &assoc)
Definition: stl_util.h:96
Botan::TLS::Connection_Sequence_Numbers::current_write_epoch
virtual uint16_t current_write_epoch() const =0

virtual std::string Botan::TLS::Channel::application_protocol | ( |  | ) | const
| pure virtual

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

Callbacks& Botan::TLS::Channel::callbacks | ( |  | ) | const
| inline protected

Definition at line 242 of file tls_channel.h.

Referenced by activate_session(), and save_session().

242 { return m_callbacks; }

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

Definition at line 222 of file tls_channel.cpp.

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.

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 }
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
Botan::TLS::Connection_Sequence_Numbers::new_read_cipher_state
virtual void new_read_cipher_state()=0
Botan::TLS::CLIENT
Definition: tls_magic.h:32
Botan::TLS::SERVER
Definition: tls_magic.h:32
Botan::OCSP::Response_Status_Code::Internal_Error
Botan::TLS::Connection_Sequence_Numbers::current_read_epoch
virtual uint16_t current_read_epoch() const =0

void Botan::TLS::Channel::change_cipher_spec_writer | ( | Connection_Side | side | ) |
| protected

Definition at line 251 of file tls_channel.cpp.

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

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 }
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
Botan::TLS::Connection_Sequence_Numbers::current_write_epoch
virtual uint16_t current_write_epoch() const =0
Botan::OCSP::Response_Status_Code::Internal_Error
Botan::TLS::Connection_Sequence_Numbers::new_write_cipher_state
virtual void new_write_cipher_state()=0

void Botan::TLS::Channel::close | ( |  | ) |
| inline

Send a close notification alert

Definition at line 149 of file tls_channel.h.

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

149 { send_warning_alert(Alert::CLOSE_NOTIFY); }
Botan::TLS::Channel::send_warning_alert
void send_warning_alert(Alert::Type type)
Definition: tls_channel.h:139
Botan::TLS::Alert::CLOSE_NOTIFY
Definition: tls_alert.h:28

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

Definition at line 146 of file tls_channel.cpp.

References 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().

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 }
placeholders
Botan::TLS::Channel::new_handshake_state
virtual Handshake_State * new_handshake_state(class Handshake_IO *io)=0
Botan::OCSP::Response_Status_Code::Internal_Error
Botan::TLS::Alert::PROTOCOL_VERSION
Definition: tls_alert.h:47

virtual std::vector<X509_Certificate> Botan::TLS::Channel::get_peer_cert_chain | ( | const Handshake_State & | state | ) | const
| protected pure virtual

Referenced by peer_cert_chain().

virtual void Botan::TLS::Channel::initiate_handshake | ( | Handshake_State & | state,
|  | bool | force_full_renegotiation
| ) |  |
| protected pure virtual

Referenced by renegotiate().

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

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.

References is_closed().

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

280 {
281 if(is_closed())
282 return false;
283 return (active_state() != nullptr);
284 }
Botan::TLS::Channel::is_closed
bool is_closed() const
Definition: tls_channel.cpp:286

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.

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

287 {
288 return m_has_been_closed;
289 }

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

  label | a disambiguating label string
  context | a per-association context value
  length | the length of the desired key in bytes

Returns
  key of length bytes

Definition at line 751 of file tls_channel.cpp.

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

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

virtual Handshake_State* Botan::TLS::Channel::new_handshake_state | ( | class Handshake_IO * | io | ) |
| protected pure virtual

Referenced by create_handshake_state().

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

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.

References get_peer_cert_chain().

135 {
136 if(auto active = active_state())
137 return get_peer_cert_chain(*active);
138 return std::vector<X509_Certificate>();
139 }
Botan::TLS::Channel::get_peer_cert_chain
virtual std::vector< X509_Certificate > get_peer_cert_chain(const Handshake_State &state) const =0

const Policy& Botan::TLS::Channel::policy | ( |  | ) | const
| inline protected

Definition at line 238 of file tls_channel.h.

Referenced by received_data(), and renegotiate().

238 { return m_policy; }

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
| ) |  |
| protected pure virtual

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.

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

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 {
437 send_fatal_alert(Alert::BAD_RECORD_MAC);
438 throw;
439 }
440 catch(Decoding_Error&)
441 {
442 send_fatal_alert(Alert::DECODE_ERROR);
443 throw;
444 }
445 catch(...)
446 {
447 send_fatal_alert(Alert::INTERNAL_ERROR);
448 throw;
449 }
450 }
Botan::TLS::read_record
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:497
Botan::TLS::ALERT
Definition: tls_magic.h:37
Botan::TLS::MAX_PLAINTEXT_SIZE
Definition: tls_magic.h:26
Botan::TLS::Alert::INTERNAL_ERROR
Definition: tls_alert.h:49
Botan::TLS::APPLICATION_DATA
Definition: tls_magic.h:39
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
BOTAN_ASSERT
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
Botan::TLS::Alert::DECODE_ERROR
Definition: tls_alert.h:44
Botan::TLS::Record_Header::needed
size_t needed() const
Definition: tls_record.h:99
Botan::TLS::Channel::send_fatal_alert
void send_fatal_alert(Alert::Type type)
Definition: tls_channel.h:144
Botan::TLS::CHANGE_CIPHER_SPEC
Definition: tls_magic.h:36
Botan::TLS::NO_RECORD
Definition: tls_magic.h:41
Botan::TLS::Alert::RECORD_OVERFLOW
Definition: tls_alert.h:32
BOTAN_ASSERT_IMPLICATION
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
Definition: assert.h:94
Botan::TLS::Alert::PROTOCOL_VERSION
Definition: tls_alert.h:47
Botan::TLS::Channel::policy
const Policy & policy() const
Definition: tls_channel.h:238
Botan::TLS::Policy::allow_dtls_epoch0_restart
virtual bool allow_dtls_epoch0_restart() const
Definition: tls_policy.cpp:350
Botan::TLS::Alert::UNEXPECTED_MESSAGE
Definition: tls_alert.h:29
Botan::TLS::HANDSHAKE
Definition: tls_magic.h:38
Botan::TLS::Alert::BAD_RECORD_MAC
Definition: tls_alert.h:30

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.

References received_data().

312 {
313 return this->received_data(buf.data(), buf.size());
314 }
Botan::TLS::Channel::received_data
size_t received_data(const uint8_t buf[], size_t buf_size)
Definition: tls_channel.cpp:316

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

Attempt to renegotiate the session

Parameters

  force_full_renegotiation | if true, require a full renegotiation, otherwise allow session resumption

Definition at line 205 of file tls_channel.cpp.

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

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
215 initiate_handshake(create_handshake_state(active->version()),
216 force_full_renegotiation);
217 }
218 else
219 throw Invalid_State("Cannot renegotiate on inactive connection");
220 }
Botan::TLS::Channel::create_handshake_state
Handshake_State & create_handshake_state(Protocol_Version version)
Definition: tls_channel.cpp:146
Botan::TLS::Policy::allow_resumption_for_renegotiation
virtual bool allow_resumption_for_renegotiation() const
Definition: tls_policy.cpp:345
Botan::TLS::Channel::policy
const Policy & policy() const
Definition: tls_channel.h:238
Botan::TLS::Channel::initiate_handshake
virtual void initiate_handshake(Handshake_State &state, bool force_full_renegotiation)=0

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

Definition at line 92 of file tls_channel.cpp.

References BOTAN_ASSERT_NOMSG.

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 }
BOTAN_ASSERT_NOMSG
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:68

RandomNumberGenerator& Botan::TLS::Channel::rng | ( |  | ) |
| inline protected

Definition at line 234 of file tls_channel.h.

References m_rng.

234 { return m_rng; }

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

Definition at line 141 of file tls_channel.cpp.

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

142 {
143 return callbacks().tls_session_established(session);
144 }
Botan::TLS::Callbacks::tls_session_established
virtual bool tls_session_established(const Session &session)=0
Botan::TLS::Channel::callbacks
Callbacks & callbacks() const
Definition: tls_channel.h:242

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

Definition at line 674 of file tls_channel.cpp.

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

675 {
676 const bool secure_renegotiation = client_hello->secure_renegotiation();
677
678 if(auto active = active_state())
679 {
680 const bool active_sr = active->client_hello()->secure_renegotiation();
681
682 if(active_sr != secure_renegotiation)
683 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
684 "Client changed its mind about secure renegotiation");
685 }
686
687 if(secure_renegotiation)
688 {
689 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
690
691 if(data != secure_renegotiation_data_for_client_hello())
692 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
693 "Client sent bad values for secure renegotiation");
694 }
695 }
Botan::TLS::Channel::secure_renegotiation_data_for_client_hello
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const
Definition: tls_channel.cpp:720
Botan::TLS::Alert::HANDSHAKE_FAILURE
Definition: tls_alert.h:34

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

Definition at line 697 of file tls_channel.cpp.

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

698 {
699 const bool secure_renegotiation = server_hello->secure_renegotiation();
700
701 if(auto active = active_state())
702 {
703 const bool active_sr = active->server_hello()->secure_renegotiation();
704
705 if(active_sr != secure_renegotiation)
706 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
707 "Server changed its mind about secure renegotiation");
708 }
709
710 if(secure_renegotiation)
711 {
712 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
713
714 if(data != secure_renegotiation_data_for_server_hello())
715 throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
716 "Server sent bad values for secure renegotiation");
717 }
718 }
Botan::TLS::Channel::secure_renegotiation_data_for_server_hello
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const
Definition: tls_channel.cpp:727
Botan::TLS::Alert::HANDSHAKE_FAILURE
Definition: tls_alert.h:34

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

Definition at line 720 of file tls_channel.cpp.

Referenced by secure_renegotiation_check().

721 {
722 if(auto active = active_state())
723 return active->client_finished()->verify_data();
724 return std::vector<uint8_t>();
725 }

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

Definition at line 727 of file tls_channel.cpp.

Referenced by secure_renegotiation_check().

728 {
729 if(auto active = active_state())
730 {
731 std::vector<uint8_t> buf = active->client_finished()->verify_data();
732 buf += active->server_finished()->verify_data();
733 return buf;
734 }
735
736 return std::vector<uint8_t>();
737 }

bool Botan::TLS::Channel::secure_renegotiation_supported | ( |  | ) | const

Returns
  true iff the counterparty supports the secure renegotiation extensions.

Definition at line 739 of file tls_channel.cpp.

740 {
741 if(auto active = active_state())
742 return active->server_hello()->secure_renegotiation();
743
744 if(auto pending = pending_state())
745 if(auto hello = pending->server_hello())
746 return hello->secure_renegotiation();
747
748 return false;
749 }

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

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

Referenced by send().

634 {
635 if(!is_active())
636 throw Invalid_State("Data cannot be sent on inactive TLS connection");
637
638 send_record_array(sequence_numbers().current_write_epoch(),
639 APPLICATION_DATA, buf, buf_size);
640 }
Botan::TLS::APPLICATION_DATA
Definition: tls_magic.h:39
Botan::TLS::Channel::is_active
bool is_active() const
Definition: tls_channel.cpp:279

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

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

643 {
644 this->send(cast_char_ptr_to_uint8(string.data()), string.size());
645 }
Botan::cast_char_ptr_to_uint8
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:189
Botan::TLS::Channel::send
void send(const uint8_t buf[], size_t buf_size)
Definition: tls_channel.cpp:633
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 }
Botan::TLS::Channel::send
void send(const uint8_t buf[], size_t buf_size)
Definition: tls_channel.cpp:633

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

  alert | the Alert to send

Definition at line 647 of file tls_channel.cpp.

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

648 {
649 if(alert.is_valid() && !is_closed())
650 {
651 try
652 {
653 send_record(ALERT, alert.serialize());
654 }
655 catch(...) { /* swallow it */ }
656 }
657
658 if(alert.type() == Alert::NO_RENEGOTIATION)
659 m_pending_state.reset();
660
661 if(alert.is_fatal())
662 if(auto active = active_state())
663 m_session_manager.remove_entry(active->server_hello()->session_id());
664
665 if(alert.is_fatal())
666 reset_state();
667
668 if(alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal())
669 {
670 m_has_been_closed = true;
671 }
672 }
Botan::TLS::ALERT
Definition: tls_magic.h:37
Botan::TLS::Session_Manager::remove_entry
virtual void remove_entry(const std::vector< uint8_t > &session_id)=0
Botan::TLS::Channel::is_closed
bool is_closed() const
Definition: tls_channel.cpp:286
Botan::TLS::Alert::CLOSE_NOTIFY
Definition: tls_alert.h:28
Botan::TLS::Alert::NO_RENEGOTIATION
Definition: tls_alert.h:52

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

Send a fatal alert

Definition at line 144 of file tls_channel.h.

Referenced by received_data().

144 { send_alert(Alert(type, true)); }
type
MechanismType type
Definition: p11_mechanism.cpp:44
Botan::TLS::Channel::send_alert
void send_alert(const Alert &alert)
Definition: tls_channel.cpp:647

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)); }
type
MechanismType type
Definition: p11_mechanism.cpp:44
Botan::TLS::Channel::send_alert
void send_alert(const Alert &alert)
Definition: tls_channel.cpp:647

Session_Manager& Botan::TLS::Channel::session_manager | ( |  | ) |
| inline protected

Definition at line 236 of file tls_channel.h.

236 { return m_session_manager; }

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

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:

- src/lib/tls/tls_channel.h
- src/lib/tls/tls_channel.cpp