Botan 3.13.0
Crypto and TLS for C&
Botan::TLS::Server_Impl_13 Class Referencefinal

#include <tls_server_impl_13.h>

Inheritance diagram for Botan::TLS::Server_Impl_13:
Botan::TLS::Channel_Impl_13 Botan::TLS::Channel_Impl Botan::TLS::Secret_Logger

Public Member Functions

std::string application_protocol () const override
void close ()
std::optional< std::string > external_psk_identity () const override
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_handshake_complete () const override
SymmetricKey key_material_export (std::string_view label, std::string_view context, size_t length) const override
bool new_session_ticket_supported () const override
virtual std::optional< std::chrono::milliseconds > next_retransmission_timeout () const
std::vector< X509_Certificatepeer_cert_chain () const override
std::shared_ptr< const Public_Keypeer_raw_public_key () const override
void renegotiate (bool) override
bool secure_renegotiation_supported () const override
void send_alert (const Alert &alert) override
void send_fatal_alert (Alert::Type type)
size_t send_new_session_tickets (size_t tickets) override
void send_warning_alert (Alert::Type type)
 Server_Impl_13 (const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< const Policy > &policy, const std::shared_ptr< RandomNumberGenerator > &rng)
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 Types

enum class  Compat_Mode_Situation : uint8_t {
  BeforeSendingAlert , AfterSendingFirstClientHello , BeforeSendingSecondClientHello , BeforeSendingEncryptedClientFlight ,
  AfterSendingFirstServerHello , AfterSendingHelloRetryRequest
}

Protected Member Functions

AggregatedHandshakeMessages aggregate_handshake_messages ()
AggregatedPostHandshakeMessages aggregate_post_handshake_messages ()
Callbackscallbacks () const
Credentials_Managercredentials_manager ()
bool expects_downgrade () const
bool is_downgrading () const
void opportunistically_update_traffic_keys ()
const Policypolicy () const
RandomNumberGeneratorrng ()
void send_dummy_change_cipher_spec ()
template<typename... MsgTs>
void send_handshake_message (const std::variant< MsgTs... > &message)
template<typename MsgT>
void send_handshake_message (std::reference_wrapper< MsgT > message)
void send_post_handshake_message (Post_Handshake_Message_13 message)
Session_Managersession_manager ()
void set_record_size_limits (uint16_t outgoing_limit, uint16_t incoming_limit)
void set_selected_certificate_type (Certificate_Type cert_type)

Protected Attributes

std::optional< Active_Connection_State_13m_active_state
std::unique_ptr< Cipher_Statem_cipher_state
const Connection_Side m_side
Transcript_Hash_State m_transcript_hash

Detailed Description

SSL/TLS Server 1.3 implementation

Definition at line 22 of file tls_server_impl_13.h.

Member Enumeration Documentation

◆ Compat_Mode_Situation

enum class Botan::TLS::Channel_Impl_13::Compat_Mode_Situation : uint8_t
strongprotectedinherited
Enumerator
BeforeSendingAlert 
AfterSendingFirstClientHello 
BeforeSendingSecondClientHello 
BeforeSendingEncryptedClientFlight 
AfterSendingFirstServerHello 
AfterSendingHelloRetryRequest 

Definition at line 222 of file tls_channel_impl_13.h.

222 : uint8_t {
223 BeforeSendingAlert,
224 AfterSendingFirstClientHello,
225 BeforeSendingSecondClientHello,
226 BeforeSendingEncryptedClientFlight,
227 AfterSendingFirstServerHello,
228 AfterSendingHelloRetryRequest,
229 };

Constructor & Destructor Documentation

◆ Server_Impl_13()

Botan::TLS::Server_Impl_13::Server_Impl_13 ( const std::shared_ptr< Callbacks > & callbacks,
const std::shared_ptr< Session_Manager > & session_manager,
const std::shared_ptr< Credentials_Manager > & credentials_manager,
const std::shared_ptr< const Policy > & policy,
const std::shared_ptr< RandomNumberGenerator > & rng )
explicit

Definition at line 23 of file tls_server_impl_13.cpp.

