Botan 3.3.0
Crypto and TLS for C&
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
Botan::TLS::Client_Impl_12 Class Referenceabstract

#include <tls_client_impl_12.h>

Inheritance diagram for Botan::TLS::Client_Impl_12:
Botan::TLS::Channel_Impl_12 Botan::TLS::Channel_Impl

Public Types

typedef std::function< void(Alert, const uint8_t[], size_t)> alert_cb
 
typedef std::function< void(const uint8_t[], size_t)> data_cb
 
typedef std::function< bool(const Session &) handshake_cb)
 
typedef std::function< void(const Handshake_Message &) handshake_msg_cb)
 
typedef std::function< void(const uint8_t[], size_t)> output_fn
 

Public Member Functions

std::string application_protocol () const override
 
 Client_Impl_12 (const Channel_Impl::Downgrade_Information &downgrade_info)
 
 Client_Impl_12 (const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &creds, const std::shared_ptr< const Policy > &policy, const std::shared_ptr< RandomNumberGenerator > &rng, Server_Information server_info=Server_Information(), bool datagram=false, const std::vector< std::string > &next_protocols={}, size_t reserved_io_buffer_size=TLS::Channel::IO_BUF_DEFAULT_SIZE)
 
void close ()
 
bool expects_downgrade () const
 
std::optional< std::string > external_psk_identity () const override
 
std::unique_ptr< Downgrade_Informationextract_downgrade_info ()
 
size_t from_peer (std::span< const uint8_t > data) override
 
bool is_active () const override
 
bool is_closed () const override
 
bool is_closed_for_reading () const override
 
bool is_closed_for_writing () const override
 
bool is_downgrading () const
 
bool is_handshake_complete () const override
 
SymmetricKey key_material_export (std::string_view label, std::string_view context, size_t length) const override
 
virtual bool new_session_ticket_supported () const
 
std::vector< X509_Certificatepeer_cert_chain () const override
 
std::shared_ptr< const Public_Keypeer_raw_public_key () const override
 
void renegotiate (bool force_full_renegotiation=false) override
 
bool secure_renegotiation_supported () const override
 
void send_alert (const Alert &alert) override
 
void send_fatal_alert (Alert::Type type)
 
virtual size_t send_new_session_tickets (const size_t)
 
void send_warning_alert (Alert::Type type)
 
bool timeout_check () override
 
void to_peer (std::span< const uint8_t > data) override
 
void update_traffic_keys (bool request_peer_update=false) override
 

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)
 
virtual std::unique_ptr< Handshake_Statenew_handshake_state (std::unique_ptr< class Handshake_IO > io)=0
 
const Policypolicy () const
 
void preserve_client_hello (std::span< const uint8_t > msg)
 
void preserve_peer_transcript (std::span< const uint8_t > input)
 
void request_downgrade ()
 
void request_downgrade_for_resumption (Session_with_Handle session)
 
void reset_active_association_state ()
 
RandomNumberGeneratorrng ()
 
void secure_renegotiation_check (const Client_Hello_12 *client_hello)
 
void secure_renegotiation_check (const Server_Hello_12 *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 ()
 
void set_io_buffer_size (size_t io_buf_sz)
 

Protected Attributes

std::unique_ptr< Downgrade_Informationm_downgrade_info
 

Detailed Description

SSL/TLS Client 1.2 implementation

Definition at line 24 of file tls_client_impl_12.h.

Member Typedef Documentation

◆ alert_cb

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

Definition at line 44 of file tls_channel_impl_12.h.

◆ data_cb

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

Definition at line 43 of file tls_channel_impl_12.h.

◆ handshake_cb

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

Definition at line 45 of file tls_channel_impl_12.h.

◆ handshake_msg_cb

typedef std::function<void(const Handshake_Message&) Botan::TLS::Channel_Impl_12::handshake_msg_cb)
inherited

Definition at line 46 of file tls_channel_impl_12.h.

◆ output_fn

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

Definition at line 42 of file tls_channel_impl_12.h.

Constructor & Destructor Documentation

◆ Client_Impl_12() [1/2]

Botan::TLS::Client_Impl_12::Client_Impl_12 ( const std::shared_ptr< Callbacks > & callbacks,
const std::shared_ptr< Session_Manager > & session_manager,
const std::shared_ptr< Credentials_Manager > & creds,
const std::shared_ptr< const Policy > & policy,
const std::shared_ptr< RandomNumberGenerator > & rng,
Server_Information server_info = Server_Information(),
bool datagram = false,
const std::vector< std::string > & next_protocols = {},
size_t reserved_io_buffer_size = TLS::Channel::IO_BUF_DEFAULT_SIZE )
explicit

Set up a new TLS client session

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
server_infois identifying information about the TLS server
datagramspecifies whether to use TLS 1.2 or DTLS 1.2
next_protocolsspecifies protocols to advertise with ALPN
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 84 of file tls_client_impl_12.cpp.

