Botan 2.19.3
Crypto and TLS for C&
Public Types | Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
Botan::TLS::Server Class Referencefinal

#include <tls_server.h>

Inheritance diagram for Botan::TLS::Server:
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< std::string(std::vector< std::string >)> next_protocol_fn
 
typedef std::function< void(const uint8_t[], size_t)> output_fn
 

Public Member Functions

std::string application_protocol () const override
 
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
 
std::string next_protocol () const
 
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)
 
 Server (Callbacks &callbacks, Session_Manager &session_manager, Credentials_Manager &creds, const Policy &policy, RandomNumberGenerator &rng, bool is_datagram=false, size_t reserved_io_buffer_size=TLS::Server::IO_BUF_DEFAULT_SIZE)
 
 Server (output_fn output, data_cb data_cb, alert_cb recv_alert_cb, handshake_cb hs_cb, handshake_msg_cb hs_msg_cb, Session_Manager &session_manager, Credentials_Manager &creds, const Policy &policy, RandomNumberGenerator &rng, next_protocol_fn next_proto=next_protocol_fn(), bool is_datagram=false)
 
 Server (output_fn output, data_cb data_cb, alert_cb recv_alert_cb, handshake_cb hs_cb, Session_Manager &session_manager, Credentials_Manager &creds, const Policy &policy, RandomNumberGenerator &rng, next_protocol_fn next_proto=next_protocol_fn(), bool is_datagram=false, size_t reserved_io_buffer_size=TLS::Server::IO_BUF_DEFAULT_SIZE)
 
bool timeout_check ()
 

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)
 
void inspect_handshake_message (const Handshake_Message &msg)
 
const Policypolicy () const
 
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

TLS Server

Definition at line 26 of file tls_server.h.

Member Typedef Documentation

◆ alert_cb

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

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
inherited

Definition at line 41 of file tls_channel.h.

◆ handshake_cb

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

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
inherited

Definition at line 44 of file tls_channel.h.

◆ next_protocol_fn

typedef std::function<std::string (std::vector<std::string>)> Botan::TLS::Server::next_protocol_fn

Definition at line 29 of file tls_server.h.

◆ output_fn

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

Definition at line 40 of file tls_channel.h.

Constructor & Destructor Documentation

◆ Server() [1/3]

Botan::TLS::Server::Server ( Callbacks callbacks,
Session_Manager session_manager,
Credentials_Manager creds,
const Policy policy,
RandomNumberGenerator rng,
bool  is_datagram = false,
size_t  reserved_io_buffer_size = TLS::Server::IO_BUF_DEFAULT_SIZE 
)

Server initialization

Parameters
callbackscontains a set of callback function references required by the TLS client.
session_managermanages session state
credsmanages application/user credentials
policyspecifies other connection policy information
rnga random number generator
is_datagramset to true if this server should expect DTLS connections. Otherwise TLS connections are expected.
reserved_io_buffer_sizeThis 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 298 of file tls_server.cpp.

304 :
306 true, is_datagram, io_buf_sz),
307 m_creds(creds)
308 {
309 }
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)
Callbacks & callbacks() const
Session_Manager & session_manager()
const Policy & policy() const
RandomNumberGenerator & rng()

◆ Server() [2/3]

Botan::TLS::Server::Server ( output_fn  output,
data_cb  data_cb,
alert_cb  recv_alert_cb,
handshake_cb  hs_cb,
Session_Manager session_manager,
Credentials_Manager creds,
const Policy policy,
RandomNumberGenerator rng,
next_protocol_fn  next_proto = next_protocol_fn(),
bool  is_datagram = false,
size_t  reserved_io_buffer_size = TLS::Server::IO_BUF_DEFAULT_SIZE 
)

DEPRECATED. This constructor is only provided for backward compatibility and should not be used in new implementations. It will be removed in a future release.

Definition at line 311 of file tls_server.cpp.

321 :
322 Channel(output, got_data_cb, recv_alert_cb, hs_cb,
324 rng, policy, true, is_datagram, io_buf_sz),
325 m_creds(creds),
326 m_choose_next_protocol(next_proto)
327 {
328 }
std::function< void(const Handshake_Message &)> handshake_msg_cb
Definition tls_channel.h:44

◆ Server() [3/3]

Botan::TLS::Server::Server ( output_fn  output,
data_cb  data_cb,
alert_cb  recv_alert_cb,
handshake_cb  hs_cb,
handshake_msg_cb  hs_msg_cb,
Session_Manager session_manager,
Credentials_Manager creds,
const Policy policy,
RandomNumberGenerator rng,
next_protocol_fn  next_proto = next_protocol_fn(),
bool  is_datagram = false 
)

DEPRECATED. This constructor is only provided for backward compatibility and should not be used in new implementations. It will be removed in a future release.