27 :
29 m_handshake(std::make_unique<Pending_Handshake>()) {
30#if defined(BOTAN_HAS_TLS_12)
31 if(policy->allow_tls12()) {
32 expect_downgrade({}, {});
33 }
34#endif
35
36 m_handshake->transitions.set_expected_next(Handshake_Type::ClientHello);
37}
const Policy & policy() const
Credentials_Manager & credentials_manager()
RandomNumberGenerator & rng()
Channel_Impl_13(const std::shared_ptr< Callbacks > &callbacks, const std::shared_ptr< Session_Manager > &session_manager, const std::shared_ptr< Credentials_Manager > &credentials_manager, const std::shared_ptr< RandomNumberGenerator > &rng, const std::shared_ptr< const Policy > &policy, bool is_server)
Session_Manager & session_manager()

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

Member Function Documentation

◆ aggregate_handshake_messages()

AggregatedHandshakeMessages Botan::TLS::Channel_Impl_13::aggregate_handshake_messages ( )
inlineprotectedinherited

Definition at line 258 of file tls_channel_impl_13.h.

References m_transcript_hash.

Referenced by send_handshake_message().

◆ aggregate_post_handshake_messages()

AggregatedPostHandshakeMessages Botan::TLS::Channel_Impl_13::aggregate_post_handshake_messages ( )
inlineprotectedinherited

◆ application_protocol()

std::string Botan::TLS::Server_Impl_13::application_protocol ( ) const
overridevirtual

Return the protocol notification set for this connection, if any (ALPN). This value is not tied to the session and a later renegotiation of the same session can choose a new protocol.

Implements Botan::TLS::Channel_Impl.

Definition at line 39 of file tls_server_impl_13.cpp.

39 {
40 if(m_active_state.has_value()) {
41 return m_active_state->application_protocol();
42 }
43
44 return "";
45}
std::optional< Active_Connection_State_13 > m_active_state

References application_protocol(), and Botan::TLS::Channel_Impl_13::m_active_state.

Referenced by application_protocol().

◆ callbacks()

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

◆ 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 send_warning_alert().

◆ credentials_manager()

Credentials_Manager & Botan::TLS::Channel_Impl_13::credentials_manager ( )
inlineprotectedinherited

Definition at line 270 of file tls_channel_impl_13.h.

270{ return *m_credentials_manager; }

Referenced by Channel_Impl_13(), and Botan::TLS::Server_Impl_13::Server_Impl_13().

◆ expects_downgrade()

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

Definition at line 290 of file tls_channel_impl.h.

290 {
291#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
292 return m_downgrade_info != nullptr;
293#else
294 return false;
295#endif
296 }

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::Server_Impl_13::external_psk_identity ( ) const
overridevirtual
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 85 of file tls_server_impl_13.cpp.

85 {
86 if(m_active_state.has_value()) {
87 return m_active_state->psk_identity();
88 } else if(m_handshake) {
89 return m_handshake->psk_identity;
90 } else {
91 return std::nullopt;
92 }
93}

References external_psk_identity(), and Botan::TLS::Channel_Impl_13::m_active_state.

Referenced by external_psk_identity().

◆ from_peer()

size_t Botan::TLS::Channel_Impl_13::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 68 of file tls_channel_impl_13.cpp.