92 :
93 Channel_Impl_12(callbacks, session_manager, rng, policy, false, datagram, io_buf_sz),
94 m_creds(creds),
95 m_info(std::move(info)) {
96 BOTAN_ASSERT_NONNULL(m_creds);
97 const auto version = datagram ? Protocol_Version::DTLS_V12 : Protocol_Version::TLS_V12;
98 Handshake_State& state = create_handshake_state(version);
99 send_client_hello(state, false, version, std::nullopt /* no a-priori session to resume */, next_protocols);
100}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86
RandomNumberGenerator & rng()
Handshake_State & create_handshake_state(Protocol_Version version)
Session_Manager & session_manager()
const Policy & policy() const
Channel_Impl_12(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< RandomNumberGenerator > &rng, const std::shared_ptr< const Policy > &policy, bool is_server, bool is_datagram, size_t io_buf_sz=TLS::Channel::IO_BUF_DEFAULT_SIZE)

References BOTAN_ASSERT_NONNULL, and Botan::TLS::Channel_Impl_12::create_handshake_state().

◆ Client_Impl_12() [2/2]

Botan::TLS::Client_Impl_12::Client_Impl_12 ( const Channel_Impl::Downgrade_Information & downgrade_info)
explicit

Definition at line 102 of file tls_client_impl_12.cpp.

102 :
103 Channel_Impl_12(downgrade_info.callbacks,
104 downgrade_info.session_manager,
105 downgrade_info.rng,
106 downgrade_info.policy,
107 false /* is_server */,
108 false /* datagram -- not supported by Botan in TLS 1.3 */,
109 downgrade_info.io_buffer_size),
110 m_creds(downgrade_info.creds),
111 m_info(downgrade_info.server_info) {
112 Handshake_State& state = create_handshake_state(Protocol_Version::TLS_V12);
113
114 if(!downgrade_info.client_hello_message.empty()) {
115 // Downgrade detected after receiving a TLS 1.2 server hello. We need to
116 // recreate the state as if this implementation issued the client hello.
117 std::vector<uint8_t> client_hello_msg(
118 downgrade_info.client_hello_message.begin() + 4 /* handshake header length */,
119 downgrade_info.client_hello_message.end());
120
121 state.client_hello(new Client_Hello_12(client_hello_msg));
122 state.hash().update(downgrade_info.client_hello_message);
123
124 secure_renegotiation_check(state.client_hello());
125 state.set_expected_next(Handshake_Type::ServerHello);
126 } else {
127 // Downgrade initiated after a TLS 1.2 session was found. No communication
128 // has happened yet but the found session should be used for resumption.
129 BOTAN_ASSERT_NOMSG(downgrade_info.tls12_session.has_value() &&
130 downgrade_info.tls12_session->session.version().is_pre_tls_13());
131 send_client_hello(state,
132 false,
133 downgrade_info.tls12_session->session.version(),
134 downgrade_info.tls12_session,
135 downgrade_info.next_protocols);
136 }
137}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
void secure_renegotiation_check(const Client_Hello_12 *client_hello)

References BOTAN_ASSERT_NOMSG, Botan::TLS::Handshake_State::client_hello(), Botan::TLS::Channel_Impl::Downgrade_Information::client_hello_message, Botan::TLS::Channel_Impl_12::create_handshake_state(), Botan::TLS::Handshake_State::hash(), Botan::TLS::Channel_Impl::Downgrade_Information::next_protocols, Botan::TLS::Channel_Impl_12::secure_renegotiation_check(), Botan::TLS::ServerHello, Botan::TLS::Handshake_State::set_expected_next(), Botan::TLS::Channel_Impl::Downgrade_Information::tls12_session, and Botan::TLS::Handshake_Hash::update().

Member Function Documentation

◆ activate_session()

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

Definition at line 252 of file tls_channel_impl_12.cpp.

252 {
253 std::swap(m_active_state, m_pending_state);
254 m_pending_state.reset();
255
256 if(!m_active_state->version().is_datagram_protocol()) {
257 // TLS is easy just remove all but the current state
258 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
259
260 const auto not_current_epoch = [current_epoch](uint16_t epoch) { return (epoch != current_epoch); };
261
262 map_remove_if(not_current_epoch, m_write_cipher_states);
263 map_remove_if(not_current_epoch, m_read_cipher_states);
264 }
265
267}
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:127

References Botan::TLS::Channel_Impl_12::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::Client_Impl_12::application_protocol ( ) const
inlineoverridevirtual
Returns
network protocol as advertised by the TLS server, if server sent the ALPN extension

Implements Botan::TLS::Channel_Impl.

Definition at line 65 of file tls_client_impl_12.h.

65{ return m_application_protocol; }

◆ callbacks()

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

Definition at line 190 of file tls_channel_impl_12.h.

190{ return *m_callbacks; }

Referenced by Botan::TLS::Channel_Impl_12::activate_session().

◆ change_cipher_spec_reader()

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

Definition at line 187 of file tls_channel_impl_12.cpp.

