Botan
1.11.15
|
#include <tls_channel.h>
Public Types | |
typedef std::function< void(Alert, const byte[], size_t)> | alert_cb |
typedef std::function< void(const byte[], size_t)> | data_cb |
typedef std::function< bool(const Session &)> | handshake_cb |
typedef std::function< void(const byte[], size_t)> | output_fn |
Public Member Functions | |
Channel (output_fn out, data_cb app_data_cb, alert_cb alert_cb, handshake_cb hs_cb, Session_Manager &session_manager, RandomNumberGenerator &rng, bool is_datagram, size_t reserved_io_buffer_size) | |
Channel (const Channel &) | |
void | close () |
void | heartbeat (const byte payload[], size_t payload_size, size_t pad_bytes=0) |
void | heartbeat () |
bool | heartbeat_sending_allowed () const |
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 &) |
std::vector< X509_Certificate > | peer_cert_chain () const |
bool | peer_supports_heartbeats () const |
size_t | received_data (const byte buf[], size_t buf_size) |
size_t | received_data (const std::vector< byte > &buf) |
void | renegotiate (bool force_full_renegotiation=false) |
bool | secure_renegotiation_supported () const |
void | send (const byte 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 () |
Protected Member Functions | |
void | activate_session () |
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 |
virtual Handshake_State * | new_handshake_state (class Handshake_IO *io)=0 |
virtual void | process_handshake_msg (const Handshake_State *active_state, Handshake_State &pending_state, Handshake_Type type, const std::vector< byte > &contents)=0 |
RandomNumberGenerator & | rng () |
bool | save_session (const Session &session) const |
void | secure_renegotiation_check (const class Client_Hello *client_hello) |
void | secure_renegotiation_check (const class Server_Hello *server_hello) |
std::vector< byte > | secure_renegotiation_data_for_client_hello () const |
std::vector< byte > | secure_renegotiation_data_for_server_hello () const |
Session_Manager & | session_manager () |
Generic interface for TLS endpoint
Definition at line 31 of file tls_channel.h.
typedef std::function<void (Alert, const byte[], size_t)> Botan::TLS::Channel::alert_cb |
Definition at line 36 of file tls_channel.h.
typedef std::function<void (const byte[], size_t)> Botan::TLS::Channel::data_cb |
Definition at line 35 of file tls_channel.h.
typedef std::function<bool (const Session&)> Botan::TLS::Channel::handshake_cb |
Definition at line 37 of file tls_channel.h.
typedef std::function<void (const byte[], size_t)> Botan::TLS::Channel::output_fn |
Definition at line 34 of file tls_channel.h.
Botan::TLS::Channel::Channel | ( | output_fn | out, |
data_cb | app_data_cb, | ||
alert_cb | alert_cb, | ||
handshake_cb | hs_cb, | ||
Session_Manager & | session_manager, | ||
RandomNumberGenerator & | rng, | ||
bool | is_datagram, | ||
size_t | reserved_io_buffer_size | ||
) |
Definition at line 22 of file tls_channel.cpp.
: m_is_datagram(is_datagram), m_handshake_cb(handshake_cb), m_data_cb(data_cb), m_alert_cb(alert_cb), m_output_fn(output_fn), m_rng(rng), m_session_manager(session_manager) { /* epoch 0 is plaintext, thus null cipher state */ m_write_cipher_states[0] = nullptr; m_read_cipher_states[0] = nullptr; m_writebuf.reserve(reserved_io_buffer_size); m_readbuf.reserve(reserved_io_buffer_size); }
Botan::TLS::Channel::Channel | ( | const Channel & | ) |
Botan::TLS::Channel::~Channel | ( | ) | [virtual] |
Definition at line 55 of file tls_channel.cpp.
{
// So unique_ptr destructors run correctly
}
void Botan::TLS::Channel::activate_session | ( | ) | [protected] |
Definition at line 254 of file tls_channel.cpp.
References Botan::TLS::Connection_Sequence_Numbers::current_write_epoch(), and Botan::map_remove_if().
{ std::swap(m_active_state, m_pending_state); m_pending_state.reset(); if(!m_active_state->version().is_datagram_protocol()) { // TLS is easy just remove all but the current state auto current_epoch = sequence_numbers().current_write_epoch(); const auto not_current_epoch = [current_epoch](u16bit epoch) { return (epoch != current_epoch); }; map_remove_if(not_current_epoch, m_write_cipher_states); map_remove_if(not_current_epoch, m_read_cipher_states); } }
void Botan::TLS::Channel::change_cipher_spec_reader | ( | Connection_Side | side | ) | [protected] |
Definition at line 180 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(), Botan::TLS::NO_COMPRESSION, and Botan::TLS::SERVER.
{ auto pending = pending_state(); BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello"); if(pending->server_hello()->compression_method() != NO_COMPRESSION) throw Internal_Error("Negotiated unknown compression algorithm"); sequence_numbers().new_read_cipher_state(); const u16bit epoch = sequence_numbers().current_read_epoch(); BOTAN_ASSERT(m_read_cipher_states.count(epoch) == 0, "No read cipher state currently set for next epoch"); // flip side as we are reading std::shared_ptr<Connection_Cipher_State> read_state( new Connection_Cipher_State(pending->version(), (side == CLIENT) ? SERVER : CLIENT, false, pending->ciphersuite(), pending->session_keys())); m_read_cipher_states[epoch] = read_state; }
void Botan::TLS::Channel::change_cipher_spec_writer | ( | Connection_Side | side | ) | [protected] |
Definition at line 208 of file tls_channel.cpp.
References BOTAN_ASSERT, Botan::TLS::Connection_Sequence_Numbers::current_write_epoch(), Botan::TLS::Connection_Sequence_Numbers::new_write_cipher_state(), and Botan::TLS::NO_COMPRESSION.
{ auto pending = pending_state(); BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello"); if(pending->server_hello()->compression_method() != NO_COMPRESSION) throw Internal_Error("Negotiated unknown compression algorithm"); sequence_numbers().new_write_cipher_state(); const u16bit epoch = sequence_numbers().current_write_epoch(); BOTAN_ASSERT(m_write_cipher_states.count(epoch) == 0, "No write cipher state currently set for next epoch"); std::shared_ptr<Connection_Cipher_State> write_state( new Connection_Cipher_State(pending->version(), side, true, pending->ciphersuite(), pending->session_keys())); m_write_cipher_states[epoch] = write_state; }
void Botan::TLS::Channel::close | ( | ) | [inline] |
Send a close notification alert
Definition at line 110 of file tls_channel.h.
References Botan::TLS::Alert::CLOSE_NOTIFY.
Handshake_State & Botan::TLS::Channel::create_handshake_state | ( | Protocol_Version | version | ) | [protected] |
Definition at line 93 of file tls_channel.cpp.
References Botan::TLS::Protocol_Version::is_datagram_protocol(), new_handshake_state(), and Botan::TLS::Protocol_Version::to_string().
Referenced by Botan::TLS::Client::Client(), received_data(), and renegotiate().
{ if(pending_state()) throw Internal_Error("create_handshake_state called during handshake"); if(auto active = active_state()) { Protocol_Version active_version = active->version(); if(active_version.is_datagram_protocol() != version.is_datagram_protocol()) throw std::runtime_error("Active state using version " + active_version.to_string() + " cannot change to " + version.to_string() + " in pending"); } if(!m_sequence_numbers) { if(version.is_datagram_protocol()) m_sequence_numbers.reset(new Datagram_Sequence_Numbers); else m_sequence_numbers.reset(new Stream_Sequence_Numbers); } using namespace std::placeholders; std::unique_ptr<Handshake_IO> io; if(version.is_datagram_protocol()) { // default MTU is IPv6 min MTU minus UDP/IP headers (TODO: make configurable) const u16bit mtu = 1280 - 40 - 8; io.reset(new Datagram_Handshake_IO( std::bind(&Channel::send_record_under_epoch, this, _1, _2, _3), sequence_numbers(), mtu)); } else io.reset(new Stream_Handshake_IO( std::bind(&Channel::send_record, this, _1, _2))); m_pending_state.reset(new_handshake_state(io.release())); if(auto active = active_state()) m_pending_state->set_version(active->version()); return *m_pending_state.get(); }
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().
void Botan::TLS::Channel::heartbeat | ( | const byte | payload[], |
size_t | payload_size, | ||
size_t | pad_bytes = 0 |
||
) |
Attempt to send a heartbeat message (if negotiated with counterparty)
payload | will be echoed back |
payload_size | size of payload in bytes |
pad_bytes | include 16 + pad_bytes extra bytes in the message (not echoed) |
Definition at line 487 of file tls_channel.cpp.
References Botan::TLS::Heartbeat_Message::contents(), Botan::TLS::HEARTBEAT, heartbeat(), heartbeat_sending_allowed(), Botan::TLS::Heartbeat_Message::REQUEST, rng(), and Botan::unlock().
{ if(heartbeat_sending_allowed()) { const std::vector<byte> padding = unlock(rng().random_vec(pad_size + 16)); Heartbeat_Message heartbeat(Heartbeat_Message::REQUEST, payload, payload_size, padding); send_record(HEARTBEAT, heartbeat.contents()); } }
void Botan::TLS::Channel::heartbeat | ( | ) | [inline] |
Attempt to send a heartbeat message (if negotiated with counterparty)
Definition at line 181 of file tls_channel.h.
References heartbeat().
Referenced by heartbeat(), and received_data().
{ heartbeat(nullptr, 0); }
bool Botan::TLS::Channel::heartbeat_sending_allowed | ( | ) | const |
Definition at line 279 of file tls_channel.cpp.
Referenced by heartbeat().
{ if(auto active = active_state()) return active->server_hello()->peer_can_send_heartbeats(); return false; }
virtual void Botan::TLS::Channel::initiate_handshake | ( | Handshake_State & | state, |
bool | force_full_renegotiation | ||
) | [protected, pure virtual] |
Referenced by renegotiate().
bool Botan::TLS::Channel::is_active | ( | ) | const |
Definition at line 235 of file tls_channel.cpp.
Referenced by Botan::TLS::Blocking_Client::do_handshake(), and send().
{ return (active_state() != nullptr); }
bool Botan::TLS::Channel::is_closed | ( | ) | const |
Definition at line 240 of file tls_channel.cpp.
Referenced by Botan::TLS::Blocking_Client::do_handshake(), Botan::TLS::Blocking_Client::read(), received_data(), and send_alert().
{ if(active_state() || pending_state()) return false; /* * If no active or pending state, then either we had a connection * and it has been closed, or we are a server which has never * received a connection. This case is detectable by also lacking * m_sequence_numbers */ return (m_sequence_numbers != nullptr); }
SymmetricKey Botan::TLS::Channel::key_material_export | ( | const std::string & | label, |
const std::string & | context, | ||
size_t | length | ||
) | const |
Key material export (RFC 5705)
label | a disambiguating label string |
context | a per-association context value |
length | the length of the desired key in bytes |
Definition at line 682 of file tls_channel.cpp.
References Botan::to_byte_vector().
{ if(auto active = active_state()) { std::unique_ptr<KDF> prf(active->protocol_specific_prf()); const secure_vector<byte>& master_secret = active->session_keys().master_secret(); std::vector<byte> salt; salt += to_byte_vector(label); salt += active->client_hello()->random(); salt += active->server_hello()->random(); if(context != "") { size_t context_size = context.length(); if(context_size > 0xFFFF) throw std::runtime_error("key_material_export context is too long"); salt.push_back(get_byte<u16bit>(0, context_size)); salt.push_back(get_byte<u16bit>(1, context_size)); salt += to_byte_vector(context); } return prf->derive_key(length, master_secret, salt); } else throw std::runtime_error("Channel::key_material_export connection not active"); }
virtual Handshake_State* Botan::TLS::Channel::new_handshake_state | ( | class Handshake_IO * | io | ) | [protected, pure virtual] |
Referenced by create_handshake_state().
std::vector< X509_Certificate > Botan::TLS::Channel::peer_cert_chain | ( | ) | const |
Definition at line 86 of file tls_channel.cpp.
References get_peer_cert_chain().
{ if(auto active = active_state()) return get_peer_cert_chain(*active); return std::vector<X509_Certificate>(); }
bool Botan::TLS::Channel::peer_supports_heartbeats | ( | ) | const |
Definition at line 272 of file tls_channel.cpp.
Referenced by received_data().
{ if(auto active = active_state()) return active->server_hello()->supports_heartbeats(); return false; }
virtual void Botan::TLS::Channel::process_handshake_msg | ( | const Handshake_State * | active_state, |
Handshake_State & | pending_state, | ||
Handshake_Type | type, | ||
const std::vector< byte > & | contents | ||
) | [protected, pure virtual] |
Referenced by received_data().
size_t Botan::TLS::Channel::received_data | ( | const byte | buf[], |
size_t | buf_size | ||
) |
Inject TLS traffic received from counterparty
Definition at line 291 of file tls_channel.cpp.
References Botan::TLS::ALERT, Botan::TLS::APPLICATION_DATA, Botan::TLS::Alert::BAD_RECORD_MAC, BOTAN_ASSERT, Botan::TLS::CHANGE_CIPHER_SPEC, Botan::TLS::Alert::CLOSE_NOTIFY, create_handshake_state(), Botan::TLS::Alert::DECODE_ERROR, e, Botan::TLS::HANDSHAKE, Botan::TLS::HANDSHAKE_NONE, Botan::TLS::HEARTBEAT, heartbeat(), Botan::TLS::Alert::HEARTBEAT_PAYLOAD, Botan::TLS::Alert::INTERNAL_ERROR, is_closed(), Botan::TLS::Protocol_Version::is_datagram_protocol(), Botan::TLS::Alert::is_fatal(), Botan::TLS::Heartbeat_Message::is_request(), Botan::TLS::NO_RECORD, Botan::TLS::Alert::NO_RENEGOTIATION, Botan::TLS::Heartbeat_Message::payload(), peer_supports_heartbeats(), process_handshake_msg(), Botan::TLS::Connection_Sequence_Numbers::read_accept(), Botan::TLS::read_record(), Botan::TLS::Alert::RECORD_OVERFLOW, Botan::TLS::Session_Manager::remove_entry(), Botan::TLS::Heartbeat_Message::RESPONSE, rng(), send_fatal_alert(), send_warning_alert(), Botan::ASN1::to_string(), Botan::TLS::TLS_Exception::type(), Botan::TLS::Alert::type(), and Botan::unlock().
Referenced by Botan::TLS::Blocking_Client::do_handshake(), Botan::TLS::Blocking_Client::read(), and received_data().
{ const size_t max_fragment_size = maximum_fragment_size(); try { while(!is_closed() && input_size) { secure_vector<byte> record; u64bit record_sequence = 0; Record_Type record_type = NO_RECORD; Protocol_Version record_version; size_t consumed = 0; const size_t needed = read_record(m_readbuf, input, input_size, m_is_datagram, consumed, record, &record_sequence, &record_version, &record_type, m_sequence_numbers.get(), std::bind(&TLS::Channel::read_cipher_state_epoch, this, std::placeholders::_1)); BOTAN_ASSERT(consumed > 0, "Got to eat something"); BOTAN_ASSERT(consumed <= input_size, "Record reader consumed sane amount"); input += consumed; input_size -= consumed; BOTAN_ASSERT(input_size == 0 || needed == 0, "Got a full record or consumed all input"); if(input_size == 0 && needed != 0) return needed; // need more data to complete record if(record.size() > max_fragment_size) throw TLS_Exception(Alert::RECORD_OVERFLOW, "Plaintext record is too large"); if(record_type == HANDSHAKE || record_type == CHANGE_CIPHER_SPEC) { if(!m_pending_state) { if(record_version.is_datagram_protocol()) { if(m_sequence_numbers) { /* * Might be a peer retransmit under epoch - 1 in which * case we must retransmit last flight */ sequence_numbers().read_accept(record_sequence); const u16bit epoch = record_sequence >> 48; if(epoch == sequence_numbers().current_read_epoch()) { create_handshake_state(record_version); } else if(epoch == sequence_numbers().current_read_epoch() - 1) { BOTAN_ASSERT(m_active_state, "Have active state here"); m_active_state->handshake_io().add_record(unlock(record), record_type, record_sequence); } } else if(record_sequence == 0) { create_handshake_state(record_version); } } else { create_handshake_state(record_version); } } if(m_pending_state) { m_pending_state->handshake_io().add_record(unlock(record), record_type, record_sequence); while(auto pending = m_pending_state.get()) { auto msg = pending->get_next_handshake_msg(); if(msg.first == HANDSHAKE_NONE) // no full handshake yet break; process_handshake_msg(active_state(), *pending, msg.first, msg.second); } } } else if(record_type == HEARTBEAT && peer_supports_heartbeats()) { if(!active_state()) throw Unexpected_Message("Heartbeat sent before handshake done"); Heartbeat_Message heartbeat(unlock(record)); const std::vector<byte>& payload = heartbeat.payload(); if(heartbeat.is_request()) { if(!pending_state()) { const std::vector<byte> padding = unlock(rng().random_vec(16)); Heartbeat_Message response(Heartbeat_Message::RESPONSE, &payload[0], payload.size(), padding); send_record(HEARTBEAT, response.contents()); } } else { m_alert_cb(Alert(Alert::HEARTBEAT_PAYLOAD), &payload[0], payload.size()); } } else if(record_type == APPLICATION_DATA) { if(!active_state()) throw Unexpected_Message("Application data before handshake done"); /* * OpenSSL among others sends empty records in versions * before TLS v1.1 in order to randomize the IV of the * following record. Avoid spurious callbacks. */ if(record.size() > 0) m_data_cb(&record[0], record.size()); } else if(record_type == ALERT) { Alert alert_msg(record); if(alert_msg.type() == Alert::NO_RENEGOTIATION) m_pending_state.reset(); m_alert_cb(alert_msg, nullptr, 0); if(alert_msg.is_fatal()) { if(auto active = active_state()) m_session_manager.remove_entry(active->server_hello()->session_id()); } if(alert_msg.type() == Alert::CLOSE_NOTIFY) send_warning_alert(Alert::CLOSE_NOTIFY); // reply in kind if(alert_msg.type() == Alert::CLOSE_NOTIFY || alert_msg.is_fatal()) { reset_state(); return 0; } } else if(record_type != NO_RECORD) throw Unexpected_Message("Unexpected record type " + std::to_string(record_type) + " from counterparty"); } return 0; // on a record boundary } catch(TLS_Exception& e) { send_fatal_alert(e.type()); throw; } catch(Integrity_Failure&) { send_fatal_alert(Alert::BAD_RECORD_MAC); throw; } catch(Decoding_Error&) { send_fatal_alert(Alert::DECODE_ERROR); throw; } catch(...) { send_fatal_alert(Alert::INTERNAL_ERROR); throw; } }
size_t Botan::TLS::Channel::received_data | ( | const std::vector< byte > & | buf | ) |
Inject TLS traffic received from counterparty
Definition at line 286 of file tls_channel.cpp.
References received_data().
{ return this->received_data(&buf[0], buf.size()); }
void Botan::TLS::Channel::renegotiate | ( | bool | force_full_renegotiation = false | ) |
Attempt to renegotiate the session
force_full_renegotiation | if true, require a full renegotiation, otherwise allow session resumption |
Definition at line 152 of file tls_channel.cpp.
References create_handshake_state(), and initiate_handshake().
{ if(pending_state()) // currently in handshake? return; if(auto active = active_state()) initiate_handshake(create_handshake_state(active->version()), force_full_renegotiation); else throw std::runtime_error("Cannot renegotiate on inactive connection"); }
RandomNumberGenerator& Botan::TLS::Channel::rng | ( | ) | [inline, protected] |
Definition at line 213 of file tls_channel.h.
Referenced by heartbeat(), and received_data().
{ return m_rng; }
bool Botan::TLS::Channel::save_session | ( | const Session & | session | ) | const [inline, protected] |
Definition at line 217 of file tls_channel.h.
{ return m_handshake_cb(session); }
void Botan::TLS::Channel::secure_renegotiation_check | ( | const class Client_Hello * | client_hello | ) | [protected] |
void Botan::TLS::Channel::secure_renegotiation_check | ( | const class Server_Hello * | server_hello | ) | [protected] |
std::vector< byte > Botan::TLS::Channel::secure_renegotiation_data_for_client_hello | ( | ) | const [protected] |
Definition at line 651 of file tls_channel.cpp.
{ if(auto active = active_state()) return active->client_finished()->verify_data(); return std::vector<byte>(); }
std::vector< byte > Botan::TLS::Channel::secure_renegotiation_data_for_server_hello | ( | ) | const [protected] |
Definition at line 658 of file tls_channel.cpp.
{ if(auto active = active_state()) { std::vector<byte> buf = active->client_finished()->verify_data(); buf += active->server_finished()->verify_data(); return buf; } return std::vector<byte>(); }
bool Botan::TLS::Channel::secure_renegotiation_supported | ( | ) | const |
Definition at line 670 of file tls_channel.cpp.
{ if(auto active = active_state()) return active->server_hello()->secure_renegotiation(); if(auto pending = pending_state()) if(auto hello = pending->server_hello()) return hello->secure_renegotiation(); return false; }
void Botan::TLS::Channel::send | ( | const byte | buf[], |
size_t | buf_size | ||
) |
Inject plaintext intended for counterparty Throws an exception if is_active() is false
Definition at line 569 of file tls_channel.cpp.
References Botan::TLS::APPLICATION_DATA, and is_active().
Referenced by send().
{ if(!is_active()) throw std::runtime_error("Data cannot be sent on inactive TLS connection"); send_record_array(sequence_numbers().current_write_epoch(), APPLICATION_DATA, buf, buf_size); }
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 578 of file tls_channel.cpp.
References send().
{ this->send(reinterpret_cast<const byte*>(string.c_str()), string.size()); }
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 85 of file tls_channel.h.
{ send(&val[0], val.size()); }
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.
alert | the Alert to send |
Definition at line 583 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().
{ if(alert.is_valid() && !is_closed()) { try { send_record(ALERT, alert.serialize()); } catch(...) { /* swallow it */ } } if(alert.type() == Alert::NO_RENEGOTIATION) m_pending_state.reset(); if(alert.is_fatal()) if(auto active = active_state()) m_session_manager.remove_entry(active->server_hello()->session_id()); if(alert.type() == Alert::CLOSE_NOTIFY || alert.is_fatal()) reset_state(); }
void Botan::TLS::Channel::send_fatal_alert | ( | Alert::Type | type | ) | [inline] |
Send a fatal alert
Definition at line 105 of file tls_channel.h.
Referenced by received_data().
{ send_alert(Alert(type, true)); }
void Botan::TLS::Channel::send_warning_alert | ( | Alert::Type | type | ) | [inline] |
Send a warning alert
Definition at line 100 of file tls_channel.h.
Referenced by received_data().
{ send_alert(Alert(type, false)); }
Session_Manager& Botan::TLS::Channel::session_manager | ( | ) | [inline, protected] |
Definition at line 215 of file tls_channel.h.
{ 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 143 of file tls_channel.cpp.
{ if(m_pending_state) return m_pending_state->handshake_io().timeout_check(); //FIXME: scan cipher suites and remove epochs older than 2*MSL return false; }