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_record_read.h"
17 : :
18 : : #include "crypto/s2n_cipher.h"
19 : : #include "crypto/s2n_hmac.h"
20 : : #include "crypto/s2n_sequence.h"
21 : : #include "error/s2n_errno.h"
22 : : #include "stuffer/s2n_stuffer.h"
23 : : #include "tls/s2n_cipher_suites.h"
24 : : #include "tls/s2n_connection.h"
25 : : #include "tls/s2n_crypto.h"
26 : : #include "utils/s2n_blob.h"
27 : : #include "utils/s2n_safety.h"
28 : :
29 : : int s2n_sslv2_record_header_parse(
30 : : struct s2n_connection *conn,
31 : : uint8_t *record_type,
32 : : uint8_t *client_protocol_version,
33 : : uint16_t *fragment_length)
34 : 449 : {
35 : 449 : struct s2n_stuffer *header_in = &conn->header_in;
36 : :
37 [ - + ][ # # ]: 449 : POSIX_ENSURE(s2n_stuffer_data_available(header_in) >= S2N_TLS_RECORD_HEADER_LENGTH,
38 : 449 : S2N_ERR_BAD_MESSAGE);
39 : :
40 [ - + ]: 449 : POSIX_GUARD(s2n_stuffer_read_uint16(header_in, fragment_length));
41 : :
42 : : /* The first bit of the SSLv2 message would usually indicate whether the
43 : : * length is 2 bytes long or 3 bytes long.
44 : : * See https://www.ietf.org/archive/id/draft-hickman-netscape-ssl-00.txt
45 : : *
46 : : * However, s2n-tls only supports SSLv2 for ClientHellos as defined in the
47 : : * TLS1.2 RFC. In that case, the first bit must always be set to distinguish
48 : : * SSLv2 from non-SSLv2 headers. The length is always 2 bytes.
49 : : * See https://datatracker.ietf.org/doc/html/rfc5246#appendix-E.2
50 : : *
51 : : * Since the first bit is not actually used to indicate length, we need to
52 : : * remove it from the length.
53 : : *
54 : : *= https://www.rfc-editor.org/rfc/rfc5246#appendix-E.2
55 : : *# msg_length
56 : : *# The highest bit MUST be 1; the remaining bits contain the length
57 : : *# of the following data in bytes.
58 : : */
59 [ # # ][ - + ]: 449 : POSIX_ENSURE(*fragment_length & S2N_TLS_SSLV2_HEADER_FLAG_UINT16, S2N_ERR_BAD_MESSAGE);
60 : 449 : *fragment_length ^= S2N_TLS_SSLV2_HEADER_FLAG_UINT16;
61 : :
62 : : /* We read 5 bytes into header_in because we expected a standard, non-SSLv2 record header
63 : : * instead of an SSLv2 message. We have therefore already read 3 bytes of the payload.
64 : : * We need to adjust "fragment_length" to account for the bytes we have already
65 : : * read so that we will only attempt to read the remainder of the payload on
66 : : * our next call to conn->recv.
67 : : */
68 [ + + ][ + - ]: 449 : POSIX_ENSURE(*fragment_length >= s2n_stuffer_data_available(header_in), S2N_ERR_BAD_MESSAGE);
69 : 447 : *fragment_length -= s2n_stuffer_data_available(header_in);
70 : :
71 : : /* By reading 5 bytes for a standard header we have also read the first
72 : : * 3 bytes of the SSLv2 ClientHello message.
73 : : * So we now need to parse those three bytes.
74 : : *
75 : : * The first field of an SSLv2 ClientHello is the msg_type.
76 : : * This is always '1', matching the ClientHello msg_type used by later
77 : : * handshake messages.
78 : : */
79 [ - + ]: 447 : POSIX_GUARD(s2n_stuffer_read_uint8(header_in, record_type));
80 : :
81 : : /*
82 : : * The second field of an SSLv2 ClientHello is the version.
83 : : *
84 : : * The protocol version read here will likely not be SSLv2, since we only
85 : : * accept SSLv2 ClientHellos offering higher protocol versions.
86 : : * See s2n_sslv2_client_hello_parse.
87 : : */
88 : 447 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
89 [ - + ]: 447 : POSIX_GUARD(s2n_stuffer_read_bytes(header_in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
90 : 447 : *client_protocol_version = (protocol_version[0] * 10) + protocol_version[1];
91 : :
92 [ - + ]: 447 : POSIX_GUARD(s2n_stuffer_reread(header_in));
93 : 447 : return 0;
94 : 447 : }
95 : :
96 : : /**
97 : : * - `conn`: connection with record header available in internal buffers
98 : : * - `header`: output parameter, populated after the header is parsed
99 : : */
100 : : int s2n_record_header_parse(
101 : : struct s2n_connection *conn,
102 : : struct s2n_record_header *header)
103 : 7326434 : {
104 : 7326434 : struct s2n_stuffer *in = &conn->header_in;
105 : :
106 [ - + ][ # # ]: 7326434 : S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE);
107 : :
108 [ - + ]: 7326434 : POSIX_GUARD(s2n_stuffer_read_uint8(in, &header->content_type));
109 : :
110 : : /* Once the protocol version is established, reject records with
111 : : * content_type values outside the valid TLS set {20, 21, 22, 23}.
112 : : * This is the earliest possible rejection point, before any buffer
113 : : * allocation or cryptographic work.
114 : : *
115 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
116 : : *# type: The higher-level protocol used to process the enclosed
117 : : *# fragment.
118 : : *
119 : : * Before the protocol version is established, we must be lenient
120 : : * because the first record (ClientHello) may arrive before we know
121 : : * the protocol version.
122 : : */
123 [ + + ]: 7326434 : if (conn->actual_protocol_version_established) {
124 : 6807906 : switch (header->content_type) {
125 [ + + ]: 21842 : case TLS_CHANGE_CIPHER_SPEC:
126 [ + + ]: 24402 : case TLS_ALERT:
127 [ + + ]: 64273 : case TLS_HANDSHAKE:
128 [ + + ]: 6807781 : case TLS_APPLICATION_DATA:
129 : 6807781 : break;
130 [ + + ]: 125 : default:
131 [ + - ]: 125 : POSIX_BAIL(S2N_ERR_BAD_MESSAGE);
132 : 6807906 : }
133 : 6807906 : }
134 : :
135 [ - + ]: 7326309 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &header->version));
136 : 7326309 : uint8_t major_version = header->version >> 8;
137 : 7326309 : uint8_t minor_version = header->version & 0xFF;
138 : :
139 : : /* s2n has it's own legacy format for storing version numbers */
140 : 7326309 : const uint8_t version = (major_version * 10) + minor_version;
141 : : /* We record the protocol version in the first record seen by the server for fingerprinting usecases */
142 [ + + ]: 7326309 : if (!conn->client_hello.record_version_recorded) {
143 : 3307945 : conn->client_hello.legacy_record_version = version;
144 : 3307945 : conn->client_hello.record_version_recorded = 1;
145 : 3307945 : }
146 : :
147 : : /* https://tools.ietf.org/html/rfc5246#appendix-E.1 states that servers must accept any value {03,XX} as the record
148 : : * layer version number for the first TLS record. There is some ambiguity here because the client does not know
149 : : * what version to use in the record header prior to receiving the ServerHello. Some client implementations may use
150 : : * a garbage value(not {03,XX}) in the ClientHello.
151 : : * Choose to be lenient to these clients. After protocol negotiation, we will enforce that all record versions
152 : : * match the negotiated version.
153 : : */
154 : :
155 [ + + ][ + + ]: 7326309 : S2N_ERROR_IF(conn->actual_protocol_version_established && S2N_MIN(conn->actual_protocol_version, S2N_TLS12) /* check against legacy record version (1.2) in tls 1.3 */
[ + + ][ + - ]
156 : 7326309 : != version,
157 : 7326309 : S2N_ERR_BAD_MESSAGE);
158 : :
159 : : /* Some servers send fragments that are above the maximum length (e.g.
160 : : * Openssl 1.0.1), so we don't check if the fragment length is >
161 : : * S2N_TLS_MAXIMUM_FRAGMENT_LENGTH. We allow up to 2^16.
162 : : *
163 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
164 : : *= type=exception
165 : : *= reason=Incorrect implementations exist in the wild. Ignoring instead.
166 : : *# The length MUST NOT exceed 2^14 bytes. An
167 : : *# endpoint that receives a record that exceeds this length MUST
168 : : *# terminate the connection with a "record_overflow" alert.
169 : : */
170 [ - + ]: 7326307 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &header->length));
171 [ - + ]: 7326307 : POSIX_GUARD(s2n_stuffer_reread(in));
172 : :
173 : 7326307 : return 0;
174 : 7326307 : }
175 : :
176 : : /* In TLS 1.3, handle CCS message as unprotected records all the time.
177 : : * https://tools.ietf.org/html/rfc8446#section-5
178 : : *
179 : : * In TLS 1.2 and TLS 1.3 Alert messages are plaintext or encrypted
180 : : * depending on the context of the connection. If we receive an encrypted
181 : : * alert, the record type is TLS_APPLICATION_DATA at this point. It will
182 : : * be decrypted and processed in s2n_handshake_io. We may receive a
183 : : * plaintext alert if we hit an error before the handshake completed
184 : : * (like a certificate failed to validate).
185 : : * https://tools.ietf.org/html/rfc8446#section-6
186 : : *
187 : : * This function is specific to TLS 1.3 to avoid changing the behavior
188 : : * of existing interpretation of TLS 1.2 alerts. */
189 : : static bool s2n_is_tls13_plaintext_content(struct s2n_connection *conn, uint8_t content_type)
190 : 7227482 : {
191 [ + + ]: 7227482 : if (conn->actual_protocol_version != S2N_TLS13) {
192 : 7050280 : return false;
193 : 7050280 : }
194 : :
195 : : /*
196 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.2
197 : : *# The outer opaque_type field of a TLSCiphertext record
198 : : *# is always set to the value 23 (application_data)
199 : : *
200 : : * Plaintext alerts are only valid during the handshake (e.g., if
201 : : * certificate validation fails before encryption is established).
202 : : * After the handshake completes, RFC 8446 Section 5.2 requires all
203 : : * records to be encrypted, so post-handshake alerts must arrive as
204 : : * APPLICATION_DATA records with an inner content type of ALERT.
205 : : *
206 : : * Accepting plaintext alerts post-handshake would allow an on-path
207 : : * attacker to flip the outer content_type of an encrypted record
208 : : * from APPLICATION_DATA (0x17) to ALERT (0x15), routing the raw
209 : : * AEAD ciphertext through the null cipher and into the alert parser.
210 : : * If the first two ciphertext bytes happen to form a close_notify
211 : : * (probability 1/256) or user_canceled (probability 1/256), the
212 : : * record is silently consumed — either as a fake shutdown or as a
213 : : * discarded warning — without incrementing the AEAD sequence number.
214 : : * This enables repeated, non-desynchronizing attempts at targeted
215 : : * connection kills or silent record drops.
216 : : */
217 [ + + ][ + + ]: 177202 : if (content_type == TLS_ALERT && !s2n_handshake_is_complete(conn)) {
218 : 1510 : return true;
219 : 1510 : }
220 : :
221 : : /*
222 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5
223 : : *# An implementation may receive an unencrypted record of type
224 : : *# change_cipher_spec consisting of the single byte value 0x01
225 : : *# at any time after the first ClientHello message has been
226 : : *# sent or received and before the peer's Finished message has
227 : : *# been received
228 : : *
229 : : * CCS is only valid during the handshake. Once the handshake is
230 : : * complete, a CCS record is a protocol violation and must not be
231 : : * routed through the plaintext path, as that would allow it to
232 : : * bypass the content_type validation in s2n_record_parse.
233 : : */
234 [ + + ][ + + ]: 175692 : if (content_type == TLS_CHANGE_CIPHER_SPEC && !s2n_handshake_is_complete(conn)) {
235 : 19378 : return true;
236 : 19378 : }
237 : :
238 : 156314 : return false;
239 : 175692 : }
240 : :
241 : : int s2n_record_parse(struct s2n_connection *conn)
242 : 3613741 : {
243 : 3613741 : struct s2n_record_header header = { 0 };
244 [ - + ]: 3613741 : POSIX_GUARD(s2n_record_header_parse(conn, &header));
245 : :
246 : 3613741 : struct s2n_crypto_parameters *current_client_crypto = conn->client;
247 : 3613741 : struct s2n_crypto_parameters *current_server_crypto = conn->server;
248 [ + + ]: 3613741 : if (s2n_is_tls13_plaintext_content(conn, header.content_type)) {
249 [ # # ][ - + ]: 10444 : POSIX_ENSURE_REF(conn->initial);
250 : 10444 : conn->client = conn->initial;
251 : 10444 : conn->server = conn->initial;
252 : 10444 : }
253 : :
254 : 3613741 : const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
255 : 3613741 : uint8_t *implicit_iv = conn->client->client_implicit_iv;
256 : 3613741 : struct s2n_hmac_state *mac = &conn->client->client_record_mac;
257 : 3613741 : uint8_t *sequence_number = conn->client->client_sequence_number;
258 : 3613741 : struct s2n_session_key *session_key = &conn->client->client_key;
259 : :
260 [ + + ]: 3613741 : if (conn->mode == S2N_CLIENT) {
261 : 95039 : cipher_suite = conn->server->cipher_suite;
262 : 95039 : implicit_iv = conn->server->server_implicit_iv;
263 : 95039 : mac = &conn->server->server_record_mac;
264 : 95039 : sequence_number = conn->server->server_sequence_number;
265 : 95039 : session_key = &conn->server->server_key;
266 : 95039 : }
267 : :
268 [ + + ]: 3613741 : if (s2n_is_tls13_plaintext_content(conn, header.content_type)) {
269 : 10444 : conn->client = current_client_crypto;
270 : 10444 : conn->server = current_server_crypto;
271 : 10444 : }
272 : :
273 : : /* The NULL stream cipher MUST NEVER be used for ApplicationData.
274 : : * If ApplicationData is unencrypted, we can't trust it. */
275 [ + + ]: 3613741 : if (cipher_suite->record_alg->cipher == &s2n_null_cipher) {
276 [ + - ][ + + ]: 77279 : POSIX_ENSURE(header.content_type != TLS_APPLICATION_DATA, S2N_ERR_DECRYPT);
277 : 77279 : }
278 : :
279 : : /*
280 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.2
281 : : *# The outer opaque_type field of a TLSCiphertext record
282 : : *# is always set to the value 23 (application_data)
283 : : *
284 : : * For TLS 1.3 encrypted records, the outer content_type MUST be
285 : : * TLS_APPLICATION_DATA. The AEAD AAD hardcodes this value, so the
286 : : * outer byte is not covered by the authentication tag. Without this
287 : : * check, records with unrecognized content_type values would be
288 : : * discarded after decryption without surfacing an error, which
289 : : * violates the record integrity guarantees of TLS 1.3.
290 : : *
291 : : * This check only applies to encrypted records (non-null cipher).
292 : : * During the handshake, plaintext records with other content_types
293 : : * (HANDSHAKE, ALERT, CCS) are legitimate and handled by
294 : : * s2n_is_tls13_plaintext_content above.
295 : : */
296 [ + + ]: 3613288 : if (conn->actual_protocol_version == S2N_TLS13
297 [ + + ]: 3613288 : && cipher_suite->record_alg->cipher != &s2n_null_cipher) {
298 [ + + ][ + - ]: 70055 : POSIX_ENSURE(header.content_type == TLS_APPLICATION_DATA, S2N_ERR_BAD_MESSAGE);
299 : 70055 : }
300 : :
301 : 3613280 : switch (cipher_suite->record_alg->cipher->type) {
302 [ + + ]: 3387030 : case S2N_AEAD:
303 [ + + ]: 3387030 : POSIX_GUARD(s2n_record_parse_aead(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
304 : 194489 : break;
305 [ + + ]: 194489 : case S2N_CBC:
306 [ - + ]: 41812 : POSIX_GUARD(s2n_record_parse_cbc(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
307 : 41812 : break;
308 [ + + ]: 107612 : case S2N_COMPOSITE:
309 [ - + ]: 107612 : POSIX_GUARD(s2n_record_parse_composite(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
310 : 107612 : break;
311 [ + + ]: 107612 : case S2N_STREAM:
312 [ + + ]: 76826 : POSIX_GUARD(s2n_record_parse_stream(cipher_suite, conn, &header, implicit_iv, mac, sequence_number, session_key));
313 : 60648 : break;
314 [ - + ]: 60648 : default:
315 [ # # ]: 0 : POSIX_BAIL(S2N_ERR_CIPHER_TYPE);
316 : 0 : break;
317 : 3613280 : }
318 : :
319 : 404561 : return 0;
320 : 3613280 : }
321 : :
322 : : int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t *record_type)
323 : 70003 : {
324 : 70003 : uint32_t bytes_left = s2n_stuffer_data_available(stuffer);
325 : :
326 : : /* From rfc8446 Section 5.4
327 : : * The presence of padding does not change the overall record size
328 : : * limitations: the full encoded TLSInnerPlaintext MUST NOT exceed 2^14
329 : : * + 1 octets
330 : : *
331 : : * Certain versions of Java can generate inner plaintexts with lengths up to
332 : : * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16 (See JDK-8221253)
333 : : * However, after the padding is stripped, the result will always be no more than
334 : : * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1
335 : : */
336 [ + + ][ + - ]: 70003 : S2N_ERROR_IF(bytes_left > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
337 : :
338 : : /* set cursor to the end of the stuffer */
339 [ - + ]: 70002 : POSIX_GUARD(s2n_stuffer_skip_read(stuffer, bytes_left));
340 : :
341 : : /* Record type should have values greater than zero.
342 : : * If zero, treat as padding, keep reading and wiping from the back
343 : : * until a non-zero value is found
344 : : */
345 : 70002 : *record_type = 0;
346 [ + + ]: 172821 : while (*record_type == 0) {
347 : : /* back the cursor by one to read off the last byte */
348 [ + + ]: 102823 : POSIX_GUARD(s2n_stuffer_rewind_read(stuffer, 1));
349 : :
350 : : /* set the record type */
351 [ - + ]: 102819 : POSIX_GUARD(s2n_stuffer_read_uint8(stuffer, record_type));
352 : :
353 : : /* wipe the last byte at the end of the stuffer */
354 [ - + ]: 102819 : POSIX_GUARD(s2n_stuffer_wipe_n(stuffer, 1));
355 : 102819 : }
356 : :
357 : : /* only the original plaintext should remain */
358 : : /* now reset the read cursor at where it should be */
359 [ - + ]: 69998 : POSIX_GUARD(s2n_stuffer_reread(stuffer));
360 : :
361 : : /* Even in the incorrect case above with up to 16 extra bytes, we should never see too much data after unpadding */
362 [ + + ][ + - ]: 69998 : S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
363 : :
364 : 69997 : return 0;
365 : 69998 : }
366 : :
367 : : S2N_RESULT s2n_record_wipe(struct s2n_connection *conn)
368 : 240945 : {
369 [ - + ][ # # ]: 240945 : RESULT_ENSURE_REF(conn);
370 [ - + ]: 240945 : RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->header_in));
371 [ - + ]: 240945 : RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->in));
372 : 240945 : conn->in_status = ENCRYPTED;
373 : :
374 : : /* Release the memory in conn->in, which un-taints buffer_in */
375 [ - + ]: 240945 : RESULT_GUARD_POSIX(s2n_stuffer_free(&conn->in));
376 : 240945 : conn->buffer_in.tainted = false;
377 : :
378 : : /* Reclaim any memory in buffer_in if possible.
379 : : * We want to avoid an expensive shift / copy later if possible.
380 : : */
381 [ + + ]: 240945 : if (s2n_stuffer_is_consumed(&conn->buffer_in)) {
382 [ - + ]: 240449 : RESULT_GUARD_POSIX(s2n_stuffer_rewrite(&conn->buffer_in));
383 : 240449 : }
384 : 240945 : return S2N_RESULT_OK;
385 : 240945 : }
|