Botan 3.11.1
Crypto and TLS for C&
msg_client_hello_13.cpp
Go to the documentation of this file.
1/*
2* TLS Client Hello Messages
3* (C) 2004-2011,2015,2016 Jack Lloyd
4* 2021 Elektrobit Automotive GmbH
5* 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
6* 2026 René Meusel - Rohde & Schwarz Cybersecurity GmbH
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#include <botan/tls_messages_13.h>
12
13#include <botan/assert.h>
14#include <botan/tls_alert.h>
15#include <botan/tls_callbacks.h>
16#include <botan/tls_exceptn.h>
17#include <botan/tls_extensions_13.h>
18#include <botan/tls_policy.h>
19#include <botan/internal/tls_handshake_layer_13.h>
20#include <botan/internal/tls_messages_internal.h>
21#include <botan/internal/tls_transcript_hash_13.h>
22#include <algorithm>
23
24#if defined(BOTAN_HAS_TLS_12)
25 #include <botan/tls_extensions_12.h>
26#endif
27
28namespace Botan::TLS {
29
30Client_Hello_13::Client_Hello_13(std::unique_ptr<Client_Hello_Internal> data) : Client_Hello(std::move(data)) {
31 const auto& exts = m_data->extensions();
32
33 // RFC 8446 4.1.2
34 // TLS 1.3 ClientHellos are identified as having a legacy_version of
35 // 0x0303 and a "supported_versions" extension present with 0x0304 as the
36 // highest version indicated therein.
37 //
38 // Note that we already checked for "supported_versions" before entering this
39 // c'tor in `Client_Hello_13::parse()`. This is just to be doubly sure.
40 BOTAN_ASSERT_NOMSG(exts.has<Supported_Versions>());
41
42 // RFC 8446 4.2.1
43 // Servers MAY abort the handshake upon receiving a ClientHello with
44 // legacy_version 0x0304 or later.
45 if(m_data->legacy_version().is_tls_13_or_later()) {
46 throw TLS_Exception(Alert::DecodeError, "TLS 1.3 Client Hello has invalid legacy_version");
47 }
48
49 // RFC 8446 D.5
50 // Any endpoint receiving a Hello message with ClientHello.legacy_version [...]
51 // set to 0x0300 MUST abort the handshake with a "protocol_version" alert.
52 if(m_data->legacy_version().major_version() == 3 && m_data->legacy_version().minor_version() == 0) {
53 throw TLS_Exception(Alert::ProtocolVersion, "TLS 1.3 Client Hello has invalid legacy_version");
54 }
55
56 // RFC 8446 4.1.2
57 // For every TLS 1.3 ClientHello, [the compression method] MUST contain
58 // exactly one byte, set to zero, [...]. If a TLS 1.3 ClientHello is
59 // received with any other value in this field, the server MUST abort the
60 // handshake with an "illegal_parameter" alert.
61 if(m_data->comp_methods().size() != 1 || m_data->comp_methods().front() != 0) {
62 throw TLS_Exception(Alert::IllegalParameter, "Client did not offer NULL compression");
63 }
64
65 // RFC 8446 4.2.9
66 // A client MUST provide a "psk_key_exchange_modes" extension if it
67 // offers a "pre_shared_key" extension. If clients offer "pre_shared_key"
68 // without a "psk_key_exchange_modes" extension, servers MUST abort
69 // the handshake.
70 if(exts.has<PSK>()) {
71 if(!exts.has<PSK_Key_Exchange_Modes>()) {
72 throw TLS_Exception(Alert::MissingExtension,
73 "Client Hello offered a PSK without a psk_key_exchange_modes extension");
74 }
75
76 // RFC 8446 4.2.11
77 // The "pre_shared_key" extension MUST be the last extension in the
78 // ClientHello [...]. Servers MUST check that it is the last extension
79 // and otherwise fail the handshake with an "illegal_parameter" alert.
80 if(exts.all().back()->type() != Extension_Code::PresharedKey) {
81 throw TLS_Exception(Alert::IllegalParameter, "PSK extension was not at the very end of the Client Hello");
82 }
83 }
84
85 // RFC 8446 9.2
86 // [A TLS 1.3 ClientHello] message MUST meet the following requirements:
87 //
88 // - If not containing a "pre_shared_key" extension, it MUST contain
89 // both a "signature_algorithms" extension and a "supported_groups"
90 // extension.
91 //
92 // - If containing a "supported_groups" extension, it MUST also contain
93 // a "key_share" extension, and vice versa. An empty
94 // KeyShare.client_shares vector is permitted.
95 //
96 // Servers receiving a ClientHello which does not conform to these
97 // requirements MUST abort the handshake with a "missing_extension"
98 // alert.
99 if(!exts.has<PSK>()) {
100 if(!exts.has<Supported_Groups>() || !exts.has<Signature_Algorithms>()) {
101 throw TLS_Exception(
102 Alert::MissingExtension,
103 "Non-PSK Client Hello did not contain supported_groups and signature_algorithms extensions");
104 }
105 }
106 if(exts.has<Supported_Groups>() != exts.has<Key_Share>()) {
107 throw TLS_Exception(Alert::MissingExtension,
108 "Client Hello must either contain both key_share and supported_groups extensions or neither");
109 }
110
111 if(exts.has<Key_Share>()) {
112 auto* const supported_ext = exts.get<Supported_Groups>();
113 BOTAN_ASSERT_NONNULL(supported_ext);
114 const auto supports = supported_ext->groups();
115 const auto offers = exts.get<Key_Share>()->offered_groups();
116
117 // RFC 8446 4.2.8
118 // Each KeyShareEntry value MUST correspond to a group offered in the
119 // "supported_groups" extension and MUST appear in the same order.
120 // [...]
121 // Clients MUST NOT offer any KeyShareEntry values for groups not
122 // listed in the client's "supported_groups" extension.
123 //
124 // Note: We can assume that both `offers` and `supports` are unique lists
125 // as this is ensured in the parsing code of the extensions.
126 auto found_in_supported_groups = [&supports, support_offset = -1](auto group) mutable {
127 const auto i = std::find(supports.begin(), supports.end(), group);
128 if(i == supports.end()) {
129 return false;
130 }
131
132 const auto found_at = std::distance(supports.begin(), i);
133 if(found_at <= support_offset) {
134 return false; // The order that groups appear in "key_share" and
135 // "supported_groups" must be the same
136 }
137
138 support_offset = static_cast<decltype(support_offset)>(found_at);
139 return true;
140 };
141
142 for(const auto offered : offers) {
143 // RFC 8446 4.2.8
144 // Servers MAY check for violations of these rules and abort the
145 // handshake with an "illegal_parameter" alert if one is violated.
146 if(!found_in_supported_groups(offered)) {
147 throw TLS_Exception(Alert::IllegalParameter,
148 "Offered key exchange groups do not align with claimed supported groups");
149 }
150 }
151 }
152
153 // TODO: Reject oid_filters extension if found (which is the only known extension that
154 // must not occur in the TLS 1.3 client hello.
155 // RFC 8446 4.2.5
156 // [The oid_filters extension] MUST only be sent in the CertificateRequest message.
157}
158
159/*
160 * Create a new Client Hello message
161 */
163 Callbacks& cb,
165 std::string_view hostname,
166 const std::vector<std::string>& next_protocols,
167 std::optional<Session_with_Handle>& session,
168 std::vector<ExternalPSK> psks) {
169 // RFC 8446 4.1.2
170 // In TLS 1.3, the client indicates its version preferences in the
171 // "supported_versions" extension (Section 4.2.1) and the
172 // legacy_version field MUST be set to 0x0303, which is the version
173 // number for TLS 1.2.
174 m_data->m_legacy_version = Protocol_Version::TLS_V12;
175 m_data->m_random = make_hello_random(rng, cb, policy);
176 m_data->m_suites = policy.ciphersuite_list(Protocol_Version::TLS_V13);
177
178 if(policy.allow_tls12()) {
179 // Note: DTLS 1.3 is NYI, hence dtls_12 is not checked
180 const auto legacy_suites = policy.ciphersuite_list(Protocol_Version::TLS_V12);
181 m_data->m_suites.insert(m_data->m_suites.end(), legacy_suites.cbegin(), legacy_suites.cend());
182 }
183
185 // RFC 8446 4.1.2
186 // In compatibility mode (see Appendix D.4), this field MUST be non-empty,
187 // so a client not offering a pre-TLS 1.3 session MUST generate a new
188 // 32-byte value.
189 //
190 // Note: we won't ever offer a TLS 1.2 session. In such a case we would
191 // have instantiated a TLS 1.2 client in the first place.
192 m_data->m_session_id = Session_ID(make_hello_random(rng, cb, policy));
193 }
194
195 // NOLINTBEGIN(*-owning-memory)
197 m_data->extensions().add(new Server_Name_Indicator(hostname));
198 }
199
200 m_data->extensions().add(new Supported_Groups(policy.key_exchange_groups()));
201
202 m_data->extensions().add(new Key_Share(policy, cb, rng));
203
204 m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13, policy));
205
206 m_data->extensions().add(new Signature_Algorithms(policy.acceptable_signature_schemes()));
207 if(auto cert_signing_prefs = policy.acceptable_certificate_signature_schemes()) {
208 // RFC 8446 4.2.3
209 // Implementations which have the same policy in both cases MAY omit
210 // the "signature_algorithms_cert" extension.
211 m_data->extensions().add(new Signature_Algorithms_Cert(std::move(cert_signing_prefs.value())));
212 }
213
214 // TODO: Support for PSK-only mode without a key exchange.
215 // This should be configurable in TLS::Policy and should allow no PSK
216 // support at all (e.g. to disable support for session resumption).
218
219 if(policy.support_cert_status_message()) {
220 m_data->extensions().add(new Certificate_Status_Request({}, {}));
221 }
222
223 // We currently support "record_size_limit" for TLS 1.3 exclusively. Hence,
224 // when TLS 1.2 is advertised as a supported protocol, we must not offer this
225 // extension.
226 if(policy.record_size_limit().has_value() && !policy.allow_tls12()) {
227 m_data->extensions().add(new Record_Size_Limit(policy.record_size_limit().value()));
228 }
229
230 if(!next_protocols.empty()) {
232 }
233
234 // RFC 7250 4.1
235 // In order to indicate the support of raw public keys, clients include
236 // the client_certificate_type and/or the server_certificate_type
237 // extensions in an extended client hello message.
240
241#if defined(BOTAN_HAS_TLS_12)
242 if(policy.allow_tls12()) {
243 m_data->extensions().add(new Renegotiation_Extension());
244 m_data->extensions().add(new Session_Ticket_Extension());
245
246 // EMS must always be used with TLS 1.2, regardless of the policy
247 m_data->extensions().add(new Extended_Master_Secret);
248
249 if(policy.negotiate_encrypt_then_mac()) {
250 m_data->extensions().add(new Encrypt_then_MAC);
251 }
252
253 if(m_data->extensions().has<Supported_Groups>() &&
254 !m_data->extensions().get<Supported_Groups>()->ec_groups().empty()) {
255 m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression()));
256 }
257 }
258#endif
259
260 if(session.has_value() || !psks.empty()) {
261 m_data->extensions().add(new PSK(session, std::move(psks), cb));
262 }
263 // NOLINTEND(*-owning-memory)
264
266
267 if(m_data->extensions().has<PSK>()) {
268 // RFC 8446 4.2.11
269 // The "pre_shared_key" extension MUST be the last extension in the
270 // ClientHello (this facilitates implementation [...]).
271 if(m_data->extensions().all().back()->type() != Extension_Code::PresharedKey) {
272 throw TLS_Exception(Alert::InternalError,
273 "Application modified extensions of Client Hello, PSK is not last anymore");
274 }
275 calculate_psk_binders({});
276 }
277}
278
279std::variant<Client_Hello_13, Client_Hello_12_Shim> Client_Hello_13::parse(const std::vector<uint8_t>& buf) {
280 auto data = std::make_unique<Client_Hello_Internal>(buf);
281 const auto version = data->version();
282
283 if(version.is_pre_tls_13()) {
284 return Client_Hello_12_Shim(std::move(data));
285 } else {
286 return Client_Hello_13(std::move(data));
287 }
288}
289
291 const Transcript_Hash_State& transcript_hash_state,
292 Callbacks& cb,
294 BOTAN_STATE_CHECK(m_data->extensions().has<Supported_Groups>());
295 BOTAN_STATE_CHECK(m_data->extensions().has<Key_Share>());
296
297 auto* hrr_ks = hrr.extensions().get<Key_Share>();
298 const auto& supported_groups = m_data->extensions().get<Supported_Groups>()->groups();
299
300 if(hrr.extensions().has<Key_Share>()) {
301 m_data->extensions().get<Key_Share>()->retry_offer(*hrr_ks, supported_groups, cb, rng);
302 }
303
304 // RFC 8446 4.2.2
305 // When sending the new ClientHello, the client MUST copy
306 // the contents of the extension received in the HelloRetryRequest into
307 // a "cookie" extension in the new ClientHello.
308 //
309 // RFC 8446 4.2.2
310 // Clients MUST NOT use cookies in their initial ClientHello in subsequent
311 // connections.
312 if(hrr.extensions().has<Cookie>()) {
313 BOTAN_STATE_CHECK(!m_data->extensions().has<Cookie>());
314 m_data->extensions().add(new Cookie(hrr.extensions().get<Cookie>()->get_cookie())); // NOLINT(*-owning-memory)
315 }
316
317 // Note: the consumer of the TLS implementation won't be able to distinguish
318 // invocations to this callback due to the first Client_Hello or the
319 // retried Client_Hello after receiving a Hello_Retry_Request. We assume
320 // that the user keeps and detects this state themselves.
322
323 auto* psk = m_data->extensions().get<PSK>();
324 if(psk != nullptr) {
325 // Cipher suite should always be a known suite as this is checked upstream
326 const auto cipher = Ciphersuite::by_id(hrr.ciphersuite());
327 BOTAN_ASSERT_NOMSG(cipher.has_value());
328
329 // RFC 8446 4.1.4
330 // In [...] its updated ClientHello, the client SHOULD NOT offer
331 // any pre-shared keys associated with a hash other than that of the
332 // selected cipher suite.
333 psk->filter(cipher.value());
334
335 // RFC 8446 4.2.11.2
336 // If the server responds with a HelloRetryRequest and the client
337 // then sends ClientHello2, its binder will be computed over: [...].
338 calculate_psk_binders(transcript_hash_state.clone());
339 }
340}
341
343 // RFC 8446 4.1.2
344 // The client will also send a ClientHello when the server has responded
345 // to its ClientHello with a HelloRetryRequest. In that case, the client
346 // MUST send the same ClientHello without modification, except as follows:
347
348 if(m_data->session_id() != new_ch.m_data->session_id() || m_data->random() != new_ch.m_data->random() ||
349 m_data->ciphersuites() != new_ch.m_data->ciphersuites() ||
350 m_data->comp_methods() != new_ch.m_data->comp_methods()) {
351 throw TLS_Exception(Alert::IllegalParameter, "Client Hello core values changed after Hello Retry Request");
352 }
353
354 const auto oldexts = extension_types();
355 const auto newexts = new_ch.extension_types();
356
357 // Check that extension omissions are justified
358 for(const auto oldext : oldexts) {
359 if(!newexts.contains(oldext)) {
360 auto* const ext = extensions().get(oldext);
361
362 // We don't make any assumptions about unimplemented extensions.
363 if(!ext->is_implemented()) {
364 continue;
365 }
366
367 // RFC 8446 4.1.2
368 // Removing the "early_data" extension (Section 4.2.10) if one was
369 // present. Early data is not permitted after a HelloRetryRequest.
370 if(oldext == EarlyDataIndication::static_type()) {
371 continue;
372 }
373
374 // RFC 8446 4.1.2
375 // Optionally adding, removing, or changing the length of the
376 // "padding" extension.
377 //
378 // TODO: implement the Padding extension
379 // if(oldext == Padding::static_type())
380 // continue;
381
382 throw TLS_Exception(Alert::IllegalParameter, "Extension removed in updated Client Hello");
383 }
384 }
385
386 // Check that extension additions are justified
387 for(const auto newext : newexts) {
388 if(!oldexts.contains(newext)) {
389 auto* const ext = new_ch.extensions().get(newext);
390
391 // We don't make any assumptions about unimplemented extensions.
392 if(!ext->is_implemented()) {
393 continue;
394 }
395
396 // RFC 8446 4.1.2
397 // Including a "cookie" extension if one was provided in the
398 // HelloRetryRequest.
399 if(newext == Cookie::static_type()) {
400 continue;
401 }
402
403 // RFC 8446 4.1.2
404 // Optionally adding, removing, or changing the length of the
405 // "padding" extension.
406 //
407 // TODO: implement the Padding extension
408 // if(newext == Padding::static_type())
409 // continue;
410
411 throw TLS_Exception(Alert::UnsupportedExtension, "Added an extension in updated Client Hello");
412 }
413 }
414
415 // RFC 8446 4.1.2
416 // Removing the "early_data" extension (Section 4.2.10) if one was
417 // present. Early data is not permitted after a HelloRetryRequest.
418 if(new_ch.extensions().has<EarlyDataIndication>()) {
419 throw TLS_Exception(Alert::IllegalParameter, "Updated Client Hello indicates early data");
420 }
421
422 // TODO: Contents of extensions are not checked for update compatibility, see:
423 //
424 // RFC 8446 4.1.2
425 // If a "key_share" extension was supplied in the HelloRetryRequest,
426 // replacing the list of shares with a list containing a single
427 // KeyShareEntry from the indicated group.
428 //
429 // Updating the "pre_shared_key" extension if present by recomputing
430 // the "obfuscated_ticket_age" and binder values and (optionally)
431 // removing any PSKs which are incompatible with the server's
432 // indicated cipher suite.
433 //
434 // Optionally adding, removing, or changing the length of the
435 // "padding" extension.
436}
437
438void Client_Hello_13::calculate_psk_binders(Transcript_Hash_State transcript_hash) {
439 auto* psk = m_data->extensions().get<PSK>();
440 if(psk == nullptr || psk->empty()) {
441 return;
442 }
443
444 // RFC 8446 4.2.11.2
445 // Each entry in the binders list is computed as an HMAC over a
446 // transcript hash (see Section 4.4.1) containing a partial ClientHello
447 // [...].
448 //
449 // Therefore we marshal the entire message prematurely to obtain the
450 // (truncated) transcript hash, calculate the PSK binders with it, update
451 // the Client Hello thus finalizing the message. Down the road, it will be
452 // re-marshalled with the correct binders and sent over the wire.
453 Handshake_Layer::prepare_message(*this, transcript_hash);
454 psk->calculate_binders(transcript_hash);
455}
456
457std::optional<Protocol_Version> Client_Hello_13::highest_supported_version(const Policy& policy) const {
458 // RFC 8446 4.2.1
459 // The "supported_versions" extension is used by the client to indicate
460 // which versions of TLS it supports and by the server to indicate which
461 // version it is using. The extension contains a list of supported
462 // versions in preference order, with the most preferred version first.
463 auto* const supvers = m_data->extensions().get<Supported_Versions>();
464 BOTAN_ASSERT_NONNULL(supvers);
465
466 std::optional<Protocol_Version> result;
467
468 for(const auto& v : supvers->versions()) {
469 // RFC 8446 4.2.1
470 // Servers MUST only select a version of TLS present in that extension
471 // and MUST ignore any unknown versions that are present in that
472 // extension.
473 if(!v.known_version() || !policy.acceptable_protocol_version(v)) {
474 continue;
475 }
476
477 result = (result.has_value()) ? std::optional(std::max(result.value(), v)) : std::optional(v);
478 }
479
480 return result;
481}
482
483} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
static std::optional< Ciphersuite > by_id(uint16_t suite)
void validate_updates(const Client_Hello_13 &new_ch)
static std::variant< Client_Hello_13, Client_Hello_12_Shim > parse(const std::vector< uint8_t > &buf)
std::optional< Protocol_Version > highest_supported_version(const Policy &policy) const
Client_Hello_13(const Policy &policy, Callbacks &cb, RandomNumberGenerator &rng, std::string_view hostname, const std::vector< std::string > &next_protocols, std::optional< Session_with_Handle > &session, std::vector< ExternalPSK > psks)
void retry(const Hello_Retry_Request &hrr, const Transcript_Hash_State &transcript_hash_state, Callbacks &cb, RandomNumberGenerator &rng)
const Extensions & extensions() const
std::unique_ptr< Client_Hello_Internal > m_data
std::set< Extension_Code > extension_types() const
std::vector< std::string > next_protocols() const
Handshake_Type type() const override
const std::vector< uint8_t > & get_cookie() const
static Extension_Code static_type()
static Extension_Code static_type()
virtual bool allow_tls12() const
virtual std::vector< uint16_t > ciphersuite_list(Protocol_Version version) const
virtual std::vector< Certificate_Type > accepted_server_certificate_types() const
virtual std::vector< Certificate_Type > accepted_client_certificate_types() const
virtual std::vector< Group_Params > key_exchange_groups() const
virtual bool tls_13_middlebox_compatibility_mode() const
virtual bool negotiate_encrypt_then_mac() const
virtual bool acceptable_protocol_version(Protocol_Version version) const
virtual bool support_cert_status_message() const
virtual std::optional< std::vector< Signature_Scheme > > acceptable_certificate_signature_schemes() const
virtual std::vector< Signature_Scheme > acceptable_signature_schemes() const
virtual bool use_ecc_point_compression() const
virtual std::optional< uint16_t > record_size_limit() const
const Extensions & extensions() const
static bool hostname_acceptable_for_sni(std::string_view hostname)
std::vector< Group_Params > ec_groups() const
std::vector< uint8_t > make_hello_random(RandomNumberGenerator &rng, Callbacks &cb, const Policy &policy)
Strong< std::vector< uint8_t >, struct Session_ID_ > Session_ID
holds a TLS 1.2 session ID for stateful resumption