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