Definition at line 330 of file tls_server.cpp.

340 :
341 Channel(output, got_data_cb, recv_alert_cb, hs_cb, hs_msg_cb,
342 session_manager, rng, policy, true, is_datagram),
343 m_creds(creds),
344 m_choose_next_protocol(next_proto)
345 {
346 }

Member Function Documentation

◆ activate_session()

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

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()
virtual uint16_t current_write_epoch() const =0
void map_remove_if(Pred pred, T &assoc)
Definition stl_util.h:96

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

◆ application_protocol()

std::string Botan::TLS::Server::application_protocol ( ) const
inlineoverridevirtual

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

Implements Botan::TLS::Channel.

Definition at line 113 of file tls_server.h.

113{ return m_next_protocol; }

◆ callbacks()

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

Definition at line 242 of file tls_channel.h.

242{ return m_callbacks; }

Referenced by Botan::TLS::Channel::activate_session(), and Botan::TLS::Channel::save_session().

◆ change_cipher_spec_reader()

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

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)
protectedinherited

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

Send a close notification alert

Definition at line 149 of file tls_channel.h.

◆ create_handshake_state()

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

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
virtual size_t dtls_default_mtu() const
virtual size_t dtls_initial_timeout() const

References Botan::TLS::Policy::dtls_default_mtu(), Botan::TLS::Policy::dtls_initial_timeout(), Botan::TLS::Policy::dtls_maximum_timeout(), Botan::TLS::Protocol_Version::is_datagram_protocol(), Botan::TLS::Channel::new_handshake_state(), Botan::TLS::Alert::PROTOCOL_VERSION, and Botan::TLS::Protocol_Version::to_string().

Referenced by Botan::TLS::Channel::renegotiate().

◆ inspect_handshake_message()

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

◆ is_active()

bool Botan::TLS::Channel::is_active ( ) const
inherited
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 Botan::TLS::Channel::is_closed().

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

◆ is_closed()

bool Botan::TLS::Channel::is_closed ( ) const
inherited
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(), Botan::TLS::Channel::is_active(), Botan::TLS::Blocking_Client::read(), and Botan::TLS::Channel::send_alert().

◆ key_material_export()

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

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

◆ next_protocol()

std::string Botan::TLS::Server::next_protocol ( ) const
inline

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

Definition at line 105 of file tls_server.h.

105{ return m_next_protocol; }

◆ peer_cert_chain()

std::vector< X509_Certificate > Botan::TLS::Channel::peer_cert_chain ( ) const
inherited
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 Botan::TLS::Channel::get_peer_cert_chain().

◆ policy()

const Policy & Botan::TLS::Channel::policy ( ) const
inlineprotectedinherited

Definition at line 238 of file tls_channel.h.

238{ return m_policy; }

Referenced by Botan::TLS::Channel::received_data(), and Botan::TLS::Channel::renegotiate().

◆ received_data() [1/2]

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

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 Botan::TLS::Channel::received_data().

◆ received_data() [2/2]

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

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)
virtual bool allow_dtls_epoch0_restart() const
@ 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)
@ 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, Botan::TLS::Channel::policy(), Botan::TLS::Alert::PROTOCOL_VERSION, Botan::TLS::read_record(), Botan::TLS::Alert::RECORD_OVERFLOW, Botan::TLS::Channel::send_fatal_alert(), Botan::TLS::Record_Header::sequence(), 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 Botan::TLS::Channel::received_data().

◆ renegotiate()

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

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

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

◆ reset_active_association_state()

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

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

Definition at line 234 of file tls_channel.h.

234{ return m_rng; }

◆ save_session()

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

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 Botan::TLS::Channel::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)
protectedinherited

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 Botan::TLS::Channel::secure_renegotiation_data_for_client_hello().

◆ secure_renegotiation_check() [2/2]

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

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

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 Botan::TLS::Channel::secure_renegotiation_check().

◆ secure_renegotiation_data_for_server_hello()

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

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 Botan::TLS::Channel::secure_renegotiation_check().

◆ secure_renegotiation_supported()

bool Botan::TLS::Channel::secure_renegotiation_supported ( ) const
inherited
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)
inherited

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 Botan::TLS::Channel::send().

◆ send() [2/3]

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

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 
)
inherited

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 Botan::TLS::Channel::is_active().

Referenced by Botan::TLS::Channel::send().

◆ send_alert()

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

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, Botan::TLS::Channel::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)
inlineinherited

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 Botan::TLS::Channel::received_data().

◆ send_warning_alert()

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

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

Definition at line 236 of file tls_channel.h.

236{ return m_session_manager; }

◆ timeout_check()

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

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
staticinherited

Definition at line 45 of file tls_channel.h.


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