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