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