68 {
70
71 // RFC 8446 6.1
72 // Any data received after a closure alert has been received MUST be ignored.
73 if(!m_can_read) {
74 return 0;
75 }
76
77 try {
78#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
79 if(expects_downgrade()) {
80 preserve_peer_transcript(data);
81 }
82#endif
83
84 m_record_layer.copy_data(data);
85
86 while(true) {
87 // RFC 8446 6.1
88 // Any data received after a closure alert has been received MUST be ignored.
89 //
90 // ... this data might already be in the record layer's read buffer.
91 if(!m_can_read) {
92 return 0;
93 }
94
95 auto result = m_record_layer.next_record(m_cipher_state.get());
96
97 if(std::holds_alternative<BytesNeeded>(result)) {
98 return std::get<BytesNeeded>(result);
99 }
100
101 const auto& record = std::get<Record>(result);
102
103 // RFC 8446 5.1
104 // Handshake messages MUST NOT be interleaved with other record types.
105 if(record.type != Record_Type::Handshake && m_handshake_layer.has_pending_data()) {
106 throw Unexpected_Message("Expected remainder of a handshake message");
107 }
108
109 if(record.type == Record_Type::Handshake) {
110 m_handshake_layer.copy_data(record.fragment);
111
112 if(!is_handshake_complete()) {
113 while(auto handshake_msg = m_handshake_layer.next_message(policy(), m_transcript_hash)) {
114 // RFC 8446 5.1
115 // Handshake messages MUST NOT span key changes. Implementations
116 // MUST verify that all messages immediately preceding a key change
117 // align with a record boundary; if not, then they MUST terminate the
118 // connection with an "unexpected_message" alert. Because the
119 // ClientHello, EndOfEarlyData, ServerHello, Finished, and KeyUpdate
120 // messages can immediately precede a key change, implementations
121 // MUST send these messages in alignment with a record boundary.
122 //
123 // Note: Hello_Retry_Request was added to the list below although it cannot immediately precede a key change.
124 // However, there cannot be any further sensible messages in the record after HRR.
125 //
126 // Note: Server_Hello_12 was deliberately not included in the check below because in TLS 1.2 Server Hello and
127 // other handshake messages can be legally coalesced in a single record.
128 //
129 if(holds_any_of<Client_Hello_12_Shim,
130 Client_Hello_13 /*, EndOfEarlyData,*/,
131 Server_Hello_13,
132 Hello_Retry_Request,
133 Finished_13>(handshake_msg.value()) &&
134 m_handshake_layer.has_pending_data()) {
135 throw Unexpected_Message("Unexpected additional handshake message data found in record");
136 }
137
138 process_handshake_msg(std::move(handshake_msg.value()));
139
140#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
141 if(is_downgrading()) {
142 // Downgrade to TLS 1.2 was detected. Stop everything we do and await being replaced by a 1.2 implementation.
143 return 0;
144 } else if(m_downgrade_info != nullptr) {
145 // We received a TLS 1.3 error alert that could have been a TLS 1.2 warning alert.
146 // Now that we know that we are talking to a TLS 1.3 server, shut down.
147 if(m_downgrade_info->received_tls_13_error_alert) {
148 shutdown();
149 }
150
151 // Downgrade can only be indicated in the first received peer message. This was not the case.
152 m_downgrade_info.reset();
153 }
154#endif
155
156 // After the initial handshake message is received, the record
157 // layer must be more restrictive.
158 // See RFC 8446 5.1 regarding "legacy_record_version"
159 if(!m_first_message_received) {
160 m_record_layer.disable_receiving_compat_mode();
161 m_first_message_received = true;
162 }
163 }
164 } else {
165 while(auto handshake_msg = m_handshake_layer.next_post_handshake_message(policy())) {
166 process_post_handshake_msg(std::move(handshake_msg.value()));
167 }
168 }
169 } else if(record.type == Record_Type::ChangeCipherSpec) {
171 } else if(record.type == Record_Type::ApplicationData) {
173 if(!m_cipher_state->can_decrypt_application_traffic()) {
174 throw Unexpected_Message("Application data received before handshake completion");
175 }
176 /*
177 The record sequence number is set in Record_Layer::next_record only when
178 the record contents are decrypted under the current set of traffic keys
179 */
180 if(!record.seq_no.has_value()) {
181 throw Unexpected_Message("Application data must have a sequence number");
182 }
183 callbacks().tls_record_received(record.seq_no.value(), record.fragment);
184 } else if(record.type == Record_Type::Alert) {
185 process_alert(record.fragment);
186 } else {
187 throw Unexpected_Message("Unexpected record type " + std::to_string(static_cast<size_t>(record.type)) +
188 " from counterparty");
189 }
190 }
191 } catch(TLS_Exception& e) {
192 send_fatal_alert(e.type());
193 throw;
194 } catch(Invalid_Authentication_Tag&) {
195 // RFC 8446 5.2
196 // If the decryption fails, the receiver MUST terminate the connection
197 // with a "bad_record_mac" alert.
198 send_fatal_alert(Alert::BadRecordMac);
199 throw;
200 } catch(Decoding_Error&) {
201 send_fatal_alert(Alert::DecodeError);
202 throw;
203 } catch(...) {
204 send_fatal_alert(Alert::InternalError);
205 throw;
206 }
207}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
virtual void tls_record_received(uint64_t seq_no, std::span< const uint8_t > data)=0
virtual void process_post_handshake_msg(Post_Handshake_Message_13 msg)=0
virtual void process_handshake_msg(Handshake_Message_13 msg)=0
virtual void process_dummy_change_cipher_spec()=0
std::unique_ptr< Cipher_State > m_cipher_state
void send_fatal_alert(Alert::Type type)
virtual bool is_handshake_complete() const =0
constexpr bool holds_any_of(const std::variant< Ts... > &v) noexcept
Definition stl_util.h:66

