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 <sys/param.h>
19 : :
20 : : #include "crypto/s2n_cipher.h"
21 : : #include "crypto/s2n_hmac.h"
22 : : #include "crypto/s2n_sequence.h"
23 : : #include "error/s2n_errno.h"
24 : : #include "stuffer/s2n_stuffer.h"
25 : : #include "tls/s2n_cipher_suites.h"
26 : : #include "tls/s2n_connection.h"
27 : : #include "tls/s2n_crypto.h"
28 : : #include "utils/s2n_blob.h"
29 : : #include "utils/s2n_safety.h"
30 : :
31 : : int s2n_sslv2_record_header_parse(
32 : : struct s2n_connection *conn,
33 : : uint8_t *record_type,
34 : : uint8_t *client_protocol_version,
35 : : uint16_t *fragment_length)
36 : 193 : {
37 : 193 : struct s2n_stuffer *header_in = &conn->header_in;
38 : :
39 [ # # ][ - + ]: 193 : POSIX_ENSURE(s2n_stuffer_data_available(header_in) >= S2N_TLS_RECORD_HEADER_LENGTH,
40 : 193 : S2N_ERR_BAD_MESSAGE);
41 : :
42 [ - + ]: 193 : POSIX_GUARD(s2n_stuffer_read_uint16(header_in, fragment_length));
43 : :
44 : : /* The first bit of the SSLv2 message would usually indicate whether the
45 : : * length is 2 bytes long or 3 bytes long.
46 : : * See https://www.ietf.org/archive/id/draft-hickman-netscape-ssl-00.txt
47 : : *
48 : : * However, s2n-tls only supports SSLv2 for ClientHellos as defined in the
49 : : * TLS1.2 RFC. In that case, the first bit must always be set to distinguish
50 : : * SSLv2 from non-SSLv2 headers. The length is always 2 bytes.
51 : : * See https://datatracker.ietf.org/doc/html/rfc5246#appendix-E.2
52 : : *
53 : : * Since the first bit is not actually used to indicate length, we need to
54 : : * remove it from the length.
55 : : *
56 : : *= https://www.rfc-editor.org/rfc/rfc5246#appendix-E.2
57 : : *# msg_length
58 : : *# The highest bit MUST be 1; the remaining bits contain the length
59 : : *# of the following data in bytes.
60 : : */
61 [ # # ][ - + ]: 193 : POSIX_ENSURE(*fragment_length & S2N_TLS_SSLV2_HEADER_FLAG_UINT16, S2N_ERR_BAD_MESSAGE);
62 : 193 : *fragment_length ^= S2N_TLS_SSLV2_HEADER_FLAG_UINT16;
63 : :
64 : : /* We read 5 bytes into header_in because we expected a standard, non-SSLv2 record header
65 : : * instead of an SSLv2 message. We have therefore already read 3 bytes of the payload.
66 : : * We need to adjust "fragment_length" to account for the bytes we have already
67 : : * read so that we will only attempt to read the remainder of the payload on
68 : : * our next call to conn->recv.
69 : : */
70 [ + + ][ + - ]: 193 : POSIX_ENSURE(*fragment_length >= s2n_stuffer_data_available(header_in), S2N_ERR_BAD_MESSAGE);
71 : 191 : *fragment_length -= s2n_stuffer_data_available(header_in);
72 : :
73 : : /* By reading 5 bytes for a standard header we have also read the first
74 : : * 3 bytes of the SSLv2 ClientHello message.
75 : : * So we now need to parse those three bytes.
76 : : *
77 : : * The first field of an SSLv2 ClientHello is the msg_type.
78 : : * This is always '1', matching the ClientHello msg_type used by later
79 : : * handshake messages.
80 : : */
81 [ - + ]: 191 : POSIX_GUARD(s2n_stuffer_read_uint8(header_in, record_type));
82 : :
83 : : /*
84 : : * The second field of an SSLv2 ClientHello is the version.
85 : : *
86 : : * The protocol version read here will likely not be SSLv2, since we only
87 : : * accept SSLv2 ClientHellos offering higher protocol versions.
88 : : * See s2n_sslv2_client_hello_parse.
89 : : */
90 : 191 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
91 [ - + ]: 191 : POSIX_GUARD(s2n_stuffer_read_bytes(header_in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
92 : 191 : *client_protocol_version = (protocol_version[0] * 10) + protocol_version[1];
93 : :
94 [ - + ]: 191 : POSIX_GUARD(s2n_stuffer_reread(header_in));
95 : 191 : return 0;
96 : 191 : }
97 : :
98 : : int s2n_record_header_parse(
99 : : struct s2n_connection *conn,
100 : : uint8_t *content_type,
101 : : uint16_t *fragment_length)
102 : 7340517 : {
103 : 7340517 : struct s2n_stuffer *in = &conn->header_in;
104 : :
105 [ - + ][ # # ]: 7340517 : S2N_ERROR_IF(s2n_stuffer_data_available(in) < S2N_TLS_RECORD_HEADER_LENGTH, S2N_ERR_BAD_MESSAGE);
106 : :
107 [ - + ]: 7340517 : POSIX_GUARD(s2n_stuffer_read_uint8(in, content_type));
108 : :
109 : 7340517 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
110 [ - + ]: 7340517 : POSIX_GUARD(s2n_stuffer_read_bytes(in, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
111 : :
112 : 7340517 : const uint8_t version = (protocol_version[0] * 10) + protocol_version[1];
113 : : /* We record the protocol version in the first record seen by the server for fingerprinting usecases */
114 [ + + ]: 7340517 : if (!conn->client_hello.record_version_recorded) {
115 : 3306916 : conn->client_hello.legacy_record_version = version;
116 : 3306916 : conn->client_hello.record_version_recorded = 1;
117 : 3306916 : }
118 : :
119 : : /* https://tools.ietf.org/html/rfc5246#appendix-E.1 states that servers must accept any value {03,XX} as the record
120 : : * layer version number for the first TLS record. There is some ambiguity here because the client does not know
121 : : * what version to use in the record header prior to receiving the ServerHello. Some client implementations may use
122 : : * a garbage value(not {03,XX}) in the ClientHello.
123 : : * Choose to be lenient to these clients. After protocol negotiation, we will enforce that all record versions
124 : : * match the negotiated version.
125 : : */
126 : :
127 [ + + ][ + + ]: 7340517 : S2N_ERROR_IF(conn->actual_protocol_version_established && MIN(conn->actual_protocol_version, S2N_TLS12) /* check against legacy record version (1.2) in tls 1.3 */
[ + + ][ + - ]
128 : 7340517 : != version,
129 : 7340517 : S2N_ERR_BAD_MESSAGE);
130 : :
131 : : /* Some servers send fragments that are above the maximum length (e.g.
132 : : * Openssl 1.0.1), so we don't check if the fragment length is >
133 : : * S2N_TLS_MAXIMUM_FRAGMENT_LENGTH. We allow up to 2^16.
134 : : *
135 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
136 : : *= type=exception
137 : : *= reason=Incorrect implementations exist in the wild. Ignoring instead.
138 : : *# The length MUST NOT exceed 2^14 bytes. An
139 : : *# endpoint that receives a record that exceeds this length MUST
140 : : *# terminate the connection with a "record_overflow" alert.
141 : : */
142 [ - + ]: 7340515 : POSIX_GUARD(s2n_stuffer_read_uint16(in, fragment_length));
143 [ - + ]: 7340515 : POSIX_GUARD(s2n_stuffer_reread(in));
144 : :
145 : 7340515 : return 0;
146 : 7340515 : }
147 : :
148 : : /* In TLS 1.3, handle CCS message as unprotected records all the time.
149 : : * https://tools.ietf.org/html/rfc8446#section-5
150 : : *
151 : : * In TLS 1.2 and TLS 1.3 Alert messages are plaintext or encrypted
152 : : * depending on the context of the connection. If we receive an encrypted
153 : : * alert, the record type is TLS_APPLICATION_DATA at this point. It will
154 : : * be decrypted and processed in s2n_handshake_io. We may receive a
155 : : * plaintext alert if we hit an error before the handshake completed
156 : : * (like a certificate failed to validate).
157 : : * https://tools.ietf.org/html/rfc8446#section-6
158 : : *
159 : : * This function is specific to TLS 1.3 to avoid changing the behavior
160 : : * of existing interpretation of TLS 1.2 alerts. */
161 : : static bool s2n_is_tls13_plaintext_content(struct s2n_connection *conn, uint8_t content_type)
162 : 7241694 : {
163 [ + + ][ + + ]: 7241694 : return conn->actual_protocol_version == S2N_TLS13 && (content_type == TLS_ALERT || content_type == TLS_CHANGE_CIPHER_SPEC);
[ + + ]
164 : 7241694 : }
165 : :
166 : : int s2n_record_parse(struct s2n_connection *conn)
167 : 3620847 : {
168 : 3620847 : uint8_t content_type = 0;
169 : 3620847 : uint16_t encrypted_length = 0;
170 [ - + ]: 3620847 : POSIX_GUARD(s2n_record_header_parse(conn, &content_type, &encrypted_length));
171 : :
172 : 3620847 : struct s2n_crypto_parameters *current_client_crypto = conn->client;
173 : 3620847 : struct s2n_crypto_parameters *current_server_crypto = conn->server;
174 [ + + ]: 3620847 : if (s2n_is_tls13_plaintext_content(conn, content_type)) {
175 [ - + ][ # # ]: 9544 : POSIX_ENSURE_REF(conn->initial);
176 : 9544 : conn->client = conn->initial;
177 : 9544 : conn->server = conn->initial;
178 : 9544 : }
179 : :
180 : 3620847 : const struct s2n_cipher_suite *cipher_suite = conn->client->cipher_suite;
181 : 3620847 : uint8_t *implicit_iv = conn->client->client_implicit_iv;
182 : 3620847 : struct s2n_hmac_state *mac = &conn->client->client_record_mac;
183 : 3620847 : uint8_t *sequence_number = conn->client->client_sequence_number;
184 : 3620847 : struct s2n_session_key *session_key = &conn->client->client_key;
185 : :
186 [ + + ]: 3620847 : if (conn->mode == S2N_CLIENT) {
187 : 91856 : cipher_suite = conn->server->cipher_suite;
188 : 91856 : implicit_iv = conn->server->server_implicit_iv;
189 : 91856 : mac = &conn->server->server_record_mac;
190 : 91856 : sequence_number = conn->server->server_sequence_number;
191 : 91856 : session_key = &conn->server->server_key;
192 : 91856 : }
193 : :
194 [ + + ]: 3620847 : if (s2n_is_tls13_plaintext_content(conn, content_type)) {
195 : 9544 : conn->client = current_client_crypto;
196 : 9544 : conn->server = current_server_crypto;
197 : 9544 : }
198 : :
199 : : /* The NULL stream cipher MUST NEVER be used for ApplicationData.
200 : : * If ApplicationData is unencrypted, we can't trust it. */
201 [ + + ]: 3620847 : if (cipher_suite->record_alg->cipher == &s2n_null_cipher) {
202 [ + - ][ + + ]: 75070 : POSIX_ENSURE(content_type != TLS_APPLICATION_DATA, S2N_ERR_DECRYPT);
203 : 75070 : }
204 : :
205 : 3620394 : switch (cipher_suite->record_alg->cipher->type) {
206 [ + + ]: 3396428 : case S2N_AEAD:
207 [ + + ]: 3396428 : POSIX_GUARD(s2n_record_parse_aead(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
208 : 203886 : break;
209 [ + + ]: 203886 : case S2N_CBC:
210 [ - + ]: 41767 : POSIX_GUARD(s2n_record_parse_cbc(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
211 : 41767 : break;
212 [ + + ]: 107582 : case S2N_COMPOSITE:
213 [ - + ]: 107582 : POSIX_GUARD(s2n_record_parse_composite(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
214 : 107582 : break;
215 [ + + ]: 107582 : case S2N_STREAM:
216 [ + + ]: 74617 : POSIX_GUARD(s2n_record_parse_stream(cipher_suite, conn, content_type, encrypted_length, implicit_iv, mac, sequence_number, session_key));
217 : 58439 : break;
218 [ - + ]: 58439 : default:
219 [ # # ]: 0 : POSIX_BAIL(S2N_ERR_CIPHER_TYPE);
220 : 0 : break;
221 : 3620394 : }
222 : :
223 : 411674 : return 0;
224 : 3620394 : }
225 : :
226 : : int s2n_tls13_parse_record_type(struct s2n_stuffer *stuffer, uint8_t *record_type)
227 : 67472 : {
228 : 67472 : uint32_t bytes_left = s2n_stuffer_data_available(stuffer);
229 : :
230 : : /* From rfc8446 Section 5.4
231 : : * The presence of padding does not change the overall record size
232 : : * limitations: the full encoded TLSInnerPlaintext MUST NOT exceed 2^14
233 : : * + 1 octets
234 : : *
235 : : * Certain versions of Java can generate inner plaintexts with lengths up to
236 : : * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16 (See JDK-8221253)
237 : : * However, after the padding is stripped, the result will always be no more than
238 : : * S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1
239 : : */
240 [ + + ][ + - ]: 67472 : S2N_ERROR_IF(bytes_left > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH + 16, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
241 : :
242 : : /* set cursor to the end of the stuffer */
243 [ - + ]: 67471 : POSIX_GUARD(s2n_stuffer_skip_read(stuffer, bytes_left));
244 : :
245 : : /* Record type should have values greater than zero.
246 : : * If zero, treat as padding, keep reading and wiping from the back
247 : : * until a non-zero value is found
248 : : */
249 : 67471 : *record_type = 0;
250 [ + + ]: 167759 : while (*record_type == 0) {
251 : : /* back the cursor by one to read off the last byte */
252 [ + + ]: 100292 : POSIX_GUARD(s2n_stuffer_rewind_read(stuffer, 1));
253 : :
254 : : /* set the record type */
255 [ - + ]: 100288 : POSIX_GUARD(s2n_stuffer_read_uint8(stuffer, record_type));
256 : :
257 : : /* wipe the last byte at the end of the stuffer */
258 [ - + ]: 100288 : POSIX_GUARD(s2n_stuffer_wipe_n(stuffer, 1));
259 : 100288 : }
260 : :
261 : : /* only the original plaintext should remain */
262 : : /* now reset the read cursor at where it should be */
263 [ - + ]: 67467 : POSIX_GUARD(s2n_stuffer_reread(stuffer));
264 : :
265 : : /* Even in the incorrect case above with up to 16 extra bytes, we should never see too much data after unpadding */
266 [ + + ][ + - ]: 67467 : S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) > S2N_MAXIMUM_INNER_PLAINTEXT_LENGTH - 1, S2N_ERR_MAX_INNER_PLAINTEXT_SIZE);
267 : :
268 : 67466 : return 0;
269 : 67467 : }
270 : :
271 : : S2N_RESULT s2n_record_wipe(struct s2n_connection *conn)
272 : 248058 : {
273 [ - + ][ # # ]: 248058 : RESULT_ENSURE_REF(conn);
274 [ - + ]: 248058 : RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->header_in));
275 [ - + ]: 248058 : RESULT_GUARD_POSIX(s2n_stuffer_wipe(&conn->in));
276 : 248058 : conn->in_status = ENCRYPTED;
277 : :
278 : : /* Release the memory in conn->in, which un-taints buffer_in */
279 [ - + ]: 248058 : RESULT_GUARD_POSIX(s2n_stuffer_free(&conn->in));
280 : 248058 : conn->buffer_in.tainted = false;
281 : :
282 : : /* Reclaim any memory in buffer_in if possible.
283 : : * We want to avoid an expensive shift / copy later if possible.
284 : : */
285 [ + + ]: 248058 : if (s2n_stuffer_is_consumed(&conn->buffer_in)) {
286 [ - + ]: 247562 : RESULT_GUARD_POSIX(s2n_stuffer_rewrite(&conn->buffer_in));
287 : 247562 : }
288 : 248058 : return S2N_RESULT_OK;
289 : 248058 : }
|