Botan 3.11.0
Crypto and TLS for C&
Botan::TLS::Server_Impl_12 Class Referenceabstract

#include <tls_server_impl_12.h>

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

Public Member Functions

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)
 Server_Impl_12 (const Channel_Impl::Downgrade_Information &downgrade_info)
 Server_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, bool is_datagram=false, size_t reserved_io_buffer_size=TLS::Channel::IO_BUF_DEFAULT_SIZE)
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 Server 1.2 implementation

Definition at line 24 of file tls_server_impl_12.h.

Constructor & Destructor Documentation

◆ Server_Impl_12() [1/2]

Botan::TLS::Server_Impl_12::Server_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,
bool is_datagram = false,
size_t reserved_io_buffer_size = TLS::Channel::IO_BUF_DEFAULT_SIZE )
explicit

Server initialization

Parameters
callbackscontains a set of callback function references required by the TLS server.
session_managermanages session state
credsmanages application/user credentials
policyspecifies other connection policy information
rnga random number generator
is_datagramset to true if this server should expect DTLS connections. Otherwise TLS connections are expected.
reserved_io_buffer_sizeThis many bytes of memory will be preallocated for the read and write buffers. Smaller values just mean reallocations and copies are more likely.

Definition at line 238 of file tls_server_impl_12.cpp.

244 :
245 Channel_Impl_12(callbacks, session_manager, rng, policy, true, is_datagram, io_buf_sz), m_creds(creds) {
246 BOTAN_ASSERT_NONNULL(m_creds);
247}
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
RandomNumberGenerator & rng()
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, Botan::TLS::Channel_Impl_12::callbacks(), Botan::TLS::Channel_Impl_12::Channel_Impl_12(), Botan::TLS::Channel_Impl_12::policy(), Botan::TLS::Channel_Impl_12::rng(), and Botan::TLS::Channel_Impl_12::session_manager().

◆ Server_Impl_12() [2/2]

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

Definition at line 249 of file tls_server_impl_12.cpp.

249 :
250 Channel_Impl_12(downgrade_info.callbacks,
251 downgrade_info.session_manager,
252 downgrade_info.rng,
253 downgrade_info.policy,
254 true /* is_server*/,
255 false /* TLS 1.3 does not support DTLS yet */,
256 downgrade_info.io_buffer_size),
257 m_creds(downgrade_info.creds) {}

References Botan::TLS::Channel_Impl_12::callbacks(), Botan::TLS::Channel_Impl_12::Channel_Impl_12(), Botan::TLS::Channel_Impl_12::policy(), Botan::TLS::Channel_Impl_12::rng(), and Botan::TLS::Channel_Impl_12::session_manager().

Member Function Documentation

◆ activate_session()

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

Definition at line 259 of file tls_channel_impl_12.cpp.

259 {
260 std::swap(m_active_state, m_pending_state);
261 m_pending_state.reset();
262
263 if(!m_active_state->version().is_datagram_protocol()) {
264 // TLS is easy just remove all but the current state
265 const uint16_t current_epoch = sequence_numbers().current_write_epoch();
266
267 const auto not_current_epoch = [current_epoch](uint16_t epoch) { return (epoch != current_epoch); };
268
269 map_remove_if(not_current_epoch, m_write_cipher_states);
270 map_remove_if(not_current_epoch, m_read_cipher_states);
271 }
272
274}
virtual void tls_session_activated()
void map_remove_if(Pred pred, T &assoc)
Definition stl_util.h:53

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

◆ callbacks()

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

◆ change_cipher_spec_reader()

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

Definition at line 195 of file tls_channel_impl_12.cpp.

195 {
196 const auto* pending = pending_state();
197
198 BOTAN_ASSERT(pending && pending->server_hello(), "Have received server hello");
199
200 if(pending->server_hello()->compression_method() != 0) {
201 throw Internal_Error("Negotiated unknown compression algorithm");
202 }
203
204 sequence_numbers().new_read_cipher_state();
205
206 const uint16_t epoch = sequence_numbers().current_read_epoch();
207
208 BOTAN_ASSERT(!m_read_cipher_states.contains(epoch), "No read cipher state currently set for next epoch");
209
210 // flip side as we are reading
211 auto read_state = std::make_shared<Connection_Cipher_State>(
212 pending->version(),
214 false,
215 pending->ciphersuite(),
216 pending->session_keys(),
217 pending->server_hello()->supports_encrypt_then_mac());
218
219 m_read_cipher_states[epoch] = read_state;
220}
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62

References BOTAN_ASSERT, Botan::TLS::Client, 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 222 of file tls_channel_impl_12.cpp.

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

References BOTAN_ASSERT.

◆ close()