References Botan::TLS::Alert, Botan::TLS::ApplicationData, BOTAN_ASSERT_NONNULL, BOTAN_STATE_CHECK, callbacks(), Botan::TLS::ChangeCipherSpec, Botan::TLS::Channel_Impl::expects_downgrade(), Botan::TLS::Handshake, Botan::holds_any_of(), Botan::TLS::Channel_Impl::is_downgrading(), Botan::TLS::Channel_Impl::is_handshake_complete(), m_cipher_state, m_transcript_hash, policy(), process_dummy_change_cipher_spec(), process_handshake_msg(), process_post_handshake_msg(), Botan::TLS::Channel_Impl::send_fatal_alert(), Botan::TLS::Callbacks::tls_record_received(), and Botan::TLS::TLS_Exception::type().

◆ is_active()

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

Note that the connection is active until the application has called close(), even if a CloseNotify has been received from the peer.

Implements Botan::TLS::Channel_Impl.

Definition at line 332 of file tls_channel_impl_13.cpp.

332 {
333 return m_cipher_state != nullptr && m_cipher_state->can_encrypt_application_traffic() // handshake done
334 && m_can_write; // close() hasn't been called
335}

References m_cipher_state.

Referenced by to_peer(), and update_traffic_keys().

◆ is_closed()

bool Botan::TLS::Channel_Impl_13::is_closed ( ) const
inlineoverridevirtualinherited
Returns
true iff the connection has been closed, i.e. CloseNotify has been received from the peer.

Implements Botan::TLS::Channel_Impl.

Definition at line 167 of file tls_channel_impl_13.h.

bool is_closed_for_reading() const override
bool is_closed_for_writing() const override

References is_closed_for_reading(), and is_closed_for_writing().

◆ is_closed_for_reading()

bool Botan::TLS::Channel_Impl_13::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 169 of file tls_channel_impl_13.h.

169{ return !m_can_read; }

Referenced by is_closed().

◆ is_closed_for_writing()

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

Implements Botan::TLS::Channel_Impl.

Definition at line 171 of file tls_channel_impl_13.h.

171{ return !m_can_write; }

Referenced by is_closed().

◆ is_downgrading()

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

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

See also
Downgrade_Information

Definition at line 282 of file tls_channel_impl.h.

282 {
283#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
284 return m_downgrade_info && m_downgrade_info->will_downgrade;
285#else
286 return false;
287#endif
288 }

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::Server_Impl_13::is_handshake_complete ( ) const
overridevirtual
Returns
true iff the TLS handshake has finished successfully

Implements Botan::TLS::Channel_Impl.

Definition at line 199 of file tls_server_impl_13.cpp.

199 {
200 return m_active_state.has_value() || (m_handshake != nullptr && m_handshake->state.handshake_finished());
201}

References is_handshake_complete(), and Botan::TLS::Channel_Impl_13::m_active_state.

Referenced by is_handshake_complete(), new_session_ticket_supported(), and send_new_session_tickets().

◆ key_material_export()

SymmetricKey Botan::TLS::Channel_Impl_13::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 337 of file tls_channel_impl_13.cpp.

339 {
341 BOTAN_STATE_CHECK(m_cipher_state != nullptr && m_cipher_state->can_export_keys());
342 return SymmetricKey(m_cipher_state->export_key(label, context, length));
343}
OctetString SymmetricKey
Definition symkey.h:153

References BOTAN_STATE_CHECK, Botan::TLS::Channel_Impl::is_downgrading(), and m_cipher_state.

◆ new_session_ticket_supported()

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

Reimplemented from Botan::TLS::Channel_Impl.

Definition at line 95 of file tls_server_impl_13.cpp.

95 {
96 // RFC 8446 4.2.9
97 // This extension also restricts the modes for use with PSK resumption.
98 // Servers SHOULD NOT send NewSessionTicket with tickets that are not
99 // compatible with the advertised modes; however, if a server does so,
100 // the impact will just be that the client's attempts at resumption fail.
101 //
102 // Note: Applications can overrule this by calling send_new_session_tickets()
103 // regardless of this method indicating no support for tickets.
104 //
105 // TODO: Implement other PSK KE modes than PSK_DHE_KE
106 return is_handshake_complete() && m_active_state.has_value() && m_active_state->peer_supports_psk_dhe_ke();
107}
bool is_handshake_complete() const override

