Branch data Line data Source code
1 : : /*
2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License").
5 : : * You may not use this file except in compliance with the License.
6 : : * A copy of the License is located at
7 : : *
8 : : * http://aws.amazon.com/apache2.0
9 : : *
10 : : * or in the "license" file accompanying this file. This file is distributed
11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 : : * express or implied. See the License for the specific language governing
13 : : * permissions and limitations under the License.
14 : : */
15 : :
16 : : #include "tls/s2n_client_hello.h"
17 : :
18 : : #include <stdint.h>
19 : : #include <stdlib.h>
20 : : #include <sys/param.h>
21 : : #include <time.h>
22 : :
23 : : #include "api/unstable/fingerprint.h"
24 : : #include "crypto/s2n_fips.h"
25 : : #include "crypto/s2n_hash.h"
26 : : #include "crypto/s2n_pq.h"
27 : : #include "error/s2n_errno.h"
28 : : #include "stuffer/s2n_stuffer.h"
29 : : #include "tls/extensions/s2n_client_server_name.h"
30 : : #include "tls/extensions/s2n_client_supported_groups.h"
31 : : #include "tls/extensions/s2n_extension_list.h"
32 : : #include "tls/extensions/s2n_server_key_share.h"
33 : : #include "tls/s2n_alerts.h"
34 : : #include "tls/s2n_auth_selection.h"
35 : : #include "tls/s2n_cipher_preferences.h"
36 : : #include "tls/s2n_cipher_suites.h"
37 : : #include "tls/s2n_connection.h"
38 : : #include "tls/s2n_handshake_type.h"
39 : : #include "tls/s2n_security_policies.h"
40 : : #include "tls/s2n_signature_algorithms.h"
41 : : #include "tls/s2n_tls.h"
42 : : #include "utils/s2n_bitmap.h"
43 : : #include "utils/s2n_random.h"
44 : : #include "utils/s2n_safety.h"
45 : :
46 : : struct s2n_client_hello *s2n_connection_get_client_hello(struct s2n_connection *conn)
47 : 175 : {
48 [ + + ]: 175 : if (conn->client_hello.parsed != 1) {
49 : 3 : return NULL;
50 : 3 : }
51 : :
52 : 172 : return &conn->client_hello;
53 : 175 : }
54 : :
55 : : static uint32_t min_size(struct s2n_blob *blob, uint32_t max_length)
56 : 44 : {
57 [ + + ]: 44 : return blob->size < max_length ? blob->size : max_length;
58 : 44 : }
59 : :
60 : : static S2N_RESULT s2n_generate_client_session_id(struct s2n_connection *conn)
61 : 7771 : {
62 [ # # ][ - + ]: 7771 : RESULT_ENSURE_REF(conn);
63 [ - + ][ # # ]: 7771 : RESULT_ENSURE_REF(conn->config);
64 : :
65 : : /* Session id already generated - no-op */
66 [ + + ]: 7771 : if (conn->session_id_len) {
67 : 671 : return S2N_RESULT_OK;
68 : 671 : }
69 : :
70 : : /* Only generate the session id if using tickets */
71 : 7100 : bool generate = conn->config->use_tickets;
72 : :
73 : : /* TLS1.3 doesn't require session ids. The field is actually renamed to legacy_session_id.
74 : : * However, we still set a session id if dealing with troublesome middleboxes
75 : : * (middlebox compatibility mode) or if trying to use a TLS1.2 ticket.
76 : : */
77 [ + + ]: 7100 : if (conn->client_protocol_version >= S2N_TLS13) {
78 [ + + ][ + + ]: 5239 : generate = s2n_is_middlebox_compat_enabled(conn) || conn->resume_protocol_version;
79 : 5239 : }
80 : :
81 : : /* Session id not needed - no-op */
82 [ + + ]: 7100 : if (!generate) {
83 : 2061 : return S2N_RESULT_OK;
84 : 2061 : }
85 : :
86 : : /* QUIC should not allow session ids for any reason.
87 : : *
88 : : *= https://www.rfc-editor.org/rfc/rfc9001#section-8.4
89 : : *# A server SHOULD treat the receipt of a TLS ClientHello with a non-empty
90 : : *# legacy_session_id field as a connection error of type PROTOCOL_VIOLATION.
91 : : */
92 [ + - ][ + + ]: 5039 : RESULT_ENSURE(!conn->quic_enabled, S2N_ERR_UNSUPPORTED_WITH_QUIC);
93 : :
94 : 5038 : struct s2n_blob session_id = { 0 };
95 [ - + ]: 5038 : RESULT_GUARD_POSIX(s2n_blob_init(&session_id, conn->session_id, S2N_TLS_SESSION_ID_MAX_LEN));
96 [ - + ]: 5038 : RESULT_GUARD(s2n_get_public_random_data(&session_id));
97 : 5038 : conn->session_id_len = S2N_TLS_SESSION_ID_MAX_LEN;
98 : 5038 : return S2N_RESULT_OK;
99 : 5038 : }
100 : :
101 : : ssize_t s2n_client_hello_get_raw_message_length(struct s2n_client_hello *ch)
102 : 3 : {
103 [ + - ][ + + ]: 3 : POSIX_ENSURE_REF(ch);
104 : :
105 : 2 : return ch->raw_message.size;
106 : 3 : }
107 : :
108 : : ssize_t s2n_client_hello_get_raw_message(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
109 : 3 : {
110 [ + + ][ + - ]: 3 : POSIX_ENSURE_REF(ch);
111 [ - + ][ # # ]: 2 : POSIX_ENSURE_REF(out);
112 : :
113 : 2 : uint32_t len = min_size(&ch->raw_message, max_length);
114 [ # # ][ - + ]: 2 : POSIX_CHECKED_MEMCPY(out, ch->raw_message.data, len);
[ + - ]
115 : 2 : return len;
116 : 2 : }
117 : :
118 : : ssize_t s2n_client_hello_get_cipher_suites_length(struct s2n_client_hello *ch)
119 : 3 : {
120 [ + + ][ + - ]: 3 : POSIX_ENSURE_REF(ch);
121 : :
122 : 2 : return ch->cipher_suites.size;
123 : 3 : }
124 : :
125 : : int s2n_client_hello_cb_done(struct s2n_connection *conn)
126 : 28 : {
127 [ - + ][ # # ]: 28 : POSIX_ENSURE_REF(conn);
128 [ - + ][ # # ]: 28 : POSIX_ENSURE_REF(conn->config);
129 [ # # ][ - + ]: 28 : POSIX_ENSURE(conn->config->client_hello_cb_mode == S2N_CLIENT_HELLO_CB_NONBLOCKING, S2N_ERR_INVALID_STATE);
130 [ - + ][ # # ]: 28 : POSIX_ENSURE(conn->client_hello.callback_invoked == 1, S2N_ERR_ASYNC_NOT_PERFORMED);
131 [ - + ][ # # ]: 28 : POSIX_ENSURE(conn->client_hello.parsed == 1, S2N_ERR_INVALID_STATE);
132 : :
133 : 28 : conn->client_hello.callback_async_blocked = 0;
134 : 28 : conn->client_hello.callback_async_done = 1;
135 : :
136 : 28 : return S2N_SUCCESS;
137 : 28 : }
138 : :
139 : : ssize_t s2n_client_hello_get_cipher_suites(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
140 : 3 : {
141 [ + - ][ + + ]: 3 : POSIX_ENSURE_REF(ch);
142 [ - + ][ # # ]: 2 : POSIX_ENSURE_REF(out);
143 [ - + ][ # # ]: 2 : POSIX_ENSURE_REF(ch->cipher_suites.data);
144 : :
145 : 2 : uint32_t len = min_size(&ch->cipher_suites, max_length);
146 : :
147 [ # # ][ - + ]: 2 : POSIX_CHECKED_MEMCPY(out, ch->cipher_suites.data, len);
[ + - ]
148 : :
149 : 2 : return len;
150 : 2 : }
151 : :
152 : : ssize_t s2n_client_hello_get_extensions_length(struct s2n_client_hello *ch)
153 : 3 : {
154 [ + + ][ + - ]: 3 : POSIX_ENSURE_REF(ch);
155 : :
156 : 2 : return ch->extensions.raw.size;
157 : 3 : }
158 : :
159 : : ssize_t s2n_client_hello_get_extensions(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
160 : 3 : {
161 [ + + ][ + - ]: 3 : POSIX_ENSURE_REF(ch);
162 [ - + ][ # # ]: 2 : POSIX_ENSURE_REF(out);
163 [ # # ][ - + ]: 2 : POSIX_ENSURE_REF(ch->extensions.raw.data);
164 : :
165 : 2 : uint32_t len = min_size(&ch->extensions.raw, max_length);
166 : :
167 [ - + ][ # # ]: 2 : POSIX_CHECKED_MEMCPY(out, ch->extensions.raw.data, len);
[ + - ]
168 : :
169 : 2 : return len;
170 : 2 : }
171 : :
172 : : int s2n_client_hello_get_random(struct s2n_client_hello *ch, uint8_t *out, uint32_t max_length)
173 : 5 : {
174 [ + + ][ + - ]: 5 : POSIX_ENSURE_REF(ch);
175 [ + + ][ + - ]: 4 : POSIX_ENSURE_REF(out);
176 : :
177 [ + + ][ + - ]: 3 : POSIX_ENSURE(max_length >= S2N_TLS_RANDOM_DATA_LEN, S2N_ERR_INSUFFICIENT_MEM_SIZE);
178 [ - + ][ # # ]: 2 : POSIX_CHECKED_MEMCPY(out, ch->random, S2N_TLS_RANDOM_DATA_LEN);
[ + - ]
179 : 2 : return S2N_SUCCESS;
180 : 2 : }
181 : :
182 : : int s2n_client_hello_free_raw_message(struct s2n_client_hello *client_hello)
183 : 134737 : {
184 [ - + ][ # # ]: 134737 : POSIX_ENSURE_REF(client_hello);
185 : :
186 [ - + ]: 134737 : POSIX_GUARD(s2n_free(&client_hello->raw_message));
187 : :
188 : : /* These point to data in the raw_message stuffer,
189 : : so we don't need to free them */
190 : 134737 : client_hello->cipher_suites.data = NULL;
191 : 134737 : client_hello->extensions.raw.data = NULL;
192 : :
193 : 134737 : return 0;
194 : 134737 : }
195 : :
196 : : int s2n_client_hello_free(struct s2n_client_hello **ch)
197 : 196 : {
198 [ + + ][ + - ]: 196 : POSIX_ENSURE_REF(ch);
199 [ + + ]: 195 : if (*ch == NULL) {
200 : 89 : return S2N_SUCCESS;
201 : 89 : }
202 : :
203 [ + - ][ + + ]: 106 : POSIX_ENSURE((*ch)->alloced, S2N_ERR_INVALID_ARGUMENT);
204 [ - + ]: 94 : POSIX_GUARD(s2n_client_hello_free_raw_message(*ch));
205 [ - + ]: 94 : POSIX_GUARD(s2n_free_object((uint8_t **) ch, sizeof(struct s2n_client_hello)));
206 : 94 : *ch = NULL;
207 : 94 : return S2N_SUCCESS;
208 : 94 : }
209 : :
210 : : int s2n_collect_client_hello(struct s2n_client_hello *ch, struct s2n_stuffer *source)
211 : 7915 : {
212 [ - + ][ # # ]: 7915 : POSIX_ENSURE_REF(ch);
213 [ # # ][ - + ]: 7915 : POSIX_ENSURE_REF(source);
214 : :
215 : 7915 : uint32_t size = s2n_stuffer_data_available(source);
216 [ - + ][ # # ]: 7915 : S2N_ERROR_IF(size == 0, S2N_ERR_BAD_MESSAGE);
217 : :
218 [ - + ]: 7915 : POSIX_GUARD(s2n_realloc(&ch->raw_message, size));
219 [ - + ]: 7915 : POSIX_GUARD(s2n_stuffer_read(source, &ch->raw_message));
220 : :
221 : 7915 : return 0;
222 : 7915 : }
223 : :
224 : : static S2N_RESULT s2n_client_hello_verify_for_retry(struct s2n_connection *conn,
225 : : struct s2n_client_hello *old_ch, struct s2n_client_hello *new_ch,
226 : : uint8_t *previous_client_random)
227 : 7816 : {
228 [ - + ][ # # ]: 7816 : RESULT_ENSURE_REF(conn);
229 [ # # ][ - + ]: 7816 : RESULT_ENSURE_REF(old_ch);
230 [ - + ][ # # ]: 7816 : RESULT_ENSURE_REF(new_ch);
231 [ # # ][ - + ]: 7816 : RESULT_ENSURE_REF(previous_client_random);
232 : :
233 [ + + ]: 7816 : if (!s2n_is_hello_retry_handshake(conn)) {
234 : 7157 : return S2N_RESULT_OK;
235 : 7157 : }
236 : :
237 : : /*
238 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2
239 : : *# The client will also send a
240 : : *# ClientHello when the server has responded to its ClientHello with a
241 : : *# HelloRetryRequest. In that case, the client MUST send the same
242 : : *# ClientHello without modification, except as follows:
243 : : *
244 : : * All of the exceptions that follow are extensions.
245 : : */
246 [ + - ][ + + ]: 659 : RESULT_ENSURE(old_ch->legacy_version == new_ch->legacy_version, S2N_ERR_BAD_MESSAGE);
247 [ - + ][ # # ]: 658 : RESULT_ENSURE(old_ch->compression_methods.size == new_ch->compression_methods.size, S2N_ERR_BAD_MESSAGE);
248 [ + - ][ + + ]: 658 : RESULT_ENSURE(s2n_constant_time_equals(old_ch->compression_methods.data, new_ch->compression_methods.data,
249 : 657 : new_ch->compression_methods.size),
250 : 657 : S2N_ERR_BAD_MESSAGE);
251 : :
252 : : /* Some clients are not compliant with TLS 1.3 RFC, and send mismatching values in their second
253 : : * ClientHello. For increased compatibility, these checks are skipped outside of tests. The
254 : : * checks are still included in tests to ensure the s2n-tls client remains compliant.
255 : : */
256 [ + + ]: 657 : if (s2n_in_test()) {
257 : : /* In the past, the s2n-tls client updated the client random in the second ClientHello
258 : : * which is not allowed by RFC8446: https://github.com/aws/s2n-tls/pull/3311. Although the
259 : : * issue was addressed, its existence means that old versions of the s2n-tls client will
260 : : * fail this validation.
261 : : */
262 [ + + ][ + - ]: 653 : RESULT_ENSURE(s2n_constant_time_equals(
263 : 652 : previous_client_random,
264 : 652 : conn->client_hello.random,
265 : 652 : S2N_TLS_RANDOM_DATA_LEN),
266 : 652 : S2N_ERR_BAD_MESSAGE);
267 : :
268 : : /* Some clients have been found to send a mismatching legacy session ID. */
269 [ # # ][ - + ]: 652 : RESULT_ENSURE(old_ch->session_id.size == new_ch->session_id.size, S2N_ERR_BAD_MESSAGE);
270 [ + + ][ + - ]: 652 : RESULT_ENSURE(s2n_constant_time_equals(old_ch->session_id.data, new_ch->session_id.data,
271 : 651 : new_ch->session_id.size),
272 : 651 : S2N_ERR_BAD_MESSAGE);
273 : :
274 : : /* Some clients have been found to send a mismatching cipher suite list. */
275 [ # # ][ - + ]: 651 : RESULT_ENSURE(old_ch->cipher_suites.size == new_ch->cipher_suites.size, S2N_ERR_BAD_MESSAGE);
276 [ + - ][ + + ]: 651 : RESULT_ENSURE(s2n_constant_time_equals(old_ch->cipher_suites.data, new_ch->cipher_suites.data,
277 : 651 : new_ch->cipher_suites.size),
278 : 651 : S2N_ERR_BAD_MESSAGE);
279 : 651 : }
280 : :
281 : : /*
282 : : * Now enforce that the extensions also exactly match,
283 : : * except for the exceptions described in the RFC.
284 : : */
285 [ + + ]: 14331 : for (size_t i = 0; i < s2n_array_len(s2n_supported_extensions); i++) {
286 : 13680 : s2n_parsed_extension *old_extension = &old_ch->extensions.parsed_extensions[i];
287 : 13680 : uint32_t old_size = old_extension->extension.size;
288 : 13680 : s2n_parsed_extension *new_extension = &new_ch->extensions.parsed_extensions[i];
289 : 13680 : uint32_t new_size = new_extension->extension.size;
290 : :
291 : : /* The extension type is only set if the extension is present.
292 : : * Look for a non-zero-length extension.
293 : : */
294 : 13680 : uint16_t extension_type = 0;
295 [ + + ]: 13680 : if (old_size != 0) {
296 : 4199 : extension_type = old_extension->extension_type;
297 [ + + ]: 9481 : } else if (new_size != 0) {
298 : 38 : extension_type = new_extension->extension_type;
299 : 9443 : } else {
300 : 9443 : continue;
301 : 9443 : }
302 : :
303 : 4237 : switch (extension_type) {
304 : : /*
305 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2
306 : : *# - If a "key_share" extension was supplied in the HelloRetryRequest,
307 : : *# replacing the list of shares with a list containing a single
308 : : *# KeyShareEntry from the indicated group.
309 : : */
310 [ + + ]: 651 : case TLS_EXTENSION_KEY_SHARE:
311 : : /* Handled when parsing the key share extension */
312 : 651 : break;
313 : : /*
314 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2
315 : : *# - Removing the "early_data" extension (Section 4.2.10) if one was
316 : : *# present. Early data is not permitted after a HelloRetryRequest.
317 : : */
318 [ - + ]: 0 : case TLS_EXTENSION_EARLY_DATA:
319 [ # # ][ # # ]: 0 : RESULT_ENSURE(new_size == 0, S2N_ERR_BAD_MESSAGE);
320 : 0 : break;
321 : : /*
322 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2
323 : : *# - Including a "cookie" extension if one was provided in the
324 : : *# HelloRetryRequest.
325 : : */
326 [ + + ]: 37 : case TLS_EXTENSION_COOKIE:
327 : : /* Handled when parsing the cookie extension */
328 : 37 : break;
329 : : /*
330 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.1.2
331 : : *# - Updating the "pre_shared_key" extension if present by recomputing
332 : : *# the "obfuscated_ticket_age" and binder values and (optionally)
333 : : *# removing any PSKs which are incompatible with the server's
334 : : *# indicated cipher suite.
335 : : */
336 [ + + ]: 462 : case TLS_EXTENSION_PRE_SHARED_KEY:
337 : : /* Handled when parsing the psk extension */
338 : 462 : break;
339 : :
340 : : /* Some clients have been found to send mismatching supported versions in their second
341 : : * ClientHello. The extension isn't compared byte-for-byte for increased compatibility
342 : : * with these clients.
343 : : */
344 [ + + ]: 651 : case TLS_EXTENSION_SUPPORTED_VERSIONS:
345 : : /* Additional HRR validation for the supported versions extension is performed when
346 : : * parsing the extension.
347 : : */
348 : 651 : break;
349 : :
350 : : /*
351 : : * No more exceptions.
352 : : * All other extensions must match.
353 : : */
354 [ + + ]: 2436 : default:
355 [ + - ][ + + ]: 2436 : RESULT_ENSURE(old_size == new_size, S2N_ERR_BAD_MESSAGE);
356 [ + - ][ + + ]: 4237 : RESULT_ENSURE(s2n_constant_time_equals(
357 : 4237 : new_extension->extension.data,
358 : 4237 : old_extension->extension.data,
359 : 4237 : old_size),
360 : 4237 : S2N_ERR_BAD_MESSAGE);
361 : 4237 : }
362 : 4237 : }
363 : :
364 : 651 : return S2N_RESULT_OK;
365 : 654 : }
366 : :
367 : : S2N_RESULT s2n_client_hello_parse_raw(struct s2n_client_hello *client_hello)
368 : 7908 : {
369 [ - + ][ # # ]: 7908 : RESULT_ENSURE_REF(client_hello);
370 : :
371 : 7908 : struct s2n_stuffer in_stuffer = { 0 };
372 [ - + ]: 7908 : RESULT_GUARD_POSIX(s2n_stuffer_init_written(&in_stuffer, &client_hello->raw_message));
373 : 7908 : struct s2n_stuffer *in = &in_stuffer;
374 : :
375 : : /**
376 : : * https://tools.ietf.org/rfc/rfc8446#4.1.2
377 : : * Structure of this message:
378 : : *
379 : : * uint16 ProtocolVersion;
380 : : * opaque Random[32];
381 : : *
382 : : * uint8 CipherSuite[2];
383 : : *
384 : : * struct {
385 : : * ProtocolVersion legacy_version = 0x0303;
386 : : * Random random;
387 : : * opaque legacy_session_id<0..32>;
388 : : * CipherSuite cipher_suites<2..2^16-2>;
389 : : * opaque legacy_compression_methods<1..2^8-1>;
390 : : * Extension extensions<8..2^16-1>;
391 : : * } ClientHello;
392 : : **/
393 : :
394 : : /* legacy_version */
395 : 7908 : uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
396 [ + + ]: 7908 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(in, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
397 : :
398 : : /* Encode the version as a 1 byte representation of the two protocol version bytes, with the
399 : : * major version in the tens place and the minor version in the ones place. For example, the
400 : : * TLS 1.2 protocol version is 0x0303, which is encoded as S2N_TLS12 (33).
401 : : */
402 : 7907 : client_hello->legacy_version = (client_protocol_version[0] * 10) + client_protocol_version[1];
403 : :
404 : : /* random - read and store it, erasing from raw message */
405 [ - + ]: 7907 : RESULT_GUARD_POSIX(s2n_stuffer_erase_and_read_bytes(in, client_hello->random, S2N_TLS_RANDOM_DATA_LEN));
406 : :
407 : : /* legacy_session_id */
408 : 7907 : uint8_t session_id_len = 0;
409 [ - + ]: 7907 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &session_id_len));
410 [ + - ][ + + ]: 7907 : RESULT_ENSURE(session_id_len <= S2N_TLS_SESSION_ID_MAX_LEN, S2N_ERR_BAD_MESSAGE);
411 : 7906 : uint8_t *session_id = s2n_stuffer_raw_read(in, session_id_len);
412 [ - + ][ # # ]: 7906 : RESULT_ENSURE(session_id != NULL, S2N_ERR_BAD_MESSAGE);
413 [ - + ]: 7906 : RESULT_GUARD_POSIX(s2n_blob_init(&client_hello->session_id, session_id, session_id_len));
414 : :
415 : : /* cipher suites */
416 : 7906 : uint16_t cipher_suites_length = 0;
417 [ - + ]: 7906 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(in, &cipher_suites_length));
418 [ + - ][ + + ]: 7906 : RESULT_ENSURE(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
419 [ - + ][ # # ]: 7904 : RESULT_ENSURE(cipher_suites_length % S2N_TLS_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
420 : 7904 : uint8_t *cipher_suites = s2n_stuffer_raw_read(in, cipher_suites_length);
421 [ - + ][ # # ]: 7904 : RESULT_ENSURE(cipher_suites != NULL, S2N_ERR_BAD_MESSAGE);
422 [ - + ]: 7904 : RESULT_GUARD_POSIX(s2n_blob_init(&client_hello->cipher_suites, cipher_suites, cipher_suites_length));
423 : :
424 : : /* legacy_compression_methods */
425 : 7904 : uint8_t compression_methods_len = 0;
426 [ - + ]: 7904 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &compression_methods_len));
427 : 7904 : uint8_t *compression_methods = s2n_stuffer_raw_read(in, compression_methods_len);
428 [ - + ][ # # ]: 7904 : RESULT_ENSURE(compression_methods != NULL, S2N_ERR_BAD_MESSAGE);
429 [ - + ]: 7904 : RESULT_GUARD_POSIX(s2n_blob_init(&client_hello->compression_methods, compression_methods, compression_methods_len));
430 : :
431 : : /* extensions */
432 [ + + ]: 7904 : RESULT_GUARD_POSIX(s2n_extension_list_parse(in, &client_hello->extensions));
433 : :
434 : 7903 : return S2N_RESULT_OK;
435 : 7904 : }
436 : :
437 : : int s2n_parse_client_hello(struct s2n_connection *conn)
438 : 7830 : {
439 [ # # ][ - + ]: 7830 : POSIX_ENSURE_REF(conn);
440 : :
441 : : /* SSLv2 ClientHellos are not allowed during a HelloRetryRequest */
442 [ + + ]: 7830 : if (s2n_is_hello_retry_handshake(conn)) {
443 [ + + ][ + - ]: 660 : POSIX_ENSURE(!conn->client_hello.sslv2, S2N_ERR_BAD_MESSAGE);
444 : 660 : }
445 : :
446 : : /* If a retry, move the old version of the client hello
447 : : * somewhere safe so we can compare it to the new client hello later.
448 : : */
449 : 7829 : DEFER_CLEANUP(struct s2n_client_hello previous_hello_retry = conn->client_hello,
450 : 7829 : s2n_client_hello_free_raw_message);
451 : :
452 : : /* Save the client random before clearing for retry validation */
453 : 7829 : uint8_t previous_client_random[S2N_TLS_RANDOM_DATA_LEN] = { 0 };
454 [ # # ][ - + ]: 7829 : POSIX_CHECKED_MEMCPY(previous_client_random, conn->client_hello.random,
[ + - ]
455 : 7829 : S2N_TLS_RANDOM_DATA_LEN);
456 : :
457 [ + + ]: 7829 : if (s2n_is_hello_retry_handshake(conn)) {
458 [ - + ][ # # ]: 659 : POSIX_CHECKED_MEMSET(&conn->client_hello, 0, sizeof(struct s2n_client_hello));
[ + - ]
459 : 659 : }
460 : :
461 [ - + ]: 7829 : POSIX_GUARD(s2n_collect_client_hello(&conn->client_hello, &conn->handshake.io));
462 : :
463 [ + + ]: 7829 : if (conn->client_hello.sslv2) {
464 [ + + ]: 7 : POSIX_GUARD(s2n_sslv2_client_hello_parse(conn));
465 : 6 : return S2N_SUCCESS;
466 : 7 : }
467 : :
468 : : /* Parse raw, collected client hello */
469 [ + + ]: 7822 : POSIX_GUARD_RESULT(s2n_client_hello_parse_raw(&conn->client_hello));
470 : :
471 : : /* Protocol version in the ClientHello is fixed at 0x0303(TLS 1.2) for
472 : : * future versions of TLS. Therefore, we will negotiate down if a client sends
473 : : * an unexpected value above 0x0303.
474 : : */
475 : 7819 : conn->client_protocol_version = MIN(conn->client_hello.legacy_version, S2N_TLS12);
476 : :
477 : : /* Copy the session id to the connection. */
478 : 7819 : conn->session_id_len = conn->client_hello.session_id.size;
479 [ # # ][ - + ]: 7819 : POSIX_CHECKED_MEMCPY(conn->session_id, conn->client_hello.session_id.data, conn->session_id_len);
[ + + ]
480 : :
481 [ + + ]: 7819 : POSIX_GUARD_RESULT(s2n_client_hello_verify_for_retry(conn,
482 : 7811 : &previous_hello_retry, &conn->client_hello, previous_client_random));
483 : 7811 : return S2N_SUCCESS;
484 : 7819 : }
485 : :
486 : : static S2N_RESULT s2n_client_hello_parse_message_impl(struct s2n_client_hello **result,
487 : : const uint8_t *raw_message, uint32_t raw_message_size)
488 : 94 : {
489 [ - + ][ # # ]: 94 : RESULT_ENSURE_REF(result);
490 : :
491 : 94 : DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free);
492 [ - + ]: 94 : RESULT_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_client_hello)));
493 [ - + ]: 94 : RESULT_GUARD_POSIX(s2n_blob_zero(&mem));
494 : :
495 : 94 : DEFER_CLEANUP(struct s2n_client_hello *client_hello = NULL, s2n_client_hello_free);
496 : 94 : client_hello = (struct s2n_client_hello *) (void *) mem.data;
497 : 94 : client_hello->alloced = true;
498 : 94 : ZERO_TO_DISABLE_DEFER_CLEANUP(mem);
499 : :
500 : 94 : DEFER_CLEANUP(struct s2n_stuffer in = { 0 }, s2n_stuffer_free);
501 [ - + ]: 94 : RESULT_GUARD_POSIX(s2n_stuffer_alloc(&in, raw_message_size));
502 [ - + ]: 94 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(&in, raw_message, raw_message_size));
503 : :
504 : 94 : uint8_t message_type = 0;
505 : 94 : uint32_t message_len = 0;
506 [ - + ]: 94 : RESULT_GUARD(s2n_handshake_parse_header(&in, &message_type, &message_len));
507 [ + - ][ + + ]: 94 : RESULT_ENSURE(message_type == TLS_CLIENT_HELLO, S2N_ERR_BAD_MESSAGE);
508 [ + - ][ + + ]: 88 : RESULT_ENSURE(message_len == s2n_stuffer_data_available(&in), S2N_ERR_BAD_MESSAGE);
509 : :
510 [ - + ]: 86 : RESULT_GUARD_POSIX(s2n_collect_client_hello(client_hello, &in));
511 [ # # ][ - + ]: 86 : RESULT_ENSURE(s2n_stuffer_data_available(&in) == 0, S2N_ERR_BAD_MESSAGE);
512 : :
513 [ + + ]: 86 : RESULT_GUARD(s2n_client_hello_parse_raw(client_hello));
514 : :
515 : 84 : *result = client_hello;
516 : 84 : ZERO_TO_DISABLE_DEFER_CLEANUP(client_hello);
517 : 84 : return S2N_RESULT_OK;
518 : 86 : }
519 : :
520 : : struct s2n_client_hello *s2n_client_hello_parse_message(const uint8_t *raw_message, uint32_t raw_message_size)
521 : 94 : {
522 : 94 : struct s2n_client_hello *result = NULL;
523 [ + + ]: 94 : PTR_GUARD_RESULT(s2n_client_hello_parse_message_impl(&result, raw_message, raw_message_size));
524 : 84 : return result;
525 : 94 : }
526 : :
527 : : int s2n_process_client_hello(struct s2n_connection *conn)
528 : 7801 : {
529 [ - + ][ # # ]: 7801 : POSIX_ENSURE_REF(conn);
530 [ - + ][ # # ]: 7801 : POSIX_ENSURE_REF(conn->secure);
531 [ # # ][ - + ]: 7801 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
532 : :
533 : : /* Client hello is parsed and config is finalized.
534 : : * Negotiate protocol version, cipher suite, ALPN, select a cert, etc. */
535 : 7801 : struct s2n_client_hello *client_hello = &conn->client_hello;
536 : :
537 : 7801 : const struct s2n_security_policy *security_policy = NULL;
538 [ - + ]: 7801 : POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
539 : :
540 [ - + ][ + + ]: 7801 : if (!s2n_connection_supports_tls13(conn) || !s2n_security_policy_supports_tls13(security_policy)) {
541 : 2310 : conn->server_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
542 : 2310 : conn->actual_protocol_version = MIN(conn->server_protocol_version, S2N_TLS12);
543 : 2310 : }
544 : :
545 : : /* Set default key exchange curve.
546 : : * This is going to be our fallback if the client has no preference.
547 : : *
548 : : * P-256 is our preferred fallback option because the TLS1.3 RFC requires
549 : : * all implementations to support it:
550 : : *
551 : : * https://tools.ietf.org/rfc/rfc8446#section-9.1
552 : : * A TLS-compliant application MUST support key exchange with secp256r1 (NIST P-256)
553 : : * and SHOULD support key exchange with X25519 [RFC7748]
554 : : *
555 : : *= https://www.rfc-editor.org/rfc/rfc4492#section-4
556 : : *# A client that proposes ECC cipher suites may choose not to include these extensions.
557 : : *# In this case, the server is free to choose any one of the elliptic curves or point formats listed in Section 5.
558 : : *
559 : : */
560 : 7801 : const struct s2n_ecc_preferences *ecc_pref = NULL;
561 [ - + ]: 7801 : POSIX_GUARD(s2n_connection_get_ecc_preferences(conn, &ecc_pref));
562 [ # # ][ - + ]: 7801 : POSIX_ENSURE_REF(ecc_pref);
563 : :
564 [ - + ]: 7801 : if (ecc_pref->count == 0) {
565 : 0 : conn->kex_params.server_ecc_evp_params.negotiated_curve = NULL;
566 [ + + ]: 7801 : } else if (s2n_ecc_preferences_includes_curve(ecc_pref, TLS_EC_CURVE_SECP_256_R1)) {
567 : 7778 : conn->kex_params.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp256r1;
568 : 7778 : } else {
569 : : /* If P-256 isn't allowed by the current security policy, choose the first / most preferred curve. */
570 : 23 : conn->kex_params.server_ecc_evp_params.negotiated_curve = ecc_pref->ecc_curves[0];
571 : 23 : }
572 : :
573 [ + + ]: 7801 : POSIX_GUARD(s2n_extension_list_process(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, &conn->client_hello.extensions));
574 : :
575 : : /* After parsing extensions, select a curve and corresponding keyshare to use */
576 [ + + ]: 7793 : if (conn->actual_protocol_version >= S2N_TLS13) {
577 [ - + ]: 5293 : POSIX_GUARD(s2n_extensions_server_key_share_select(conn));
578 : 5293 : }
579 : :
580 : : /* for pre TLS 1.3 connections, protocol selection is not done in supported_versions extensions, so do it here */
581 [ + + ]: 7793 : if (conn->actual_protocol_version < S2N_TLS13) {
582 : 2500 : conn->actual_protocol_version = MIN(conn->server_protocol_version, conn->client_protocol_version);
583 : 2500 : }
584 : :
585 [ + + ]: 7793 : if (conn->client_protocol_version < security_policy->minimum_protocol_version) {
586 [ - + ]: 2 : POSIX_GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
587 [ + - ]: 2 : POSIX_BAIL(S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
588 : 2 : }
589 : :
590 [ + + ]: 7791 : if (s2n_connection_is_quic_enabled(conn)) {
591 [ + + ][ + - ]: 12 : POSIX_ENSURE(conn->actual_protocol_version >= S2N_TLS13, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
592 : 12 : }
593 : :
594 : : /* Find potential certificate matches before we choose the cipher. */
595 [ - + ]: 7790 : POSIX_GUARD(s2n_conn_find_name_matching_certs(conn));
596 : :
597 : : /* Save the previous cipher suite */
598 : 7790 : uint8_t previous_cipher_suite_iana[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
599 [ - + ][ # # ]: 7790 : POSIX_CHECKED_MEMCPY(previous_cipher_suite_iana, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN);
[ + - ]
600 : :
601 : : /* Now choose the ciphers we have certs for. */
602 [ + + ]: 7790 : if (conn->client_hello.sslv2) {
603 [ - + ]: 5 : POSIX_GUARD(s2n_set_cipher_as_sslv2_server(conn, client_hello->cipher_suites.data,
604 : 5 : client_hello->cipher_suites.size / S2N_SSLv2_CIPHER_SUITE_LEN));
605 : 7785 : } else {
606 [ + + ]: 7785 : POSIX_GUARD(s2n_set_cipher_as_tls_server(conn, client_hello->cipher_suites.data,
607 : 7785 : client_hello->cipher_suites.size / 2));
608 : 7785 : }
609 : :
610 : : /* Check if this is the second client hello in a hello retry handshake */
611 [ + + ][ + + ]: 7773 : if (s2n_is_hello_retry_handshake(conn) && conn->handshake.message_number > 0) {
612 : : /**
613 : : *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4
614 : : *# Servers MUST ensure that they negotiate the
615 : : *# same cipher suite when receiving a conformant updated ClientHello (if
616 : : *# the server selects the cipher suite as the first step in the
617 : : *# negotiation, then this will happen automatically).
618 : : **/
619 [ + + ][ + - ]: 647 : POSIX_ENSURE(s2n_constant_time_equals(previous_cipher_suite_iana, conn->secure->cipher_suite->iana_value,
620 : 647 : S2N_TLS_CIPHER_SUITE_LEN),
621 : 647 : S2N_ERR_BAD_MESSAGE);
622 : 647 : }
623 : :
624 : : /* If we're using a PSK, we don't need to choose a signature algorithm or certificate,
625 : : * because no additional auth is required. */
626 [ + + ]: 7771 : if (conn->psk_params.chosen_psk != NULL) {
627 : 1066 : return S2N_SUCCESS;
628 : 1066 : }
629 : :
630 : : /* And set the signature and hash algorithm used for key exchange signatures */
631 [ + + ]: 6705 : POSIX_GUARD_RESULT(s2n_signature_algorithm_select(conn));
632 : :
633 : : /* And finally, set the certs specified by the final auth + sig_alg combo. */
634 [ + + ]: 6702 : POSIX_GUARD(s2n_select_certs_for_server_auth(conn, &conn->handshake_params.our_chain_and_key));
635 : :
636 : 6700 : return S2N_SUCCESS;
637 : 6702 : }
638 : :
639 : : static S2N_RESULT s2n_client_hello_process_cb_response(struct s2n_connection *conn, int rc)
640 : 122 : {
641 [ + + ]: 122 : if (rc < 0) {
642 : 4 : goto fail;
643 : 4 : }
644 [ - + ]: 118 : switch (conn->config->client_hello_cb_mode) {
645 [ + + ]: 90 : case S2N_CLIENT_HELLO_CB_BLOCKING: {
646 [ + + ]: 90 : if (rc) {
647 : 5 : conn->server_name_used = 1;
648 : 5 : }
649 : 90 : return S2N_RESULT_OK;
650 : 0 : }
651 [ + + ]: 28 : case S2N_CLIENT_HELLO_CB_NONBLOCKING: {
652 [ + + ]: 28 : if (conn->client_hello.callback_async_done) {
653 : 9 : return S2N_RESULT_OK;
654 : 9 : }
655 : 19 : conn->client_hello.callback_async_blocked = 1;
656 [ + - ]: 19 : RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED);
657 : 19 : }
658 : 118 : }
659 : 4 : fail:
660 : : /* rc < 0 */
661 [ - + ]: 4 : RESULT_GUARD_POSIX(s2n_queue_reader_handshake_failure_alert(conn));
662 [ + - ]: 4 : RESULT_BAIL(S2N_ERR_CANCELLED);
663 : 4 : }
664 : :
665 : : int s2n_client_hello_recv(struct s2n_connection *conn)
666 : 7850 : {
667 [ + + ][ + - ]: 7850 : POSIX_ENSURE(!conn->client_hello.callback_async_blocked, S2N_ERR_ASYNC_BLOCKED);
668 : :
669 : : /* Only parse the ClientHello once */
670 [ + + ]: 7839 : if (!conn->client_hello.parsed) {
671 [ + + ]: 7815 : POSIX_GUARD(s2n_parse_client_hello(conn));
672 : : /* Mark the collected client hello as available when parsing is done and before the client hello callback */
673 : 7803 : conn->client_hello.parsed = true;
674 : 7803 : }
675 : :
676 : : /* Only invoke the ClientHello callback once.
677 : : * This means that we do NOT invoke the callback again on the second ClientHello
678 : : * in a TLS1.3 retry handshake. We explicitly check for a retry because the
679 : : * callback state may have been cleared while parsing the second ClientHello.
680 : : */
681 [ + + ][ + + ]: 7827 : if (!conn->client_hello.callback_invoked && !IS_HELLO_RETRY_HANDSHAKE(conn)) {
682 : : /* Mark the client hello callback as invoked to avoid calling it again. */
683 : 7156 : conn->client_hello.callback_invoked = true;
684 : :
685 : : /* Do NOT move this null check. A test exists to assert that a server connection can get
686 : : * as far as the client hello callback without using its config. To do this we need a
687 : : * specific error for a null config just before the client hello callback. The test's
688 : : * assertions are weakened if this check is moved. */
689 [ + - ][ + + ]: 7156 : POSIX_ENSURE(conn->config, S2N_ERR_CONFIG_NULL_BEFORE_CH_CALLBACK);
690 : :
691 : : /* Call client_hello_cb if exists, letting application to modify s2n_connection or swap s2n_config */
692 [ + + ]: 7153 : if (conn->config->client_hello_cb) {
693 : 124 : int rc = conn->config->client_hello_cb(conn, conn->config->client_hello_cb_ctx);
694 [ + + ]: 124 : POSIX_GUARD_RESULT(s2n_client_hello_process_cb_response(conn, rc));
695 : 124 : }
696 : 7153 : }
697 : :
698 [ + + ]: 7801 : POSIX_GUARD(s2n_process_client_hello(conn));
699 : :
700 : 7766 : return 0;
701 : 7801 : }
702 : :
703 : : S2N_RESULT s2n_cipher_suite_validate_available(struct s2n_connection *conn, struct s2n_cipher_suite *cipher)
704 : 162362 : {
705 [ # # ][ - + ]: 162362 : RESULT_ENSURE_REF(conn);
706 [ - + ][ # # ]: 162362 : RESULT_ENSURE_REF(cipher);
707 [ + + ][ + - ]: 162362 : RESULT_ENSURE_EQ(cipher->available, true);
708 [ + + ][ + - ]: 160402 : RESULT_ENSURE_LTE(cipher->minimum_required_tls_version, conn->client_protocol_version);
709 [ + + ]: 159955 : if (s2n_connection_is_quic_enabled(conn)) {
710 [ + + ][ + - ]: 251 : RESULT_ENSURE_GTE(cipher->minimum_required_tls_version, S2N_TLS13);
711 : 251 : }
712 : 159743 : return S2N_RESULT_OK;
713 : 159955 : }
714 : :
715 : : int s2n_client_hello_send(struct s2n_connection *conn)
716 : 7774 : {
717 [ # # ][ - + ]: 7774 : POSIX_ENSURE_REF(conn);
718 : :
719 : 7774 : const struct s2n_security_policy *security_policy = NULL;
720 [ - + ]: 7774 : POSIX_GUARD(s2n_connection_get_security_policy(conn, &security_policy));
721 : :
722 : 7774 : const struct s2n_cipher_preferences *cipher_preferences = security_policy->cipher_preferences;
723 [ # # ][ - + ]: 7774 : POSIX_ENSURE_REF(cipher_preferences);
724 : :
725 [ - + ][ + + ]: 7774 : if (!s2n_connection_supports_tls13(conn) || !s2n_security_policy_supports_tls13(security_policy)) {
726 : 1835 : conn->client_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
727 : 1835 : conn->actual_protocol_version = MIN(conn->actual_protocol_version, S2N_TLS12);
728 : 1835 : }
729 : :
730 : 7774 : struct s2n_stuffer *out = &conn->handshake.io;
731 : 7774 : uint8_t client_protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
732 : :
733 : 7774 : uint8_t reported_protocol_version = MIN(conn->client_protocol_version, S2N_TLS12);
734 : 7774 : conn->client_hello.legacy_version = reported_protocol_version;
735 : 7774 : client_protocol_version[0] = reported_protocol_version / 10;
736 : 7774 : client_protocol_version[1] = reported_protocol_version % 10;
737 [ - + ]: 7774 : POSIX_GUARD(s2n_stuffer_write_bytes(out, client_protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
738 : :
739 : 7774 : struct s2n_blob client_random = { 0 };
740 [ - + ]: 7774 : POSIX_GUARD(s2n_blob_init(&client_random, conn->client_hello.random, S2N_TLS_RANDOM_DATA_LEN));
741 [ + + ]: 7774 : if (!s2n_is_hello_retry_handshake(conn)) {
742 : : /* Only generate the random data for our first client hello.
743 : : * If we retry, we'll reuse the value. */
744 [ - + ]: 7112 : POSIX_GUARD_RESULT(s2n_get_public_random_data(&client_random));
745 : 7112 : }
746 [ - + ]: 7774 : POSIX_GUARD(s2n_stuffer_write(out, &client_random));
747 : :
748 [ + + ]: 7774 : POSIX_GUARD_RESULT(s2n_generate_client_session_id(conn));
749 [ - + ]: 7773 : POSIX_GUARD(s2n_stuffer_write_uint8(out, conn->session_id_len));
750 [ + + ]: 7773 : if (conn->session_id_len > 0) {
751 [ - + ]: 5709 : POSIX_GUARD(s2n_stuffer_write_bytes(out, conn->session_id, conn->session_id_len));
752 : 5709 : }
753 : :
754 : : /* Reserve space for size of the list of available ciphers */
755 : 7773 : struct s2n_stuffer_reservation available_cipher_suites_size;
756 [ - + ]: 7773 : POSIX_GUARD(s2n_stuffer_reserve_uint16(out, &available_cipher_suites_size));
757 : :
758 : : /* Now, write the IANA values of every available cipher suite in our list */
759 : 7773 : struct s2n_cipher_suite *cipher = NULL;
760 : 7773 : bool tls12_is_possible = false;
761 [ + + ]: 170135 : for (size_t i = 0; i < security_policy->cipher_preferences->count; i++) {
762 : 162362 : cipher = cipher_preferences->suites[i];
763 [ + + ]: 162362 : if (s2n_result_is_error(s2n_cipher_suite_validate_available(conn, cipher))) {
764 : 2619 : continue;
765 : 2619 : }
766 [ + + ]: 159743 : if (cipher->minimum_required_tls_version < S2N_TLS13) {
767 : 142161 : tls12_is_possible = true;
768 : 142161 : }
769 [ - + ]: 159743 : POSIX_GUARD(s2n_stuffer_write_bytes(out, cipher->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
770 : 159743 : }
771 : :
772 : : /**
773 : : * For initial handshakes:
774 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.4
775 : : *# o The client MUST include either an empty "renegotiation_info"
776 : : *# extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling
777 : : *# cipher suite value in the ClientHello. Including both is NOT
778 : : *# RECOMMENDED.
779 : : * For maximum backwards compatibility, we choose to use the TLS_EMPTY_RENEGOTIATION_INFO_SCSV cipher suite
780 : : * rather than the "renegotiation_info" extension.
781 : : *
782 : : * For renegotiation handshakes:
783 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.5
784 : : *# The SCSV MUST NOT be included.
785 : : */
786 [ + + ][ + + ]: 7773 : if (tls12_is_possible && !s2n_handshake_is_renegotiation(conn)) {
787 : 7432 : uint8_t renegotiation_info_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
788 [ - + ]: 7432 : POSIX_GUARD(s2n_stuffer_write_bytes(out, renegotiation_info_scsv, S2N_TLS_CIPHER_SUITE_LEN));
789 : 7432 : }
790 : :
791 : : /* Write size of the list of available ciphers */
792 : 7773 : uint32_t ciphers_size = 0;
793 [ - + ]: 7773 : POSIX_GUARD(s2n_stuffer_get_vector_size(&available_cipher_suites_size, &ciphers_size));
794 [ + + ][ + - ]: 7773 : POSIX_ENSURE(ciphers_size > 0, S2N_ERR_INVALID_CIPHER_PREFERENCES);
795 [ - + ]: 7772 : POSIX_GUARD(s2n_stuffer_write_reservation(&available_cipher_suites_size, ciphers_size));
796 : :
797 : : /* Zero compression methods */
798 [ - + ]: 7772 : POSIX_GUARD(s2n_stuffer_write_uint8(out, 1));
799 [ - + ]: 7772 : POSIX_GUARD(s2n_stuffer_write_uint8(out, 0));
800 : :
801 : : /* Write the extensions */
802 [ - + ]: 7772 : POSIX_GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CLIENT_HELLO, conn, out));
803 : :
804 : : /* Once the message is complete, finish calculating the PSK binders.
805 : : *
806 : : * The PSK binders require all the sizes in the ClientHello to be written correctly,
807 : : * including the extension size and extension list size, and therefore have
808 : : * to be calculated AFTER we finish writing the entire extension list. */
809 [ - + ]: 7772 : POSIX_GUARD_RESULT(s2n_finish_psk_extension(conn));
810 : :
811 : : /* If early data was not requested as part of the ClientHello, it never will be. */
812 [ + + ]: 7772 : if (conn->early_data_state == S2N_UNKNOWN_EARLY_DATA_STATE) {
813 [ - + ]: 6571 : POSIX_GUARD_RESULT(s2n_connection_set_early_data_state(conn, S2N_EARLY_DATA_NOT_REQUESTED));
814 : 6571 : }
815 : :
816 : 7772 : return S2N_SUCCESS;
817 : 7772 : }
818 : :
819 : : /*
820 : : * s2n-tls does NOT support SSLv2. However, it does support SSLv2 ClientHellos.
821 : : * Clients may send SSLv2 ClientHellos advertising higher protocol versions for
822 : : * backwards compatibility reasons. See https://tools.ietf.org/rfc/rfc2246 Appendix E.
823 : : *
824 : : * In this case, conn->client_hello.legacy_version and conn->client_protocol_version
825 : : * will be higher than SSLv2.
826 : : *
827 : : * See http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html Section 2.5
828 : : * for a description of the expected SSLv2 format.
829 : : * Alternatively, the TLS1.0 RFC includes a more modern description of the format:
830 : : * https://tools.ietf.org/rfc/rfc2246 Appendix E.1
831 : : */
832 : : int s2n_sslv2_client_hello_parse(struct s2n_connection *conn)
833 : 7 : {
834 : 7 : struct s2n_client_hello *client_hello = &conn->client_hello;
835 : 7 : conn->client_protocol_version = MIN(client_hello->legacy_version, S2N_TLS12);
836 : :
837 : 7 : struct s2n_stuffer in_stuffer = { 0 };
838 [ - + ]: 7 : POSIX_GUARD(s2n_stuffer_init(&in_stuffer, &client_hello->raw_message));
839 [ - + ]: 7 : POSIX_GUARD(s2n_stuffer_skip_write(&in_stuffer, client_hello->raw_message.size));
840 : 7 : struct s2n_stuffer *in = &in_stuffer;
841 : :
842 : : /* We start 5 bytes into the record */
843 : 7 : uint16_t cipher_suites_length = 0;
844 [ - + ]: 7 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));
845 [ + + ][ + - ]: 7 : POSIX_ENSURE(cipher_suites_length > 0, S2N_ERR_BAD_MESSAGE);
846 [ # # ][ - + ]: 6 : POSIX_ENSURE(cipher_suites_length % S2N_SSLv2_CIPHER_SUITE_LEN == 0, S2N_ERR_BAD_MESSAGE);
847 : :
848 : 6 : uint16_t session_id_length = 0;
849 [ - + ]: 6 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &session_id_length));
850 : :
851 : 6 : uint16_t challenge_length = 0;
852 [ - + ]: 6 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &challenge_length));
853 : :
854 [ - + ][ # # ]: 6 : S2N_ERROR_IF(challenge_length > S2N_TLS_RANDOM_DATA_LEN, S2N_ERR_BAD_MESSAGE);
855 : :
856 : 6 : client_hello->cipher_suites.size = cipher_suites_length;
857 : 6 : client_hello->cipher_suites.data = s2n_stuffer_raw_read(in, cipher_suites_length);
858 [ - + ][ # # ]: 6 : POSIX_ENSURE_REF(client_hello->cipher_suites.data);
859 : :
860 [ - + ][ # # ]: 6 : S2N_ERROR_IF(session_id_length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
861 [ - + ]: 6 : POSIX_GUARD(s2n_blob_init(&client_hello->session_id, s2n_stuffer_raw_read(in, session_id_length), session_id_length));
862 [ - + ][ # # ]: 6 : if (session_id_length > 0 && session_id_length <= S2N_TLS_SESSION_ID_MAX_LEN) {
863 [ # # ][ # # ]: 0 : POSIX_CHECKED_MEMCPY(conn->session_id, client_hello->session_id.data, session_id_length);
[ # # ]
864 : 0 : conn->session_id_len = (uint8_t) session_id_length;
865 : 0 : }
866 : :
867 : 6 : struct s2n_blob b = { 0 };
868 [ - + ]: 6 : POSIX_GUARD(s2n_blob_init(&b, conn->client_hello.random, S2N_TLS_RANDOM_DATA_LEN));
869 : :
870 : 6 : b.data += S2N_TLS_RANDOM_DATA_LEN - challenge_length;
871 : 6 : b.size -= S2N_TLS_RANDOM_DATA_LEN - challenge_length;
872 : :
873 [ - + ]: 6 : POSIX_GUARD(s2n_stuffer_read(in, &b));
874 : :
875 : 6 : return 0;
876 : 6 : }
877 : :
878 : : int s2n_client_hello_get_parsed_extension(s2n_tls_extension_type extension_type,
879 : : s2n_parsed_extensions_list *parsed_extension_list, s2n_parsed_extension **parsed_extension)
880 : 745 : {
881 [ - + ][ # # ]: 745 : POSIX_ENSURE_REF(parsed_extension_list);
882 [ # # ][ - + ]: 745 : POSIX_ENSURE_REF(parsed_extension);
883 : :
884 : 745 : s2n_extension_type_id extension_type_id = 0;
885 [ - + ]: 745 : POSIX_GUARD(s2n_extension_supported_iana_value_to_id(extension_type, &extension_type_id));
886 : :
887 : 745 : s2n_parsed_extension *found_parsed_extension = &parsed_extension_list->parsed_extensions[extension_type_id];
888 [ + - ][ + + ]: 745 : POSIX_ENSURE(found_parsed_extension->extension.data, S2N_ERR_EXTENSION_NOT_RECEIVED);
889 [ + + ][ + - ]: 324 : POSIX_ENSURE(found_parsed_extension->extension_type == extension_type, S2N_ERR_INVALID_PARSED_EXTENSIONS);
890 : :
891 : 323 : *parsed_extension = found_parsed_extension;
892 : 323 : return S2N_SUCCESS;
893 : 324 : }
894 : :
895 : : ssize_t s2n_client_hello_get_extension_length(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type)
896 : 41 : {
897 [ + - ][ + + ]: 41 : POSIX_ENSURE_REF(ch);
898 : :
899 : 39 : s2n_parsed_extension *parsed_extension = NULL;
900 [ + + ]: 39 : if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
901 : 2 : return 0;
902 : 2 : }
903 : :
904 : 37 : return parsed_extension->extension.size;
905 : 39 : }
906 : :
907 : : ssize_t s2n_client_hello_get_extension_by_id(struct s2n_client_hello *ch, s2n_tls_extension_type extension_type, uint8_t *out, uint32_t max_length)
908 : 42 : {
909 [ + + ][ + - ]: 42 : POSIX_ENSURE_REF(ch);
910 [ - + ][ # # ]: 40 : POSIX_ENSURE_REF(out);
911 : :
912 : 40 : s2n_parsed_extension *parsed_extension = NULL;
913 [ + + ]: 40 : if (s2n_client_hello_get_parsed_extension(extension_type, &ch->extensions, &parsed_extension) != S2N_SUCCESS) {
914 : 3 : return 0;
915 : 3 : }
916 : :
917 : 37 : uint32_t len = min_size(&parsed_extension->extension, max_length);
918 [ # # ][ - + ]: 37 : POSIX_CHECKED_MEMCPY(out, parsed_extension->extension.data, len);
[ + - ]
919 : 37 : return len;
920 : 37 : }
921 : :
922 : : int s2n_client_hello_get_session_id_length(struct s2n_client_hello *ch, uint32_t *out_length)
923 : 2 : {
924 [ # # ][ - + ]: 2 : POSIX_ENSURE_REF(ch);
925 [ - + ][ # # ]: 2 : POSIX_ENSURE_REF(out_length);
926 : 2 : *out_length = ch->session_id.size;
927 : 2 : return S2N_SUCCESS;
928 : 2 : }
929 : :
930 : : int s2n_client_hello_get_session_id(struct s2n_client_hello *ch, uint8_t *out, uint32_t *out_length, uint32_t max_length)
931 : 1 : {
932 [ - + ][ # # ]: 1 : POSIX_ENSURE_REF(ch);
933 [ - + ][ # # ]: 1 : POSIX_ENSURE_REF(out);
934 [ # # ][ - + ]: 1 : POSIX_ENSURE_REF(out_length);
935 : :
936 : 1 : uint32_t len = min_size(&ch->session_id, max_length);
937 [ - + ][ # # ]: 1 : POSIX_CHECKED_MEMCPY(out, ch->session_id.data, len);
[ + - ]
938 : 1 : *out_length = len;
939 : :
940 : 1 : return S2N_SUCCESS;
941 : 1 : }
942 : :
943 : : int s2n_client_hello_get_compression_methods_length(struct s2n_client_hello *ch, uint32_t *out_length)
944 : 4 : {
945 [ + + ][ + - ]: 4 : POSIX_ENSURE_REF(ch);
946 [ + - ][ + + ]: 3 : POSIX_ENSURE_REF(out_length);
947 : 2 : *out_length = ch->compression_methods.size;
948 : 2 : return S2N_SUCCESS;
949 : 3 : }
950 : :
951 : : int s2n_client_hello_get_compression_methods(struct s2n_client_hello *ch, uint8_t *list, uint32_t list_length, uint32_t *out_length)
952 : 6 : {
953 [ + + ][ + - ]: 6 : POSIX_ENSURE_REF(ch);
954 [ + - ][ + + ]: 5 : POSIX_ENSURE_REF(list);
955 [ + - ][ + + ]: 4 : POSIX_ENSURE_REF(out_length);
956 : :
957 [ + + ][ + - ]: 3 : POSIX_ENSURE(list_length >= ch->compression_methods.size, S2N_ERR_INSUFFICIENT_MEM_SIZE);
958 [ - + ][ # # ]: 2 : POSIX_CHECKED_MEMCPY(list, ch->compression_methods.data, ch->compression_methods.size);
[ + - ]
959 : 2 : *out_length = ch->compression_methods.size;
960 : 2 : return S2N_SUCCESS;
961 : 2 : }
962 : :
963 : : int s2n_client_hello_get_legacy_protocol_version(struct s2n_client_hello *ch, uint8_t *out)
964 : 3 : {
965 [ + + ][ + - ]: 3 : POSIX_ENSURE_REF(ch);
966 [ + - ][ + + ]: 2 : POSIX_ENSURE_REF(out);
967 : 1 : *out = ch->legacy_version;
968 : 1 : return S2N_SUCCESS;
969 : 2 : }
970 : :
971 : : int s2n_client_hello_get_legacy_record_version(struct s2n_client_hello *ch, uint8_t *out)
972 : 3 : {
973 [ + + ][ + - ]: 3 : POSIX_ENSURE_REF(ch);
974 [ + - ][ + + ]: 2 : POSIX_ENSURE_REF(out);
975 [ - + ][ # # ]: 1 : POSIX_ENSURE(ch->record_version_recorded, S2N_ERR_INVALID_ARGUMENT);
976 : 1 : *out = ch->legacy_record_version;
977 : 1 : return S2N_SUCCESS;
978 : 1 : }
979 : :
980 : : S2N_RESULT s2n_client_hello_get_raw_extension(uint16_t extension_iana,
981 : : struct s2n_blob *raw_extensions, struct s2n_blob *extension)
982 : 6 : {
983 [ - + ][ # # ]: 6 : RESULT_ENSURE_REF(raw_extensions);
984 [ # # ][ - + ]: 6 : RESULT_ENSURE_REF(extension);
985 : :
986 : 6 : *extension = (struct s2n_blob){ 0 };
987 : :
988 : 6 : struct s2n_stuffer raw_extensions_stuffer = { 0 };
989 [ - + ]: 6 : RESULT_GUARD_POSIX(s2n_stuffer_init(&raw_extensions_stuffer, raw_extensions));
990 [ - + ]: 6 : RESULT_GUARD_POSIX(s2n_stuffer_skip_write(&raw_extensions_stuffer, raw_extensions->size));
991 : :
992 [ + + ]: 12 : while (s2n_stuffer_data_available(&raw_extensions_stuffer) > 0) {
993 : 10 : uint16_t extension_type = 0;
994 [ - + ]: 10 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&raw_extensions_stuffer, &extension_type));
995 : :
996 : 10 : uint16_t extension_size = 0;
997 [ - + ]: 10 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&raw_extensions_stuffer, &extension_size));
998 : :
999 : 10 : uint8_t *extension_data = s2n_stuffer_raw_read(&raw_extensions_stuffer, extension_size);
1000 [ - + ][ # # ]: 10 : RESULT_ENSURE_REF(extension_data);
1001 : :
1002 [ + + ]: 10 : if (extension_iana == extension_type) {
1003 [ - + ]: 4 : RESULT_GUARD_POSIX(s2n_blob_init(extension, extension_data, extension_size));
1004 : 4 : return S2N_RESULT_OK;
1005 : 4 : }
1006 : 10 : }
1007 : 2 : return S2N_RESULT_OK;
1008 : 6 : }
1009 : :
1010 : : int s2n_client_hello_has_extension(struct s2n_client_hello *ch, uint16_t extension_iana, bool *exists)
1011 : 237 : {
1012 [ + + ][ + - ]: 237 : POSIX_ENSURE_REF(ch);
1013 [ # # ][ - + ]: 236 : POSIX_ENSURE_REF(exists);
1014 : :
1015 : 236 : *exists = false;
1016 : :
1017 : 236 : s2n_extension_type_id extension_type_id = s2n_unsupported_extension;
1018 [ + + ]: 236 : if (s2n_extension_supported_iana_value_to_id(extension_iana, &extension_type_id) == S2N_SUCCESS) {
1019 : 233 : s2n_parsed_extension *parsed_extension = NULL;
1020 [ + + ]: 233 : if (s2n_client_hello_get_parsed_extension(extension_iana, &ch->extensions, &parsed_extension) == S2N_SUCCESS) {
1021 : 89 : *exists = true;
1022 : 89 : }
1023 : 233 : return S2N_SUCCESS;
1024 : 233 : }
1025 : :
1026 : 3 : struct s2n_blob extension = { 0 };
1027 [ - + ]: 3 : POSIX_GUARD_RESULT(s2n_client_hello_get_raw_extension(extension_iana, &ch->extensions.raw, &extension));
1028 [ + + ]: 3 : if (extension.data != NULL) {
1029 : 2 : *exists = true;
1030 : 2 : }
1031 : 3 : return S2N_SUCCESS;
1032 : 3 : }
1033 : :
1034 : : int s2n_client_hello_get_supported_groups(struct s2n_client_hello *ch, uint16_t *groups,
1035 : : uint16_t groups_count_max, uint16_t *groups_count_out)
1036 : 34 : {
1037 [ + + ][ + - ]: 34 : POSIX_ENSURE_REF(groups_count_out);
1038 : 33 : *groups_count_out = 0;
1039 [ + + ][ + - ]: 33 : POSIX_ENSURE_REF(ch);
1040 [ + + ][ + - ]: 32 : POSIX_ENSURE_REF(groups);
1041 : :
1042 : 31 : s2n_parsed_extension *supported_groups_extension = NULL;
1043 [ + + ]: 31 : POSIX_GUARD(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SUPPORTED_GROUPS, &ch->extensions, &supported_groups_extension));
1044 [ - + ][ # # ]: 29 : POSIX_ENSURE_REF(supported_groups_extension);
1045 : :
1046 : 29 : struct s2n_stuffer extension_stuffer = { 0 };
1047 [ - + ]: 29 : POSIX_GUARD(s2n_stuffer_init_written(&extension_stuffer, &supported_groups_extension->extension));
1048 : :
1049 : 29 : uint16_t supported_groups_count = 0;
1050 [ + + ]: 29 : POSIX_GUARD_RESULT(s2n_supported_groups_parse_count(&extension_stuffer, &supported_groups_count));
1051 [ + + ][ + - ]: 27 : POSIX_ENSURE(supported_groups_count <= groups_count_max, S2N_ERR_INSUFFICIENT_MEM_SIZE);
1052 : :
1053 [ + + ]: 199 : for (size_t i = 0; i < supported_groups_count; i++) {
1054 : : /* s2n_stuffer_read_uint16 is used to read each of the supported groups in network-order
1055 : : * endianness.
1056 : : */
1057 [ - + ]: 173 : POSIX_GUARD(s2n_stuffer_read_uint16(&extension_stuffer, &groups[i]));
1058 : 173 : }
1059 : :
1060 : 26 : *groups_count_out = supported_groups_count;
1061 : :
1062 : 26 : return S2N_SUCCESS;
1063 : 26 : }
1064 : :
1065 : : int s2n_client_hello_get_server_name_length(struct s2n_client_hello *ch, uint16_t *length)
1066 : 3 : {
1067 [ + + ][ + - ]: 3 : POSIX_ENSURE_REF(ch);
1068 [ + + ][ + - ]: 2 : POSIX_ENSURE_REF(length);
1069 : 1 : *length = 0;
1070 : :
1071 : 1 : s2n_parsed_extension *server_name_extension = NULL;
1072 [ - + ]: 1 : POSIX_GUARD(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SERVER_NAME, &ch->extensions, &server_name_extension));
1073 [ # # ][ - + ]: 1 : POSIX_ENSURE_REF(server_name_extension);
1074 : :
1075 : 1 : struct s2n_stuffer extension_stuffer = { 0 };
1076 [ - + ]: 1 : POSIX_GUARD(s2n_stuffer_init_written(&extension_stuffer, &server_name_extension->extension));
1077 : :
1078 : 1 : struct s2n_blob blob = { 0 };
1079 [ - + ]: 1 : POSIX_GUARD_RESULT(s2n_client_server_name_parse(&extension_stuffer, &blob));
1080 : 1 : *length = blob.size;
1081 : :
1082 : 1 : return S2N_SUCCESS;
1083 : 1 : }
1084 : :
1085 : : int s2n_client_hello_get_server_name(struct s2n_client_hello *ch, uint8_t *server_name, uint16_t length, uint16_t *out_length)
1086 : 5 : {
1087 [ + - ][ + + ]: 5 : POSIX_ENSURE_REF(out_length);
1088 [ + + ][ + - ]: 4 : POSIX_ENSURE_REF(ch);
1089 [ + - ][ + + ]: 3 : POSIX_ENSURE_REF(server_name);
1090 : 2 : *out_length = 0;
1091 : :
1092 : 2 : s2n_parsed_extension *server_name_extension = NULL;
1093 [ - + ]: 2 : POSIX_GUARD(s2n_client_hello_get_parsed_extension(S2N_EXTENSION_SERVER_NAME, &ch->extensions, &server_name_extension));
1094 [ # # ][ - + ]: 2 : POSIX_ENSURE_REF(server_name_extension);
1095 : :
1096 : 2 : struct s2n_stuffer extension_stuffer = { 0 };
1097 [ - + ]: 2 : POSIX_GUARD(s2n_stuffer_init_written(&extension_stuffer, &server_name_extension->extension));
1098 : :
1099 : 2 : struct s2n_blob blob = { 0 };
1100 [ - + ]: 2 : POSIX_GUARD_RESULT(s2n_client_server_name_parse(&extension_stuffer, &blob));
1101 [ + + ][ + - ]: 2 : POSIX_ENSURE_LTE(blob.size, length);
1102 [ - + ][ # # ]: 1 : POSIX_CHECKED_MEMCPY(server_name, blob.data, blob.size);
[ + - ]
1103 : :
1104 : 1 : *out_length = blob.size;
1105 : :
1106 : 1 : return S2N_SUCCESS;
1107 : 1 : }
|