187 {
188 auto pending = pending_state();
189
190 BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello");
191
192 if(pending->server_hello()->compression_method() != 0) {
193 throw Internal_Error("Negotiated unknown compression algorithm");
194 }
195
196 sequence_numbers().new_read_cipher_state();
197
198 const uint16_t epoch = sequence_numbers().current_read_epoch();
199
200 BOTAN_ASSERT(!m_read_cipher_states.contains(epoch), "No read cipher state currently set for next epoch");
201
202 // flip side as we are reading
203 std::shared_ptr<Connection_Cipher_State> read_state(
204 new Connection_Cipher_State(pending->version(),
206 false,
207 pending->ciphersuite(),
208 pending->session_keys(),
209 pending->server_hello()->supports_encrypt_then_mac()));
210
211 m_read_cipher_states[epoch] = read_state;
212}
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:50
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_Impl_12::change_cipher_spec_writer ( Connection_Side side)
protectedinherited

Definition at line 214 of file tls_channel_impl_12.cpp.

214 {
215 auto pending = pending_state();
216
217 BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello");
218
219 if(pending->server_hello()->compression_method() != 0) {
220 throw Internal_Error("Negotiated unknown compression algorithm");
221 }
222
223 sequence_numbers().new_write_cipher_state();
224
225 const uint16_t epoch = sequence_numbers().current_write_epoch();
226
227 BOTAN_ASSERT(!m_write_cipher_states.contains(epoch), "No write cipher state currently set for next epoch");
228
229 std::shared_ptr<Connection_Cipher_State> write_state(
230 new Connection_Cipher_State(pending->version(),
231 side,
232 true,
233 pending->ciphersuite(),
234 pending->session_keys(),
235 pending->server_hello()->supports_encrypt_then_mac()));
236
237 m_write_cipher_states[epoch] = write_state;
238}

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_Impl::close ( )
inlineinherited

Send a close notification alert

Definition at line 80 of file tls_channel_impl.h.

80{ send_warning_alert(Alert::CloseNotify); }
void send_warning_alert(Alert::Type type)

References Botan::TLS::Channel_Impl::send_warning_alert().

◆ create_handshake_state()

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

Definition at line 112 of file tls_channel_impl_12.cpp.

112 {
113 if(pending_state()) {
114 throw Internal_Error("create_handshake_state called during handshake");
115 }
116
117 if(auto active = active_state()) {
118 Protocol_Version active_version = active->version();
119
120 if(active_version.is_datagram_protocol() != version.is_datagram_protocol()) {
121 throw TLS_Exception(Alert::ProtocolVersion,
122 "Active state using version " + active_version.to_string() + " cannot change to " +
123 version.to_string() + " in pending");
124 }
125 }
126
127 if(!m_sequence_numbers) {
128 if(version.is_datagram_protocol()) {
129 m_sequence_numbers = std::make_unique<Datagram_Sequence_Numbers>();
130 } else {
131 m_sequence_numbers = std::make_unique<Stream_Sequence_Numbers>();
132 }
133 }
134
135 using namespace std::placeholders;
136
137 std::unique_ptr<Handshake_IO> io;
138 if(version.is_datagram_protocol()) {
139 io =
140 std::make_unique<Datagram_Handshake_IO>(std::bind(&Channel_Impl_12::send_record_under_epoch, this, _1, _2, _3),
141 sequence_numbers(),
142 static_cast<uint16_t>(policy().dtls_default_mtu()),
143 policy().dtls_initial_timeout(),
144 policy().dtls_maximum_timeout());
145 } else {
146 io = std::make_unique<Stream_Handshake_IO>(std::bind(&Channel_Impl_12::send_record, this, _1, _2));
147 }
148
149 m_pending_state = new_handshake_state(std::move(io));
150
151 if(auto active = active_state()) {
152 m_pending_state->set_version(active->version());
153 }
154
155 return *m_pending_state;
156}
virtual std::unique_ptr< Handshake_State > new_handshake_state(std::unique_ptr< class Handshake_IO > io)=0

References Botan::TLS::Protocol_Version::is_datagram_protocol(), Botan::TLS::Channel_Impl_12::new_handshake_state(), Botan::TLS::Channel_Impl_12::policy(), and Botan::TLS::Protocol_Version::to_string().

Referenced by Client_Impl_12(), Client_Impl_12(), and Botan::TLS::Channel_Impl_12::renegotiate().

◆ expects_downgrade()

bool Botan::TLS::Channel_Impl::expects_downgrade ( ) const
inlineinherited

Definition at line 278 of file tls_channel_impl.h.

278{ return m_downgrade_info != nullptr; }
std::unique_ptr< Downgrade_Information > m_downgrade_info

References Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Client_Impl_13::Client_Impl_13(), and Botan::TLS::Channel_Impl_13::from_peer().

◆ external_psk_identity()

std::optional< std::string > Botan::TLS::Channel_Impl_12::external_psk_identity ( ) const
overridevirtualinherited
Returns
identity of the PSK used for this connection or std::nullopt if no PSK was used.

Implements Botan::TLS::Channel_Impl.

Definition at line 103 of file tls_channel_impl_12.cpp.

103 {
104 const auto* state = (active_state() != nullptr) ? active_state() : pending_state();
105 if(state) {
106 return state->psk_identity();
107 } else {
108 return std::nullopt;
109 }
110}