References is_handshake_complete(), Botan::TLS::Channel_Impl_13::m_active_state, and new_session_ticket_supported().

Referenced by new_session_ticket_supported().

◆ next_retransmission_timeout()

virtual std::optional< std::chrono::milliseconds > Botan::TLS::Channel_Impl::next_retransmission_timeout ( ) const
inlinevirtualinherited

Reimplemented in Botan::TLS::Channel_Impl_12.

Definition at line 92 of file tls_channel_impl.h.

92{ return std::nullopt; }

◆ opportunistically_update_traffic_keys()

void Botan::TLS::Channel_Impl_13::opportunistically_update_traffic_keys ( )
inlineprotectedinherited

Schedule a traffic key update to opportunistically happen before the channel sends application data the next time. Such a key update will never request a reciprocal key update from the peer.

Definition at line 240 of file tls_channel_impl_13.h.

240{ m_opportunistic_key_update = true; }

Referenced by handle().

◆ peer_cert_chain()

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

Implements Botan::TLS::Channel_Impl.

Definition at line 47 of file tls_server_impl_13.cpp.

47 {
48 if(m_active_state.has_value()) {
49 return m_active_state->peer_certs();
50 }
51
52 if(m_handshake) {
53 if(m_handshake->state.has_client_certificate_msg() &&
54 m_handshake->state.client_certificate().has_certificate_chain()) {
55 return m_handshake->state.client_certificate().cert_chain();
56 }
57
58 if(m_handshake->resumed_session.has_value()) {
59 return m_handshake->resumed_session->peer_certs();
60 }
61 }
62
63 return {};
64}

References Botan::TLS::Channel_Impl_13::m_active_state, and peer_cert_chain().

Referenced by peer_cert_chain(), and send_new_session_tickets().

◆ peer_raw_public_key()

std::shared_ptr< const Public_Key > Botan::TLS::Server_Impl_13::peer_raw_public_key ( ) const
overridevirtual
Returns
raw public key of the peer (may be nullptr)

Implements Botan::TLS::Channel_Impl.

Definition at line 66 of file tls_server_impl_13.cpp.

66 {
67 if(m_active_state.has_value()) {
68 return m_active_state->peer_raw_public_key();
69 }
70
71 if(m_handshake) {
72 if(m_handshake->state.has_client_certificate_msg() &&
73 m_handshake->state.client_certificate().is_raw_public_key()) {
74 return m_handshake->state.client_certificate().public_key();
75 }
76
77 if(m_handshake->resumed_session.has_value()) {
78 return m_handshake->resumed_session->peer_raw_public_key();
79 }
80 }
81
82 return nullptr;
83}

References Botan::TLS::Channel_Impl_13::m_active_state, and peer_raw_public_key().

Referenced by peer_raw_public_key(), and send_new_session_tickets().

◆ policy()

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

◆ renegotiate()

void Botan::TLS::Channel_Impl_13::renegotiate ( bool )
inlineoverridevirtualinherited

Attempt to renegotiate the session

Implements Botan::TLS::Channel_Impl.

Definition at line 185 of file tls_channel_impl_13.h.

185 {
186 throw Invalid_Argument("renegotiation is not allowed in TLS 1.3");
187 }

◆ rng()

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

◆ secure_renegotiation_supported()

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

Implements Botan::TLS::Channel_Impl.

Definition at line 201 of file tls_channel_impl_13.h.

201 {
202 // Secure renegotiation is not supported in TLS 1.3, though BoGo
203 // tests expect us to claim that it is available.
204 return true;
205 }

◆ send_alert()

void Botan::TLS::Channel_Impl_13::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 306 of file tls_channel_impl_13.cpp.

306 {
307 if(alert.is_valid() && m_can_write) {
308 try {
310 send_record(Record_Type::Alert, alert.serialize());
311 } catch(...) { /* swallow it */
312 }
313 }
314
315 // Note: In TLS 1.3 sending a CloseNotify must not immediately lead to closing the reading end.
316 // RFC 8446 6.1
317 // Each party MUST send a "close_notify" alert before closing its write
318 // side of the connection, unless it has already sent some error alert.
319 // This does not have any effect on its read side of the connection.
320 if(is_close_notify_alert(alert) && m_can_write) {
321 m_can_write = false;
322 if(m_cipher_state) {
323 m_cipher_state->clear_write_keys();
324 }
325 }
326
327 if(is_error_alert(alert)) {
328 shutdown();
329 }
330}
virtual void maybe_handle_compatibility_mode(Compat_Mode_Situation situation)=0

