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 : : /* Use usleep */
17 : : #define _XOPEN_SOURCE 500
18 : : #include <errno.h>
19 : : #include <unistd.h>
20 : :
21 : : #include "api/s2n.h"
22 : : #include "error/s2n_errno.h"
23 : : #include "stuffer/s2n_stuffer.h"
24 : : #include "tls/s2n_alerts.h"
25 : : #include "tls/s2n_connection.h"
26 : : #include "tls/s2n_handshake.h"
27 : : #include "tls/s2n_ktls.h"
28 : : #include "tls/s2n_post_handshake.h"
29 : : #include "tls/s2n_record.h"
30 : : #include "tls/s2n_resume.h"
31 : : #include "tls/s2n_tls.h"
32 : : #include "utils/s2n_blob.h"
33 : : #include "utils/s2n_io.h"
34 : : #include "utils/s2n_safety.h"
35 : :
36 : : S2N_RESULT s2n_recv_in_init(struct s2n_connection *conn, uint32_t written, uint32_t total)
37 : 360550 : {
38 [ # # ][ - + ]: 360550 : RESULT_ENSURE_REF(conn);
39 : :
40 : : /* If we're going to initialize conn->in to point to more memory than
41 : : * is actually readable, make sure that the additional memory exists.
42 : : */
43 [ # # ][ - + ]: 360550 : RESULT_ENSURE_LTE(written, total);
44 : 360550 : uint32_t remaining = total - written;
45 [ - + ][ # # ]: 360550 : RESULT_ENSURE_LTE(remaining, s2n_stuffer_space_remaining(&conn->buffer_in));
46 : :
47 : 360550 : uint8_t *data = s2n_stuffer_raw_read(&conn->buffer_in, written);
48 [ - + ][ # # ]: 360550 : RESULT_ENSURE_REF(data);
49 [ - + ]: 360550 : RESULT_GUARD_POSIX(s2n_stuffer_free(&conn->in));
50 [ - + ]: 360550 : RESULT_GUARD_POSIX(s2n_blob_init(&conn->in.blob, data, total));
51 [ - + ]: 360550 : RESULT_GUARD_POSIX(s2n_stuffer_skip_write(&conn->in, written));
52 : 360550 : return S2N_RESULT_OK;
53 : 360550 : }
54 : :
55 : : S2N_RESULT s2n_read_in_bytes(struct s2n_connection *conn, struct s2n_stuffer *output, uint32_t length)
56 : 794918 : {
57 [ + + ]: 1382770 : while (s2n_stuffer_data_available(output) < length) {
58 : 893713 : uint32_t remaining = length - s2n_stuffer_data_available(output);
59 [ + + ]: 893713 : if (conn->recv_buffering) {
60 [ + + ]: 606 : remaining = S2N_MAX(remaining, s2n_stuffer_space_remaining(output));
61 : 606 : }
62 : 893713 : errno = 0;
63 : 893713 : int r = s2n_connection_recv_stuffer(output, conn, remaining);
64 [ + + ]: 893713 : if (r == 0) {
65 : 6 : s2n_atomic_flag_set(&conn->read_closed);
66 : 6 : }
67 [ + + ]: 893713 : RESULT_GUARD(s2n_io_check_read_result(r));
68 : 587852 : conn->wire_bytes_in += r;
69 : 587852 : }
70 : :
71 : 489057 : return S2N_RESULT_OK;
72 : 794918 : }
73 : :
74 : : static S2N_RESULT s2n_recv_buffer_in(struct s2n_connection *conn, size_t min_size)
75 : 795668 : {
76 [ - + ]: 795668 : RESULT_GUARD_POSIX(s2n_stuffer_resize_if_empty(&conn->buffer_in, S2N_LARGE_FRAGMENT_LENGTH));
77 : 795668 : uint32_t buffer_in_available = s2n_stuffer_data_available(&conn->buffer_in);
78 [ + + ]: 795668 : if (buffer_in_available < min_size) {
79 : 794453 : uint32_t remaining = min_size - buffer_in_available;
80 [ + + ]: 794453 : if (s2n_stuffer_space_remaining(&conn->buffer_in) < remaining) {
81 [ - + ]: 566 : RESULT_GUARD_POSIX(s2n_stuffer_shift(&conn->buffer_in));
82 : 566 : }
83 [ + + ]: 794453 : RESULT_GUARD(s2n_read_in_bytes(conn, &conn->buffer_in, min_size));
84 : 794453 : }
85 : 489864 : return S2N_RESULT_OK;
86 : 795668 : }
87 : :
88 : : /**
89 : : * An S2N_SUCCESS return from this method means that a full record is available
90 : : * in plaintext in conn->in.
91 : : */
92 : : int s2n_read_full_record(struct s2n_connection *conn, uint8_t *record_type, int *isSSLv2)
93 : 589175 : {
94 : 589175 : *isSSLv2 = 0;
95 : :
96 [ + + ]: 589175 : if (conn->ktls_recv_enabled) {
97 : 21 : return s2n_ktls_read_full_record(conn, record_type);
98 : 21 : }
99 : :
100 : : /* If the record has already been decrypted, then leave it alone */
101 [ + + ]: 589154 : if (conn->in_status == PLAINTEXT) {
102 : : /* Only application data packets count as plaintext */
103 : 35237 : *record_type = TLS_APPLICATION_DATA;
104 : 35237 : return S2N_SUCCESS;
105 : 35237 : }
106 : :
107 : : /* Read the record until we at least have a header */
108 [ - + ]: 553917 : POSIX_GUARD(s2n_stuffer_reread(&conn->header_in));
109 : 553917 : uint32_t header_available = s2n_stuffer_data_available(&conn->header_in);
110 [ + + ]: 553917 : if (header_available < S2N_TLS_RECORD_HEADER_LENGTH) {
111 : 435427 : uint32_t header_remaining = S2N_TLS_RECORD_HEADER_LENGTH - header_available;
112 : 435427 : s2n_result ret = s2n_recv_buffer_in(conn, header_remaining);
113 [ + + ]: 435427 : uint32_t header_read = S2N_MIN(header_remaining, s2n_stuffer_data_available(&conn->buffer_in));
114 [ - + ]: 435427 : POSIX_GUARD(s2n_stuffer_copy(&conn->buffer_in, &conn->header_in, header_read));
115 [ + + ]: 435427 : POSIX_GUARD_RESULT(ret);
116 : 435427 : }
117 : :
118 : 363548 : uint16_t fragment_length = 0;
119 : :
120 : : /* If the first bit is set then this is an SSLv2 record */
121 [ + + ]: 363548 : if (conn->header_in.blob.data[0] & S2N_TLS_SSLV2_HEADER_FLAG) {
122 : 435 : *isSSLv2 = 1;
123 [ - + ][ + - ]: 435 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_sslv2_record_header_parse(conn, record_type, &conn->client_hello.legacy_version, &fragment_length)));
124 : 363113 : } else {
125 : 363113 : struct s2n_record_header header = { 0 };
126 [ + + ][ + - ]: 363113 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_record_header_parse(conn, &header)));
127 : 362987 : *record_type = header.content_type;
128 : 362987 : fragment_length = header.length;
129 : 362987 : }
130 : :
131 : : /* Read enough to have the whole record */
132 : 363422 : uint32_t fragment_available = s2n_stuffer_data_available(&conn->in);
133 [ + + ][ + + ]: 363422 : if (fragment_available < fragment_length || fragment_length == 0) {
134 [ - + ]: 360241 : POSIX_GUARD(s2n_stuffer_rewind_read(&conn->buffer_in, fragment_available));
135 : 360241 : s2n_result ret = s2n_recv_buffer_in(conn, fragment_length);
136 [ + + ]: 360241 : uint32_t fragment_read = S2N_MIN(fragment_length, s2n_stuffer_data_available(&conn->buffer_in));
137 [ - + ]: 360241 : POSIX_GUARD_RESULT(s2n_recv_in_init(conn, fragment_read, fragment_length));
138 [ + + ]: 360241 : POSIX_GUARD_RESULT(ret);
139 : 360241 : }
140 : :
141 [ + + ]: 247987 : if (*isSSLv2) {
142 : 5 : return 0;
143 : 5 : }
144 : :
145 : : /* Decrypt and parse the record */
146 [ + + ]: 247982 : if (s2n_early_data_is_trial_decryption_allowed(conn, *record_type)) {
147 [ + + ][ + - ]: 987 : POSIX_ENSURE(s2n_record_parse(conn) >= S2N_SUCCESS, S2N_ERR_EARLY_DATA_TRIAL_DECRYPT);
148 : 246995 : } else {
149 [ + + ][ + - ]: 246995 : WITH_ERROR_BLINDING(conn, POSIX_GUARD(s2n_record_parse(conn)));
150 : 246995 : }
151 : :
152 : : /* In TLS 1.3, encrypted handshake records would appear to be of record type
153 : : * TLS_APPLICATION_DATA. The actual record content type is found after the encrypted
154 : : * is decrypted.
155 : : */
156 [ + + ][ + + ]: 246560 : if (conn->actual_protocol_version == S2N_TLS13 && *record_type == TLS_APPLICATION_DATA) {
157 [ - + ]: 69988 : POSIX_GUARD(s2n_tls13_parse_record_type(&conn->in, record_type));
158 : 69988 : }
159 : :
160 : 246560 : return 0;
161 : 246560 : }
162 : :
163 : : ssize_t s2n_recv_impl(struct s2n_connection *conn, void *buf, ssize_t size_signed, s2n_blocked_status *blocked)
164 : 371553 : {
165 [ - + ][ # # ]: 371553 : POSIX_ENSURE_GTE(size_signed, 0);
166 : 371553 : size_t size = size_signed;
167 : 371553 : ssize_t bytes_read = 0;
168 : 371553 : struct s2n_blob out = { 0 };
169 [ - + ]: 371553 : POSIX_GUARD(s2n_blob_init(&out, (uint8_t *) buf, 0));
170 : :
171 : : /*
172 : : * Set the `blocked` status to BLOCKED_ON_READ by default
173 : : *
174 : : * The only case in which it should be updated is on a successful read into the provided buffer.
175 : : *
176 : : * Unfortunately, the current `blocked` behavior has become ossified by buggy applications that ignore
177 : : * error types and only read `blocked`. As such, it's very important to avoid changing how this value is updated
178 : : * as it could break applications.
179 : : */
180 : 371553 : *blocked = S2N_BLOCKED_ON_READ;
181 : :
182 [ + + ]: 371553 : if (!s2n_connection_check_io_status(conn, S2N_IO_READABLE)) {
183 : : /*
184 : : *= https://www.rfc-editor.org/rfc/rfc8446#6.1
185 : : *# If a transport-level close
186 : : *# is received prior to a "close_notify", the receiver cannot know that
187 : : *# all the data that was sent has been received.
188 : : *
189 : : *= https://www.rfc-editor.org/rfc/rfc8446#6.1
190 : : *# If the application protocol using TLS provides that any data may be
191 : : *# carried over the underlying transport after the TLS connection is
192 : : *# closed, the TLS implementation MUST receive a "close_notify" alert
193 : : *# before indicating end-of-data to the application layer.
194 : : */
195 [ + + ][ + - ]: 1683 : POSIX_ENSURE(s2n_atomic_flag_test(&conn->close_notify_received), S2N_ERR_CLOSED);
196 : 29 : *blocked = S2N_NOT_BLOCKED;
197 : 29 : return 0;
198 : 1683 : }
199 : :
200 [ + - ][ + + ]: 369870 : POSIX_ENSURE(!s2n_connection_is_quic_enabled(conn), S2N_ERR_UNSUPPORTED_WITH_QUIC);
201 [ + + ]: 369869 : POSIX_GUARD_RESULT(s2n_early_data_validate_recv(conn));
202 : :
203 [ + + ][ + + ]: 397185 : while (size && s2n_connection_check_io_status(conn, S2N_IO_READABLE)) {
204 : 389395 : int isSSLv2 = 0;
205 : 389395 : uint8_t record_type = 0;
206 : 389395 : int r = s2n_read_full_record(conn, &record_type, &isSSLv2);
207 [ + + ]: 389395 : if (r < 0) {
208 : : /* Don't propagate the error if we already read some bytes. */
209 [ + + ][ + + ]: 181280 : if (bytes_read && (s2n_errno == S2N_ERR_CLOSED || s2n_errno == S2N_ERR_IO_BLOCKED)) {
[ + - ]
210 : 285 : break;
211 : 285 : }
212 : :
213 : : /* If we get here, it's an error condition.
214 : : * For stateful resumption, invalidate the session on error to prevent resumption with
215 : : * potentially corrupted session state. This ensures that a bad session state does not
216 : : * lead to repeated failures during resumption attempts.
217 : : */
218 [ + + ][ - + ]: 180995 : if (s2n_errno != S2N_ERR_IO_BLOCKED && s2n_allowed_to_cache_connection(conn) && conn->session_id_len) {
[ # # ]
219 : 0 : conn->config->cache_delete(conn, conn->config->cache_delete_data, conn->session_id, conn->session_id_len);
220 : 0 : }
221 : :
222 : 180995 : S2N_ERROR_PRESERVE_ERRNO();
223 : 180995 : }
224 : :
225 [ + + ][ + - ]: 208115 : S2N_ERROR_IF(isSSLv2, S2N_ERR_BAD_MESSAGE);
226 : :
227 [ + + ]: 208113 : if (record_type != TLS_HANDSHAKE) {
228 : : /*
229 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
230 : : *# - Handshake messages MUST NOT be interleaved with other record
231 : : *# types. That is, if a handshake message is split over two or more
232 : : *# records, there MUST NOT be any other records between them.
233 : : */
234 [ + + ][ + - ]: 183425 : POSIX_ENSURE(s2n_stuffer_is_wiped(&conn->post_handshake.in), S2N_ERR_BAD_MESSAGE);
235 : :
236 : : /* If not handling a handshake message, free the post-handshake memory.
237 : : * Post-handshake messages are infrequent enough that we don't want to
238 : : * keep a potentially large buffer around unnecessarily.
239 : : */
240 [ + + ]: 183423 : if (!s2n_stuffer_is_freed(&conn->post_handshake.in)) {
241 [ - + ]: 1012 : POSIX_GUARD(s2n_stuffer_free(&conn->post_handshake.in));
242 : 1012 : }
243 : 183423 : }
244 : :
245 [ + + ]: 208111 : if (record_type != TLS_APPLICATION_DATA) {
246 : 26209 : switch (record_type) {
247 [ + + ]: 1 : case TLS_CHANGE_CIPHER_SPEC:
248 : : /* CCS records are discarded. In TLS 1.3, CCS is a no-op
249 : : * for middlebox compatibility (RFC 8446 Section 5) and is
250 : : * only expected during the handshake. Post-handshake CCS
251 : : * is now rejected by s2n_record_parse, so this case is
252 : : * only reachable during the handshake or for TLS 1.2. */
253 : 1 : break;
254 [ + + ]: 1520 : case TLS_ALERT:
255 [ + + ]: 1520 : POSIX_GUARD(s2n_process_alert_fragment(conn));
256 : 13 : break;
257 [ + + ]: 24688 : case TLS_HANDSHAKE: {
258 : 24688 : s2n_result result = s2n_post_handshake_recv(conn);
259 : : /* Ignore any errors due to insufficient input data from io.
260 : : * The next iteration of this loop will attempt to read more input data.
261 : : */
262 [ + + ][ + + ]: 24688 : if (s2n_result_is_error(result) && s2n_errno != S2N_ERR_IO_BLOCKED) {
263 [ + - ][ # # ]: 41 : WITH_ERROR_BLINDING(conn, POSIX_GUARD_RESULT(result));
264 : 41 : }
265 : 24647 : break;
266 : 24688 : }
267 [ - + ]: 24647 : default:
268 [ # # ]: 0 : POSIX_BAIL(S2N_ERR_BAD_MESSAGE);
269 : 26209 : }
270 [ - + ]: 24661 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
271 : 24661 : continue;
272 : 24661 : }
273 : :
274 [ + + ]: 181902 : out.size = S2N_MIN(size, s2n_stuffer_data_available(&conn->in));
275 : :
276 [ - + ]: 181902 : POSIX_GUARD(s2n_stuffer_erase_and_read(&conn->in, &out));
277 : 181902 : bytes_read += out.size;
278 : :
279 : 181902 : out.data += out.size;
280 : 181902 : size -= out.size;
281 : :
282 : : /* Are we ready for more encrypted data? */
283 [ + + ]: 181902 : if (s2n_stuffer_data_available(&conn->in) == 0) {
284 [ - + ]: 146742 : POSIX_GUARD_RESULT(s2n_record_wipe(conn));
285 : 146742 : }
286 : :
287 : : /* If we've read some data, return it in legacy mode */
288 [ + - ][ + + ]: 181902 : if (bytes_read && !conn->config->recv_multi_record) {
289 : 179243 : break;
290 : 179243 : }
291 : 181902 : }
292 : :
293 : : /* Due to the history of this API, some applications depend on the blocked status to know if
294 : : * the connection's `in` stuffer was completely cleared. This behavior needs to be preserved.
295 : : *
296 : : * Moving forward, applications should instead use `s2n_peek`, which accomplishes the same thing
297 : : * without conflating being blocked on reading from the OS socket vs blocked on the application's
298 : : * buffer size.
299 : : */
300 [ + + ]: 187318 : if (s2n_stuffer_data_available(&conn->in) == 0) {
301 : 152156 : *blocked = S2N_NOT_BLOCKED;
302 : 152156 : }
303 : :
304 : 187318 : return bytes_read;
305 : 369865 : }
306 : :
307 : : ssize_t s2n_recv(struct s2n_connection *conn, void *buf, ssize_t size, s2n_blocked_status *blocked)
308 : 371555 : {
309 [ # # ][ - + ]: 371555 : POSIX_ENSURE_REF(conn);
310 [ + + ][ + - ]: 371555 : POSIX_ENSURE(!conn->recv_in_use, S2N_ERR_REENTRANCY);
311 : 371553 : conn->recv_in_use = true;
312 : :
313 : 371553 : ssize_t result = s2n_recv_impl(conn, buf, size, blocked);
314 [ + + ]: 371553 : POSIX_GUARD_RESULT(s2n_early_data_record_bytes(conn, result));
315 : :
316 : : /* finish the recv call */
317 [ - + ]: 371552 : POSIX_GUARD_RESULT(s2n_connection_dynamic_free_in_buffer(conn));
318 : :
319 : 371552 : conn->recv_in_use = false;
320 : 371552 : return result;
321 : 371552 : }
322 : :
323 : : uint32_t s2n_peek(struct s2n_connection *conn)
324 : 4459 : {
325 [ + + ]: 4459 : if (conn == NULL) {
326 : 1 : return 0;
327 : 1 : }
328 : :
329 : : /* If we have partially buffered an encrypted record,
330 : : * we should not report those bytes as available to read.
331 : : */
332 [ + + ]: 4458 : if (conn->in_status != PLAINTEXT) {
333 : 1305 : return 0;
334 : 1305 : }
335 : :
336 : 3153 : return s2n_stuffer_data_available(&conn->in);
337 : 4458 : }
338 : :
339 : : uint32_t s2n_peek_buffered(struct s2n_connection *conn)
340 : 5 : {
341 [ + + ]: 5 : if (conn == NULL) {
342 : 1 : return 0;
343 : 1 : }
344 : 4 : return s2n_stuffer_data_available(&conn->buffer_in);
345 : 5 : }
|