Botan 3.11.0
Crypto and TLS for C&
msg_server_hello_13.cpp
Go to the documentation of this file.
1/*
2* TLS Server Hello and Server Hello Done
3* (C) 2004-2011,2015,2016,2019 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/tls_alert.h>
14#include <botan/tls_callbacks.h>
15#include <botan/tls_exceptn.h>
16#include <botan/tls_extensions_13.h>
17#include <botan/tls_policy.h>
18#include <botan/internal/loadstor.h>
19#include <botan/internal/stl_util.h>
20#include <botan/internal/tls_messages_internal.h>
21
22namespace Botan::TLS {
23
24const Server_Hello_13::Server_Hello_Tag Server_Hello_13::as_server_hello;
25const Server_Hello_13::Hello_Retry_Request_Tag Server_Hello_13::as_hello_retry_request;
26const Server_Hello_13::Hello_Retry_Request_Creation_Tag Server_Hello_13::as_new_hello_retry_request;
27
28std::variant<Hello_Retry_Request, Server_Hello_13> Server_Hello_13::create(const Client_Hello_13& ch,
29 bool hello_retry_request_allowed,
30 Session_Manager& session_mgr,
31 Credentials_Manager& credentials_mgr,
33 const Policy& policy,
34 Callbacks& cb) {
35 const auto& exts = ch.extensions();
36
37 // RFC 8446 4.2.9
38 // [With PSK with (EC)DHE key establishment], the client and server MUST
39 // supply "key_share" values [...].
40 //
41 // Note: We currently do not support PSK without (EC)DHE, hence, we can
42 // assume that those extensions are available.
43 BOTAN_ASSERT_NOMSG(exts.has<Supported_Groups>() && exts.has<Key_Share>());
44 const auto& supported_by_client = exts.get<Supported_Groups>()->groups();
45 const auto& offered_by_client = exts.get<Key_Share>()->offered_groups();
46 const auto selected_group = policy.choose_key_exchange_group(supported_by_client, offered_by_client);
47
48 // RFC 8446 4.1.1
49 // If there is no overlap between the received "supported_groups" and the
50 // groups supported by the server, then the server MUST abort the
51 // handshake with a "handshake_failure" or an "insufficient_security" alert.
52 if(selected_group == Named_Group::NONE) {
53 throw TLS_Exception(Alert::HandshakeFailure, "Client did not offer any acceptable group");
54 }
55
56 // RFC 8446 4.2.8:
57 // Servers MUST NOT send a KeyShareEntry for any group not indicated in the
58 // client's "supported_groups" extension [...]
59 if(!value_exists(supported_by_client, selected_group)) {
60 throw TLS_Exception(Alert::InternalError, "Application selected a group that is not supported by the client");
61 }
62
63 // RFC 8446 4.1.4
64 // The server will send this message in response to a ClientHello
65 // message if it is able to find an acceptable set of parameters but the
66 // ClientHello does not contain sufficient information to proceed with
67 // the handshake.
68 //
69 // In this case, the Client Hello did not contain a key share offer for
70 // the group selected by the application.
71 if(!value_exists(offered_by_client, selected_group)) {
72 // RFC 8446 4.1.4
73 // If a client receives a second HelloRetryRequest in the same
74 // connection (i.e., where the ClientHello was itself in response to a
75 // HelloRetryRequest), it MUST abort the handshake with an
76 // "unexpected_message" alert.
77 BOTAN_STATE_CHECK(hello_retry_request_allowed);
78 return Hello_Retry_Request(ch, selected_group, policy, cb);
79 } else {
80 return Server_Hello_13(ch, selected_group, session_mgr, credentials_mgr, rng, cb, policy);
81 }
82}
83
84std::variant<Hello_Retry_Request, Server_Hello_13, Server_Hello_12_Shim> Server_Hello_13::parse(
85 const std::vector<uint8_t>& buf) {
86 auto data = std::make_unique<Server_Hello_Internal>(buf);
87 const auto version = data->version();
88
89 // server hello that appears to be pre-TLS 1.3, takes precedence over...
90 if(version.is_pre_tls_13()) {
91 return Server_Hello_12_Shim(std::move(data));
92 }
93
94 // ... the TLS 1.3 "special case" aka. Hello_Retry_Request
95 if(version == Protocol_Version::TLS_V13) {
96 if(data->is_hello_retry_request()) {
97 return Hello_Retry_Request(std::move(data));
98 }
99
100 return Server_Hello_13(std::move(data));
101 }
102
103 throw TLS_Exception(Alert::ProtocolVersion, "unexpected server hello version: " + version.to_string());
104}
105
106/**
107 * Validation that applies to both Server Hello and Hello Retry Request
108 */
110 BOTAN_ASSERT_NOMSG(m_data->version() == Protocol_Version::TLS_V13);
111
112 // Note: checks that cannot be performed without contextual information
113 // are done in the specific TLS client implementation.
114 // Note: The Supported_Version extension makes sure internally that
115 // exactly one entry is provided.
116
117 // Note: Hello Retry Request basic validation is equivalent with the
118 // basic validations required for Server Hello
119 //
120 // RFC 8446 4.1.4
121 // Upon receipt of a HelloRetryRequest, the client MUST check the
122 // legacy_version, [...], and legacy_compression_method as specified in
123 // Section 4.1.3 and then process the extensions, starting with determining
124 // the version using "supported_versions".
125
126 // RFC 8446 4.1.3
127 // In TLS 1.3, [...] the legacy_version field MUST be set to 0x0303
128 if(legacy_version() != Protocol_Version::TLS_V12) {
129 throw TLS_Exception(Alert::ProtocolVersion,
130 "legacy_version '" + legacy_version().to_string() + "' is not allowed");
131 }
132
133 // RFC 8446 4.1.3
134 // legacy_compression_method: A single byte which MUST have the value 0.
135 if(compression_method() != 0x00) {
136 throw TLS_Exception(Alert::DecodeError, "compression is not supported in TLS 1.3");
137 }
138
139 // RFC 8446 4.1.3
140 // All TLS 1.3 ServerHello messages MUST contain the "supported_versions" extension.
141 if(!extensions().has<Supported_Versions>()) {
142 throw TLS_Exception(Alert::MissingExtension, "server hello did not contain 'supported version' extension");
143 }
144
145 // RFC 8446 4.2.1
146 // A server which negotiates TLS 1.3 MUST respond by sending
147 // a "supported_versions" extension containing the selected version
148 // value (0x0304).
149 if(selected_version() != Protocol_Version::TLS_V13) {
150 throw TLS_Exception(Alert::IllegalParameter, "TLS 1.3 Server Hello selected a different version");
151 }
152}
153
154Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
155 Server_Hello_13::Server_Hello_Tag /*tag*/) :
156 Server_Hello(std::move(data)) {
157 BOTAN_ASSERT_NOMSG(!m_data->is_hello_retry_request());
159
160 const auto& exts = extensions();
161
162 // RFC 8446 4.1.3
163 // The ServerHello MUST only include extensions which are required to
164 // establish the cryptographic context and negotiate the protocol version.
165 // [...]
166 // Other extensions (see Section 4.2) are sent separately in the
167 // EncryptedExtensions message.
168 //
169 // Note that further validation dependent on the client hello is done in the
170 // TLS client implementation.
171 const std::set<Extension_Code> allowed = {
175 };
176
177 // As the ServerHello shall only contain essential extensions, we don't give
178 // any slack for extensions not implemented by Botan here.
179 if(exts.contains_other_than(allowed)) {
180 throw TLS_Exception(Alert::UnsupportedExtension, "Server Hello contained an extension that is not allowed");
181 }
182
183 // RFC 8446 4.1.3
184 // Current ServerHello messages additionally contain
185 // either the "pre_shared_key" extension or the "key_share"
186 // extension, or both [...].
187 if(!exts.has<Key_Share>() && !exts.has<PSK>()) {
188 throw TLS_Exception(Alert::MissingExtension, "server hello must contain key exchange information");
189 }
190}
191
192Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
193 Server_Hello_13::Hello_Retry_Request_Tag /*tag*/) :
194 Server_Hello(std::move(data)) {
195 BOTAN_ASSERT_NOMSG(m_data->is_hello_retry_request());
197
198 const auto& exts = extensions();
199
200 // RFC 8446 4.1.4
201 // The HelloRetryRequest extensions defined in this specification are:
202 // - supported_versions (see Section 4.2.1)
203 // - cookie (see Section 4.2.2)
204 // - key_share (see Section 4.2.8)
205 const std::set<Extension_Code> allowed = {
209 };
210
211 // As the Hello Retry Request shall only contain essential extensions, we
212 // don't give any slack for extensions not implemented by Botan here.
213 if(exts.contains_other_than(allowed)) {
214 throw TLS_Exception(Alert::UnsupportedExtension,
215 "Hello Retry Request contained an extension that is not allowed");
216 }
217
218 // RFC 8446 4.1.4
219 // Clients MUST abort the handshake with an "illegal_parameter" alert if
220 // the HelloRetryRequest would not result in any change in the ClientHello.
221 if(!exts.has<Key_Share>() && !exts.has<Cookie>()) {
222 throw TLS_Exception(Alert::IllegalParameter, "Hello Retry Request does not request any changes to Client Hello");
223 }
224}
225
226Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data,
227 Hello_Retry_Request_Creation_Tag /*tag*/) :
228 Server_Hello(std::move(data)) {}
229
230namespace {
231
232uint16_t choose_ciphersuite(const Client_Hello_13& ch, const Policy& policy) {
233 auto pref_list = ch.ciphersuites();
234 // TODO: DTLS might need to make this version dynamic
235 auto other_list = policy.ciphersuite_list(Protocol_Version::TLS_V13);
236
238 std::swap(pref_list, other_list);
239 }
240
241 for(auto suite_id : pref_list) {
242 // TODO: take potentially available PSKs into account to select a
243 // compatible ciphersuite.
244 //
245 // Assuming the client sent one or more PSKs, we would first need to find
246 // the hash functions they are associated to. For session tickets, that
247 // would mean decrypting the ticket and comparing the cipher suite used in
248 // those tickets. For (currently not yet supported) pre-assigned PSKs, the
249 // hash function needs to be specified along with them.
250 //
251 // Then we could refine the ciphersuite selection using the required hash
252 // function for the PSK(s) we are wishing to use down the road.
253 //
254 // For now, we just negotiate the cipher suite blindly and hope for the
255 // best. As long as PSKs are used for session resumption only, this has a
256 // high chance of success. Previous handshakes with this client have very
257 // likely selected the same ciphersuite anyway.
258 //
259 // See also RFC 8446 4.2.11
260 // When session resumption is the primary use case of PSKs, the most
261 // straightforward way to implement the PSK/cipher suite matching
262 // requirements is to negotiate the cipher suite first [...].
263 if(value_exists(other_list, suite_id)) {
264 return suite_id;
265 }
266 }
267
268 // RFC 8446 4.1.1
269 // If the server is unable to negotiate a supported set of parameters
270 // [...], it MUST abort the handshake with either a "handshake_failure"
271 // or "insufficient_security" fatal alert [...].
272 throw TLS_Exception(Alert::HandshakeFailure, "Can't agree on a ciphersuite with client");
273}
274} // namespace
275
277 std::optional<Named_Group> key_exchange_group,
278 Session_Manager& session_mgr,
279 Credentials_Manager& credentials_mgr,
281 Callbacks& cb,
282 const Policy& policy) :
283 Server_Hello(std::make_unique<Server_Hello_Internal>(
285 ch.session_id(),
287 choose_ciphersuite(ch, policy),
288 uint8_t(0) /* compression method */
289 )) {
290 // RFC 8446 4.2.1
291 // A server which negotiates TLS 1.3 MUST respond by sending a
292 // "supported_versions" extension containing the selected version
293 // value (0x0304). It MUST set the ServerHello.legacy_version field to
294 // 0x0303 (TLS 1.2).
295 //
296 // Note that the legacy version (TLS 1.2) is set in this constructor's
297 // initializer list, accordingly.
298 m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13)); // NOLINT(*-owning-memory)
299
300 if(key_exchange_group.has_value()) {
301 BOTAN_ASSERT_NOMSG(ch.extensions().has<Key_Share>());
302 m_data->extensions().add(Key_Share::create_as_encapsulation(
303 key_exchange_group.value(), *ch.extensions().get<Key_Share>(), policy, cb, rng));
304 }
305
306 const auto& ch_exts = ch.extensions();
307
308 if(ch_exts.has<PSK>()) {
309 const auto cs = Ciphersuite::by_id(m_data->ciphersuite());
310 BOTAN_ASSERT_NOMSG(cs);
311
312 // RFC 8446 4.2.9
313 // A client MUST provide a "psk_key_exchange_modes" extension if it
314 // offers a "pre_shared_key" extension.
315 //
316 // Note: Client_Hello_13 constructor already performed a graceful check.
317 auto* const psk_modes = ch_exts.get<PSK_Key_Exchange_Modes>();
318 BOTAN_ASSERT_NONNULL(psk_modes);
319
320 // TODO: also support PSK_Key_Exchange_Mode::PSK_KE
321 // (PSK-based handshake without an additional ephemeral key exchange)
322 if(value_exists(psk_modes->modes(), PSK_Key_Exchange_Mode::PSK_DHE_KE)) {
323 if(auto server_psk = ch_exts.get<PSK>()->select_offered_psk(
324 ch.sni_hostname(), cs.value(), session_mgr, credentials_mgr, cb, policy)) {
325 // RFC 8446 4.2.11
326 // In order to accept PSK key establishment, the server sends a
327 // "pre_shared_key" extension indicating the selected identity.
328 m_data->extensions().add(std::move(server_psk));
329 }
330 }
331 }
332
333 cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type());
334}
335
336std::optional<Protocol_Version> Server_Hello_13::random_signals_downgrade() const {
337 const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3);
338 if(last8 == DOWNGRADE_TLS11) {
339 return Protocol_Version::TLS_V11;
340 }
341 if(last8 == DOWNGRADE_TLS12) {
342 return Protocol_Version::TLS_V12;
343 }
344
345 return std::nullopt;
346}
347
349 auto* const versions_ext = m_data->extensions().get<Supported_Versions>();
350 BOTAN_ASSERT_NOMSG(versions_ext);
351 const auto& versions = versions_ext->versions();
352 BOTAN_ASSERT_NOMSG(versions.size() == 1);
353 return versions.front();
354}
355
356Hello_Retry_Request::Hello_Retry_Request(std::unique_ptr<Server_Hello_Internal> data) :
358
360 Named_Group selected_group,
361 const Policy& policy,
362 Callbacks& cb) :
363 Server_Hello_13(std::make_unique<Server_Hello_Internal>(
364 Protocol_Version::TLS_V12 /* legacy_version */,
365 ch.session_id(),
366 std::vector<uint8_t>(HELLO_RETRY_REQUEST_MARKER.begin(), HELLO_RETRY_REQUEST_MARKER.end()),
367 choose_ciphersuite(ch, policy),
368 uint8_t(0) /* compression method */,
369 true /* is Hello Retry Request */
370 ),
372 // RFC 8446 4.1.4
373 // As with the ServerHello, a HelloRetryRequest MUST NOT contain any
374 // extensions that were not first offered by the client in its
375 // ClientHello, with the exception of optionally the "cookie" [...]
376 // extension.
379
381
382 // RFC 8446 4.1.4
383 // The server's extensions MUST contain "supported_versions".
384 //
385 // RFC 8446 4.2.1
386 // A server which negotiates TLS 1.3 MUST respond by sending a
387 // "supported_versions" extension containing the selected version
388 // value (0x0304). It MUST set the ServerHello.legacy_version field to
389 // 0x0303 (TLS 1.2).
390 //
391 // Note that the legacy version (TLS 1.2) is set in this constructor's
392 // initializer list, accordingly.
393 // NOLINTBEGIN(*-owning-memory)
394 m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13));
395
396 m_data->extensions().add(new Key_Share(selected_group));
397 // NOLINTEND(*-owning-memory)
398
400}
401
402} // namespace Botan::TLS
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
virtual void tls_modify_extensions(Extensions &extn, Connection_Side which_side, Handshake_Type which_message)
const Extensions & extensions() const
const std::vector< uint16_t > & ciphersuites() const
Hello_Retry_Request(std::unique_ptr< Server_Hello_Internal > data)
Handshake_Type type() const override
std::vector< Named_Group > offered_groups() const
virtual std::vector< uint16_t > ciphersuite_list(Protocol_Version version) const
virtual bool server_uses_own_ciphersuite_preferences() const
virtual Group_Params choose_key_exchange_group(const std::vector< Group_Params > &supported_by_peer, const std::vector< Group_Params > &offered_by_peer) const
static std::variant< Hello_Retry_Request, Server_Hello_13, Server_Hello_12_Shim > parse(const std::vector< uint8_t > &buf)
static const struct Botan::TLS::Server_Hello_13::Hello_Retry_Request_Tag as_hello_retry_request
static const struct Botan::TLS::Server_Hello_13::Hello_Retry_Request_Creation_Tag as_new_hello_retry_request
Server_Hello_13(std::unique_ptr< Server_Hello_Internal > data, Server_Hello_Tag tag=as_server_hello)
std::optional< Protocol_Version > random_signals_downgrade() const
static std::variant< Hello_Retry_Request, Server_Hello_13 > create(const Client_Hello_13 &ch, bool hello_retry_request_allowed, Session_Manager &session_mgr, Credentials_Manager &credentials_mgr, RandomNumberGenerator &rng, const Policy &policy, Callbacks &cb)
Protocol_Version selected_version() const final
static const struct Botan::TLS::Server_Hello_13::Server_Hello_Tag as_server_hello
Server_Hello(const Server_Hello &)=delete
const Session_ID & session_id() const
std::unique_ptr< Server_Hello_Internal > m_data
const Extensions & extensions() const
Protocol_Version legacy_version() const
constexpr uint64_t DOWNGRADE_TLS12
Definition tls_magic.h:118
Group_Params Named_Group
std::vector< uint8_t > make_server_hello_random(RandomNumberGenerator &rng, Protocol_Version offered_version, Callbacks &cb, const Policy &policy)
constexpr uint64_t DOWNGRADE_TLS11
Definition tls_magic.h:107
constexpr std::array< uint8_t, 32 > HELLO_RETRY_REQUEST_MARKER
Definition tls_magic.h:126
bool value_exists(const std::vector< T > &vec, const V &val)
Definition stl_util.h:43
std::string to_string(ErrorType type)
Convert an ErrorType to string.
Definition exceptn.cpp:13
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504