References Botan::TLS::Alert, BeforeSendingAlert, Botan::TLS::Alert::is_valid(), m_cipher_state, maybe_handle_compatibility_mode(), and Botan::TLS::Alert::serialize().

◆ send_dummy_change_cipher_spec()

void Botan::TLS::Channel_Impl_13::send_dummy_change_cipher_spec ( )
protectedinherited

Definition at line 271 of file tls_channel_impl_13.cpp.

271 {
272 // RFC 9846 5.
273 // The change_cipher_spec record is used only for compatibility purposes
274 // (see Appendix E.4).
275 //
276 // An implementation may receive an unencrypted record of type
277 // change_cipher_spec consisting of the single byte value 0x01 at any time
278 // after the first ClientHello message has been sent or received and
279 // before the peer's Finished message has been received.
281
282 send_record(Record_Type::ChangeCipherSpec, {0x01});
283}

References BOTAN_STATE_CHECK, Botan::TLS::ChangeCipherSpec, and Botan::TLS::Channel_Impl::is_handshake_complete().

◆ 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 send_alert().

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

◆ send_handshake_message() [1/2]

template<typename... MsgTs>
void Botan::TLS::Channel_Impl_13::send_handshake_message ( const std::variant< MsgTs... > & message)
inlineprotectedinherited

Definition at line 243 of file tls_channel_impl_13.h.

243 {
245 }
AggregatedHandshakeMessages & add(Handshake_Message_13_Ref message)
AggregatedHandshakeMessages aggregate_handshake_messages()
constexpr GeneralVariantT generalize_to(SpecialT &&specific)
Converts a given variant into another variant-ish whose type states are a super set of the given vari...
Definition stl_util.h:88

References Botan::TLS::Channel_Impl_13::AggregatedHandshakeMessages::add(), aggregate_handshake_messages(), Botan::generalize_to(), and Botan::TLS::Channel_Impl_13::AggregatedMessages::send().

Referenced by Botan::TLS::Client_Impl_13::Client_Impl_13(), and send_handshake_message().

◆ send_handshake_message() [2/2]

template<typename MsgT>
void Botan::TLS::Channel_Impl_13::send_handshake_message ( std::reference_wrapper< MsgT > message)
inlineprotectedinherited

Definition at line 248 of file tls_channel_impl_13.h.

248 {
250 }
void send_handshake_message(const std::variant< MsgTs... > &message)

References Botan::generalize_to(), and send_handshake_message().

◆ send_new_session_tickets()

size_t Botan::TLS::Server_Impl_13::send_new_session_tickets ( size_t )
overridevirtual

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 from Botan::TLS::Channel_Impl.

Definition at line 109 of file tls_server_impl_13.cpp.

109 {
112
113 if(tickets == 0) {
114 return 0;
115 }
116
117 auto flight = aggregate_post_handshake_messages();
118 size_t tickets_created = 0;
119
121
122 for(size_t i = 0; i < tickets; ++i) {
123 auto nonce = m_cipher_state->next_ticket_nonce();
124 const uint32_t ticket_age_add = load_be(rng().random_array<4>());
125 const Session session(m_cipher_state->psk(nonce),
126 std::nullopt, // early data not yet implemented
127 ticket_age_add,
128 policy().session_ticket_lifetime(),
129 m_active_state->version(),
130 m_active_state->ciphersuite_code(),
134 Server_Information(m_active_state->sni_hostname()),
135 callbacks().tls_current_timestamp());
136
137 if(callbacks().tls_should_persist_resumption_information(session)) {
138 if(auto handle = session_manager().establish(session)) {
139 flight.add(New_Session_Ticket_13(std::move(nonce), session, handle.value(), callbacks()));
140 ++tickets_created;
141 }
142 }
143 }
144
145 if(flight.contains_messages()) {
146 flight.send();
147 }
148
149 return tickets_created;
150}
AggregatedPostHandshakeMessages aggregate_post_handshake_messages()
std::vector< X509_Certificate > peer_cert_chain() const override
std::shared_ptr< const Public_Key > peer_raw_public_key() const override
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504

