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_serialize.h"
17 : :
18 : : #include "crypto/s2n_sequence.h"
19 : : #include "tls/s2n_connection.h"
20 : : #include "tls/s2n_tls13_key_schedule.h"
21 : :
22 : : static bool s2n_libcrypto_supports_evp_aead_tls(void)
23 : 7 : {
24 : : #ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_AEAD_TLS
25 : : return true;
26 : : #else
27 : 7 : return false;
28 : 7 : #endif
29 : 7 : }
30 : :
31 : : int s2n_connection_serialization_length(struct s2n_connection *conn, uint32_t *length)
32 : 55 : {
33 [ + + ][ + - ]: 55 : POSIX_ENSURE_REF(conn);
34 [ - + ][ # # ]: 54 : POSIX_ENSURE_REF(conn->config);
35 [ # # ][ - + ]: 54 : POSIX_ENSURE_REF(conn->secure);
36 [ - + ][ # # ]: 54 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
37 [ + + ][ + - ]: 54 : POSIX_ENSURE_REF(length);
38 : :
39 [ - + ][ # # ]: 53 : POSIX_ENSURE(conn->config->serialized_connection_version != S2N_SERIALIZED_CONN_NONE,
40 : 53 : S2N_ERR_INVALID_STATE);
41 : :
42 [ + + ]: 53 : if (conn->actual_protocol_version >= S2N_TLS13) {
43 : 46 : uint8_t secret_size = 0;
44 [ - + ]: 46 : POSIX_GUARD(s2n_hmac_digest_size(conn->secure->cipher_suite->prf_alg, &secret_size));
45 : 46 : *length = S2N_SERIALIZED_CONN_FIXED_SIZE + (secret_size * 3);
46 : 46 : } else {
47 : 7 : *length = S2N_SERIALIZED_CONN_TLS12_SIZE;
48 : 7 : }
49 : :
50 : 53 : return S2N_SUCCESS;
51 : 53 : }
52 : :
53 : : static S2N_RESULT s2n_connection_serialize_tls13_secrets(struct s2n_connection *conn, struct s2n_stuffer *output)
54 : 8 : {
55 [ # # ][ - + ]: 8 : RESULT_ENSURE_REF(conn);
56 [ - + ][ # # ]: 8 : RESULT_ENSURE_REF(conn->secure);
57 [ # # ][ - + ]: 8 : RESULT_ENSURE_REF(conn->secure->cipher_suite);
58 : :
59 : 8 : uint8_t secret_size = 0;
60 [ - + ]: 8 : RESULT_GUARD_POSIX(s2n_hmac_digest_size(conn->secure->cipher_suite->prf_alg, &secret_size));
61 : :
62 [ - + ]: 8 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls13.client_app_secret,
63 : 8 : secret_size));
64 [ - + ]: 8 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls13.server_app_secret,
65 : 8 : secret_size));
66 [ - + ]: 8 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls13.resumption_master_secret,
67 : 8 : secret_size));
68 : 8 : return S2N_RESULT_OK;
69 : 8 : }
70 : :
71 : : static S2N_RESULT s2n_connection_serialize_secrets(struct s2n_connection *conn, struct s2n_stuffer *output)
72 : 5 : {
73 [ - + ][ # # ]: 5 : RESULT_ENSURE_REF(conn);
74 : :
75 [ - + ]: 5 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls12.master_secret,
76 : 5 : S2N_TLS_SECRET_LEN));
77 [ - + ]: 5 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->handshake_params.client_random,
78 : 5 : S2N_TLS_RANDOM_DATA_LEN));
79 [ - + ]: 5 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->handshake_params.server_random,
80 : 5 : S2N_TLS_RANDOM_DATA_LEN));
81 : 5 : return S2N_RESULT_OK;
82 : 5 : }
83 : :
84 : : int s2n_connection_serialize(struct s2n_connection *conn, uint8_t *buffer, uint32_t buffer_length)
85 : 20 : {
86 [ + + ][ + - ]: 20 : POSIX_ENSURE_REF(conn);
87 [ - + ][ # # ]: 19 : POSIX_ENSURE_REF(conn->secure);
88 [ # # ][ - + ]: 19 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
89 [ # # ][ - + ]: 19 : POSIX_ENSURE_REF(conn->config);
90 [ + - ][ + + ]: 19 : POSIX_ENSURE_REF(buffer);
91 : :
92 [ + - ][ + + ]: 18 : POSIX_ENSURE(conn->config->serialized_connection_version != S2N_SERIALIZED_CONN_NONE,
93 : 17 : S2N_ERR_INVALID_STATE);
94 : :
95 : : /* This method must be called after negotiation */
96 [ + - ][ + + ]: 17 : POSIX_ENSURE(s2n_handshake_is_complete(conn), S2N_ERR_HANDSHAKE_NOT_COMPLETE);
97 : :
98 : : /* The connection must not be closed already. Otherwise, we might have an alert
99 : : * queued up that would be sent in cleartext after we disable encryption. */
100 : 16 : s2n_io_status status = S2N_IO_FULL_DUPLEX;
101 [ + + ][ + - ]: 16 : POSIX_ENSURE(s2n_connection_check_io_status(conn, status), S2N_ERR_CLOSED);
102 : :
103 : : /* Best effort check for pending input or output data.
104 : : * This method should not be called until the application has stopped sending and receiving.
105 : : * Saving partial read or partial write state would complicate this problem.
106 : : */
107 [ + + ][ + - ]: 15 : POSIX_ENSURE(s2n_stuffer_data_available(&conn->header_in) == 0, S2N_ERR_INVALID_STATE);
108 [ # # ][ - + ]: 14 : POSIX_ENSURE(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_INVALID_STATE);
109 [ - + ][ # # ]: 14 : POSIX_ENSURE(s2n_stuffer_data_available(&conn->out) == 0, S2N_ERR_INVALID_STATE);
110 : :
111 : 14 : uint32_t context_length = 0;
112 [ - + ]: 14 : POSIX_GUARD(s2n_connection_serialization_length(conn, &context_length));
113 [ + - ][ + + ]: 14 : POSIX_ENSURE(buffer_length >= context_length, S2N_ERR_INSUFFICIENT_MEM_SIZE);
114 : :
115 : 13 : struct s2n_blob context_blob = { 0 };
116 [ - + ]: 13 : POSIX_GUARD(s2n_blob_init(&context_blob, buffer, buffer_length));
117 : 13 : struct s2n_stuffer output = { 0 };
118 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_init(&output, &context_blob));
119 : :
120 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_write_uint64(&output, S2N_SERIALIZED_CONN_V1));
121 : :
122 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_write_uint8(&output, conn->actual_protocol_version / 10));
123 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_write_uint8(&output, conn->actual_protocol_version % 10));
124 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_write_bytes(&output, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
125 : :
126 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_write_bytes(&output, conn->secure->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
127 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_write_bytes(&output, conn->secure->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
128 : :
129 [ - + ]: 13 : POSIX_GUARD(s2n_stuffer_write_uint16(&output, conn->max_outgoing_fragment_length));
130 : :
131 [ + + ]: 13 : if (conn->actual_protocol_version >= S2N_TLS13) {
132 [ - + ]: 8 : POSIX_GUARD_RESULT(s2n_connection_serialize_tls13_secrets(conn, &output));
133 : 8 : } else {
134 [ - + ]: 5 : POSIX_GUARD_RESULT(s2n_connection_serialize_secrets(conn, &output));
135 : 5 : }
136 : :
137 : : /* Users should not be able to send/recv on the connection after serialization as that
138 : : * could lead to nonce reuse. We close the connection to prevent the application from sending
139 : : * more application data. However, the application could still send a close_notify alert record
140 : : * to shutdown the connection, so we also intentionally wipe keys and disable encryption.
141 : : *
142 : : * A plaintext close_notify alert is not a security concern, although the peer will likely consider
143 : : * it an error.
144 : : */
145 [ - + ]: 13 : POSIX_GUARD_RESULT(s2n_connection_set_closed(conn));
146 [ - + ]: 13 : POSIX_GUARD_RESULT(s2n_crypto_parameters_wipe(conn->secure));
147 : :
148 : 13 : return S2N_SUCCESS;
149 : 13 : }
150 : :
151 : : struct s2n_connection_deserialize {
152 : : uint8_t protocol_version;
153 : : struct s2n_cipher_suite *cipher_suite;
154 : : uint8_t client_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
155 : : uint8_t server_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
156 : : uint16_t max_fragment_len;
157 : : union {
158 : : struct {
159 : : uint8_t master_secret[S2N_TLS_SECRET_LEN];
160 : : uint8_t client_random[S2N_TLS_RANDOM_DATA_LEN];
161 : : uint8_t server_random[S2N_TLS_RANDOM_DATA_LEN];
162 : : } tls12;
163 : : struct {
164 : : uint8_t secret_size;
165 : : uint8_t client_application_secret[S2N_TLS_SECRET_LEN];
166 : : uint8_t server_application_secret[S2N_TLS_SECRET_LEN];
167 : : uint8_t resumption_master_secret[S2N_TLS_SECRET_LEN];
168 : : } tls13;
169 : : } version;
170 : : };
171 : :
172 : : static S2N_RESULT s2n_connection_deserialize_tls13_secrets(struct s2n_stuffer *input,
173 : : struct s2n_connection_deserialize *parsed_values)
174 : 7 : {
175 [ - + ][ # # ]: 7 : RESULT_ENSURE_REF(input);
176 [ - + ][ # # ]: 7 : RESULT_ENSURE_REF(parsed_values);
177 : :
178 [ - + ]: 7 : RESULT_GUARD_POSIX(s2n_hmac_digest_size(parsed_values->cipher_suite->prf_alg,
179 : 7 : &parsed_values->version.tls13.secret_size));
180 [ - + ]: 7 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls13.client_application_secret,
181 : 7 : parsed_values->version.tls13.secret_size));
182 [ - + ]: 7 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls13.server_application_secret,
183 : 7 : parsed_values->version.tls13.secret_size));
184 [ - + ]: 7 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls13.resumption_master_secret,
185 : 7 : parsed_values->version.tls13.secret_size));
186 : :
187 : 7 : return S2N_RESULT_OK;
188 : 7 : }
189 : :
190 : : static S2N_RESULT s2n_connection_deserialize_secrets(struct s2n_stuffer *input,
191 : : struct s2n_connection_deserialize *parsed_values)
192 : 3 : {
193 [ - + ][ # # ]: 3 : RESULT_ENSURE_REF(input);
194 [ # # ][ - + ]: 3 : RESULT_ENSURE_REF(parsed_values);
195 : :
196 [ - + ]: 3 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.master_secret, S2N_TLS_SECRET_LEN));
197 [ - + ]: 3 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.client_random, S2N_TLS_RANDOM_DATA_LEN));
198 [ - + ]: 3 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.server_random, S2N_TLS_RANDOM_DATA_LEN));
199 : :
200 : 3 : return S2N_RESULT_OK;
201 : 3 : }
202 : :
203 : : static S2N_RESULT s2n_connection_deserialize_parse(uint8_t *buffer, uint32_t buffer_length,
204 : : struct s2n_connection_deserialize *parsed_values)
205 : 11 : {
206 [ # # ][ - + ]: 11 : RESULT_ENSURE_REF(parsed_values);
207 : :
208 : 11 : struct s2n_blob context_blob = { 0 };
209 [ - + ]: 11 : RESULT_GUARD_POSIX(s2n_blob_init(&context_blob, buffer, buffer_length));
210 : 11 : struct s2n_stuffer input = { 0 };
211 [ - + ]: 11 : RESULT_GUARD_POSIX(s2n_stuffer_init_written(&input, &context_blob));
212 : :
213 : 11 : uint64_t serialized_version = 0;
214 [ - + ]: 11 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint64(&input, &serialized_version));
215 : : /* No other version is supported currently */
216 [ + + ][ + - ]: 11 : RESULT_ENSURE_EQ(serialized_version, S2N_SERIALIZED_CONN_V1);
217 : :
218 : 10 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
219 [ - + ]: 10 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
220 : 10 : parsed_values->protocol_version = (protocol_version[0] * 10) + protocol_version[1];
221 : :
222 : 10 : uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
223 [ - + ]: 10 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN));
224 [ - + ]: 10 : RESULT_GUARD(s2n_cipher_suite_from_iana(cipher_suite, S2N_TLS_CIPHER_SUITE_LEN, &parsed_values->cipher_suite));
225 : :
226 [ - + ]: 10 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, parsed_values->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
227 [ - + ]: 10 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, parsed_values->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
228 : :
229 [ - + ]: 10 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&input, &parsed_values->max_fragment_len));
230 : :
231 [ + + ]: 10 : if (parsed_values->protocol_version >= S2N_TLS13) {
232 [ - + ]: 7 : RESULT_GUARD(s2n_connection_deserialize_tls13_secrets(&input, parsed_values));
233 : 7 : } else {
234 [ - + ]: 3 : RESULT_GUARD(s2n_connection_deserialize_secrets(&input, parsed_values));
235 : 3 : }
236 : :
237 : 10 : return S2N_RESULT_OK;
238 : 10 : }
239 : :
240 : : /* Boringssl and AWS-LC do a special check in tls13 during the first call to encrypt after
241 : : * initialization. In the first call they assume that the sequence number will be 0, and therefore
242 : : * the provided nonce is equivalent to the implicit IV because 0 ^ iv = iv. The recovered implicit IV
243 : : * is stored and used later on to ensure the monotonicity of sequence numbers.
244 : : *
245 : : * In the case of deserialization, in the first call the sequence number may not be 0.
246 : : * Therefore the provided nonce cannot be considered to be the implicit IV because n ^ iv != iv.
247 : : * This inability to get the correct implicit IV causes issues with encryption later on.
248 : : *
249 : : * To resolve this we preform one throwaway encryption call with a zero sequence number after
250 : : * deserialization. This allows the libcrypto to recover the implicit IV correctly.
251 : : */
252 : : static S2N_RESULT s2n_initialize_implicit_iv(struct s2n_connection *conn, struct s2n_connection_deserialize *parsed_values)
253 : 7 : {
254 [ # # ][ - + ]: 7 : RESULT_ENSURE_REF(conn);
255 [ - + ][ # # ]: 7 : RESULT_ENSURE_REF(parsed_values);
256 [ # # ][ - + ]: 7 : RESULT_ENSURE_REF(conn->secure);
257 [ - + ][ # # ]: 7 : RESULT_ENSURE_REF(conn->server);
258 [ - + ][ # # ]: 7 : RESULT_ENSURE_REF(conn->client);
259 : :
260 [ + - ]: 7 : if (!s2n_libcrypto_supports_evp_aead_tls()) {
261 : 7 : return S2N_RESULT_OK;
262 : 7 : }
263 : :
264 : 0 : uint8_t *seq_num = parsed_values->server_sequence_number;
265 : 0 : uint8_t *implicit_iv = conn->server->server_implicit_iv;
266 : 0 : struct s2n_session_key key = conn->server->server_key;
267 [ # # ]: 0 : if (conn->mode == S2N_CLIENT) {
268 : 0 : seq_num = parsed_values->client_sequence_number;
269 : 0 : implicit_iv = conn->client->client_implicit_iv;
270 : 0 : key = conn->client->client_key;
271 : 0 : }
272 : :
273 : 0 : uint64_t parsed_sequence_num = 0;
274 : 0 : struct s2n_blob seq_num_blob = { 0 };
275 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&seq_num_blob, seq_num, S2N_TLS_SEQUENCE_NUM_LEN));
276 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_sequence_number_to_uint64(&seq_num_blob, &parsed_sequence_num));
277 : :
278 : : /* we don't need to initialize the context when the sequence number is 0 */
279 [ # # ]: 0 : if (parsed_sequence_num == 0) {
280 : 0 : return S2N_RESULT_OK;
281 : 0 : }
282 : :
283 : 0 : uint8_t in_data[S2N_TLS_GCM_TAG_LEN] = { 0 };
284 : 0 : struct s2n_blob in_blob = { 0 };
285 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&in_blob, in_data, sizeof(in_data)));
286 : :
287 : 0 : struct s2n_blob iv_blob = { 0 };
288 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&iv_blob, implicit_iv, S2N_TLS13_FIXED_IV_LEN));
289 : :
290 : 0 : struct s2n_blob aad_blob = { 0 };
291 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&aad_blob, NULL, 0));
292 : :
293 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(conn->secure->cipher_suite);
294 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(conn->secure->cipher_suite->record_alg);
295 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(conn->secure->cipher_suite->record_alg->cipher);
296 [ # # ]: 0 : RESULT_GUARD_POSIX(conn->secure->cipher_suite->record_alg->cipher->io.aead.encrypt(&key,
297 : 0 : &iv_blob, &aad_blob, &in_blob, &in_blob));
298 : :
299 : 0 : return S2N_RESULT_OK;
300 : 0 : }
301 : :
302 : : static S2N_RESULT s2n_restore_tls13_secrets(struct s2n_connection *conn, struct s2n_connection_deserialize *parsed_values)
303 : 7 : {
304 [ # # ][ - + ]: 7 : RESULT_ENSURE_REF(conn);
305 [ - + ][ # # ]: 7 : RESULT_ENSURE_REF(parsed_values);
306 : :
307 [ # # ][ - + ]: 7 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls13.client_app_secret,
[ + - ]
308 : 7 : parsed_values->version.tls13.client_application_secret, parsed_values->version.tls13.secret_size);
309 [ - + ][ # # ]: 7 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls13.server_app_secret,
[ + - ]
310 : 7 : parsed_values->version.tls13.server_application_secret, parsed_values->version.tls13.secret_size);
311 [ - + ][ # # ]: 7 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls13.resumption_master_secret,
[ + - ]
312 : 7 : parsed_values->version.tls13.resumption_master_secret, parsed_values->version.tls13.secret_size);
313 : :
314 [ - + ]: 7 : RESULT_GUARD(s2n_tls13_key_schedule_set_key(conn, S2N_MASTER_SECRET, S2N_SERVER));
315 [ - + ]: 7 : RESULT_GUARD(s2n_tls13_key_schedule_set_key(conn, S2N_MASTER_SECRET, S2N_CLIENT));
316 : :
317 [ - + ]: 7 : RESULT_GUARD(s2n_initialize_implicit_iv(conn, parsed_values));
318 : :
319 : 7 : return S2N_RESULT_OK;
320 : 7 : }
321 : :
322 : : static S2N_RESULT s2n_restore_secrets(struct s2n_connection *conn, struct s2n_connection_deserialize *parsed_values)
323 : 3 : {
324 [ - + ][ # # ]: 3 : RESULT_ENSURE_REF(conn);
325 [ - + ][ # # ]: 3 : RESULT_ENSURE_REF(parsed_values);
326 : :
327 [ - + ][ # # ]: 3 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls12.master_secret, parsed_values->version.tls12.master_secret,
[ + - ]
328 : 3 : S2N_TLS_SECRET_LEN);
329 [ - + ][ # # ]: 3 : RESULT_CHECKED_MEMCPY(conn->handshake_params.client_random, parsed_values->version.tls12.client_random,
[ + - ]
330 : 3 : S2N_TLS_RANDOM_DATA_LEN);
331 [ - + ][ # # ]: 3 : RESULT_CHECKED_MEMCPY(conn->handshake_params.server_random, parsed_values->version.tls12.server_random,
[ + - ]
332 : 3 : S2N_TLS_RANDOM_DATA_LEN);
333 [ - + ]: 3 : RESULT_GUARD_POSIX(s2n_prf_key_expansion(conn));
334 : :
335 : 3 : return S2N_RESULT_OK;
336 : 3 : }
337 : :
338 : : int s2n_connection_deserialize(struct s2n_connection *conn, uint8_t *buffer, uint32_t buffer_length)
339 : 13 : {
340 [ + + ][ + - ]: 13 : POSIX_ENSURE_REF(conn);
341 [ - + ][ # # ]: 12 : POSIX_ENSURE_REF(conn->secure);
342 [ + + ][ + - ]: 12 : POSIX_ENSURE_REF(buffer);
343 : :
344 : : /* Read parsed values into a temporary struct so that the connection is unaltered if parsing fails */
345 : 11 : struct s2n_connection_deserialize parsed_values = { 0 };
346 [ + + ][ + - ]: 11 : POSIX_ENSURE(s2n_result_is_ok(s2n_connection_deserialize_parse(buffer, buffer_length, &parsed_values)),
347 : 10 : S2N_ERR_INVALID_SERIALIZED_CONNECTION);
348 : :
349 : : /* Rehydrate fields now that parsing has completed successfully */
350 : 10 : conn->actual_protocol_version = parsed_values.protocol_version;
351 : 10 : conn->secure->cipher_suite = parsed_values.cipher_suite;
352 [ - + ]: 10 : POSIX_GUARD_RESULT(s2n_connection_set_max_fragment_length(conn, parsed_values.max_fragment_len));
353 : :
354 : : /* Mark the connection as having been deserialized */
355 : 10 : conn->deserialized_conn = true;
356 : :
357 : : /* Key expansion */
358 [ + + ]: 10 : if (parsed_values.protocol_version >= S2N_TLS13) {
359 [ - + ]: 7 : POSIX_GUARD_RESULT(s2n_restore_tls13_secrets(conn, &parsed_values));
360 : 7 : } else {
361 [ - + ]: 3 : POSIX_GUARD_RESULT(s2n_restore_secrets(conn, &parsed_values));
362 : 3 : }
363 : :
364 : : /* Wait until after key generation to restore sequence numbers since they get zeroed during
365 : : * key expansion */
366 [ - + ][ # # ]: 10 : POSIX_CHECKED_MEMCPY(conn->secure->client_sequence_number, parsed_values.client_sequence_number,
[ + - ]
367 : 10 : S2N_TLS_SEQUENCE_NUM_LEN);
368 [ - + ][ # # ]: 10 : POSIX_CHECKED_MEMCPY(conn->secure->server_sequence_number, parsed_values.server_sequence_number,
[ + - ]
369 : 10 : S2N_TLS_SEQUENCE_NUM_LEN);
370 : :
371 : 10 : conn->client = conn->secure;
372 : 10 : conn->server = conn->secure;
373 : :
374 : 10 : return S2N_SUCCESS;
375 : 10 : }
|