Botan 3.13.0
Crypto and TLS for C&
tls_channel_impl_13.h
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#ifndef BOTAN_TLS_CHANNEL_IMPL_13_H_
11#define BOTAN_TLS_CHANNEL_IMPL_13_H_
12
13#include <botan/tls_messages_13.h>
14#include <botan/internal/stl_util.h>
15#include <botan/internal/tls_channel_impl.h>
16#include <botan/internal/tls_connection_state_13.h>
17#include <botan/internal/tls_handshake_layer_13.h>
18#include <botan/internal/tls_record_layer_13.h>
19#include <botan/internal/tls_transcript_hash_13.h>
20
21namespace Botan::TLS {
22
23class Cipher_State;
24
25/**
26 * Encapsulates the callbacks in the state machine described in RFC 8446 7.1,
27 * that will make the realisation the SSLKEYLOGFILE for connection debugging
28 * specified in ietf.org/archive/id/draft-thomson-tls-keylogfile-00.html
29 *
30 * The class is split from the rest of the Channel_Impl_13 for mockability.
31 */
32class Secret_Logger /* NOLINT(*-special-member-functions) */ {
33 public:
34 virtual ~Secret_Logger() = default;
35
36 friend class Cipher_State;
37
38 protected:
39 /**
40 * Used exclusively in the Cipher_State to pass secret data to
41 * a user-provided Callbacks::tls_ssl_key_log_data() iff
42 * Policy::allow_ssl_key_log_file() returns true.
43 */
44 virtual void maybe_log_secret(std::string_view label, std::span<const uint8_t> secret) const = 0;
45};
46
47/**
48* Generic interface for TLS 1.3 endpoint
49*/
51 protected Secret_Logger {
52 protected:
53 /**
54 * Helper class to coalesce handshake messages into a single TLS record
55 * of type 'Handshake'. This is used entirely internally in the Channel,
56 * Client and Server implementations.
57 *
58 * Note that implementations should use the derived classes that either
59 * aggregate conventional Handshake messages or Post-Handshake messages.
60 */
62 public:
63 AggregatedMessages(Channel_Impl_13& channel, Handshake_Layer& handshake_layer);
64
69
71
72 /**
73 * Send the messages aggregated in the message buffer.
74 */
75 void send() const;
76
77 bool contains_messages() const { return !m_message_buffer.empty(); }
78
79 protected:
80 std::vector<uint8_t> m_message_buffer; // NOLINT(*non-private-member-variable*)
81
82 Channel_Impl_13& m_channel; // NOLINT(*non-private-member-variable*)
83 Handshake_Layer& m_handshake_layer; // NOLINT(*non-private-member-variable*)
84 };
85
86 /**
87 * Aggregate conventional handshake messages. This will update the given
88 * Transcript_Hash_State accordingly as individual messages are added to
89 * the aggregation.
90 */
92 public:
94 Handshake_Layer& handshake_layer,
95 Transcript_Hash_State& transcript_hash);
96
97 /**
98 * Adds a single handshake message to the send buffer. Note that this
99 * updates the handshake transcript hash regardless of sending the
100 * message.
101 */
103
104 private:
105 Transcript_Hash_State& m_transcript_hash;
106 };
107
108 /**
109 * Aggregate post-handshake messages. In contrast to ordinary handshake
110 * messages this does not maintain a Transcript_Hash_State.
111 */
118
119 public:
120 /**
121 * Set up a new TLS 1.3 session
122 *
123 * @param callbacks contains a set of callback function references
124 * required by the TLS endpoint.
125 * @param session_manager manages session state
126 * @param credentials_manager manages application/user credentials
127 * @param rng a random number generator
128 * @param policy specifies other connection policy information
129 * @param is_server whether this is a server session or not
130 */
131 explicit Channel_Impl_13(const std::shared_ptr<Callbacks>& callbacks,
132 const std::shared_ptr<Session_Manager>& session_manager,
133 const std::shared_ptr<Credentials_Manager>& credentials_manager,
134 const std::shared_ptr<RandomNumberGenerator>& rng,
135 const std::shared_ptr<const Policy>& policy,
136 bool is_server);
137
138 Channel_Impl_13(const Channel_Impl_13& other) = delete;
142
144
145 size_t from_peer(std::span<const uint8_t> data) override;
146 void to_peer(std::span<const uint8_t> data) override;
147
148 /**
149 * Send a TLS alert message. If the alert is fatal, the internal
150 * state (keys, etc) will be reset.
151 * @param alert the Alert to send
152 */
153 void send_alert(const Alert& alert) override;
154
155 /**
156 * @return true iff the connection is active for sending application data
157 *
158 * Note that the connection is active until the application has called
159 * `close()`, even if a CloseNotify has been received from the peer.
160 */
161 bool is_active() const override;
162
163 /**
164 * @return true iff the connection has been closed, i.e. CloseNotify
165 * has been received from the peer.
166 */
167 bool is_closed() const override { return is_closed_for_reading() && is_closed_for_writing(); }
168
169 bool is_closed_for_reading() const override { return !m_can_read; }
170
171 bool is_closed_for_writing() const override { return !m_can_write; }
172
173 /**
174 * Key material export (RFC 5705)
175 * @param label a disambiguating label string
176 * @param context a per-association context value
177 * @param length the length of the desired key in bytes
178 * @return key of length bytes
179 */
180 SymmetricKey key_material_export(std::string_view label, std::string_view context, size_t length) const override;
181
182 /**
183 * Attempt to renegotiate the session
184 */
185 void renegotiate(bool /* unused */) override {
186 throw Invalid_Argument("renegotiation is not allowed in TLS 1.3");
187 }
188
189 /**
190 * Attempt to update the session's traffic key material
191 * Note that this is possible with a TLS 1.3 channel, only.
192 *
193 * @param request_peer_update if true, require a reciprocal key update
194 */
195 void update_traffic_keys(bool request_peer_update = false) override;
196
197 /**
198 * @return true iff the counterparty supports the secure
199 * renegotiation extensions.
200 */
201 bool secure_renegotiation_supported() const override {
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 }
206
207 /**
208 * Perform a handshake timeout check. This does nothing unless
209 * this is a DTLS channel with a pending handshake state, in
210 * which case we check for timeout and potentially retransmit
211 * handshake packets.
212 *
213 * In the TLS 1.3 implementation, this always returns false.
214 */
215 bool timeout_check() override { return false; }
216
217 protected:
221
230
232
233 void handle(const Key_Update& key_update);
234
235 /**
236 * Schedule a traffic key update to opportunistically happen before the
237 * channel sends application data the next time. Such a key update will
238 * never request a reciprocal key update from the peer.
239 */
240 void opportunistically_update_traffic_keys() { m_opportunistic_key_update = true; }
241
242 template <typename... MsgTs>
243 void send_handshake_message(const std::variant<MsgTs...>& message) {
245 }
246
247 template <typename MsgT>
248 void send_handshake_message(std::reference_wrapper<MsgT> message) {
250 }
251
255
257
261
265
266 Callbacks& callbacks() const { return *m_callbacks; }
267
268 Session_Manager& session_manager() { return *m_session_manager; }
269
270 Credentials_Manager& credentials_manager() { return *m_credentials_manager; }
271
272 RandomNumberGenerator& rng() { return *m_rng; }
273
274 const Policy& policy() const { return *m_policy; }
275
276 private:
277 void send_record(Record_Type record_type, const std::vector<uint8_t>& record);
278
279 void process_alert(const secure_vector<uint8_t>& record);
280
281 /**
282 * Terminate the connection (on sending or receiving an error alert) and
283 * clear secrets
284 */
285 void shutdown();
286
287 protected:
288 const Connection_Side m_side; // NOLINT(*non-private-member-variable*)
289 Transcript_Hash_State m_transcript_hash; // NOLINT(*non-private-member-variable*)
290 std::unique_ptr<Cipher_State> m_cipher_state; // NOLINT(*non-private-member-variable*)
291 std::optional<Active_Connection_State_13> m_active_state; // NOLINT(*non-private-member-variable*)
292
293#if defined(BOTAN_HAS_TLS_DOWNGRADE_SUPPORT)
294 /**
295 * Indicate that we have to expect a downgrade to TLS 1.2. In which case the current
296 * implementation (i.e. Client_Impl_13 or Server_Impl_13) will need to be replaced
297 * by their respective counter parts.
298 *
299 * This will prepare an internal structure where any information required to downgrade
300 * can be preserved.
301 * @sa `Channel_Impl::Downgrade_Information`
302 */
303 void expect_downgrade(const Server_Information& server_info, const std::vector<std::string>& next_protocols);
304#endif
305
306 /**
307 * Set the record size limits as negotiated by the "record_size_limit"
308 * extension (RFC 8449).
309 *
310 * @param outgoing_limit the maximal number of plaintext bytes to be
311 * sent in a protected record
312 * @param incoming_limit the maximal number of plaintext bytes to be
313 * accepted in a received protected record
314 */
315 void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit);
316
317 /**
318 * Set the expected certificate type needed to parse Certificate
319 * messages in the handshake layer. See RFC 7250 and 8446 4.4.2 for
320 * further details.
321 */
323
324 private:
325 /* callbacks */
326 std::shared_ptr<Callbacks> m_callbacks;
327
328 /* external state */
329 std::shared_ptr<Session_Manager> m_session_manager;
330 std::shared_ptr<Credentials_Manager> m_credentials_manager;
331 std::shared_ptr<RandomNumberGenerator> m_rng;
332 std::shared_ptr<const Policy> m_policy;
333
334 /* handshake state */
335 Record_Layer m_record_layer;
336 Handshake_Layer m_handshake_layer;
337
338 bool m_can_read;
339 bool m_can_write;
340
341 bool m_opportunistic_key_update;
342 bool m_first_message_sent;
343 bool m_first_message_received;
344
345 uint64_t m_last_key_update_ms = 0;
346};
347} // namespace Botan::TLS
348
349#endif
AggregatedHandshakeMessages & add(Handshake_Message_13_Ref message)
AggregatedHandshakeMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer, Transcript_Hash_State &transcript_hash)
AggregatedMessages & operator=(AggregatedMessages &&)=delete
AggregatedMessages(const AggregatedMessages &)=delete
AggregatedMessages(AggregatedMessages &&)=delete
AggregatedMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer)
AggregatedMessages & operator=(const AggregatedMessages &)=delete
AggregatedMessages(Channel_Impl_13 &channel, Handshake_Layer &handshake_layer)
AggregatedPostHandshakeMessages & add(Post_Handshake_Message_13 message)
virtual void maybe_handle_compatibility_mode(Compat_Mode_Situation situation)=0
const Policy & policy() const
void send_handshake_message(const std::variant< MsgTs... > &message)
AggregatedPostHandshakeMessages aggregate_post_handshake_messages()
SymmetricKey key_material_export(std::string_view label, std::string_view context, size_t length) const override
Channel_Impl_13 & operator=(Channel_Impl_13 &&other)=delete
void handle(const Key_Update &key_update)
AggregatedHandshakeMessages aggregate_handshake_messages()
Credentials_Manager & credentials_manager()
void send_post_handshake_message(Post_Handshake_Message_13 message)
RandomNumberGenerator & rng()
Channel_Impl_13 & operator=(const Channel_Impl_13 &other)=delete
bool is_closed_for_reading() const override
bool secure_renegotiation_supported() const override
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
std::optional< Active_Connection_State_13 > m_active_state
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 send_handshake_message(std::reference_wrapper< MsgT > message)
void update_traffic_keys(bool request_peer_update=false) override
virtual void process_dummy_change_cipher_spec()=0
Session_Manager & session_manager()
bool is_closed() const override
Channel_Impl_13(const Channel_Impl_13 &other)=delete
std::unique_ptr< Cipher_State > m_cipher_state
Channel_Impl_13(Channel_Impl_13 &&other)=delete
void set_selected_certificate_type(Certificate_Type cert_type)
bool is_closed_for_writing() const override
void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit)
Channel_Impl(const Channel_Impl &other)=delete
virtual void maybe_log_secret(std::string_view label, std::span< const uint8_t > secret) const =0
virtual ~Secret_Logger()=default
detail::as_wrapped_references_t< Handshake_Message_13 > Handshake_Message_13_Ref
std::variant< Client_Hello_13, Client_Hello_12_Shim, Server_Hello_13, Server_Hello_12_Shim, Hello_Retry_Request, Encrypted_Extensions, Certificate_13, Certificate_Request_13, Certificate_Verify_13, Finished_13 > Handshake_Message_13
std::variant< New_Session_Ticket_13, Key_Update > Post_Handshake_Message_13
OctetString SymmetricKey
Definition symkey.h:153
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
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