◆ extract_downgrade_info()

std::unique_ptr< Downgrade_Information > Botan::TLS::Channel_Impl::extract_downgrade_info ( )
inlineinherited
See also
Downgrade_Information

Definition at line 276 of file tls_channel_impl.h.

276{ return std::exchange(m_downgrade_info, {}); }

References Botan::TLS::Channel_Impl::m_downgrade_info.

◆ from_peer()

size_t Botan::TLS::Channel_Impl_12::from_peer ( std::span< const uint8_t > data)
overridevirtualinherited

Inject TLS traffic received from counterparty

Returns
a hint as the how many more bytes we need to q the current record (this may be 0 if on a record boundary)

Implements Botan::TLS::Channel_Impl.

Definition at line 269 of file tls_channel_impl_12.cpp.

269 {
270 const bool allow_epoch0_restart = m_is_datagram && m_is_server && policy().allow_dtls_epoch0_restart();
271
272 auto input = data.data();
273 auto input_size = data.size();
274
275 try {
276 while(input_size) {
277 size_t consumed = 0;
278
279 auto get_epoch = [this](uint16_t epoch) { return read_cipher_state_epoch(epoch); };
280
281 const Record_Header record = read_record(m_is_datagram,
282 m_readbuf,
283 input,
284 input_size,
285 consumed,
286 m_record_buf,
287 m_sequence_numbers.get(),
288 get_epoch,
289 allow_epoch0_restart);
290
291 const size_t needed = record.needed();
292
293 BOTAN_ASSERT(consumed > 0, "Got to eat something");
294
295 BOTAN_ASSERT(consumed <= input_size, "Record reader consumed sane amount");
296
297 input += consumed;
298 input_size -= consumed;
299
300 BOTAN_ASSERT(input_size == 0 || needed == 0, "Got a full record or consumed all input");
301
302 if(input_size == 0 && needed != 0) {
303 return needed; // need more data to complete record
304 }
305
306 // Ignore invalid records in DTLS
307 if(m_is_datagram && record.type() == Record_Type::Invalid) {
308 return 0;
309 }
310
311 if(m_record_buf.size() > MAX_PLAINTEXT_SIZE) {
312 throw TLS_Exception(Alert::RecordOverflow, "TLS plaintext record is larger than allowed maximum");
313 }
314
315 const bool epoch0_restart = m_is_datagram && record.epoch() == 0 && active_state();
316 BOTAN_ASSERT_IMPLICATION(epoch0_restart, allow_epoch0_restart, "Allowed state");
317
318 const bool initial_record = epoch0_restart || (!pending_state() && !active_state());
319
320 if(record.type() != Record_Type::Alert) {
321 if(initial_record) {
322 // For initial records just check for basic sanity
323 if(record.version().major_version() != 3 && record.version().major_version() != 0xFE) {
324 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version in initial record");
325 }
326 } else if(auto pending = pending_state()) {
327 if(pending->server_hello() != nullptr && record.version() != pending->version()) {
328 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version");
329 }
330 } else if(auto active = active_state()) {
331 if(record.version() != active->version()) {
332 throw TLS_Exception(Alert::ProtocolVersion, "Received unexpected record version");
333 }
334 }
335 }
336
337 if(record.type() == Record_Type::Handshake || record.type() == Record_Type::ChangeCipherSpec) {
338 if(m_has_been_closed) {
339 throw TLS_Exception(Alert::UnexpectedMessage, "Received handshake data after connection closure");
340 }
341 process_handshake_ccs(m_record_buf, record.sequence(), record.type(), record.version(), epoch0_restart);
342 } else if(record.type() == Record_Type::ApplicationData) {
343 if(m_has_been_closed) {
344 throw TLS_Exception(Alert::UnexpectedMessage, "Received application data after connection closure");
345 }
346 if(pending_state() != nullptr) {
347 throw TLS_Exception(Alert::UnexpectedMessage, "Can't interleave application and handshake data");
348 }
349 process_application_data(record.sequence(), m_record_buf);
350 } else if(record.type() == Record_Type::Alert) {
351 process_alert(m_record_buf);
352 } else if(record.type() != Record_Type::Invalid) {
353 throw Unexpected_Message("Unexpected record type " + std::to_string(static_cast<size_t>(record.type())) +
354 " from counterparty");
355 }
356 }
357
358 return 0; // on a record boundary
359 } catch(TLS_Exception& e) {
360 send_fatal_alert(e.type());
361 throw;
362 } catch(Invalid_Authentication_Tag&) {
363 send_fatal_alert(Alert::BadRecordMac);
364 throw;
365 } catch(Decoding_Error&) {
366 send_fatal_alert(Alert::DecodeError);
367 throw;
368 } catch(...) {
369 send_fatal_alert(Alert::InternalError);
370 throw;
371 }
372}
#define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg)
Definition assert.h:77
void send_fatal_alert(Alert::Type type)
virtual bool allow_dtls_epoch0_restart() const
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, const get_cipherstate_fn &get_cipherstate, bool allow_epoch0_restart)
@ MAX_PLAINTEXT_SIZE
Definition tls_magic.h:30