void Botan::TLS::Channel_Impl::close ( )
inlineinherited

Send a close notification alert

Definition at line 76 of file tls_channel_impl.h.

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

References send_warning_alert().

◆ create_handshake_state()

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

Definition at line 114 of file tls_channel_impl_12.cpp.

114 {
115 if(pending_state() != nullptr) {
116 throw Internal_Error("create_handshake_state called during handshake");
117 }
118
119 if(const auto* active = active_state()) {
120 const Protocol_Version active_version = active->version();
121
122 if(active_version.is_datagram_protocol() != version.is_datagram_protocol()) {
123 throw TLS_Exception(Alert::ProtocolVersion,
124 "Active state using version " + active_version.to_string() + " cannot change to " +
125 version.to_string() + " in pending");
126 }
127 }
128
129 if(!m_sequence_numbers) {
130 if(version.is_datagram_protocol()) {
131 m_sequence_numbers = std::make_unique<Datagram_Sequence_Numbers>();
132 } else {
133 m_sequence_numbers = std::make_unique<Stream_Sequence_Numbers>();
134 }
135 }
136
137 using namespace std::placeholders;
138
139 std::unique_ptr<Handshake_IO> io;
140 if(version.is_datagram_protocol()) {
141 const uint16_t mtu = static_cast<uint16_t>(policy().dtls_default_mtu());
142 const size_t initial_timeout_ms = policy().dtls_initial_timeout();
143 const size_t max_timeout_ms = policy().dtls_maximum_timeout();
144
145 auto send_record_f = [this](uint16_t epoch, Record_Type record_type, const std::vector<uint8_t>& record) {
146 send_record_under_epoch(epoch, record_type, record);
147 };
148 io = std::make_unique<Datagram_Handshake_IO>(
149 send_record_f, sequence_numbers(), mtu, initial_timeout_ms, max_timeout_ms);
150 } else {
151 auto send_record_f = [this](Record_Type rec_type, const std::vector<uint8_t>& record) {
152 send_record(rec_type, record);
153 };
154 io = std::make_unique<Stream_Handshake_IO>(send_record_f);
155 }
156
157 m_pending_state = new_handshake_state(std::move(io));
158
159 if(const auto* active = active_state()) {
160 m_pending_state->set_version(active->version());
161 }
162
163 return *m_pending_state;
164}
virtual std::unique_ptr< Handshake_State > new_handshake_state(std::unique_ptr< class Handshake_IO > io)=0
virtual size_t dtls_maximum_timeout() const
virtual size_t dtls_default_mtu() const
virtual size_t dtls_initial_timeout() const

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

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

◆ expects_downgrade()

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

Definition at line 276 of file tls_channel_impl.h.

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

References 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 105 of file tls_channel_impl_12.cpp.

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

◆ extract_downgrade_info()

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

Definition at line 274 of file tls_channel_impl.h.

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

References 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 276 of file tls_channel_impl_12.cpp.

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

References Botan::TLS::Alert, Botan::TLS::Policy::allow_dtls_epoch0_restart(), Botan::TLS::ApplicationData, BOTAN_ASSERT, BOTAN_ASSERT_IMPLICATION, Botan::TLS::ChangeCipherSpec, Botan::TLS::ClientHello, 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(), 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 251 of file tls_channel_impl_12.cpp.

251 {
252 return !is_closed() && is_handshake_complete();
253}
bool is_handshake_complete() const override

References is_closed(), and is_handshake_complete().

Referenced by 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 255 of file tls_channel_impl_12.cpp.

255 {
256 return m_has_been_closed;
257}

Referenced by is_active(), is_closed_for_reading(), is_closed_for_writing(), and 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 94 of file tls_channel_impl_12.h.

94{ return is_closed(); }

References 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 96 of file tls_channel_impl_12.h.

96{ return is_closed(); }

References 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 269 of file tls_channel_impl.h.

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

References 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 247 of file tls_channel_impl_12.cpp.

247 {
248 return (active_state() != nullptr);
249}

Referenced by 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 639 of file tls_channel_impl_12.cpp.

