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