Botan 3.11.0
Crypto and TLS for C&
tls_extensions_13.h
Go to the documentation of this file.
1/*
2* TLS 1.3 Specific Extensions
3* (C) 2011,2012,2016,2018,2019 Jack Lloyd
4* (C) 2016 Juraj Somorovsky
5* (C) 2016 Matthias Gierlings
6* (C) 2021 Elektrobit Automotive GmbH
7* (C) 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
8* (C) 2023 Fabian Albert, René Meusel - Rohde & Schwarz Cybersecurity
9* (C) 2026 René Meusel - Rohde & Schwarz Cybersecurity
10*
11* Botan is released under the Simplified BSD License (see license.txt)
12*/
13
14#ifndef BOTAN_TLS_EXTENSIONS_13_H_
15#define BOTAN_TLS_EXTENSIONS_13_H_
16
17#include <botan/pkix_types.h>
18#include <botan/tls_extensions.h>
19#include <botan/tls_external_psk.h>
20#include <botan/tls_session.h>
21
22namespace Botan {
23
26
27namespace TLS {
28
29class Callbacks;
30class Cipher_State;
31class Ciphersuite;
32class Policy;
33class Session_Manager;
34class TLS_Data_Reader;
36
37enum class PSK_Key_Exchange_Mode : uint8_t { PSK_KE = 0, PSK_DHE_KE = 1 };
38
39/**
40* Cookie from RFC 8446 4.2.2
41*/
42class BOTAN_UNSTABLE_API Cookie final : public Extension {
43 public:
45
46 Extension_Code type() const override { return static_type(); }
47
48 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
49
50 bool empty() const override { return m_cookie.empty(); }
51
52 const std::vector<uint8_t>& get_cookie() const { return m_cookie; }
53
54 explicit Cookie(const std::vector<uint8_t>& cookie);
55
56 explicit Cookie(TLS_Data_Reader& reader, uint16_t extension_size);
57
58 private:
59 std::vector<uint8_t> m_cookie;
60};
61
62/**
63* Pre-Shared Key Exchange Modes from RFC 8446 4.2.9
64*/
66 public:
68
69 Extension_Code type() const override { return static_type(); }
70
71 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
72
73 bool empty() const override { return m_modes.empty(); }
74
75 const std::vector<PSK_Key_Exchange_Mode>& modes() const { return m_modes; }
76
77 explicit PSK_Key_Exchange_Modes(std::vector<PSK_Key_Exchange_Mode> modes) : m_modes(std::move(modes)) {}
78
79 explicit PSK_Key_Exchange_Modes(TLS_Data_Reader& reader, uint16_t extension_size);
80
81 private:
82 std::vector<PSK_Key_Exchange_Mode> m_modes;
83};
84
85/**
86 * Certificate Authorities Extension from RFC 8446 4.2.4
87 */
89 public:
91
92 Extension_Code type() const override { return static_type(); }
93
94 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
95
96 bool empty() const override { return m_distinguished_names.empty(); }
97
98 const std::vector<X509_DN>& distinguished_names() const { return m_distinguished_names; }
99
100 Certificate_Authorities(TLS_Data_Reader& reader, uint16_t extension_size);
101 explicit Certificate_Authorities(std::vector<X509_DN> acceptable_DNs);
102
103 private:
104 std::vector<X509_DN> m_distinguished_names;
105};
106
107/**
108 * Pre-Shared Key extension from RFC 8446 4.2.11
109 */
110class BOTAN_UNSTABLE_API PSK final : public Extension /* NOLINT(*-special-member-functions) */ {
111 public:
113
114 Extension_Code type() const override { return static_type(); }
115
116 std::vector<uint8_t> serialize(Connection_Side side) const override;
117
118 /**
119 * Returns the PSK identity (in case of an externally provided PSK) and
120 * the cipher state representing the PSK selected by the server. Note that
121 * this destructs the list of offered PSKs and its cipher states and must
122 * therefore not be called more than once.
123 *
124 * @note Technically, PSKs used for resumption also carry an identity.
125 * Though, typically, this is an opaque value meaningful only to the
126 * peer and of no authoritative value for the user. We therefore
127 * report the identity of externally provided PSKs only.
128 */
129 std::pair<std::optional<std::string>, std::unique_ptr<Cipher_State>> take_selected_psk_info(
130 const PSK& server_psk, const Ciphersuite& cipher);
131
132 /**
133 * Selects one of the offered PSKs that is compatible with \p cipher.
134 * @retval PSK extension object that can be added to the Server Hello response
135 * @retval std::nullptr if no PSK offered by the client is convenient
136 */
137 std::unique_ptr<PSK> select_offered_psk(std::string_view host,
138 const Ciphersuite& cipher,
139 Session_Manager& session_mgr,
140 Credentials_Manager& credentials_mgr,
141 Callbacks& callbacks,
142 const Policy& policy);
143
144 /**
145 * Remove PSK identities from the list in \p m_psk that are not compatible
146 * with the passed in \p cipher suite.
147 * This is useful to react to Hello Retry Requests. See RFC 8446 4.1.4.
148 */
149 void filter(const Ciphersuite& cipher);
150
151 /**
152 * Pulls the preshared key or the Session to resume from a PSK extension
153 * in Server Hello.
154 */
155 std::variant<Session, ExternalPSK> take_session_to_resume_or_psk();
156
157 bool empty() const override;
158
159 PSK(TLS_Data_Reader& reader, uint16_t extension_size, Handshake_Type message_type);
160
161 /**
162 * Creates a PSK extension with a TLS 1.3 session object containing a
163 * master_secret. Note that it will extract that secret from the session,
164 * and won't create a copy of it.
165 *
166 * @param session_to_resume the session to be resumed; note that the
167 * master secret will be taken away from the
168 * session object.
169 * @param psks a list of non-resumption PSKs that should be
170 * offered to the server
171 * @param callbacks the application's callbacks
172 */
173 PSK(std::optional<Session_with_Handle>& session_to_resume, std::vector<ExternalPSK> psks, Callbacks& callbacks);
174
175 ~PSK() override;
176
177 void calculate_binders(const Transcript_Hash_State& truncated_transcript_hash);
178 bool validate_binder(const PSK& server_psk, const std::vector<uint8_t>& binder) const;
179
180 // TODO: Implement pure PSK negotiation that is not used for session
181 // resumption.
182
183 private:
184 /**
185 * Creates a PSK extension that specifies the server's selection of an
186 * offered client PSK. The @p session_to_resume is kept internally
187 * and used later for the initialization of the Cipher_State object.
188 *
189 * Note: This constructor is called internally in PSK::select_offered_psk().
190 */
191 PSK(Session session_to_resume, uint16_t psk_index);
192
193 /**
194 * Creates a PSK extension that specifies the server's selection of an
195 * externally provided PSK offered by the client. The @p psk is kept
196 * internally and used later for the initialization of the Cipher_State object.
197 *
198 * Note: This constructor is called internally in PSK::select_offered_psk().
199 */
200 PSK(ExternalPSK psk, uint16_t psk_index);
201
202 private:
203 class PSK_Internal;
204 std::unique_ptr<PSK_Internal> m_impl;
205};
206
207/**
208* Key_Share from RFC 8446 4.2.8
209*/
210class BOTAN_UNSTABLE_API Key_Share final : public Extension /* NOLINT(*-special-member-functions) */ {
211 public:
213
214 Extension_Code type() const override { return static_type(); }
215
216 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
217
218 bool empty() const override;
219
220 /**
221 * Creates a Key_Share extension meant for the Server Hello that
222 * performs a key encapsulation with the selected public key from
223 * the client.
224 *
225 * @note This will retain the shared secret in the Key_Share extension
226 * until it is retrieved via take_shared_secret().
227 */
228 static std::unique_ptr<Key_Share> create_as_encapsulation(Group_Params selected_group,
229 const Key_Share& client_keyshare,
230 const Policy& policy,
231 Callbacks& cb,
233
234 /**
235 * Decapsulate the shared secret with the peer's key share. This method
236 * can be called on a ClientHello's Key_Share with a ServerHello's
237 * Key_Share.
238 *
239 * @note After the decapsulation the client's private key is destroyed.
240 * Multiple calls will result in an exception.
241 */
242 secure_vector<uint8_t> decapsulate(const Key_Share& server_keyshare,
243 const Policy& policy,
244 Callbacks& cb,
246
247 /**
248 * Update a ClientHello's Key_Share to comply with a HelloRetryRequest.
249 *
250 * This will create new Key_Share_Entries and should only be called on a ClientHello Key_Share with a HelloRetryRequest Key_Share.
251 */
252 void retry_offer(const Key_Share& retry_request_keyshare,
253 const std::vector<Named_Group>& supported_groups,
254 Callbacks& cb,
256
257 /**
258 * @return key exchange groups the peer offered key share entries for
259 */
260 std::vector<Named_Group> offered_groups() const;
261
262 /**
263 * @return key exchange group that was selected by a Hello Retry Request
264 */
265 Named_Group selected_group() const;
266
267 /**
268 * @returns the shared secret that was obtained by constructing this
269 * Key_Share object with the peer's.
270 *
271 * @note the shared secret value is std:move'd out. Multiple calls will
272 * result in an exception.
273 */
274 secure_vector<uint8_t> take_shared_secret();
275
276 Key_Share(TLS_Data_Reader& reader, uint16_t extension_size, Handshake_Type message_type);
277
278 // constructor used for ClientHello msg
279 Key_Share(const Policy& policy, Callbacks& cb, RandomNumberGenerator& rng);
280
281 // constructor used for HelloRetryRequest msg
282 explicit Key_Share(Named_Group selected_group);
283
284 // destructor implemented in .cpp to hide Key_Share_Impl
285 ~Key_Share() override;
286
287 private:
288 // constructor used for ServerHello
289 // (called via create_as_encapsulation())
291 const Key_Share& client_keyshare,
292 const Policy& policy,
293 Callbacks& cb,
295
296 private:
297 class Key_Share_Impl;
298 std::unique_ptr<Key_Share_Impl> m_impl;
299};
300
301/**
302 * Indicates usage or support of early data as described in RFC 8446 4.2.10.
303 */
305 public:
307
308 Extension_Code type() const override { return static_type(); }
309
310 std::vector<uint8_t> serialize(Connection_Side whoami) const override;
311
312 bool empty() const override;
313
314 std::optional<uint32_t> max_early_data_size() const { return m_max_early_data_size; }
315
316 EarlyDataIndication(TLS_Data_Reader& reader, uint16_t extension_size, Handshake_Type message_type);
317
318 /**
319 * The max_early_data_size is exclusively provided by servers when using
320 * this extension in the NewSessionTicket message! Otherwise it stays
321 * std::nullopt and results in an empty extension. (RFC 8446 4.2.10).
322 */
323 explicit EarlyDataIndication(std::optional<uint32_t> max_early_data_size = std::nullopt) :
324 m_max_early_data_size(max_early_data_size) {}
325
326 private:
327 std::optional<uint32_t> m_max_early_data_size;
328};
329
330} // namespace TLS
331
332} // namespace Botan
333
334#endif
#define BOTAN_UNSTABLE_API
Definition api.h:34
Certificate_Authorities(TLS_Data_Reader &reader, uint16_t extension_size)
Extension_Code type() const override
const std::vector< X509_DN > & distinguished_names() const
bool empty() const override
const std::vector< uint8_t > & get_cookie() const
Cookie(const std::vector< uint8_t > &cookie)
static Extension_Code static_type()
Extension_Code type() const override
std::optional< uint32_t > max_early_data_size() const
EarlyDataIndication(std::optional< uint32_t > max_early_data_size=std::nullopt)
Extension_Code type() const override
static Extension_Code static_type()
EarlyDataIndication(TLS_Data_Reader &reader, uint16_t extension_size, Handshake_Type message_type)
static Extension_Code static_type()
Key_Share(TLS_Data_Reader &reader, uint16_t extension_size, Handshake_Type message_type)
Extension_Code type() const override
Extension_Code type() const override
static Extension_Code static_type()
const std::vector< PSK_Key_Exchange_Mode > & modes() const
PSK_Key_Exchange_Modes(std::vector< PSK_Key_Exchange_Mode > modes)
Extension_Code type() const override
bool validate_binder(const PSK &server_psk, const std::vector< uint8_t > &binder) const
void calculate_binders(const Transcript_Hash_State &truncated_transcript_hash)
~PSK() override
static Extension_Code static_type()
PSK(TLS_Data_Reader &reader, uint16_t extension_size, Handshake_Type message_type)
Group_Params Named_Group
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68