References Botan::TLS::Channel_Impl_13::aggregate_post_handshake_messages(), BOTAN_STATE_CHECK, Botan::TLS::Channel_Impl_13::callbacks(), is_handshake_complete(), Botan::load_be(), Botan::TLS::Channel_Impl_13::m_active_state, Botan::TLS::Channel_Impl_13::m_cipher_state, peer_cert_chain(), peer_raw_public_key(), Botan::TLS::Channel_Impl_13::policy(), Botan::TLS::Channel_Impl_13::rng(), send_new_session_tickets(), Botan::TLS::Server, and Botan::TLS::Channel_Impl_13::session_manager().

Referenced by send_new_session_tickets().

◆ send_post_handshake_message()

void Botan::TLS::Channel_Impl_13::send_post_handshake_message ( Post_Handshake_Message_13 message)
inlineprotectedinherited

◆ 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 send_alert().

Referenced by close().

◆ session_manager()

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

◆ set_record_size_limits()

void Botan::TLS::Channel_Impl_13::set_record_size_limits ( uint16_t outgoing_limit,
uint16_t incoming_limit )
protectedinherited

Set the record size limits as negotiated by the "record_size_limit" extension (RFC 8449).

Parameters
outgoing_limitthe maximal number of plaintext bytes to be sent in a protected record
incoming_limitthe maximal number of plaintext bytes to be accepted in a received protected record

Definition at line 458 of file tls_channel_impl_13.cpp.

458 {
459 m_record_layer.set_record_size_limits(outgoing_limit, incoming_limit);
460}

◆ set_selected_certificate_type()

void Botan::TLS::Channel_Impl_13::set_selected_certificate_type ( Certificate_Type cert_type)
protectedinherited

Set the expected certificate type needed to parse Certificate messages in the handshake layer. See RFC 7250 and 8446 4.4.2 for further details.

Definition at line 462 of file tls_channel_impl_13.cpp.

462 {
463 m_handshake_layer.set_selected_certificate_type(cert_type);
464}

◆ timeout_check()

bool Botan::TLS::Channel_Impl_13::timeout_check ( )
inlineoverridevirtualinherited

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.

In the TLS 1.3 implementation, this always returns false.

Implements Botan::TLS::Channel_Impl.

Definition at line 215 of file tls_channel_impl_13.h.

215{ return false; }

◆ to_peer()

void Botan::TLS::Channel_Impl_13::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 285 of file tls_channel_impl_13.cpp.

285 {
286 if(!is_active()) {
287 throw Invalid_State("Data cannot be sent on inactive TLS connection");
288 }
289
290 // RFC 8446 4.6.3
291 // If the request_update field [of a received KeyUpdate] is set to
292 // "update_requested", then the receiver MUST send a KeyUpdate of its own
293 // with request_update set to "update_not_requested" prior to sending its
294 // next Application Data record.
295 // This mechanism allows either side to force an update to the entire
296 // connection, but causes an implementation which receives multiple
297 // KeyUpdates while it is silent to respond with a single update.
298 if(m_opportunistic_key_update) {
299 update_traffic_keys(false /* update_requested */);
300 m_opportunistic_key_update = false;
301 }
302
303 send_record(Record_Type::ApplicationData, {data.begin(), data.end()});
304}
void update_traffic_keys(bool request_peer_update=false) override

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

◆ update_traffic_keys()

void Botan::TLS::Channel_Impl_13::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 345 of file tls_channel_impl_13.cpp.

345 {
348 send_post_handshake_message(Key_Update(request_peer_update));
349 m_cipher_state->update_write_keys(*this);
350}
void send_post_handshake_message(Post_Handshake_Message_13 message)

References BOTAN_ASSERT_NONNULL, BOTAN_STATE_CHECK, is_active(), Botan::TLS::Channel_Impl::is_downgrading(), Botan::TLS::Channel_Impl::is_handshake_complete(), m_cipher_state, and send_post_handshake_message().

Referenced by to_peer().

Member Data Documentation

◆ m_active_state

◆ m_cipher_state

std::unique_ptr<Cipher_State> Botan::TLS::Channel_Impl_13::m_cipher_state
protectedinherited

◆ m_side

const Connection_Side Botan::TLS::Channel_Impl_13::m_side
protectedinherited

Definition at line 288 of file tls_channel_impl_13.h.

Referenced by Channel_Impl_13().

◆ m_transcript_hash

Transcript_Hash_State Botan::TLS::Channel_Impl_13::m_transcript_hash
protectedinherited

Definition at line 289 of file tls_channel_impl_13.h.

Referenced by aggregate_handshake_messages(), and from_peer().


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