/src/botan/src/lib/tls/msg_server_hello.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * TLS Server Hello and Server Hello Done |
3 | | * (C) 2004-2011,2015,2016,2019 Jack Lloyd |
4 | | * 2016 Matthias Gierlings |
5 | | * 2017 Harry Reimann, Rohde & Schwarz Cybersecurity |
6 | | * 2021 Elektrobit Automotive GmbH |
7 | | * 2022 René Meusel, Hannes Rantzsch - neXenio GmbH |
8 | | * |
9 | | * Botan is released under the Simplified BSD License (see license.txt) |
10 | | */ |
11 | | |
12 | | #include <botan/tls_messages.h> |
13 | | |
14 | | #include <botan/mem_ops.h> |
15 | | #include <botan/tls_callbacks.h> |
16 | | #include <botan/tls_exceptn.h> |
17 | | #include <botan/tls_extensions.h> |
18 | | #include <botan/tls_session_manager.h> |
19 | | #include <botan/internal/ct_utils.h> |
20 | | #include <botan/internal/stl_util.h> |
21 | | #include <botan/internal/tls_handshake_hash.h> |
22 | | #include <botan/internal/tls_handshake_io.h> |
23 | | #include <botan/internal/tls_reader.h> |
24 | | #include <botan/internal/tls_session_key.h> |
25 | | |
26 | | #include <array> |
27 | | |
28 | | namespace Botan::TLS { |
29 | | |
30 | | namespace { |
31 | | |
32 | | const uint64_t DOWNGRADE_TLS11 = 0x444F574E47524400; |
33 | | const uint64_t DOWNGRADE_TLS12 = 0x444F574E47524401; |
34 | | |
35 | | // SHA-256("HelloRetryRequest") |
36 | | const std::vector<uint8_t> HELLO_RETRY_REQUEST_MARKER = { |
37 | | 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, |
38 | | 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C}; |
39 | | |
40 | 7.24k | bool random_signals_hello_retry_request(const std::vector<uint8_t>& random) { |
41 | 7.24k | return CT::is_equal(random.data(), HELLO_RETRY_REQUEST_MARKER.data(), HELLO_RETRY_REQUEST_MARKER.size()).as_bool(); |
42 | 7.24k | } |
43 | | |
44 | | std::vector<uint8_t> make_server_hello_random(RandomNumberGenerator& rng, |
45 | | Protocol_Version offered_version, |
46 | | Callbacks& cb, |
47 | 21.2k | const Policy& policy) { |
48 | 21.2k | BOTAN_UNUSED(offered_version); |
49 | 21.2k | auto random = make_hello_random(rng, cb, policy); |
50 | | |
51 | | // RFC 8446 4.1.3 |
52 | | // TLS 1.3 has a downgrade protection mechanism embedded in the server's |
53 | | // random value. TLS 1.3 servers which negotiate TLS 1.2 or below in |
54 | | // response to a ClientHello MUST set the last 8 bytes of their Random |
55 | | // value specially in their ServerHello. |
56 | | // |
57 | | // If negotiating TLS 1.2, TLS 1.3 servers MUST set the last 8 bytes of |
58 | | // their Random value to the bytes: [DOWNGRADE_TLS12] |
59 | 21.2k | if(offered_version.is_pre_tls_13() && policy.allow_tls13()) { |
60 | 21.2k | constexpr size_t downgrade_signal_length = sizeof(DOWNGRADE_TLS12); |
61 | 21.2k | BOTAN_ASSERT_NOMSG(random.size() >= downgrade_signal_length); |
62 | 21.2k | auto lastbytes = random.data() + random.size() - downgrade_signal_length; |
63 | 21.2k | store_be(DOWNGRADE_TLS12, lastbytes); |
64 | 21.2k | } |
65 | | |
66 | 21.2k | return random; |
67 | 21.2k | } |
68 | | |
69 | | } // namespace |
70 | | |
71 | | /** |
72 | | * Version-agnostic internal server hello data container that allows |
73 | | * parsing Server_Hello messages without prior knowledge of the contained |
74 | | * protocol version. |
75 | | */ |
76 | | class Server_Hello_Internal { |
77 | | public: |
78 | | /** |
79 | | * Deserialize a Server Hello message |
80 | | */ |
81 | 7.28k | Server_Hello_Internal(const std::vector<uint8_t>& buf) { |
82 | 7.28k | if(buf.size() < 38) { |
83 | 39 | throw Decoding_Error("Server_Hello: Packet corrupted"); |
84 | 39 | } |
85 | | |
86 | 7.24k | TLS_Data_Reader reader("ServerHello", buf); |
87 | | |
88 | 7.24k | const uint8_t major_version = reader.get_byte(); |
89 | 7.24k | const uint8_t minor_version = reader.get_byte(); |
90 | | |
91 | 7.24k | m_legacy_version = Protocol_Version(major_version, minor_version); |
92 | | |
93 | | // RFC 8446 4.1.3 |
94 | | // Upon receiving a message with type server_hello, implementations MUST |
95 | | // first examine the Random value and, if it matches this value, process |
96 | | // it as described in Section 4.1.4 [Hello Retry Request]). |
97 | 7.24k | m_random = reader.get_fixed<uint8_t>(32); |
98 | 7.24k | m_is_hello_retry_request = random_signals_hello_retry_request(m_random); |
99 | | |
100 | 7.24k | m_session_id = Session_ID(reader.get_range<uint8_t>(1, 0, 32)); |
101 | 7.24k | m_ciphersuite = reader.get_uint16_t(); |
102 | 7.24k | m_comp_method = reader.get_byte(); |
103 | | |
104 | | // Note that this code path might parse a TLS 1.2 (or older) server hello message that |
105 | | // is nevertheless marked as being a 'hello retry request' (potentially maliciously). |
106 | | // Extension parsing will however not be affected by the associated flag. |
107 | | // Only after parsing the extensions will the upstream code be able to decide |
108 | | // whether we're dealing with TLS 1.3 or older. |
109 | 7.24k | m_extensions.deserialize( |
110 | 7.24k | reader, |
111 | 7.24k | Connection_Side::Server, |
112 | 7.24k | m_is_hello_retry_request ? Handshake_Type::HelloRetryRequest : Handshake_Type::ServerHello); |
113 | 7.24k | } |
114 | | |
115 | | Server_Hello_Internal(Protocol_Version lv, |
116 | | Session_ID sid, |
117 | | std::vector<uint8_t> r, |
118 | | const uint16_t cs, |
119 | | const uint8_t cm, |
120 | | bool is_hrr = false) : |
121 | 21.2k | m_legacy_version(lv), |
122 | 21.2k | m_session_id(std::move(sid)), |
123 | 21.2k | m_random(std::move(r)), |
124 | 21.2k | m_is_hello_retry_request(is_hrr), |
125 | 21.2k | m_ciphersuite(cs), |
126 | 21.2k | m_comp_method(cm) {} |
127 | | |
128 | 10.1k | Protocol_Version version() const { |
129 | | // RFC 8446 4.2.1 |
130 | | // A server which negotiates a version of TLS prior to TLS 1.3 MUST set |
131 | | // ServerHello.version and MUST NOT send the "supported_versions" |
132 | | // extension. A server which negotiates TLS 1.3 MUST respond by sending |
133 | | // a "supported_versions" extension containing the selected version |
134 | | // value (0x0304). |
135 | | // |
136 | | // Note: Here we just take a message parsing decision, further validation of |
137 | | // the extension's contents is done later. |
138 | 10.1k | return (extensions().has<Supported_Versions>()) ? Protocol_Version::TLS_V13 : m_legacy_version; |
139 | 10.1k | } |
140 | | |
141 | 64.3k | Protocol_Version legacy_version() const { return m_legacy_version; } |
142 | | |
143 | 21.8k | const Session_ID& session_id() const { return m_session_id; } |
144 | | |
145 | 31.0k | const std::vector<uint8_t>& random() const { return m_random; } |
146 | | |
147 | 85.2k | uint16_t ciphersuite() const { return m_ciphersuite; } |
148 | | |
149 | 22.1k | uint8_t comp_method() const { return m_comp_method; } |
150 | | |
151 | 600 | bool is_hello_retry_request() const { return m_is_hello_retry_request; } |
152 | | |
153 | 10.1k | const Extensions& extensions() const { return m_extensions; } |
154 | | |
155 | 98.2k | Extensions& extensions() { return m_extensions; } |
156 | | |
157 | | private: |
158 | | Protocol_Version m_legacy_version; |
159 | | Session_ID m_session_id; |
160 | | std::vector<uint8_t> m_random; |
161 | | bool m_is_hello_retry_request; |
162 | | uint16_t m_ciphersuite; |
163 | | uint8_t m_comp_method; |
164 | | |
165 | | Extensions m_extensions; |
166 | | }; |
167 | | |
168 | 26.3k | Server_Hello::Server_Hello(std::unique_ptr<Server_Hello_Internal> data) : m_data(std::move(data)) {} |
169 | | |
170 | 18.8k | Server_Hello::Server_Hello(Server_Hello&&) noexcept = default; |
171 | 0 | Server_Hello& Server_Hello::operator=(Server_Hello&&) noexcept = default; |
172 | | |
173 | 45.2k | Server_Hello::~Server_Hello() = default; |
174 | | |
175 | | /* |
176 | | * Serialize a Server Hello message |
177 | | */ |
178 | 21.2k | std::vector<uint8_t> Server_Hello::serialize() const { |
179 | 21.2k | std::vector<uint8_t> buf; |
180 | 21.2k | buf.reserve(1024); // working around GCC warning |
181 | | |
182 | 21.2k | buf.push_back(m_data->legacy_version().major_version()); |
183 | 21.2k | buf.push_back(m_data->legacy_version().minor_version()); |
184 | 21.2k | buf += m_data->random(); |
185 | | |
186 | 21.2k | append_tls_length_value(buf, m_data->session_id().get(), 1); |
187 | | |
188 | 21.2k | buf.push_back(get_byte<0>(m_data->ciphersuite())); |
189 | 21.2k | buf.push_back(get_byte<1>(m_data->ciphersuite())); |
190 | | |
191 | 21.2k | buf.push_back(m_data->comp_method()); |
192 | | |
193 | 21.2k | buf += m_data->extensions().serialize(Connection_Side::Server); |
194 | | |
195 | 21.2k | return buf; |
196 | 21.2k | } |
197 | | |
198 | 63.6k | Handshake_Type Server_Hello::type() const { |
199 | 63.6k | return Handshake_Type::ServerHello; |
200 | 63.6k | } |
201 | | |
202 | 766 | Protocol_Version Server_Hello::legacy_version() const { |
203 | 766 | return m_data->legacy_version(); |
204 | 766 | } |
205 | | |
206 | 9.79k | const std::vector<uint8_t>& Server_Hello::random() const { |
207 | 9.79k | return m_data->random(); |
208 | 9.79k | } |
209 | | |
210 | 993 | uint8_t Server_Hello::compression_method() const { |
211 | 993 | return m_data->comp_method(); |
212 | 993 | } |
213 | | |
214 | 617 | const Session_ID& Server_Hello::session_id() const { |
215 | 617 | return m_data->session_id(); |
216 | 617 | } |
217 | | |
218 | 21.6k | uint16_t Server_Hello::ciphersuite() const { |
219 | 21.6k | return m_data->ciphersuite(); |
220 | 21.6k | } |
221 | | |
222 | 0 | std::set<Extension_Code> Server_Hello::extension_types() const { |
223 | 0 | return m_data->extensions().extension_types(); |
224 | 0 | } |
225 | | |
226 | 465 | const Extensions& Server_Hello::extensions() const { |
227 | 465 | return m_data->extensions(); |
228 | 465 | } |
229 | | |
230 | | // New session case |
231 | | Server_Hello_12::Server_Hello_12(Handshake_IO& io, |
232 | | Handshake_Hash& hash, |
233 | | const Policy& policy, |
234 | | Callbacks& cb, |
235 | | RandomNumberGenerator& rng, |
236 | | const std::vector<uint8_t>& reneg_info, |
237 | | const Client_Hello_12& client_hello, |
238 | | const Server_Hello_12::Settings& server_settings, |
239 | | std::string_view next_protocol) : |
240 | 21.2k | Server_Hello(std::make_unique<Server_Hello_Internal>( |
241 | 21.2k | server_settings.protocol_version(), |
242 | 21.2k | server_settings.session_id(), |
243 | 21.2k | make_server_hello_random(rng, server_settings.protocol_version(), cb, policy), |
244 | 21.2k | server_settings.ciphersuite(), |
245 | 21.2k | uint8_t(0))) { |
246 | 21.2k | if(client_hello.supports_extended_master_secret()) { |
247 | 1.68k | m_data->extensions().add(new Extended_Master_Secret); |
248 | 1.68k | } |
249 | | |
250 | | // Sending the extension back does not commit us to sending a stapled response |
251 | 21.2k | if(client_hello.supports_cert_status_message() && policy.support_cert_status_message()) { |
252 | 2.67k | m_data->extensions().add(new Certificate_Status_Request); |
253 | 2.67k | } |
254 | | |
255 | 21.2k | if(!next_protocol.empty() && client_hello.supports_alpn()) { |
256 | 4.39k | m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol)); |
257 | 4.39k | } |
258 | | |
259 | 21.2k | const auto c = Ciphersuite::by_id(m_data->ciphersuite()); |
260 | | |
261 | 21.2k | if(c && c->cbc_ciphersuite() && client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) { |
262 | 3.43k | m_data->extensions().add(new Encrypt_then_MAC); |
263 | 3.43k | } |
264 | | |
265 | 21.2k | if(c && c->ecc_ciphersuite() && client_hello.extension_types().contains(Extension_Code::EcPointFormats)) { |
266 | 1.14k | m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression())); |
267 | 1.14k | } |
268 | | |
269 | 21.2k | if(client_hello.secure_renegotiation()) { |
270 | 6.46k | m_data->extensions().add(new Renegotiation_Extension(reneg_info)); |
271 | 6.46k | } |
272 | | |
273 | 21.2k | if(client_hello.supports_session_ticket() && server_settings.offer_session_ticket()) { |
274 | 0 | m_data->extensions().add(new Session_Ticket_Extension()); |
275 | 0 | } |
276 | | |
277 | 21.2k | if(m_data->legacy_version().is_datagram_protocol()) { |
278 | 1 | const std::vector<uint16_t> server_srtp = policy.srtp_profiles(); |
279 | 1 | const std::vector<uint16_t> client_srtp = client_hello.srtp_profiles(); |
280 | | |
281 | 1 | if(!server_srtp.empty() && !client_srtp.empty()) { |
282 | 0 | uint16_t shared = 0; |
283 | | // always using server preferences for now |
284 | 0 | for(auto s_srtp : server_srtp) { |
285 | 0 | for(auto c_srtp : client_srtp) { |
286 | 0 | if(shared == 0 && s_srtp == c_srtp) { |
287 | 0 | shared = s_srtp; |
288 | 0 | } |
289 | 0 | } |
290 | 0 | } |
291 | |
|
292 | 0 | if(shared) { |
293 | 0 | m_data->extensions().add(new SRTP_Protection_Profiles(shared)); |
294 | 0 | } |
295 | 0 | } |
296 | 1 | } |
297 | | |
298 | 21.2k | cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type()); |
299 | | |
300 | 21.2k | hash.update(io.send(*this)); |
301 | 21.2k | } |
302 | | |
303 | | // Resuming |
304 | | Server_Hello_12::Server_Hello_12(Handshake_IO& io, |
305 | | Handshake_Hash& hash, |
306 | | const Policy& policy, |
307 | | Callbacks& cb, |
308 | | RandomNumberGenerator& rng, |
309 | | const std::vector<uint8_t>& reneg_info, |
310 | | const Client_Hello_12& client_hello, |
311 | | const Session& resumed_session, |
312 | | bool offer_session_ticket, |
313 | | std::string_view next_protocol) : |
314 | 0 | Server_Hello(std::make_unique<Server_Hello_Internal>(resumed_session.version(), |
315 | 0 | client_hello.session_id(), |
316 | 0 | make_hello_random(rng, cb, policy), |
317 | 0 | resumed_session.ciphersuite_code(), |
318 | 0 | uint8_t(0))) { |
319 | 0 | if(client_hello.supports_extended_master_secret()) { |
320 | 0 | m_data->extensions().add(new Extended_Master_Secret); |
321 | 0 | } |
322 | |
|
323 | 0 | if(!next_protocol.empty() && client_hello.supports_alpn()) { |
324 | 0 | m_data->extensions().add(new Application_Layer_Protocol_Notification(next_protocol)); |
325 | 0 | } |
326 | |
|
327 | 0 | if(client_hello.supports_encrypt_then_mac() && policy.negotiate_encrypt_then_mac()) { |
328 | 0 | Ciphersuite c = resumed_session.ciphersuite(); |
329 | 0 | if(c.cbc_ciphersuite()) { |
330 | 0 | m_data->extensions().add(new Encrypt_then_MAC); |
331 | 0 | } |
332 | 0 | } |
333 | |
|
334 | 0 | if(resumed_session.ciphersuite().ecc_ciphersuite() && |
335 | 0 | client_hello.extension_types().contains(Extension_Code::EcPointFormats)) { |
336 | 0 | m_data->extensions().add(new Supported_Point_Formats(policy.use_ecc_point_compression())); |
337 | 0 | } |
338 | |
|
339 | 0 | if(client_hello.secure_renegotiation()) { |
340 | 0 | m_data->extensions().add(new Renegotiation_Extension(reneg_info)); |
341 | 0 | } |
342 | |
|
343 | 0 | if(client_hello.supports_session_ticket() && offer_session_ticket) { |
344 | 0 | m_data->extensions().add(new Session_Ticket_Extension()); |
345 | 0 | } |
346 | |
|
347 | 0 | cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type()); |
348 | |
|
349 | 0 | hash.update(io.send(*this)); |
350 | 0 | } |
351 | | |
352 | | Server_Hello_12::Server_Hello_12(const std::vector<uint8_t>& buf) : |
353 | 2.27k | Server_Hello_12(std::make_unique<Server_Hello_Internal>(buf)) {} |
354 | | |
355 | 4.89k | Server_Hello_12::Server_Hello_12(std::unique_ptr<Server_Hello_Internal> data) : Server_Hello(std::move(data)) { |
356 | 4.89k | if(!m_data->version().is_pre_tls_13()) { |
357 | 201 | throw TLS_Exception(Alert::ProtocolVersion, "Expected server hello of (D)TLS 1.2 or lower"); |
358 | 201 | } |
359 | 4.89k | } |
360 | | |
361 | 0 | Protocol_Version Server_Hello_12::selected_version() const { |
362 | 0 | return legacy_version(); |
363 | 0 | } |
364 | | |
365 | 21.2k | bool Server_Hello_12::secure_renegotiation() const { |
366 | 21.2k | return m_data->extensions().has<Renegotiation_Extension>(); |
367 | 21.2k | } |
368 | | |
369 | 6.46k | std::vector<uint8_t> Server_Hello_12::renegotiation_info() const { |
370 | 6.46k | if(Renegotiation_Extension* reneg = m_data->extensions().get<Renegotiation_Extension>()) { |
371 | 6.46k | return reneg->renegotiation_info(); |
372 | 6.46k | } |
373 | 0 | return std::vector<uint8_t>(); |
374 | 6.46k | } |
375 | | |
376 | 5.73k | bool Server_Hello_12::supports_extended_master_secret() const { |
377 | 5.73k | return m_data->extensions().has<Extended_Master_Secret>(); |
378 | 5.73k | } |
379 | | |
380 | 986 | bool Server_Hello_12::supports_encrypt_then_mac() const { |
381 | 986 | return m_data->extensions().has<Encrypt_then_MAC>(); |
382 | 986 | } |
383 | | |
384 | 0 | bool Server_Hello_12::supports_certificate_status_message() const { |
385 | 0 | return m_data->extensions().has<Certificate_Status_Request>(); |
386 | 0 | } |
387 | | |
388 | 732 | bool Server_Hello_12::supports_session_ticket() const { |
389 | 732 | return m_data->extensions().has<Session_Ticket_Extension>(); |
390 | 732 | } |
391 | | |
392 | 244 | uint16_t Server_Hello_12::srtp_profile() const { |
393 | 244 | if(auto srtp = m_data->extensions().get<SRTP_Protection_Profiles>()) { |
394 | 0 | auto prof = srtp->profiles(); |
395 | 0 | if(prof.size() != 1 || prof[0] == 0) { |
396 | 0 | throw Decoding_Error("Server sent malformed DTLS-SRTP extension"); |
397 | 0 | } |
398 | 0 | return prof[0]; |
399 | 0 | } |
400 | | |
401 | 244 | return 0; |
402 | 244 | } |
403 | | |
404 | 0 | std::string Server_Hello_12::next_protocol() const { |
405 | 0 | if(auto alpn = m_data->extensions().get<Application_Layer_Protocol_Notification>()) { |
406 | 0 | return alpn->single_protocol(); |
407 | 0 | } |
408 | 0 | return ""; |
409 | 0 | } |
410 | | |
411 | 0 | bool Server_Hello_12::prefers_compressed_ec_points() const { |
412 | 0 | if(auto ecc_formats = m_data->extensions().get<Supported_Point_Formats>()) { |
413 | 0 | return ecc_formats->prefers_compressed(); |
414 | 0 | } |
415 | 0 | return false; |
416 | 0 | } |
417 | | |
418 | 0 | std::optional<Protocol_Version> Server_Hello_12::random_signals_downgrade() const { |
419 | 0 | const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3); |
420 | 0 | if(last8 == DOWNGRADE_TLS11) { |
421 | 0 | return Protocol_Version::TLS_V11; |
422 | 0 | } |
423 | 0 | if(last8 == DOWNGRADE_TLS12) { |
424 | 0 | return Protocol_Version::TLS_V12; |
425 | 0 | } |
426 | | |
427 | 0 | return std::nullopt; |
428 | 0 | } |
429 | | |
430 | | /* |
431 | | * Create a new Server Hello Done message |
432 | | */ |
433 | 21.1k | Server_Hello_Done::Server_Hello_Done(Handshake_IO& io, Handshake_Hash& hash) { |
434 | 21.1k | hash.update(io.send(*this)); |
435 | 21.1k | } |
436 | | |
437 | | /* |
438 | | * Deserialize a Server Hello Done message |
439 | | */ |
440 | 0 | Server_Hello_Done::Server_Hello_Done(const std::vector<uint8_t>& buf) { |
441 | 0 | if(!buf.empty()) { |
442 | 0 | throw Decoding_Error("Server_Hello_Done: Must be empty, and is not"); |
443 | 0 | } |
444 | 0 | } |
445 | | |
446 | | /* |
447 | | * Serialize a Server Hello Done message |
448 | | */ |
449 | 21.1k | std::vector<uint8_t> Server_Hello_Done::serialize() const { |
450 | 21.1k | return std::vector<uint8_t>(); |
451 | 21.1k | } |
452 | | |
453 | | #if defined(BOTAN_HAS_TLS_13) |
454 | | |
455 | | const Server_Hello_13::Server_Hello_Tag Server_Hello_13::as_server_hello; |
456 | | const Server_Hello_13::Hello_Retry_Request_Tag Server_Hello_13::as_hello_retry_request; |
457 | | const Server_Hello_13::Hello_Retry_Request_Creation_Tag Server_Hello_13::as_new_hello_retry_request; |
458 | | |
459 | | std::variant<Hello_Retry_Request, Server_Hello_13> Server_Hello_13::create(const Client_Hello_13& ch, |
460 | | bool hello_retry_request_allowed, |
461 | | Session_Manager& session_mgr, |
462 | | Credentials_Manager& credentials_mgr, |
463 | | RandomNumberGenerator& rng, |
464 | | const Policy& policy, |
465 | 0 | Callbacks& cb) { |
466 | 0 | const auto& exts = ch.extensions(); |
467 | | |
468 | | // RFC 8446 4.2.9 |
469 | | // [With PSK with (EC)DHE key establishment], the client and server MUST |
470 | | // supply "key_share" values [...]. |
471 | | // |
472 | | // Note: We currently do not support PSK without (EC)DHE, hence, we can |
473 | | // assume that those extensions are available. |
474 | 0 | BOTAN_ASSERT_NOMSG(exts.has<Supported_Groups>() && exts.has<Key_Share>()); |
475 | 0 | const auto& supported_by_client = exts.get<Supported_Groups>()->groups(); |
476 | 0 | const auto& offered_by_client = exts.get<Key_Share>()->offered_groups(); |
477 | 0 | const auto selected_group = policy.choose_key_exchange_group(supported_by_client, offered_by_client); |
478 | | |
479 | | // RFC 8446 4.1.1 |
480 | | // If there is no overlap between the received "supported_groups" and the |
481 | | // groups supported by the server, then the server MUST abort the |
482 | | // handshake with a "handshake_failure" or an "insufficient_security" alert. |
483 | 0 | if(selected_group == Named_Group::NONE) { |
484 | 0 | throw TLS_Exception(Alert::HandshakeFailure, "Client did not offer any acceptable group"); |
485 | 0 | } |
486 | | |
487 | | // RFC 8446 4.2.8: |
488 | | // Servers MUST NOT send a KeyShareEntry for any group not indicated in the |
489 | | // client's "supported_groups" extension [...] |
490 | 0 | if(!value_exists(supported_by_client, selected_group)) { |
491 | 0 | throw TLS_Exception(Alert::InternalError, "Application selected a group that is not supported by the client"); |
492 | 0 | } |
493 | | |
494 | | // RFC 8446 4.1.4 |
495 | | // The server will send this message in response to a ClientHello |
496 | | // message if it is able to find an acceptable set of parameters but the |
497 | | // ClientHello does not contain sufficient information to proceed with |
498 | | // the handshake. |
499 | | // |
500 | | // In this case, the Client Hello did not contain a key share offer for |
501 | | // the group selected by the application. |
502 | 0 | if(!value_exists(offered_by_client, selected_group)) { |
503 | | // RFC 8446 4.1.4 |
504 | | // If a client receives a second HelloRetryRequest in the same |
505 | | // connection (i.e., where the ClientHello was itself in response to a |
506 | | // HelloRetryRequest), it MUST abort the handshake with an |
507 | | // "unexpected_message" alert. |
508 | 0 | BOTAN_STATE_CHECK(hello_retry_request_allowed); |
509 | 0 | return Hello_Retry_Request(ch, selected_group, policy, cb); |
510 | 0 | } else { |
511 | 0 | return Server_Hello_13(ch, selected_group, session_mgr, credentials_mgr, rng, cb, policy); |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | | std::variant<Hello_Retry_Request, Server_Hello_13, Server_Hello_12> Server_Hello_13::parse( |
516 | 5.01k | const std::vector<uint8_t>& buf) { |
517 | 5.01k | auto data = std::make_unique<Server_Hello_Internal>(buf); |
518 | 5.01k | const auto version = data->version(); |
519 | | |
520 | | // server hello that appears to be pre-TLS 1.3, takes precedence over... |
521 | 5.01k | if(version.is_pre_tls_13()) { |
522 | 4.51k | return Server_Hello_12(std::move(data)); |
523 | 4.51k | } |
524 | | |
525 | | // ... the TLS 1.3 "special case" aka. Hello_Retry_Request |
526 | 493 | if(version == Protocol_Version::TLS_V13) { |
527 | 300 | if(data->is_hello_retry_request()) { |
528 | 0 | return Hello_Retry_Request(std::move(data)); |
529 | 0 | } |
530 | | |
531 | 300 | return Server_Hello_13(std::move(data)); |
532 | 300 | } |
533 | | |
534 | 193 | throw TLS_Exception(Alert::ProtocolVersion, "unexpected server hello version: " + version.to_string()); |
535 | 493 | } |
536 | | |
537 | | /** |
538 | | * Validation that applies to both Server Hello and Hello Retry Request |
539 | | */ |
540 | 300 | void Server_Hello_13::basic_validation() const { |
541 | 300 | BOTAN_ASSERT_NOMSG(m_data->version() == Protocol_Version::TLS_V13); |
542 | | |
543 | | // Note: checks that cannot be performed without contextual information |
544 | | // are done in the specific TLS client implementation. |
545 | | // Note: The Supported_Version extension makes sure internally that |
546 | | // exactly one entry is provided. |
547 | | |
548 | | // Note: Hello Retry Request basic validation is equivalent with the |
549 | | // basic validations required for Server Hello |
550 | | // |
551 | | // RFC 8446 4.1.4 |
552 | | // Upon receipt of a HelloRetryRequest, the client MUST check the |
553 | | // legacy_version, [...], and legacy_compression_method as specified in |
554 | | // Section 4.1.3 and then process the extensions, starting with determining |
555 | | // the version using "supported_versions". |
556 | | |
557 | | // RFC 8446 4.1.3 |
558 | | // In TLS 1.3, [...] the legacy_version field MUST be set to 0x0303 |
559 | 300 | if(legacy_version() != Protocol_Version::TLS_V12) { |
560 | 49 | throw TLS_Exception(Alert::ProtocolVersion, |
561 | 49 | "legacy_version '" + legacy_version().to_string() + "' is not allowed"); |
562 | 49 | } |
563 | | |
564 | | // RFC 8446 4.1.3 |
565 | | // legacy_compression_method: A single byte which MUST have the value 0. |
566 | 251 | if(compression_method() != 0x00) { |
567 | 4 | throw TLS_Exception(Alert::DecodeError, "compression is not supported in TLS 1.3"); |
568 | 4 | } |
569 | | |
570 | | // RFC 8446 4.1.3 |
571 | | // All TLS 1.3 ServerHello messages MUST contain the "supported_versions" extension. |
572 | 247 | if(!extensions().has<Supported_Versions>()) { |
573 | 0 | throw TLS_Exception(Alert::MissingExtension, "server hello did not contain 'supported version' extension"); |
574 | 0 | } |
575 | | |
576 | | // RFC 8446 4.2.1 |
577 | | // A server which negotiates TLS 1.3 MUST respond by sending |
578 | | // a "supported_versions" extension containing the selected version |
579 | | // value (0x0304). |
580 | 247 | if(selected_version() != Protocol_Version::TLS_V13) { |
581 | 29 | throw TLS_Exception(Alert::IllegalParameter, "TLS 1.3 Server Hello selected a different version"); |
582 | 29 | } |
583 | 247 | } |
584 | | |
585 | | Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Server_Hello_13::Server_Hello_Tag) : |
586 | 300 | Server_Hello(std::move(data)) { |
587 | 300 | BOTAN_ASSERT_NOMSG(!m_data->is_hello_retry_request()); |
588 | 300 | basic_validation(); |
589 | | |
590 | 300 | const auto& exts = extensions(); |
591 | | |
592 | | // RFC 8446 4.1.3 |
593 | | // The ServerHello MUST only include extensions which are required to |
594 | | // establish the cryptographic context and negotiate the protocol version. |
595 | | // [...] |
596 | | // Other extensions (see Section 4.2) are sent separately in the |
597 | | // EncryptedExtensions message. |
598 | | // |
599 | | // Note that further validation dependent on the client hello is done in the |
600 | | // TLS client implementation. |
601 | 300 | const std::set<Extension_Code> allowed = { |
602 | 300 | Extension_Code::KeyShare, |
603 | 300 | Extension_Code::SupportedVersions, |
604 | 300 | Extension_Code::PresharedKey, |
605 | 300 | }; |
606 | | |
607 | | // As the ServerHello shall only contain essential extensions, we don't give |
608 | | // any slack for extensions not implemented by Botan here. |
609 | 300 | if(exts.contains_other_than(allowed)) { |
610 | 28 | throw TLS_Exception(Alert::UnsupportedExtension, "Server Hello contained an extension that is not allowed"); |
611 | 28 | } |
612 | | |
613 | | // RFC 8446 4.1.3 |
614 | | // Current ServerHello messages additionally contain |
615 | | // either the "pre_shared_key" extension or the "key_share" |
616 | | // extension, or both [...]. |
617 | 272 | if(!exts.has<Key_Share>() && !exts.has<PSK_Key_Exchange_Modes>()) { |
618 | 7 | throw TLS_Exception(Alert::MissingExtension, "server hello must contain key exchange information"); |
619 | 7 | } |
620 | 272 | } |
621 | | |
622 | | Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, |
623 | | Server_Hello_13::Hello_Retry_Request_Tag) : |
624 | 0 | Server_Hello(std::move(data)) { |
625 | 0 | BOTAN_ASSERT_NOMSG(m_data->is_hello_retry_request()); |
626 | 0 | basic_validation(); |
627 | |
|
628 | 0 | const auto& exts = extensions(); |
629 | | |
630 | | // RFC 8446 4.1.4 |
631 | | // The HelloRetryRequest extensions defined in this specification are: |
632 | | // - supported_versions (see Section 4.2.1) |
633 | | // - cookie (see Section 4.2.2) |
634 | | // - key_share (see Section 4.2.8) |
635 | 0 | const std::set<Extension_Code> allowed = { |
636 | 0 | Extension_Code::Cookie, |
637 | 0 | Extension_Code::SupportedVersions, |
638 | 0 | Extension_Code::KeyShare, |
639 | 0 | }; |
640 | | |
641 | | // As the Hello Retry Request shall only contain essential extensions, we |
642 | | // don't give any slack for extensions not implemented by Botan here. |
643 | 0 | if(exts.contains_other_than(allowed)) { |
644 | 0 | throw TLS_Exception(Alert::UnsupportedExtension, |
645 | 0 | "Hello Retry Request contained an extension that is not allowed"); |
646 | 0 | } |
647 | | |
648 | | // RFC 8446 4.1.4 |
649 | | // Clients MUST abort the handshake with an "illegal_parameter" alert if |
650 | | // the HelloRetryRequest would not result in any change in the ClientHello. |
651 | 0 | if(!exts.has<Key_Share>() && !exts.has<Cookie>()) { |
652 | 0 | throw TLS_Exception(Alert::IllegalParameter, "Hello Retry Request does not request any changes to Client Hello"); |
653 | 0 | } |
654 | 0 | } |
655 | | |
656 | | Server_Hello_13::Server_Hello_13(std::unique_ptr<Server_Hello_Internal> data, Hello_Retry_Request_Creation_Tag) : |
657 | 0 | Server_Hello(std::move(data)) {} |
658 | | |
659 | | namespace { |
660 | | |
661 | 0 | uint16_t choose_ciphersuite(const Client_Hello_13& ch, const Policy& policy) { |
662 | 0 | auto pref_list = ch.ciphersuites(); |
663 | | // TODO: DTLS might need to make this version dynamic |
664 | 0 | auto other_list = policy.ciphersuite_list(Protocol_Version::TLS_V13); |
665 | |
|
666 | 0 | if(policy.server_uses_own_ciphersuite_preferences()) { |
667 | 0 | std::swap(pref_list, other_list); |
668 | 0 | } |
669 | |
|
670 | 0 | for(auto suite_id : pref_list) { |
671 | | // TODO: take potentially available PSKs into account to select a |
672 | | // compatible ciphersuite. |
673 | | // |
674 | | // Assuming the client sent one or more PSKs, we would first need to find |
675 | | // the hash functions they are associated to. For session tickets, that |
676 | | // would mean decrypting the ticket and comparing the cipher suite used in |
677 | | // those tickets. For (currently not yet supported) pre-assigned PSKs, the |
678 | | // hash function needs to be specified along with them. |
679 | | // |
680 | | // Then we could refine the ciphersuite selection using the required hash |
681 | | // function for the PSK(s) we are wishing to use down the road. |
682 | | // |
683 | | // For now, we just negotiate the cipher suite blindly and hope for the |
684 | | // best. As long as PSKs are used for session resumption only, this has a |
685 | | // high chance of success. Previous handshakes with this client have very |
686 | | // likely selected the same ciphersuite anyway. |
687 | | // |
688 | | // See also RFC 8446 4.2.11 |
689 | | // When session resumption is the primary use case of PSKs, the most |
690 | | // straightforward way to implement the PSK/cipher suite matching |
691 | | // requirements is to negotiate the cipher suite first [...]. |
692 | 0 | if(value_exists(other_list, suite_id)) { |
693 | 0 | return suite_id; |
694 | 0 | } |
695 | 0 | } |
696 | | |
697 | | // RFC 8446 4.1.1 |
698 | | // If the server is unable to negotiate a supported set of parameters |
699 | | // [...], it MUST abort the handshake with either a "handshake_failure" |
700 | | // or "insufficient_security" fatal alert [...]. |
701 | 0 | throw TLS_Exception(Alert::HandshakeFailure, "Can't agree on a ciphersuite with client"); |
702 | 0 | } |
703 | | } // namespace |
704 | | |
705 | | Server_Hello_13::Server_Hello_13(const Client_Hello_13& ch, |
706 | | std::optional<Named_Group> key_exchange_group, |
707 | | Session_Manager& session_mgr, |
708 | | Credentials_Manager& credentials_mgr, |
709 | | RandomNumberGenerator& rng, |
710 | | Callbacks& cb, |
711 | | const Policy& policy) : |
712 | 0 | Server_Hello(std::make_unique<Server_Hello_Internal>( |
713 | 0 | Protocol_Version::TLS_V12, |
714 | 0 | ch.session_id(), |
715 | 0 | make_server_hello_random(rng, Protocol_Version::TLS_V13, cb, policy), |
716 | 0 | choose_ciphersuite(ch, policy), |
717 | 0 | uint8_t(0) /* compression method */ |
718 | 0 | )) { |
719 | | // RFC 8446 4.2.1 |
720 | | // A server which negotiates TLS 1.3 MUST respond by sending a |
721 | | // "supported_versions" extension containing the selected version |
722 | | // value (0x0304). It MUST set the ServerHello.legacy_version field to |
723 | | // 0x0303 (TLS 1.2). |
724 | | // |
725 | | // Note that the legacy version (TLS 1.2) is set in this constructor's |
726 | | // initializer list, accordingly. |
727 | 0 | m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13)); |
728 | |
|
729 | 0 | if(key_exchange_group.has_value()) { |
730 | 0 | BOTAN_ASSERT_NOMSG(ch.extensions().has<Key_Share>()); |
731 | 0 | m_data->extensions().add(Key_Share::create_as_encapsulation( |
732 | 0 | key_exchange_group.value(), *ch.extensions().get<Key_Share>(), policy, cb, rng)); |
733 | 0 | } |
734 | |
|
735 | 0 | auto& ch_exts = ch.extensions(); |
736 | |
|
737 | 0 | if(ch_exts.has<PSK>()) { |
738 | 0 | const auto cs = Ciphersuite::by_id(m_data->ciphersuite()); |
739 | 0 | BOTAN_ASSERT_NOMSG(cs); |
740 | | |
741 | | // RFC 8446 4.2.9 |
742 | | // A client MUST provide a "psk_key_exchange_modes" extension if it |
743 | | // offers a "pre_shared_key" extension. |
744 | | // |
745 | | // Note: Client_Hello_13 constructor already performed a graceful check. |
746 | 0 | const auto psk_modes = ch_exts.get<PSK_Key_Exchange_Modes>(); |
747 | 0 | BOTAN_ASSERT_NONNULL(psk_modes); |
748 | | |
749 | | // TODO: also support PSK_Key_Exchange_Mode::PSK_KE |
750 | | // (PSK-based handshake without an additional ephemeral key exchange) |
751 | 0 | if(value_exists(psk_modes->modes(), PSK_Key_Exchange_Mode::PSK_DHE_KE)) { |
752 | 0 | if(auto server_psk = ch_exts.get<PSK>()->select_offered_psk( |
753 | 0 | ch.sni_hostname(), cs.value(), session_mgr, credentials_mgr, cb, policy)) { |
754 | | // RFC 8446 4.2.11 |
755 | | // In order to accept PSK key establishment, the server sends a |
756 | | // "pre_shared_key" extension indicating the selected identity. |
757 | 0 | m_data->extensions().add(std::move(server_psk)); |
758 | 0 | } |
759 | 0 | } |
760 | 0 | } |
761 | |
|
762 | 0 | cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type()); |
763 | 0 | } |
764 | | |
765 | 0 | std::optional<Protocol_Version> Server_Hello_13::random_signals_downgrade() const { |
766 | 0 | const uint64_t last8 = load_be<uint64_t>(m_data->random().data(), 3); |
767 | 0 | if(last8 == DOWNGRADE_TLS11) { |
768 | 0 | return Protocol_Version::TLS_V11; |
769 | 0 | } |
770 | 0 | if(last8 == DOWNGRADE_TLS12) { |
771 | 0 | return Protocol_Version::TLS_V12; |
772 | 0 | } |
773 | | |
774 | 0 | return std::nullopt; |
775 | 0 | } |
776 | | |
777 | 247 | Protocol_Version Server_Hello_13::selected_version() const { |
778 | 247 | const auto versions_ext = m_data->extensions().get<Supported_Versions>(); |
779 | 247 | BOTAN_ASSERT_NOMSG(versions_ext); |
780 | 247 | const auto& versions = versions_ext->versions(); |
781 | 247 | BOTAN_ASSERT_NOMSG(versions.size() == 1); |
782 | 247 | return versions.front(); |
783 | 247 | } |
784 | | |
785 | | Hello_Retry_Request::Hello_Retry_Request(std::unique_ptr<Server_Hello_Internal> data) : |
786 | 0 | Server_Hello_13(std::move(data), Server_Hello_13::as_hello_retry_request) {} |
787 | | |
788 | | Hello_Retry_Request::Hello_Retry_Request(const Client_Hello_13& ch, |
789 | | Named_Group selected_group, |
790 | | const Policy& policy, |
791 | | Callbacks& cb) : |
792 | 0 | Server_Hello_13(std::make_unique<Server_Hello_Internal>(Protocol_Version::TLS_V12 /* legacy_version */, |
793 | 0 | ch.session_id(), |
794 | 0 | HELLO_RETRY_REQUEST_MARKER, |
795 | 0 | choose_ciphersuite(ch, policy), |
796 | 0 | uint8_t(0) /* compression method */, |
797 | 0 | true /* is Hello Retry Request */ |
798 | 0 | ), |
799 | 0 | as_new_hello_retry_request) { |
800 | | // RFC 8446 4.1.4 |
801 | | // As with the ServerHello, a HelloRetryRequest MUST NOT contain any |
802 | | // extensions that were not first offered by the client in its |
803 | | // ClientHello, with the exception of optionally the "cookie" [...] |
804 | | // extension. |
805 | 0 | BOTAN_STATE_CHECK(ch.extensions().has<Supported_Groups>()); |
806 | 0 | BOTAN_STATE_CHECK(ch.extensions().has<Key_Share>()); |
807 | |
|
808 | 0 | BOTAN_STATE_CHECK(!value_exists(ch.extensions().get<Key_Share>()->offered_groups(), selected_group)); |
809 | | |
810 | | // RFC 8446 4.1.4 |
811 | | // The server's extensions MUST contain "supported_versions". |
812 | | // |
813 | | // RFC 8446 4.2.1 |
814 | | // A server which negotiates TLS 1.3 MUST respond by sending a |
815 | | // "supported_versions" extension containing the selected version |
816 | | // value (0x0304). It MUST set the ServerHello.legacy_version field to |
817 | | // 0x0303 (TLS 1.2). |
818 | | // |
819 | | // Note that the legacy version (TLS 1.2) is set in this constructor's |
820 | | // initializer list, accordingly. |
821 | 0 | m_data->extensions().add(new Supported_Versions(Protocol_Version::TLS_V13)); |
822 | |
|
823 | 0 | m_data->extensions().add(new Key_Share(selected_group)); |
824 | |
|
825 | 0 | cb.tls_modify_extensions(m_data->extensions(), Connection_Side::Server, type()); |
826 | 0 | } |
827 | | |
828 | | #endif // BOTAN_HAS_TLS_13 |
829 | | |
830 | | } // namespace Botan::TLS |