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_connection.h"
17 : : #include "tls/s2n_early_data.h"
18 : : #include "utils/s2n_mem.h"
19 : : #include "utils/s2n_safety.h"
20 : :
21 : : int s2n_end_of_early_data_send(struct s2n_connection *conn)
22 : 78 : {
23 [ + + ]: 78 : if (conn->early_data_expected) {
24 [ - + ]: 40 : POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
25 [ + - ]: 40 : POSIX_BAIL(S2N_ERR_EARLY_DATA_BLOCKED);
26 : 40 : }
27 : :
28 [ - + ]: 38 : POSIX_GUARD_RESULT(s2n_connection_set_early_data_state(conn, S2N_END_OF_EARLY_DATA));
29 : 38 : return S2N_SUCCESS;
30 : 38 : }
31 : :
32 : : int s2n_end_of_early_data_recv(struct s2n_connection *conn)
33 : 37 : {
34 [ # # ][ - + ]: 37 : POSIX_ENSURE(!s2n_connection_is_quic_enabled(conn), S2N_ERR_BAD_MESSAGE);
35 [ - + ]: 37 : POSIX_GUARD_RESULT(s2n_connection_set_early_data_state(conn, S2N_END_OF_EARLY_DATA));
36 : 37 : return S2N_SUCCESS;
37 : 37 : }
38 : :
39 : : /**
40 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.10
41 : : *# If the client attempts a 0-RTT handshake but the server
42 : : *# rejects it, the server will generally not have the 0-RTT record
43 : : *# protection keys and must instead use trial decryption (either with
44 : : *# the 1-RTT handshake keys or by looking for a cleartext ClientHello in
45 : : *# the case of a HelloRetryRequest) to find the first non-0-RTT message.
46 : : */
47 : : bool s2n_early_data_is_trial_decryption_allowed(struct s2n_connection *conn, uint8_t record_type)
48 : 246518 : {
49 [ + - ][ + + ]: 246518 : return conn && (conn->early_data_state == S2N_EARLY_DATA_REJECTED)
50 [ + + ]: 246518 : && record_type == TLS_APPLICATION_DATA
51 : : /* Only servers receive early data. */
52 [ + + ]: 246518 : && (conn->mode == S2N_SERVER)
53 : : /* Early data is only expected during the handshake. */
54 [ + + ]: 246518 : && (s2n_conn_get_current_message_type(conn) != APPLICATION_DATA);
55 : 246518 : }
56 : :
57 : : static bool s2n_is_early_data_io(struct s2n_connection *conn)
58 : 651742 : {
59 [ + + ]: 651742 : if (s2n_conn_get_current_message_type(conn) == APPLICATION_DATA) {
60 : 524207 : return false;
61 : 524207 : }
62 : :
63 : : /* It would be more accurate to not include this check.
64 : : * However, before the early data feature was added, s2n_send and s2n_recv
65 : : * did not verify that they were being called after a complete handshake.
66 : : * Enforcing that broke several S2N tests, and might have broken customers too.
67 : : *
68 : : * Therefore, only consider this early data if the customer has indicated that
69 : : * they are aware of early data, either because early data is currently expected
70 : : * or early data is in a state that indicates that early data was previously expected.
71 : : */
72 [ + + ]: 127535 : if (conn->early_data_expected
73 [ + + ][ + + ]: 127535 : || (conn->mode == S2N_CLIENT && conn->early_data_state == S2N_EARLY_DATA_REQUESTED)
74 [ + + ]: 127535 : || conn->early_data_state == S2N_EARLY_DATA_ACCEPTED
75 [ + + ]: 127535 : || conn->early_data_state == S2N_END_OF_EARLY_DATA) {
76 : 1937 : return true;
77 : 1937 : }
78 : 125598 : return false;
79 : 127535 : }
80 : :
81 : : S2N_RESULT s2n_early_data_record_bytes(struct s2n_connection *conn, ssize_t data_len)
82 : 653816 : {
83 [ + + ][ + - ]: 653816 : RESULT_ENSURE_REF(conn);
84 [ + + ][ + + ]: 653815 : if (data_len < 0 || !s2n_is_early_data_io(conn)) {
85 : 653403 : return S2N_RESULT_OK;
86 : 653403 : }
87 : :
88 : : /* Ensure the bytes read are within the bounds of what we can actually record. */
89 [ + + ]: 412 : if ((size_t) data_len > (UINT64_MAX - conn->early_data_bytes)) {
90 : 1 : conn->early_data_bytes = UINT64_MAX;
91 [ + - ]: 1 : RESULT_BAIL(S2N_ERR_INTEGER_OVERFLOW);
92 : 1 : }
93 : :
94 : : /* Record the early data bytes read, even if they exceed the max_early_data_size.
95 : : * This will ensure that if this method is called again, it will fail again:
96 : : * Once we receive too many bytes, we can't proceed with the connection. */
97 : 411 : conn->early_data_bytes += data_len;
98 : :
99 : 411 : uint32_t max_early_data_size = 0;
100 [ - + ]: 411 : RESULT_GUARD_POSIX(s2n_connection_get_max_early_data_size(conn, &max_early_data_size));
101 [ + + ][ + - ]: 411 : RESULT_ENSURE(conn->early_data_bytes <= max_early_data_size, S2N_ERR_MAX_EARLY_DATA_SIZE);
102 : :
103 : 405 : return S2N_RESULT_OK;
104 : 411 : }
105 : :
106 : : S2N_RESULT s2n_early_data_validate_send(struct s2n_connection *conn, uint32_t bytes_to_send)
107 : 23246 : {
108 [ + - ][ + + ]: 23246 : RESULT_ENSURE_REF(conn);
109 [ + + ]: 23245 : if (!s2n_is_early_data_io(conn)) {
110 : 22614 : return S2N_RESULT_OK;
111 : 22614 : }
112 : :
113 [ + + ][ + - ]: 631 : RESULT_ENSURE(conn->early_data_expected, S2N_ERR_EARLY_DATA_NOT_ALLOWED);
114 [ + + ][ + - ]: 627 : RESULT_ENSURE(conn->mode == S2N_CLIENT, S2N_ERR_EARLY_DATA_NOT_ALLOWED);
115 [ + - ][ + + ]: 626 : RESULT_ENSURE(conn->early_data_state == S2N_EARLY_DATA_REQUESTED
[ + + ]
116 : 623 : || conn->early_data_state == S2N_EARLY_DATA_ACCEPTED,
117 : 623 : S2N_ERR_EARLY_DATA_NOT_ALLOWED);
118 : :
119 : 623 : uint32_t allowed_early_data_size = 0;
120 [ - + ]: 623 : RESULT_GUARD_POSIX(s2n_connection_get_remaining_early_data_size(conn, &allowed_early_data_size));
121 [ + - ][ + + ]: 623 : RESULT_ENSURE(bytes_to_send <= allowed_early_data_size, S2N_ERR_MAX_EARLY_DATA_SIZE);
122 : :
123 : 621 : return S2N_RESULT_OK;
124 : 623 : }
125 : :
126 : : S2N_RESULT s2n_early_data_validate_recv(struct s2n_connection *conn)
127 : 418443 : {
128 [ + + ][ + - ]: 418443 : RESULT_ENSURE_REF(conn);
129 [ + + ]: 418442 : if (!s2n_is_early_data_io(conn)) {
130 : 418308 : return S2N_RESULT_OK;
131 : 418308 : }
132 : :
133 [ - + ][ # # ]: 134 : RESULT_ENSURE(conn->early_data_expected, S2N_ERR_EARLY_DATA_NOT_ALLOWED);
134 [ + - ][ + + ]: 134 : RESULT_ENSURE(conn->mode == S2N_SERVER, S2N_ERR_EARLY_DATA_NOT_ALLOWED);
135 [ + + ][ + - ]: 133 : RESULT_ENSURE(conn->early_data_state == S2N_EARLY_DATA_ACCEPTED, S2N_ERR_EARLY_DATA_NOT_ALLOWED);
136 [ + - ][ + + ]: 128 : RESULT_ENSURE(s2n_conn_get_current_message_type(conn) == END_OF_EARLY_DATA, S2N_ERR_EARLY_DATA_NOT_ALLOWED);
137 : 126 : return S2N_RESULT_OK;
138 : 128 : }
139 : :
140 : : static bool s2n_early_data_can_continue(struct s2n_connection *conn)
141 : 9701 : {
142 : 9701 : uint32_t remaining_early_data_size = 0;
143 [ + - ]: 9701 : return s2n_connection_get_remaining_early_data_size(conn, &remaining_early_data_size) >= S2N_SUCCESS
144 [ + + ]: 9701 : && remaining_early_data_size > 0;
145 : 9701 : }
146 : :
147 : : S2N_RESULT s2n_send_early_data_impl(struct s2n_connection *conn, const uint8_t *data, ssize_t data_len_signed,
148 : : ssize_t *data_sent, s2n_blocked_status *blocked)
149 : 1484 : {
150 [ # # ][ - + ]: 1484 : RESULT_ENSURE_GTE(data_len_signed, 0);
151 : 1484 : size_t data_len = data_len_signed;
152 [ - + ][ # # ]: 1484 : RESULT_ENSURE_REF(conn);
153 [ + - ][ + + ]: 1484 : RESULT_ENSURE_REF(blocked);
154 : 1483 : *blocked = S2N_NOT_BLOCKED;
155 [ + - ][ + + ]: 1483 : RESULT_ENSURE_REF(data_sent);
156 : 1482 : *data_sent = 0;
157 : :
158 [ + + ][ + - ]: 1482 : RESULT_ENSURE(conn->mode == S2N_CLIENT, S2N_ERR_SERVER_MODE);
159 [ - + ][ # # ]: 1481 : RESULT_ENSURE(s2n_connection_supports_tls13(conn), S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
160 : :
161 [ + + ]: 1481 : if (!s2n_early_data_can_continue(conn)) {
162 : 68 : return S2N_RESULT_OK;
163 : 68 : }
164 : :
165 : : /* Attempt to make progress in the handshake even if s2n_send eventually fails.
166 : : * We only care about the result of this call if it would prevent us from calling s2n_send. */
167 : 1413 : int negotiate_result = s2n_negotiate(conn, blocked);
168 [ + + ]: 1413 : if (negotiate_result < S2N_SUCCESS) {
169 [ + + ]: 1392 : if (s2n_error_get_type(s2n_errno) != S2N_ERR_T_BLOCKED) {
170 [ + - ]: 1 : RESULT_GUARD_POSIX(negotiate_result);
171 [ + + ][ + + ]: 1391 : } else if (*blocked != S2N_BLOCKED_ON_EARLY_DATA && *blocked != S2N_BLOCKED_ON_READ) {
172 [ + - ]: 1246 : RESULT_GUARD_POSIX(negotiate_result);
173 : 1246 : }
174 : 1392 : }
175 : : /* Save the error status for later */
176 : 166 : int negotiate_error = s2n_errno;
177 : 166 : s2n_blocked_status negotiate_blocked = *blocked;
178 : :
179 : : /* Attempt to send the early data.
180 : : * We only care about the result of this call if it fails. */
181 : 166 : uint32_t early_data_to_send = 0;
182 [ - + ]: 166 : RESULT_GUARD_POSIX(s2n_connection_get_remaining_early_data_size(conn, &early_data_to_send));
183 [ + + ]: 166 : early_data_to_send = S2N_MIN(data_len, early_data_to_send);
184 [ + + ]: 166 : if (early_data_to_send) {
185 : 71 : ssize_t send_result = s2n_send(conn, data, early_data_to_send, blocked);
186 [ + + ]: 71 : RESULT_GUARD_POSIX(send_result);
187 : 61 : *data_sent = send_result;
188 : 61 : }
189 : 156 : *blocked = S2N_NOT_BLOCKED;
190 : :
191 : : /* Since the send was successful, report the result of the original negotiate call.
192 : : * If we got this far, the result must have been success or a blocking error. */
193 [ + + ]: 156 : if (negotiate_result < S2N_SUCCESS) {
194 [ # # ][ - + ]: 135 : RESULT_ENSURE_EQ(s2n_error_get_type(negotiate_error), S2N_ERR_T_BLOCKED);
195 [ + + ]: 135 : if (negotiate_blocked == S2N_BLOCKED_ON_EARLY_DATA) {
196 : 30 : return S2N_RESULT_OK;
197 [ + + ]: 105 : } else if (s2n_early_data_can_continue(conn)) {
198 : 90 : *blocked = negotiate_blocked;
199 [ + - ]: 90 : RESULT_BAIL(negotiate_error);
200 : 90 : } else {
201 : 15 : return S2N_RESULT_OK;
202 : 15 : }
203 : 135 : }
204 : 21 : return S2N_RESULT_OK;
205 : 156 : }
206 : :
207 : : int s2n_send_early_data(struct s2n_connection *conn, const uint8_t *data, ssize_t data_len,
208 : : ssize_t *data_sent, s2n_blocked_status *blocked)
209 : 1485 : {
210 [ + + ][ + - ]: 1485 : POSIX_ENSURE_REF(conn);
211 : :
212 : : /* Calling this method indicates that we expect early data. */
213 [ - + ]: 1484 : POSIX_GUARD(s2n_connection_set_early_data_expected(conn));
214 : :
215 : 1484 : s2n_result result = s2n_send_early_data_impl(conn, data, data_len, data_sent, blocked);
216 : :
217 : : /* Unless s2n_send_early_data is called again (undoing this), we are done sending early data.
218 : : * If s2n_negotiate is called next, we could send the EndOfEarlyData message. */
219 [ - + ]: 1484 : POSIX_GUARD(s2n_connection_set_end_of_early_data(conn));
220 : :
221 [ + + ]: 1484 : POSIX_GUARD_RESULT(result);
222 : 134 : return S2N_SUCCESS;
223 : 1484 : }
224 : :
225 : : S2N_RESULT s2n_recv_early_data_impl(struct s2n_connection *conn, uint8_t *data, ssize_t max_data_len,
226 : : ssize_t *data_received, s2n_blocked_status *blocked)
227 : 4126 : {
228 [ # # ][ - + ]: 4126 : RESULT_ENSURE_REF(conn);
229 [ + + ][ + - ]: 4126 : RESULT_ENSURE_REF(blocked);
230 : 4125 : *blocked = S2N_NOT_BLOCKED;
231 [ + - ][ + + ]: 4125 : RESULT_ENSURE_REF(data_received);
232 : 4124 : *data_received = 0;
233 : :
234 [ + + ][ + - ]: 4124 : RESULT_ENSURE(conn->mode == S2N_SERVER, S2N_ERR_CLIENT_MODE);
235 : :
236 [ + + ]: 4123 : if (!s2n_early_data_can_continue(conn)) {
237 : 79 : return S2N_RESULT_OK;
238 : 79 : }
239 : :
240 : 4044 : int negotiate_result = S2N_SUCCESS;
241 [ + + ]: 4093 : while ((negotiate_result = s2n_negotiate(conn, blocked)) != S2N_SUCCESS) {
242 [ + + ]: 4072 : if (s2n_error_get_type(s2n_errno) != S2N_ERR_T_BLOCKED) {
243 [ + - ]: 1 : RESULT_GUARD_POSIX(negotiate_result);
244 [ + + ]: 4071 : } else if (max_data_len <= *data_received) {
245 [ + - ]: 29 : RESULT_GUARD_POSIX(negotiate_result);
246 [ + + ]: 4042 : } else if (*blocked != S2N_BLOCKED_ON_EARLY_DATA) {
247 [ + + ]: 3992 : if (s2n_early_data_can_continue(conn)) {
248 [ + - ]: 3959 : RESULT_GUARD_POSIX(negotiate_result);
249 : 3959 : } else {
250 : 33 : *blocked = S2N_NOT_BLOCKED;
251 : 33 : return S2N_RESULT_OK;
252 : 33 : }
253 : 3992 : }
254 : :
255 : 50 : ssize_t recv_result = s2n_recv(conn, data + *data_received,
256 : 50 : max_data_len - *data_received, blocked);
257 [ + + ]: 50 : RESULT_GUARD_POSIX(recv_result);
258 : 49 : *data_received += recv_result;
259 : 49 : }
260 : 21 : return S2N_RESULT_OK;
261 : 4044 : }
262 : :
263 : : int s2n_recv_early_data(struct s2n_connection *conn, uint8_t *data, ssize_t max_data_len,
264 : : ssize_t *data_received, s2n_blocked_status *blocked)
265 : 4127 : {
266 : : /* Calling this method indicates that we expect early data. */
267 [ + + ]: 4127 : POSIX_GUARD(s2n_connection_set_early_data_expected(conn));
268 : :
269 : 4126 : s2n_result result = s2n_recv_early_data_impl(conn, data, max_data_len, data_received, blocked);
270 : :
271 : : /* Unless s2n_recv_early_data is called again (undoing this), we are done accepting early data. */
272 [ - + ]: 4126 : POSIX_GUARD(s2n_connection_set_end_of_early_data(conn));
273 : :
274 [ + + ]: 4126 : POSIX_GUARD_RESULT(result);
275 : 133 : return S2N_SUCCESS;
276 : 4126 : }
|