References Botan::TLS::Alert, Botan::TLS::Policy::allow_dtls_epoch0_restart(), Botan::TLS::ApplicationData, BOTAN_ASSERT, BOTAN_ASSERT_IMPLICATION, Botan::TLS::ChangeCipherSpec, Botan::TLS::Record_Header::epoch(), Botan::TLS::Handshake, Botan::TLS::Invalid, Botan::TLS::Protocol_Version::major_version(), Botan::TLS::MAX_PLAINTEXT_SIZE, Botan::TLS::Record_Header::needed(), Botan::TLS::Channel_Impl_12::policy(), Botan::TLS::read_record(), Botan::TLS::Channel_Impl::send_fatal_alert(), Botan::TLS::Record_Header::sequence(), Botan::TLS::Record_Header::type(), Botan::TLS::TLS_Exception::type(), and Botan::TLS::Record_Header::version().

◆ inspect_handshake_message()

void Botan::TLS::Channel_Impl_12::inspect_handshake_message ( const Handshake_Message & msg)
protectedinherited

◆ is_active()

bool Botan::TLS::Channel_Impl_12::is_active ( ) const
overridevirtualinherited
Returns
true iff the connection is active for sending application data

Implements Botan::TLS::Channel_Impl.

Definition at line 244 of file tls_channel_impl_12.cpp.

244 {
245 return !is_closed() && is_handshake_complete();
246}
bool is_handshake_complete() const override

References Botan::TLS::Channel_Impl_12::is_closed(), and Botan::TLS::Channel_Impl_12::is_handshake_complete().

Referenced by Botan::TLS::Channel_Impl_12::to_peer().

◆ is_closed()

bool Botan::TLS::Channel_Impl_12::is_closed ( ) const
overridevirtualinherited
Returns
true iff the connection has been definitely closed

Implements Botan::TLS::Channel_Impl.

Definition at line 248 of file tls_channel_impl_12.cpp.

248 {
249 return m_has_been_closed;
250}

Referenced by Botan::TLS::Channel_Impl_12::is_active(), Botan::TLS::Channel_Impl_12::is_closed_for_reading(), Botan::TLS::Channel_Impl_12::is_closed_for_writing(), and Botan::TLS::Channel_Impl_12::send_alert().

◆ is_closed_for_reading()

bool Botan::TLS::Channel_Impl_12::is_closed_for_reading ( ) const
inlineoverridevirtualinherited
Returns
true iff the connection is active for sending application data

Implements Botan::TLS::Channel_Impl.

Definition at line 101 of file tls_channel_impl_12.h.

101{ return is_closed(); }

References Botan::TLS::Channel_Impl_12::is_closed().

◆ is_closed_for_writing()

bool Botan::TLS::Channel_Impl_12::is_closed_for_writing ( ) const
inlineoverridevirtualinherited
Returns
true iff the connection has been definitely closed

Implements Botan::TLS::Channel_Impl.

Definition at line 103 of file tls_channel_impl_12.h.

103{ return is_closed(); }

References Botan::TLS::Channel_Impl_12::is_closed().

◆ is_downgrading()

bool Botan::TLS::Channel_Impl::is_downgrading ( ) const
inlineinherited

Indicates whether a downgrade to TLS 1.2 or lower is in progress

See also
Downgrade_Information

Definition at line 271 of file tls_channel_impl.h.

271{ return m_downgrade_info && m_downgrade_info->will_downgrade; }

References Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Channel_Impl_13::from_peer(), Botan::TLS::Channel_Impl_13::key_material_export(), and Botan::TLS::Channel_Impl_13::update_traffic_keys().

◆ is_handshake_complete()

bool Botan::TLS::Channel_Impl_12::is_handshake_complete ( ) const
overridevirtualinherited
Returns
true iff the TLS handshake completed successfully

Implements Botan::TLS::Channel_Impl.

Definition at line 240 of file tls_channel_impl_12.cpp.

240 {
241 return (active_state() != nullptr);
242}

Referenced by Botan::TLS::Channel_Impl_12::is_active().

◆ key_material_export()

SymmetricKey Botan::TLS::Channel_Impl_12::key_material_export ( std::string_view label,
std::string_view context,
size_t length ) const
overridevirtualinherited

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

Implements Botan::TLS::Channel_Impl.

Definition at line 617 of file tls_channel_impl_12.cpp.

619 {
620 if(auto active = active_state()) {
621 if(pending_state() != nullptr) {
622 throw Invalid_State("Channel_Impl_12::key_material_export cannot export during renegotiation");
623 }
624
625 auto prf = active->protocol_specific_prf();
626
627 const secure_vector<uint8_t>& master_secret = active->session_keys().master_secret();
628
629 std::vector<uint8_t> salt;
630 salt += active->client_hello()->random();
631 salt += active->server_hello()->random();
632
633 if(!context.empty()) {
634 size_t context_size = context.length();
635 if(context_size > 0xFFFF) {
636 throw Invalid_Argument("key_material_export context is too long");
637 }
638 salt.push_back(get_byte<0>(static_cast<uint16_t>(context_size)));
639 salt.push_back(get_byte<1>(static_cast<uint16_t>(context_size)));
640 salt += to_byte_vector(context);
641 }
642
643 return SymmetricKey(prf->derive_key(length, master_secret, salt, to_byte_vector(label)));
644 } else {
645 throw Invalid_State("Channel_Impl_12::key_material_export connection not active");
646 }
647}
T to_byte_vector(std::string_view s)
Definition stl_util.h:29
OctetString SymmetricKey
Definition symkey.h:141

