Botan  1.11.15
Public Types | Public Member Functions | Protected Member Functions
Botan::TLS::Client Class Reference

#include <tls_client.h>

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

List of all members.

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_Certificatepeer_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_Statecreate_handshake_state (Protocol_Version version)
RandomNumberGeneratorrng ()
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< bytesecure_renegotiation_data_for_client_hello () const
std::vector< bytesecure_renegotiation_data_for_server_hello () const
Session_Managersession_manager ()

Detailed Description

SSL/TLS Client

Definition at line 22 of file tls_client.h.


Member Typedef Documentation

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

Parameters:
output_fnis called with data for the outbound socket
app_data_cbis called when new application data is received
alert_cbis called when a TLS alert is received
handshake_cbis called when a handshake is completed
session_managermanages session state
credsmanages application/user credentials
policyspecifies other connection policy information
rnga random number generator
server_infois identifying information about the TLS server
offer_versionspecifies which version we will offer to the TLS server.
next_protocolallows 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.

Parameters:
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 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.


Constructor & Destructor Documentation

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);
   }

Member Function Documentation

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.

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)

Parameters:
payloadwill be echoed back
payload_sizesize of payload in bytes
pad_bytesinclude 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); }
Returns:
true iff we are allowed to send heartbeat messages

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]
Returns:
true iff the connection is active for sending application data

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]
Returns:
true iff the connection has been definitely closed

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)

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 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]
Returns:
certificate chain of the peer (may be empty)

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>();
   }
Returns:
true iff the peer supports heartbeat messages

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

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

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

Parameters:
force_full_renegotiationif 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>();
   }
Returns:
true iff the counterparty supports the secure renegotiation extensions.

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());
   }
template<typename Alloc >
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.

Parameters:
alertthe 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;
   }

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