641 {
642 if(const auto* active = active_state()) {
643 if(pending_state() != nullptr) {
644 throw Invalid_State("Channel_Impl_12::key_material_export cannot export during renegotiation");
645 }
646
647 auto prf = active->protocol_specific_prf();
648
649 const secure_vector<uint8_t>& master_secret = active->session_keys().master_secret();
650
651 BOTAN_ASSERT_NONNULL(active->client_hello());
652 BOTAN_ASSERT_NONNULL(active->server_hello());
653 std::vector<uint8_t> salt;
654 salt += active->client_hello()->random();
655 salt += active->server_hello()->random();
656
657 if(!context.empty()) {
658 const size_t context_size = context.length();
659 if(context_size > 0xFFFF) {
660 throw Invalid_Argument("key_material_export context is too long");
661 }
662 salt.push_back(get_byte<0>(static_cast<uint16_t>(context_size)));
663 salt.push_back(get_byte<1>(static_cast<uint16_t>(context_size)));
664 salt += as_span_of_bytes(context);
665 }
666
667 return SymmetricKey(prf->derive_key(length, master_secret, salt, as_span_of_bytes(label)));
668 } else {
669 throw Invalid_State("Channel_Impl_12::key_material_export connection not active");
670 }
671}
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79
OctetString SymmetricKey
Definition symkey.h:140
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
Definition mem_utils.h:59
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68

References Botan::as_span_of_bytes(), BOTAN_ASSERT_NONNULL, and Botan::get_byte().

◆ 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

Referenced by create_handshake_state().

◆ 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 140 of file tls_channel_impl.h.

140{ 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 98 of file tls_channel_impl_12.cpp.

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

References 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 109 of file tls_channel_impl_12.h.

109{ return nullptr; }

◆ policy()

◆ preserve_client_hello()

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

Definition at line 229 of file tls_channel_impl.h.

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

References BOTAN_STATE_CHECK, and 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 224 of file tls_channel_impl.h.

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

References BOTAN_STATE_CHECK, and 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 175 of file tls_channel_impl_12.cpp.

175 {
176 if(pending_state() != nullptr) { // currently in handshake?
177 return;
178 }
179
180 if(const auto* active = active_state()) {
181 if(!force_full_renegotiation) {
182 force_full_renegotiation = !policy().allow_resumption_for_renegotiation();
183 }
184
185 initiate_handshake(create_handshake_state(active->version()), force_full_renegotiation);
186 } else {
187 throw Invalid_State("Cannot renegotiate on inactive connection");
188 }
189}
Handshake_State & create_handshake_state(Protocol_Version version)
virtual void initiate_handshake(Handshake_State &state, bool force_full_renegotiation)=0
virtual bool allow_resumption_for_renegotiation() const

References Botan::TLS::Policy::allow_resumption_for_renegotiation(), create_handshake_state(), initiate_handshake(), and 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 performed 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 250 of file tls_channel_impl.h.

250 {
252 m_downgrade_info->will_downgrade = true;
253 }

References BOTAN_STATE_CHECK, and m_downgrade_info.

Referenced by request_downgrade_for_resumption().

◆ request_downgrade_for_resumption()

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

Definition at line 255 of file tls_channel_impl.h.

255 {
256 BOTAN_STATE_CHECK(m_downgrade_info && m_downgrade_info->client_hello_message.empty() &&
257 m_downgrade_info->peer_transcript.empty() && !m_downgrade_info->tls12_session.has_value());
258 BOTAN_ASSERT_NOMSG(session.session.version().is_pre_tls_13());
259 m_downgrade_info->tls12_session = std::move(session);
261 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::TLS::Protocol_Version::is_pre_tls_13(), m_downgrade_info, request_downgrade(), Botan::TLS::Session_with_Handle::session, and Botan::TLS::Session_Base::version().

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

◆ reset_active_association_state()

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

Definition at line 60 of file tls_channel_impl_12.cpp.

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

References BOTAN_ASSERT_NOMSG.

◆ 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 561 of file tls_channel_impl_12.cpp.

561 {
562 BOTAN_ASSERT_NONNULL(client_hello);
563 const bool secure_renegotiation = client_hello->secure_renegotiation();
564
565 if(const auto* active = active_state()) {
566 BOTAN_ASSERT_NONNULL(active->client_hello());
567 const bool active_sr = active->client_hello()->secure_renegotiation();
568
569 if(active_sr != secure_renegotiation) {
570 throw TLS_Exception(Alert::HandshakeFailure, "Client changed its mind about secure renegotiation");
571 }
572 }
573
574 if(secure_renegotiation) {
575 const std::vector<uint8_t>& data = client_hello->renegotiation_info();
576
578 throw TLS_Exception(Alert::HandshakeFailure, "Client sent bad values for secure renegotiation");
579 }
580 }
581}
std::vector< uint8_t > secure_renegotiation_data_for_client_hello() const

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

Referenced by Botan::TLS::Client_Impl_12::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 583 of file tls_channel_impl_12.cpp.

583 {
584 BOTAN_ASSERT_NONNULL(server_hello);
585 const bool secure_renegotiation = server_hello->secure_renegotiation();
586
587 if(const auto* active = active_state()) {
588 BOTAN_ASSERT_NONNULL(active->server_hello());
589 const bool active_sr = active->server_hello()->secure_renegotiation();
590
591 if(active_sr != secure_renegotiation) {
592 throw TLS_Exception(Alert::HandshakeFailure, "Server changed its mind about secure renegotiation");
593 }
594 }
595
596 if(secure_renegotiation) {
597 const std::vector<uint8_t>& data = server_hello->renegotiation_info();
598
600 throw TLS_Exception(Alert::HandshakeFailure, "Server sent bad values for secure renegotiation");
601 }
602 }
603}
std::vector< uint8_t > secure_renegotiation_data_for_server_hello() const

