|
Botan
1.11.15
|
#include <tls_client.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 < std::string(std::vector < std::string >)> | next_protocol_fn |
| typedef std::function< void(const byte[], size_t)> | output_fn |
Public Member Functions | |
| Client (output_fn out, data_cb app_data_cb, alert_cb alert_cb, handshake_cb hs_cb, Session_Manager &session_manager, Credentials_Manager &creds, const Policy &policy, RandomNumberGenerator &rng, const Server_Information &server_info=Server_Information(), const Protocol_Version offer_version=Protocol_Version::latest_tls_version(), next_protocol_fn next_protocol=next_protocol_fn(), size_t reserved_io_buffer_size=16 *1024) | |
| 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 |
| 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 () |
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) |
| 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 () |
SSL/TLS Client
Definition at line 22 of file tls_client.h.
typedef std::function<void (Alert, const byte[], size_t)> Botan::TLS::Channel::alert_cb [inherited] |
Definition at line 36 of file tls_channel.h.
typedef std::function<void (const byte[], size_t)> Botan::TLS::Channel::data_cb [inherited] |
Definition at line 35 of file tls_channel.h.
typedef std::function<bool (const Session&)> Botan::TLS::Channel::handshake_cb [inherited] |
Definition at line 37 of file tls_channel.h.
| typedef std::function<std::string (std::vector<std::string>)> Botan::TLS::Client::next_protocol_fn |
Set up a new TLS client session
| output_fn | is called with data for the outbound socket |
| app_data_cb | is called when new application data is received |
| alert_cb | is called when a TLS alert is received |
| handshake_cb | is called when a handshake is completed |
| session_manager | manages session state |
| creds | manages application/user credentials |
| policy | specifies other connection policy information |
| rng | a random number generator |
| server_info | is identifying information about the TLS server |
| offer_version | specifies which version we will offer to the TLS server. |
| next_protocol | allows the client to specify what the next protocol will be. For more information read http://technotes.googlecode.com/git/nextprotoneg.html. |
If the function is not empty, NPN will be negotiated and if the server supports NPN the function will be called with the list of protocols the server advertised; the client should return the protocol it would like to use.
| reserved_io_buffer_size | 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 63 of file tls_client.h.
typedef std::function<void (const byte[], size_t)> Botan::TLS::Channel::output_fn [inherited] |
Definition at line 34 of file tls_channel.h.
| Botan::TLS::Client::Client | ( | output_fn | out, |
| data_cb | app_data_cb, | ||
| alert_cb | alert_cb, | ||
| handshake_cb | hs_cb, | ||
| Session_Manager & | session_manager, | ||
| Credentials_Manager & | creds, | ||
| const Policy & | policy, | ||
| RandomNumberGenerator & | rng, | ||
| const Server_Information & | server_info = Server_Information(), |
||
| const Protocol_Version | offer_version = Protocol_Version::latest_tls_version(), |
||
| next_protocol_fn | next_protocol = next_protocol_fn(), |
||
| size_t | reserved_io_buffer_size = 16*1024 |
||
| ) |
Definition at line 49 of file tls_client.cpp.
References Botan::TLS::Channel::create_handshake_state(), Botan::TLS::Server_Information::hostname(), and Botan::Credentials_Manager::srp_identifier().
: Channel(output_fn, proc_cb, alert_cb, handshake_cb, session_manager, rng, offer_version.is_datagram_protocol(), io_buf_sz), m_policy(policy), m_creds(creds), m_info(info) { const std::string srp_identifier = m_creds.srp_identifier("tls-client", m_info.hostname()); Handshake_State& state = create_handshake_state(offer_version); send_client_hello(state, false, offer_version, srp_identifier, npn); }
| void Botan::TLS::Channel::activate_session | ( | ) | [protected, inherited] |
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, inherited] |
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, inherited] |
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, inherited] |
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, inherited] |
Definition at line 93 of file tls_channel.cpp.
References Botan::TLS::Protocol_Version::is_datagram_protocol(), Botan::TLS::Channel::new_handshake_state(), and Botan::TLS::Protocol_Version::to_string().
Referenced by Client(), Botan::TLS::Channel::received_data(), and Botan::TLS::Channel::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();
}
| void Botan::TLS::Channel::heartbeat | ( | const byte | payload[], |
| size_t | payload_size, | ||
| size_t | pad_bytes = 0 |
||
| ) | [inherited] |
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, Botan::TLS::Channel::heartbeat(), Botan::TLS::Channel::heartbeat_sending_allowed(), Botan::TLS::Heartbeat_Message::REQUEST, Botan::TLS::Channel::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, inherited] |
Attempt to send a heartbeat message (if negotiated with counterparty)
Definition at line 181 of file tls_channel.h.
References Botan::TLS::Channel::heartbeat().
Referenced by Botan::TLS::Channel::heartbeat(), and Botan::TLS::Channel::received_data().
{ heartbeat(nullptr, 0); }
| bool Botan::TLS::Channel::heartbeat_sending_allowed | ( | ) | const [inherited] |
Definition at line 279 of file tls_channel.cpp.
Referenced by Botan::TLS::Channel::heartbeat().
{
if(auto active = active_state())
return active->server_hello()->peer_can_send_heartbeats();
return false;
}
| bool Botan::TLS::Channel::is_active | ( | ) | const [inherited] |
Definition at line 235 of file tls_channel.cpp.
Referenced by Botan::TLS::Blocking_Client::do_handshake(), and Botan::TLS::Channel::send().
{
return (active_state() != nullptr);
}
| bool Botan::TLS::Channel::is_closed | ( | ) | const [inherited] |
Definition at line 240 of file tls_channel.cpp.
Referenced by Botan::TLS::Blocking_Client::do_handshake(), Botan::TLS::Blocking_Client::read(), Botan::TLS::Channel::received_data(), and Botan::TLS::Channel::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 [inherited] |
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");
}
| std::vector< X509_Certificate > Botan::TLS::Channel::peer_cert_chain | ( | ) | const [inherited] |
Definition at line 86 of file tls_channel.cpp.
References Botan::TLS::Channel::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 [inherited] |
Definition at line 272 of file tls_channel.cpp.
Referenced by Botan::TLS::Channel::received_data().
{
if(auto active = active_state())
return active->server_hello()->supports_heartbeats();
return false;
}
| size_t Botan::TLS::Channel::received_data | ( | const byte | buf[], |
| size_t | buf_size | ||
| ) | [inherited] |
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, Botan::TLS::Channel::create_handshake_state(), Botan::TLS::Alert::DECODE_ERROR, e, Botan::TLS::HANDSHAKE, Botan::TLS::HANDSHAKE_NONE, Botan::TLS::HEARTBEAT, Botan::TLS::Channel::heartbeat(), Botan::TLS::Alert::HEARTBEAT_PAYLOAD, Botan::TLS::Alert::INTERNAL_ERROR, Botan::TLS::Channel::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(), Botan::TLS::Channel::peer_supports_heartbeats(), Botan::TLS::Channel::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, Botan::TLS::Channel::rng(), Botan::TLS::Channel::send_fatal_alert(), Botan::TLS::Channel::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 Botan::TLS::Channel::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 | ) | [inherited] |
Inject TLS traffic received from counterparty
Definition at line 286 of file tls_channel.cpp.
References Botan::TLS::Channel::received_data().
{
return this->received_data(&buf[0], buf.size());
}
| void Botan::TLS::Channel::renegotiate | ( | bool | force_full_renegotiation = false | ) | [inherited] |
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 Botan::TLS::Channel::create_handshake_state(), and Botan::TLS::Channel::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, inherited] |
Definition at line 213 of file tls_channel.h.
Referenced by Botan::TLS::Channel::heartbeat(), and Botan::TLS::Channel::received_data().
{ return m_rng; }
| bool Botan::TLS::Channel::save_session | ( | const Session & | session | ) | const [inline, protected, inherited] |
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, inherited] |
| void Botan::TLS::Channel::secure_renegotiation_check | ( | const class Server_Hello * | server_hello | ) | [protected, inherited] |
| std::vector< byte > Botan::TLS::Channel::secure_renegotiation_data_for_client_hello | ( | ) | const [protected, inherited] |
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, inherited] |
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 [inherited] |
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 | ||
| ) | [inherited] |
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 Botan::TLS::Channel::is_active().
Referenced by Botan::TLS::Channel::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 | ) | [inherited] |
Inject plaintext intended for counterparty Throws an exception if is_active() is false
Definition at line 578 of file tls_channel.cpp.
References Botan::TLS::Channel::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, inherited] |
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 | ) | [inherited] |
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, 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().
{
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, inherited] |
Send a fatal alert
Definition at line 105 of file tls_channel.h.
Referenced by Botan::TLS::Channel::received_data().
{ send_alert(Alert(type, true)); }
| void Botan::TLS::Channel::send_warning_alert | ( | Alert::Type | type | ) | [inline, inherited] |
Send a warning alert
Definition at line 100 of file tls_channel.h.
Referenced by Botan::TLS::Channel::received_data().
{ send_alert(Alert(type, false)); }
| Session_Manager& Botan::TLS::Channel::session_manager | ( | ) | [inline, protected, inherited] |
Definition at line 215 of file tls_channel.h.
{ return m_session_manager; }
| 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 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;
}
1.7.6.1