References Botan::to_byte_vector().

◆ new_handshake_state()

virtual std::unique_ptr< Handshake_State > Botan::TLS::Channel_Impl_12::new_handshake_state ( std::unique_ptr< class Handshake_IO > io)
protectedpure virtualinherited

◆ new_session_ticket_supported()

virtual bool Botan::TLS::Channel_Impl::new_session_ticket_supported ( ) const
inlinevirtualinherited
Returns
true if this channel can issue TLS 1.3 style session tickets.

Reimplemented in Botan::TLS::Server_Impl_13.

Definition at line 144 of file tls_channel_impl.h.

144{ return false; }

◆ peer_cert_chain()

std::vector< X509_Certificate > Botan::TLS::Channel_Impl_12::peer_cert_chain ( ) const
overridevirtualinherited
Returns
certificate chain of the peer (may be empty)

Implements Botan::TLS::Channel_Impl.

Definition at line 96 of file tls_channel_impl_12.cpp.

96 {
97 if(auto active = active_state()) {
98 return get_peer_cert_chain(*active);
99 }
100 return std::vector<X509_Certificate>();
101}
virtual std::vector< X509_Certificate > get_peer_cert_chain(const Handshake_State &state) const =0

References Botan::TLS::Channel_Impl_12::get_peer_cert_chain().

◆ peer_raw_public_key()

std::shared_ptr< const Public_Key > Botan::TLS::Channel_Impl_12::peer_raw_public_key ( ) const
inlineoverridevirtualinherited

Note: Raw public key for authentication (RFC7250) is currently not implemented for TLS 1.2.

Returns
raw public key of the peer (will be nullptr)

Implements Botan::TLS::Channel_Impl.

Definition at line 116 of file tls_channel_impl_12.h.

116{ return nullptr; }

◆ policy()

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

◆ preserve_client_hello()

void Botan::TLS::Channel_Impl::preserve_client_hello ( std::span< const uint8_t > msg)
inlineprotectedinherited

Definition at line 231 of file tls_channel_impl.h.

231 {
233 m_downgrade_info->client_hello_message.assign(msg.begin(), msg.end());
234 }
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Client_Impl_13::Client_Impl_13().

◆ preserve_peer_transcript()

void Botan::TLS::Channel_Impl::preserve_peer_transcript ( std::span< const uint8_t > input)
inlineprotectedinherited

Definition at line 226 of file tls_channel_impl.h.

226 {
228 m_downgrade_info->peer_transcript.insert(m_downgrade_info->peer_transcript.end(), input.begin(), input.end());
229 }

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Channel_Impl_13::from_peer().

◆ renegotiate()

void Botan::TLS::Channel_Impl_12::renegotiate ( bool force_full_renegotiation = false)
overridevirtualinherited

Attempt to renegotiate the session

Parameters
force_full_renegotiationif true, require a full renegotiation, otherwise allow session resumption

Implements Botan::TLS::Channel_Impl.

Definition at line 167 of file tls_channel_impl_12.cpp.

167 {
168 if(pending_state()) { // currently in handshake?
169 return;
170 }
171
172 if(auto active = active_state()) {
173 if(force_full_renegotiation == false) {
174 force_full_renegotiation = !policy().allow_resumption_for_renegotiation();
175 }
176
177 initiate_handshake(create_handshake_state(active->version()), force_full_renegotiation);
178 } else {
179 throw Invalid_State("Cannot renegotiate on inactive connection");
180 }
181}
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_Impl_12::create_handshake_state(), Botan::TLS::Channel_Impl_12::initiate_handshake(), and Botan::TLS::Channel_Impl_12::policy().

◆ request_downgrade()

void Botan::TLS::Channel_Impl::request_downgrade ( )
inlineprotectedinherited

Implementations use this to signal that the peer indicated a protocol version downgrade. After calling request_downgrade() no further state changes must be perfomed by the implementation. Particularly, no further handshake messages must be emitted. Instead, they must yield control flow back to the underlying Channel implementation to perform the protocol version downgrade.

Definition at line 252 of file tls_channel_impl.h.

252 {
254 m_downgrade_info->will_downgrade = true;
255 }

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

Referenced by Botan::TLS::Channel_Impl::request_downgrade_for_resumption().

◆ request_downgrade_for_resumption()

void Botan::TLS::Channel_Impl::request_downgrade_for_resumption ( Session_with_Handle session)
inlineprotectedinherited

◆ reset_active_association_state()

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

Definition at line 58 of file tls_channel_impl_12.cpp.