References BOTAN_ASSERT_NONNULL, Botan::TLS::Server_Hello_12::renegotiation_info(), Botan::TLS::Server_Hello_12::secure_renegotiation(), and 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 605 of file tls_channel_impl_12.cpp.

605 {
606 if(const auto* active = active_state()) {
607 BOTAN_ASSERT_NONNULL(active->client_finished());
608 return active->client_finished()->verify_data();
609 }
610 return std::vector<uint8_t>();
611}

References BOTAN_ASSERT_NONNULL.

Referenced by 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 613 of file tls_channel_impl_12.cpp.

613 {
614 if(const auto* active = active_state()) {
615 BOTAN_ASSERT_NONNULL(active->client_finished());
616 BOTAN_ASSERT_NONNULL(active->server_finished());
617 std::vector<uint8_t> buf = active->client_finished()->verify_data();
618 buf += active->server_finished()->verify_data();
619 return buf;
620 }
621
622 return std::vector<uint8_t>();
623}

References BOTAN_ASSERT_NONNULL.

Referenced by 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 625 of file tls_channel_impl_12.cpp.

625 {
626 if(const auto* active = active_state()) {
627 return active->server_hello()->secure_renegotiation();
628 }
629
630 if(const auto* pending = pending_state()) {
631 if(const auto* hello = pending->server_hello()) {
632 return hello->secure_renegotiation();
633 }
634 }
635
636 return false;
637}

◆ 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 532 of file tls_channel_impl_12.cpp.

532 {
533 const bool ready_to_send_anything = !is_closed() && m_sequence_numbers;
534 if(alert.is_valid() && ready_to_send_anything) {
535 try {
536 send_record(Record_Type::Alert, alert.serialize());
537 } catch(...) { /* swallow it */
538 }
539 }
540
541 if(alert.type() == Alert::NoRenegotiation) {
542 m_pending_state.reset();
543 }
544
545 if(alert.is_fatal()) {
546 if(const auto* active = active_state()) {
547 BOTAN_ASSERT_NONNULL(active->server_hello());
548 const auto& session_id = active->server_hello()->session_id();
549 if(!session_id.empty()) {
550 session_manager().remove(Session_Handle(Session_ID(session_id)));
551 }
552 }
553 reset_state();
554 }
555
556 if(alert.type() == Alert::CloseNotify || alert.is_fatal()) {
557 m_has_been_closed = true;
558 }
559}
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

References Botan::TLS::Alert, BOTAN_ASSERT_NONNULL, is_closed(), Botan::TLS::Alert::is_fatal(), Botan::TLS::Alert::is_valid(), Botan::TLS::Session_Manager::remove(), Botan::TLS::Alert::serialize(), 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 71 of file tls_channel_impl.h.

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

References Botan::TLS::Alert, and 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 153 of file tls_channel_impl.h.

153{ return 0; }

◆ send_warning_alert()

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

Send a warning alert

Definition at line 66 of file tls_channel_impl.h.

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

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

Referenced by close().

◆ session_manager()

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

◆ set_io_buffer_size()

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

Definition at line 237 of file tls_channel_impl.h.

237 {
239 m_downgrade_info->io_buffer_size = io_buf_sz;
240 }

References BOTAN_STATE_CHECK, and 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 166 of file tls_channel_impl_12.cpp.

166 {
167 if(m_pending_state) {
168 return m_pending_state->handshake_io().timeout_check();
169 }
170
171 //FIXME: scan cipher suites and remove epochs older than 2*MSL
172 return false;
173}

◆ 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 524 of file tls_channel_impl_12.cpp.

524 {
525 if(!is_active()) {
526 throw Invalid_State("Data cannot be sent on inactive TLS connection");
527 }
528
529 send_record_array(sequence_numbers().current_write_epoch(), Record_Type::ApplicationData, data.data(), data.size());
530}

References Botan::TLS::ApplicationData, and 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 191 of file tls_channel_impl_12.cpp.

191 {
192 throw Invalid_Argument("cannot update traffic keys on a TLS 1.2 channel");
193}

Member Data Documentation

◆ m_downgrade_info


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