Botan 3.11.1
Crypto and TLS for C&
tls_channel_impl_13.cpp
Go to the documentation of this file.
1/*
2* TLS Channel - implementation for TLS 1.3
3* (C) 2022 Jack Lloyd
4* 2021 Elektrobit Automotive GmbH
5* 2022 Hannes Rantzsch, René Meusel - neXenio GmbH
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/internal/tls_channel_impl_13.h>
11
12#include <botan/tls_callbacks.h>
13#include <botan/tls_exceptn.h>
14#include <botan/tls_messages_13.h>
15#include <botan/internal/concat_util.h>
16#include <botan/internal/tls_cipher_state.h>
17
18#include <array>
19
20namespace {
21bool is_user_canceled_alert(const Botan::TLS::Alert& alert) {
22 return alert.type() == Botan::TLS::Alert::UserCanceled;
23}
24
25bool is_close_notify_alert(const Botan::TLS::Alert& alert) {
26 return alert.type() == Botan::TLS::Alert::CloseNotify;
27}
28
29bool is_error_alert(const Botan::TLS::Alert& alert) {
30 // In TLS 1.3 all alerts except for closure alerts are considered error alerts.
31 // (RFC 8446 6.)
32 return !is_close_notify_alert(alert) && !is_user_canceled_alert(alert);
33}
34} // namespace
35
36namespace Botan::TLS {
37
38Channel_Impl_13::Channel_Impl_13(const std::shared_ptr<Callbacks>& callbacks,
39 const std::shared_ptr<Session_Manager>& session_manager,
40 const std::shared_ptr<Credentials_Manager>& credentials_manager,
41 const std::shared_ptr<RandomNumberGenerator>& rng,
42 const std::shared_ptr<const Policy>& policy,
43 bool is_server) :
45 m_callbacks(callbacks),
46 m_session_manager(session_manager),
47 m_credentials_manager(credentials_manager),
48 m_rng(rng),
49 m_policy(policy),
50 m_record_layer(m_side),
51 m_handshake_layer(m_side),
52 m_can_read(true),
53 m_can_write(true),
54 m_opportunistic_key_update(false),
55 m_first_message_sent(false),
56 m_first_message_received(false) {
57 BOTAN_ASSERT_NONNULL(m_callbacks);
58 BOTAN_ASSERT_NONNULL(m_session_manager);
59 BOTAN_ASSERT_NONNULL(m_credentials_manager);
61 BOTAN_ASSERT_NONNULL(m_policy);
63
65
66size_t Channel_Impl_13::from_peer(std::span<const uint8_t> data) {
68
69 // RFC 8446 6.1
70 // Any data received after a closure alert has been received MUST be ignored.
71 if(!m_can_read) {
72 return 0;
73 }
74
75 try {
76 if(expects_downgrade()) {
78 }
79
80 m_record_layer.copy_data(data);
81
82 while(true) {
83 // RFC 8446 6.1
84 // Any data received after a closure alert has been received MUST be ignored.
85 //
86 // ... this data might already be in the record layer's read buffer.
87 if(!m_can_read) {
88 return 0;
89 }
90
91 auto result = m_record_layer.next_record(m_cipher_state.get());
92
93 if(std::holds_alternative<BytesNeeded>(result)) {
94 return std::get<BytesNeeded>(result);
95 }
96
97 const auto& record = std::get<Record>(result);
98
99 // RFC 8446 5.1
100 // Handshake messages MUST NOT be interleaved with other record types.
101 if(record.type != Record_Type::Handshake && m_handshake_layer.has_pending_data()) {
102 throw Unexpected_Message("Expected remainder of a handshake message");
103 }
104
105 if(record.type == Record_Type::Handshake) {
106 m_handshake_layer.copy_data(record.fragment);
107
108 if(!is_handshake_complete()) {
109 while(auto handshake_msg = m_handshake_layer.next_message(policy(), m_transcript_hash)) {
110 // RFC 8446 5.1
111 // Handshake messages MUST NOT span key changes. Implementations
112 // MUST verify that all messages immediately preceding a key change
113 // align with a record boundary; if not, then they MUST terminate the
114 // connection with an "unexpected_message" alert. Because the
115 // ClientHello, EndOfEarlyData, ServerHello, Finished, and KeyUpdate
116 // messages can immediately precede a key change, implementations
117 // MUST send these messages in alignment with a record boundary.
118 //
119 // Note: Hello_Retry_Request was added to the list below although it cannot immediately precede a key change.
120 // However, there cannot be any further sensible messages in the record after HRR.
121 //
122 // Note: Server_Hello_12 was deliberately not included in the check below because in TLS 1.2 Server Hello and
123 // other handshake messages can be legally coalesced in a single record.
124 //
126 Client_Hello_13 /*, EndOfEarlyData,*/,
129 Finished_13>(handshake_msg.value()) &&
130 m_handshake_layer.has_pending_data()) {
131 throw Unexpected_Message("Unexpected additional handshake message data found in record");
132 }
133
134 process_handshake_msg(std::move(handshake_msg.value()));
135
136 if(is_downgrading()) {
137 // Downgrade to TLS 1.2 was detected. Stop everything we do and await being replaced by a 1.2 implementation.
138 return 0;
139 } else if(m_downgrade_info != nullptr) {
140 // We received a TLS 1.3 error alert that could have been a TLS 1.2 warning alert.
141 // Now that we know that we are talking to a TLS 1.3 server, shut down.
142 if(m_downgrade_info->received_tls_13_error_alert) {
143 shutdown();
144 }
145
146 // Downgrade can only be indicated in the first received peer message. This was not the case.
147 m_downgrade_info.reset();
148 }
149
150 // After the initial handshake message is received, the record
151 // layer must be more restrictive.
152 // See RFC 8446 5.1 regarding "legacy_record_version"
153 if(!m_first_message_received) {
154 m_record_layer.disable_receiving_compat_mode();
155 m_first_message_received = true;
156 }
157 }
158 } else {
159 while(auto handshake_msg = m_handshake_layer.next_post_handshake_message(policy())) {
160 process_post_handshake_msg(std::move(handshake_msg.value()));
161 }
162 }
163 } else if(record.type == Record_Type::ChangeCipherSpec) {
165 } else if(record.type == Record_Type::ApplicationData) {
167 if(!m_cipher_state->can_decrypt_application_traffic()) {
168 throw Unexpected_Message("Application data received before handshake completion");
169 }
170 BOTAN_ASSERT(record.seq_no.has_value(), "decrypted application traffic had a sequence number");
171 callbacks().tls_record_received(record.seq_no.value(), record.fragment);
172 } else if(record.type == Record_Type::Alert) {
173 process_alert(record.fragment);
174 } else {
175 throw Unexpected_Message("Unexpected record type " + std::to_string(static_cast<size_t>(record.type)) +
176 " from counterparty");
177 }
178 }
179 } catch(TLS_Exception& e) {
181 throw;
183 // RFC 8446 5.2
184 // If the decryption fails, the receiver MUST terminate the connection
185 // with a "bad_record_mac" alert.
186 send_fatal_alert(Alert::BadRecordMac);
187 throw;
188 } catch(Decoding_Error&) {
189 send_fatal_alert(Alert::DecodeError);
190 throw;
191 } catch(...) {
192 send_fatal_alert(Alert::InternalError);
193 throw;
194 }
195}
196
197void Channel_Impl_13::handle(const Key_Update& key_update) {
198 // make sure Key_Update appears only at the end of a record; see description above
199 if(m_handshake_layer.has_pending_data()) {
200 throw Unexpected_Message("Unexpected additional post-handshake message data found in record");
201 }
202
204 m_cipher_state->update_read_keys(*this);
205
206 // TODO: introduce some kind of rate limit of key updates, otherwise we
207 // might be forced into an endless loop of key updates.
208
209 // RFC 8446 4.6.3
210 // If the request_update field is set to "update_requested", then the
211 // receiver MUST send a KeyUpdate of its own with request_update set to
212 // "update_not_requested" prior to sending its next Application Data
213 // record.
214 if(key_update.expects_reciprocation()) {
215 // RFC 8446 4.6.3
216 // This mechanism allows either side to force an update to the
217 // multiple KeyUpdates while it is silent to respond with a single
218 // update.
220 }
221}
222
225
227 Handshake_Layer& handshake_layer,
228 Transcript_Hash_State& transcript_hash) :
229 AggregatedMessages(channel, handshake_layer), m_transcript_hash(transcript_hash) {}
230
232 const Handshake_Message_13_Ref message) {
233 std::visit([&](const auto msg) { m_channel.callbacks().tls_inspect_handshake_msg(msg.get()); }, message);
234 m_message_buffer += m_handshake_layer.prepare_message(message, m_transcript_hash);
235 return *this;
236}
237
240 std::visit([&](const auto& msg) { m_channel.callbacks().tls_inspect_handshake_msg(msg); }, message);
241 m_message_buffer += m_handshake_layer.prepare_post_handshake_message(message);
242 return *this;
243}
244
248 return std::exchange(m_message_buffer, {});
249}
250
252 // RFC 8446 5.
253 // The change_cipher_spec record is used only for compatibility purposes
254 // (see Appendix D.4).
255 //
256 // The only allowed CCS message content is 0x01, all other CCS records MUST
257 // be rejected by TLS 1.3 implementations.
258 send_record(Record_Type::ChangeCipherSpec, {0x01});
259}
260
261void Channel_Impl_13::to_peer(std::span<const uint8_t> data) {
262 if(!is_active()) {
263 throw Invalid_State("Data cannot be sent on inactive TLS connection");
264 }
265
266 // RFC 8446 4.6.3
267 // If the request_update field [of a received KeyUpdate] is set to
268 // "update_requested", then the receiver MUST send a KeyUpdate of its own
269 // with request_update set to "update_not_requested" prior to sending its
270 // next Application Data record.
271 // This mechanism allows either side to force an update to the entire
272 // connection, but causes an implementation which receives multiple
273 // KeyUpdates while it is silent to respond with a single update.
274 if(m_opportunistic_key_update) {
275 update_traffic_keys(false /* update_requested */);
276 m_opportunistic_key_update = false;
277 }
278
279 send_record(Record_Type::ApplicationData, {data.begin(), data.end()});
280}
281
283 if(alert.is_valid() && m_can_write) {
284 try {
285 send_record(Record_Type::Alert, alert.serialize());
286 } catch(...) { /* swallow it */
287 }
288 }
289
290 // Note: In TLS 1.3 sending a CloseNotify must not immediately lead to closing the reading end.
291 // RFC 8446 6.1
292 // Each party MUST send a "close_notify" alert before closing its write
293 // side of the connection, unless it has already sent some error alert.
294 // This does not have any effect on its read side of the connection.
295 if(is_close_notify_alert(alert) && m_can_write) {
296 m_can_write = false;
297 if(m_cipher_state) {
298 m_cipher_state->clear_write_keys();
299 }
300 }
301
302 if(is_error_alert(alert)) {
303 shutdown();
304 }
305}
306
308 return m_cipher_state != nullptr && m_cipher_state->can_encrypt_application_traffic() // handshake done
309 && m_can_write; // close() hasn't been called
310}
311
313 std::string_view context,
314 size_t length) const {
316 BOTAN_STATE_CHECK(m_cipher_state != nullptr && m_cipher_state->can_export_keys());
317 return SymmetricKey(m_cipher_state->export_key(label, context, length));
318}
319
327
328void Channel_Impl_13::send_record(Record_Type type, const std::vector<uint8_t>& record) {
330 BOTAN_STATE_CHECK(m_can_write);
331
332 auto to_write = m_record_layer.prepare_records(type, record, m_cipher_state.get());
333
334 // After the initial handshake message is sent, the record layer must
335 // adhere to a more strict record specification. Note that for the
336 // server case this is a NOOP.
337 // See (RFC 8446 5.1. regarding "legacy_record_version")
338 if(!m_first_message_sent && type == Record_Type::Handshake) {
339 m_record_layer.disable_sending_compat_mode();
340 m_first_message_sent = true;
341 }
342
343 // The dummy CCS must not be prepended if the following record is
344 // an unprotected Alert record.
345 if(prepend_ccs() && (m_cipher_state || type != Record_Type::Alert)) {
346 std::array<uint8_t, 1> ccs_content = {0x01};
347 const auto ccs = m_record_layer.prepare_records(Record_Type::ChangeCipherSpec, ccs_content, m_cipher_state.get());
348 to_write = concat(ccs, to_write);
349 }
350
351 callbacks().tls_emit_data(to_write);
352}
353
354void Channel_Impl_13::process_alert(const secure_vector<uint8_t>& record) {
355 const Alert alert(record);
356
357 if(is_close_notify_alert(alert)) {
358 m_can_read = false;
359 if(m_cipher_state) {
360 m_cipher_state->clear_read_keys();
361 }
362 m_record_layer.clear_read_buffer();
363 }
364
365 // user canceled alerts are ignored
366
367 // RFC 8446 5.
368 // All the alerts listed in Section 6.2 MUST be sent with
369 // AlertLevel=fatal and MUST be treated as error alerts when received
370 // regardless of the AlertLevel in the message. Unknown Alert types
371 // MUST be treated as error alerts.
372 if(is_error_alert(alert) && !alert.is_fatal()) {
373 // In TLS 1.2 error alerts might be marked as 'warnings' and would not
374 // demand an immediate shutdown. Until we are sure to talk to a TLS 1.3
375 // peer we must defer the shutdown and refrain from raising a decode
376 // error.
377 if(expects_downgrade()) {
378 m_downgrade_info->received_tls_13_error_alert = true;
379 } else {
380 throw TLS_Exception(Alert::DecodeError, "Error alert not marked fatal"); // will shutdown in send_alert
381 }
382 }
383
384 if(alert.is_fatal()) {
385 shutdown();
386 }
387
388 callbacks().tls_alert(alert);
389
390 // Respond with our "close_notify" if the application requests us to.
391 if(is_close_notify_alert(alert) && callbacks().tls_peer_closed_connection()) {
392 close();
393 }
394}
395
396void Channel_Impl_13::shutdown() {
397 // RFC 8446 6.2
398 // Upon transmission or receipt of a fatal alert message, both
399 // parties MUST immediately close the connection.
400 m_can_read = false;
401 m_can_write = false;
402 m_cipher_state.reset();
403}
404
406 const std::vector<std::string>& next_protocols) {
408 {},
409 {},
410 {},
411 server_info,
412 next_protocols,
414 m_callbacks,
415 m_session_manager,
416 m_credentials_manager,
417 m_rng,
418 m_policy,
419 false, // received_tls_13_error_alert
420 false // will_downgrade
421 };
422 m_downgrade_info = std::make_unique<Downgrade_Information>(std::move(di));
423}
424
425void Channel_Impl_13::set_record_size_limits(const uint16_t outgoing_limit, const uint16_t incoming_limit) {
426 m_record_layer.set_record_size_limits(outgoing_limit, incoming_limit);
427}
428
430 m_handshake_layer.set_selected_certificate_type(cert_type);
431}
432
433} // namespace Botan::TLS
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
bool is_valid() const
Definition tls_alert.h:78
std::vector< uint8_t > serialize() const
Definition tls_alert.cpp:32
bool is_fatal() const
Definition tls_alert.h:93
Type type() const
Definition tls_alert.h:100
virtual void tls_record_received(uint64_t seq_no, std::span< const uint8_t > data)=0
virtual void tls_alert(Alert alert)=0
virtual void tls_emit_data(std::span< const uint8_t > data)=0
AggregatedHandshakeMessages & add(Handshake_Message_13_Ref message)
AggregatedHandshakeMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer, Transcript_Hash_State &transcript_hash)
AggregatedMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer)
AggregatedPostHandshakeMessages & add(Post_Handshake_Message_13 message)
const Policy & policy() const
void expect_downgrade(const Server_Information &server_info, const std::vector< std::string > &next_protocols)
SymmetricKey key_material_export(std::string_view label, std::string_view context, size_t length) const override
void handle(const Key_Update &key_update)
std::vector< uint8_t > send_post_handshake_message(Post_Handshake_Message_13 message)
Credentials_Manager & credentials_manager()
RandomNumberGenerator & rng()
void to_peer(std::span< const uint8_t > data) override
Transcript_Hash_State m_transcript_hash
virtual void process_post_handshake_msg(Post_Handshake_Message_13 msg)=0
virtual void process_handshake_msg(Handshake_Message_13 msg)=0
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)
void send_alert(const Alert &alert) override
size_t from_peer(std::span< const uint8_t > data) override
void update_traffic_keys(bool request_peer_update=false) override
virtual void process_dummy_change_cipher_spec()=0
Session_Manager & session_manager()
std::unique_ptr< Cipher_State > m_cipher_state
void set_selected_certificate_type(Certificate_Type cert_type)
void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit)
void preserve_peer_transcript(std::span< const uint8_t > input)
void send_fatal_alert(Alert::Type type)
std::unique_ptr< Downgrade_Information > m_downgrade_info
virtual bool is_handshake_complete() const =0
static constexpr size_t IO_BUF_DEFAULT_SIZE
Definition tls_channel.h:37
bool expects_reciprocation() const
std::vector< uint8_t > prepare_records(Record_Type type, std::span< const uint8_t > data, Cipher_State *cipher_state=nullptr) const
Alert::Type type() const
Definition tls_exceptn.h:21
detail::as_wrapped_references_t< Handshake_Message_13 > Handshake_Message_13_Ref
std::variant< New_Session_Ticket_13, Key_Update > Post_Handshake_Message_13
OctetString SymmetricKey
Definition symkey.h:140
constexpr bool holds_any_of(const std::variant< Ts... > &v) noexcept
Definition stl_util.h:65
constexpr auto concat(Rs &&... ranges)
Definition concat_util.h:90
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68