58 {
59 // This operation only makes sense for DTLS
60 BOTAN_ASSERT_NOMSG(m_is_datagram);
61 m_active_state.reset();
62 m_read_cipher_states.clear();
63 m_write_cipher_states.clear();
64
65 m_write_cipher_states[0] = nullptr;
66 m_read_cipher_states[0] = nullptr;
67
68 if(m_sequence_numbers) {
69 m_sequence_numbers->reset();
70 }
71}

References BOTAN_ASSERT_NOMSG.

◆ rng()

RandomNumberGenerator & Botan::TLS::Channel_Impl_12::rng ( )
inlineprotectedinherited

Definition at line 184 of file tls_channel_impl_12.h.

184{ return *m_rng; }

◆ secure_renegotiation_check() [1/2]

void Botan::TLS::Channel_Impl_12::secure_renegotiation_check ( const Client_Hello_12 * client_hello)
protectedinherited

Definition at line 546 of file tls_channel_impl_12.cpp.

546 {
547 const bool secure_renegotiation = client_hello->secure_renegotiation();
548
549 if(auto active = active_state()) {
550 const bool active_sr = active->client_hello()->secure_renegotiation();
551
552 if(active_sr != secure_renegotiation) {
553 throw TLS_Exception(Alert::HandshakeFailure, "Client changed its mind about secure renegotiation");
554 }
555 }
556
557 if(secure_renegotiation) {
558 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
559
561 throw TLS_Exception(Alert::HandshakeFailure, "Client sent bad values for secure renegotiation");
562 }
563 }
564}
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const

References Botan::TLS::Client_Hello_12::renegotiation_info(), Botan::TLS::Client_Hello_12::secure_renegotiation(), and Botan::TLS::Channel_Impl_12::secure_renegotiation_data_for_client_hello().

Referenced by Client_Impl_12().

◆ secure_renegotiation_check() [2/2]

void Botan::TLS::Channel_Impl_12::secure_renegotiation_check ( const Server_Hello_12 * server_hello)
protectedinherited

Definition at line 566 of file tls_channel_impl_12.cpp.

566 {
567 const bool secure_renegotiation = server_hello->secure_renegotiation();
568
569 if(auto active = active_state()) {
570 const bool active_sr = active->server_hello()->secure_renegotiation();
571
572 if(active_sr != secure_renegotiation) {
573 throw TLS_Exception(Alert::HandshakeFailure, "Server changed its mind about secure renegotiation");
574 }
575 }
576
577 if(secure_renegotiation) {
578 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
579
581 throw TLS_Exception(Alert::HandshakeFailure, "Server sent bad values for secure renegotiation");
582 }
583 }
584}
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const

References Botan::TLS::Server_Hello_12::renegotiation_info(), Botan::TLS::Server_Hello_12::secure_renegotiation(), and Botan::TLS::Channel_Impl_12::secure_renegotiation_data_for_server_hello().

◆ secure_renegotiation_data_for_client_hello()

std::vector< uint8_t > Botan::TLS::Channel_Impl_12::secure_renegotiation_data_for_client_hello ( ) const
protectedinherited

Definition at line 586 of file tls_channel_impl_12.cpp.

586 {
587 if(auto active = active_state()) {
588 return active->client_finished()->verify_data();
589 }
590 return std::vector<uint8_t>();
591}

Referenced by Botan::TLS::Channel_Impl_12::secure_renegotiation_check().

◆ secure_renegotiation_data_for_server_hello()

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

Definition at line 593 of file tls_channel_impl_12.cpp.

593 {
594 if(auto active = active_state()) {
595 std::vector<uint8_t> buf = active->client_finished()->verify_data();
596 buf += active->server_finished()->verify_data();
597 return buf;
598 }
599
600 return std::vector<uint8_t>();
601}

Referenced by Botan::TLS::Channel_Impl_12::secure_renegotiation_check().

◆ secure_renegotiation_supported()

bool Botan::TLS::Channel_Impl_12::secure_renegotiation_supported ( ) const
overridevirtualinherited
Returns
true iff the counterparty supports the secure renegotiation extensions.

Implements Botan::TLS::Channel_Impl.

Definition at line 603 of file tls_channel_impl_12.cpp.

603 {
604 if(auto active = active_state()) {
605 return active->server_hello()->secure_renegotiation();
606 }
607
608 if(auto pending = pending_state()) {
609 if(auto hello = pending->server_hello()) {
610 return hello->secure_renegotiation();
611 }
612 }
613
614 return false;
615}

◆ send_alert()

void Botan::TLS::Channel_Impl_12::send_alert ( const Alert & alert)
overridevirtualinherited

Send a TLS alert message. If the alert is fatal, the internal state (keys, etc) will be reset.

Parameters
alertthe Alert to send

Implements Botan::TLS::Channel_Impl.

Definition at line 518 of file tls_channel_impl_12.cpp.

