Botan 3.6.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 */
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;
82
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 explicit Channel_Impl_13(const Channel_Impl_13&) = delete;
140
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
222 /**
223 * @return whether a change cipher spec record should be prepended _now_
224 *
225 * This method can be used by subclasses to indicate that send_record
226 * should prepend a CCS before the actual record. This is useful for
227 * middlebox compatibility mode. See RFC 8446 D.4.
228 */
229 virtual bool prepend_ccs() { return false; }
230
231 void handle(const Key_Update& key_update);
232
233 /**
234 * Schedule a traffic key update to opportunistically happen before the
235 * channel sends application data the next time. Such a key update will
236 * never request a reciprocal key update from the peer.
237 */
238 void opportunistically_update_traffic_keys() { m_opportunistic_key_update = true; }
239
240 template <typename... MsgTs>
241 std::vector<uint8_t> send_handshake_message(const std::variant<MsgTs...>& message) {
243 }
244
245 template <typename MsgT>
246 std::vector<uint8_t> send_handshake_message(std::reference_wrapper<MsgT> message) {
248 }
249
251 return aggregate_post_handshake_messages().add(std::move(message)).send();
252 }
253
255
259
263
264 Callbacks& callbacks() const { return *m_callbacks; }
265
266 Session_Manager& session_manager() { return *m_session_manager; }
267
268 Credentials_Manager& credentials_manager() { return *m_credentials_manager; }
269
270 RandomNumberGenerator& rng() { return *m_rng; }
271
272 const Policy& policy() const { return *m_policy; }
273
274 private:
275 void send_record(Record_Type record_type, const std::vector<uint8_t>& record);
276
277 void process_alert(const secure_vector<uint8_t>& record);
278
279 /**
280 * Terminate the connection (on sending or receiving an error alert) and
281 * clear secrets
282 */
283 void shutdown();
284
285 protected:
288 std::unique_ptr<Cipher_State> m_cipher_state;
289
290 /**
291 * Indicate that we have to expect a downgrade to TLS 1.2. In which case the current
292 * implementation (i.e. Client_Impl_13 or Server_Impl_13) will need to be replaced
293 * by their respective counter parts.
294 *
295 * This will prepare an internal structure where any information required to downgrade
296 * can be preserved.
297 * @sa `Channel_Impl::Downgrade_Information`
298 */
299 void expect_downgrade(const Server_Information& server_info, const std::vector<std::string>& next_protocols);
300
301 /**
302 * Set the record size limits as negotiated by the "record_size_limit"
303 * extension (RFC 8449).
304 *
305 * @param outgoing_limit the maximal number of plaintext bytes to be
306 * sent in a protected record
307 * @param incoming_limit the maximal number of plaintext bytes to be
308 * accepted in a received protected record
309 */
310 void set_record_size_limits(uint16_t outgoing_limit, uint16_t incoming_limit);
311
312 /**
313 * Set the expected certificate type needed to parse Certificate
314 * messages in the handshake layer. See RFC 7250 and 8446 4.4.2 for
315 * further details.
316 */
318
319 private:
320 /* callbacks */
321 std::shared_ptr<Callbacks> m_callbacks;
322
323 /* external state */
324 std::shared_ptr<Session_Manager> m_session_manager;
325 std::shared_ptr<Credentials_Manager> m_credentials_manager;
326 std::shared_ptr<RandomNumberGenerator> m_rng;
327 std::shared_ptr<const Policy> m_policy;
328
329 /* handshake state */
330 Record_Layer m_record_layer;
331 Handshake_Layer m_handshake_layer;
332
333 bool m_can_read;
334 bool m_can_write;
335
336 bool m_opportunistic_key_update;
337 bool m_first_message_sent;
338 bool m_first_message_received;
339};
340} // namespace Botan::TLS
341
342#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
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(const Channel_Impl_13 &)=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)
bool is_closed_for_reading() const override
bool secure_renegotiation_supported() const override
void to_peer(std::span< const uint8_t > data) override
Channel_Impl_13 & operator=(const Channel_Impl_13 &)=delete
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
std::unique_ptr< Cipher_State > m_cipher_state
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)
virtual void maybe_log_secret(std::string_view label, std::span< const uint8_t > secret) const =0
virtual ~Secret_Logger()=default
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
constexpr GeneralVariantT generalize_to(SpecialT &&specific) noexcept
Converts a given variant into another variant-ish whose type states are a super set of the given vari...
Definition stl_util.h:315
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61