518 {
519 const bool ready_to_send_anything = !is_closed() && m_sequence_numbers;
520 if(alert.is_valid() && ready_to_send_anything) {
521 try {
522 send_record(Record_Type::Alert, alert.serialize());
523 } catch(...) { /* swallow it */
524 }
525 }
526
527 if(alert.type() == Alert::NoRenegotiation) {
528 m_pending_state.reset();
529 }
530
531 if(alert.is_fatal()) {
532 if(auto active = active_state()) {
533 const auto& session_id = active->server_hello()->session_id();
534 if(!session_id.empty()) {
535 session_manager().remove(Session_ID(session_id));
536 }
537 }
538 reset_state();
539 }
540
541 if(alert.type() == Alert::CloseNotify || alert.is_fatal()) {
542 m_has_been_closed = true;
543 }
544}
virtual size_t remove(const Session_Handle &handle)=0
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption
Definition tls_session.h:32

References Botan::TLS::Alert, Botan::TLS::Channel_Impl_12::is_closed(), Botan::TLS::Alert::is_fatal(), Botan::TLS::Alert::is_valid(), Botan::TLS::Session_Manager::remove(), Botan::TLS::Alert::serialize(), Botan::TLS::Channel_Impl_12::session_manager(), and Botan::TLS::Alert::type().

◆ send_fatal_alert()

void Botan::TLS::Channel_Impl::send_fatal_alert ( Alert::Type type)
inlineinherited

Send a fatal alert

Definition at line 75 of file tls_channel_impl.h.

75{ send_alert(Alert(type, true)); }
virtual void send_alert(const Alert &alert)=0

References Botan::TLS::Alert, and Botan::TLS::Channel_Impl::send_alert().

Referenced by Botan::TLS::Channel_Impl_12::from_peer(), and Botan::TLS::Channel_Impl_13::from_peer().

◆ send_new_session_tickets()

virtual size_t Botan::TLS::Channel_Impl::send_new_session_tickets ( const size_t )
inlinevirtualinherited

Send tickets new session tickets to the peer. This is only supported on TLS 1.3 servers.

If the server's Session_Manager does not accept the generated Session objects, the server implementation won't be able to send new tickets. Additionally, anything but TLS 1.3 servers will return 0 (because they don't support sending such session tickets).

Returns
the number of session tickets successfully sent to the client

Reimplemented in Botan::TLS::Server_Impl_13.

Definition at line 157 of file tls_channel_impl.h.

157{ return 0; }

◆ send_warning_alert()

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

Send a warning alert

Definition at line 70 of file tls_channel_impl.h.

70{ send_alert(Alert(type, false)); }

References Botan::TLS::Alert, and Botan::TLS::Channel_Impl::send_alert().

Referenced by Botan::TLS::Channel_Impl::close().

◆ session_manager()

Session_Manager & Botan::TLS::Channel_Impl_12::session_manager ( )
inlineprotectedinherited

Definition at line 186 of file tls_channel_impl_12.h.

186{ return *m_session_manager; }

Referenced by Botan::TLS::Channel_Impl_12::send_alert().

◆ set_io_buffer_size()

void Botan::TLS::Channel_Impl::set_io_buffer_size ( size_t io_buf_sz)
inlineprotectedinherited

Definition at line 239 of file tls_channel_impl.h.

239 {
241 m_downgrade_info->io_buffer_size = io_buf_sz;
242 }

References BOTAN_STATE_CHECK, and Botan::TLS::Channel_Impl::m_downgrade_info.

◆ timeout_check()

bool Botan::TLS::Channel_Impl_12::timeout_check ( )
overridevirtualinherited

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.

Implements Botan::TLS::Channel_Impl.

Definition at line 158 of file tls_channel_impl_12.cpp.

158 {
159 if(m_pending_state) {
160 return m_pending_state->handshake_io().timeout_check();
161 }
162
163 //FIXME: scan cipher suites and remove epochs older than 2*MSL
164 return false;
165}

◆ to_peer()

void Botan::TLS::Channel_Impl_12::to_peer ( std::span< const uint8_t > data)
overridevirtualinherited

Inject plaintext intended for counterparty Throws an exception if is_active() is false

Implements Botan::TLS::Channel_Impl.

Definition at line 510 of file tls_channel_impl_12.cpp.

510 {
511 if(!is_active()) {
512 throw Invalid_State("Data cannot be sent on inactive TLS connection");
513 }
514
515 send_record_array(sequence_numbers().current_write_epoch(), Record_Type::ApplicationData, data.data(), data.size());
516}

References Botan::TLS::ApplicationData, and Botan::TLS::Channel_Impl_12::is_active().

◆ update_traffic_keys()

void Botan::TLS::Channel_Impl_12::update_traffic_keys ( bool request_peer_update = false)
overridevirtualinherited

Attempt to update the session's traffic key material Note that this is possible with a TLS 1.3 channel, only.

Parameters
request_peer_updateif true, require a reciprocal key update

Implements Botan::TLS::Channel_Impl.

Definition at line 183 of file tls_channel_impl_12.cpp.

183 {
184 throw Invalid_Argument("cannot update traffic keys on a TLS 1.2 channel");
185}

Member Data Documentation

◆ m_downgrade_info

std::unique_ptr<Downgrade_Information> Botan::TLS::Channel_Impl::m_downgrade_info
protectedinherited

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