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 <stdint.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <strings.h>
20 #include <time.h>
21 #include <unistd.h>
22 #include <sys/param.h>
23
24 #include <s2n.h>
25 #include <stdbool.h>
26
27 #include "crypto/s2n_fips.h"
28
29 #include "error/s2n_errno.h"
30
31 #include "tls/extensions/s2n_client_server_name.h"
32 #include "tls/s2n_alerts.h"
33 #include "tls/s2n_cipher_suites.h"
34 #include "tls/s2n_connection.h"
35 #include "tls/s2n_connection_evp_digests.h"
36 #include "tls/s2n_handshake.h"
37 #include "tls/s2n_kem.h"
38 #include "tls/s2n_prf.h"
39 #include "tls/s2n_record.h"
40 #include "tls/s2n_resume.h"
41 #include "tls/s2n_security_policies.h"
42 #include "tls/s2n_tls.h"
43 #include "tls/s2n_tls_parameters.h"
44
45 #include "crypto/s2n_certificate.h"
46 #include "crypto/s2n_cipher.h"
47 #include "crypto/s2n_crypto.h"
48 #include "crypto/s2n_openssl_x509.h"
49
50 #include "utils/s2n_blob.h"
51 #include "utils/s2n_compiler.h"
52 #include "utils/s2n_mem.h"
53 #include "utils/s2n_random.h"
54 #include "utils/s2n_safety.h"
55 #include "utils/s2n_socket.h"
56 #include "utils/s2n_timer.h"
57
58 #define S2N_SET_KEY_SHARE_LIST_EMPTY(keyshares) (keyshares |= 1)
59 #define S2N_SET_KEY_SHARE_REQUEST(keyshares, i) (keyshares |= ( 1 << ( i + 1 )))
60
s2n_connection_new_hmacs(struct s2n_connection * conn)61 static int s2n_connection_new_hmacs(struct s2n_connection *conn)
62 {
63 /* Allocate long-term memory for the Connection's HMAC states */
64 POSIX_GUARD(s2n_hmac_new(&conn->initial.client_record_mac));
65 POSIX_GUARD(s2n_hmac_new(&conn->initial.server_record_mac));
66 POSIX_GUARD(s2n_hmac_new(&conn->secure.client_record_mac));
67 POSIX_GUARD(s2n_hmac_new(&conn->secure.server_record_mac));
68
69 return 0;
70 }
71
s2n_connection_init_hmacs(struct s2n_connection * conn)72 static int s2n_connection_init_hmacs(struct s2n_connection *conn)
73 {
74 /* Initialize all of the Connection's HMAC states */
75 POSIX_GUARD(s2n_hmac_init(&conn->initial.client_record_mac, S2N_HMAC_NONE, NULL, 0));
76 POSIX_GUARD(s2n_hmac_init(&conn->initial.server_record_mac, S2N_HMAC_NONE, NULL, 0));
77 POSIX_GUARD(s2n_hmac_init(&conn->secure.client_record_mac, S2N_HMAC_NONE, NULL, 0));
78 POSIX_GUARD(s2n_hmac_init(&conn->secure.server_record_mac, S2N_HMAC_NONE, NULL, 0));
79
80 return 0;
81 }
82
s2n_connection_new(s2n_mode mode)83 struct s2n_connection *s2n_connection_new(s2n_mode mode)
84 {
85 struct s2n_blob blob = {0};
86 PTR_GUARD_POSIX(s2n_alloc(&blob, sizeof(struct s2n_connection)));
87 PTR_GUARD_POSIX(s2n_blob_zero(&blob));
88
89 /* Cast 'through' void to acknowledge that we are changing alignment,
90 * which is ok, as blob.data is always aligned.
91 */
92 struct s2n_connection* conn = (struct s2n_connection *)(void *)blob.data;
93
94 PTR_GUARD_POSIX(s2n_connection_set_config(conn, s2n_fetch_default_config()));
95
96 conn->mode = mode;
97 conn->blinding = S2N_BUILT_IN_BLINDING;
98 conn->close_notify_queued = 0;
99 conn->client_session_resumed = 0;
100 conn->session_id_len = 0;
101 conn->verify_host_fn = NULL;
102 conn->data_for_verify_host = NULL;
103 conn->verify_host_fn_overridden = 0;
104 conn->data_for_verify_host = NULL;
105 conn->send = NULL;
106 conn->recv = NULL;
107 conn->send_io_context = NULL;
108 conn->recv_io_context = NULL;
109 conn->corked_io = 0;
110 conn->context = NULL;
111 conn->security_policy_override = NULL;
112 conn->ticket_lifetime_hint = 0;
113 conn->session_ticket_status = S2N_NO_TICKET;
114
115 /* Allocate the fixed-size stuffers */
116 blob = (struct s2n_blob) {0};
117 PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->alert_in_data, S2N_ALERT_LENGTH));
118 PTR_GUARD_POSIX(s2n_stuffer_init(&conn->alert_in, &blob));
119
120 blob = (struct s2n_blob) {0};
121 PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->reader_alert_out_data, S2N_ALERT_LENGTH));
122 PTR_GUARD_POSIX(s2n_stuffer_init(&conn->reader_alert_out, &blob));
123
124 blob = (struct s2n_blob) {0};
125 PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->writer_alert_out_data, S2N_ALERT_LENGTH));
126 PTR_GUARD_POSIX(s2n_stuffer_init(&conn->writer_alert_out, &blob));
127
128 blob = (struct s2n_blob) {0};
129 PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->ticket_ext_data, S2N_TLS12_TICKET_SIZE_IN_BYTES));
130 PTR_GUARD_POSIX(s2n_stuffer_init(&conn->client_ticket_to_decrypt, &blob));
131
132 /* Allocate long term key memory */
133 PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->secure.client_key));
134 PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->secure.server_key));
135 PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->initial.client_key));
136 PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->initial.server_key));
137
138 /* Allocate long term hash and HMAC memory */
139 PTR_GUARD_RESULT(s2n_prf_new(conn));
140 PTR_GUARD_RESULT(s2n_handshake_hashes_new(&conn->handshake.hashes));
141
142 PTR_GUARD_POSIX(s2n_connection_new_hmacs(conn));
143 PTR_GUARD_POSIX(s2n_connection_init_hmacs(conn));
144
145 /* Initialize the growable stuffers. Zero length at first, but the resize
146 * in _wipe will fix that
147 */
148 blob = (struct s2n_blob) {0};
149 PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->header_in_data, S2N_TLS_RECORD_HEADER_LENGTH));
150 PTR_GUARD_POSIX(s2n_stuffer_init(&conn->header_in, &blob));
151 PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->out, 0));
152 PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->in, 0));
153 PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->handshake.io, 0));
154 PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->client_hello.raw_message, 0));
155 PTR_GUARD_POSIX(s2n_connection_wipe(conn));
156 PTR_GUARD_RESULT(s2n_timer_start(conn->config, &conn->write_timer));
157
158 /* Initialize the cookie stuffer with zero length. If a cookie extension
159 * is received, the stuffer will be resized according to the cookie length */
160 PTR_GUARD_POSIX(s2n_stuffer_growable_alloc(&conn->cookie_stuffer, 0));
161
162 return conn;
163 }
164
s2n_connection_free_keys(struct s2n_connection * conn)165 static int s2n_connection_free_keys(struct s2n_connection *conn)
166 {
167 POSIX_GUARD(s2n_session_key_free(&conn->secure.client_key));
168 POSIX_GUARD(s2n_session_key_free(&conn->secure.server_key));
169 POSIX_GUARD(s2n_session_key_free(&conn->initial.client_key));
170 POSIX_GUARD(s2n_session_key_free(&conn->initial.server_key));
171
172 return 0;
173 }
174
s2n_connection_zero(struct s2n_connection * conn,int mode,struct s2n_config * config)175 static int s2n_connection_zero(struct s2n_connection *conn, int mode, struct s2n_config *config)
176 {
177 /* Zero the whole connection structure */
178 POSIX_CHECKED_MEMSET(conn, 0, sizeof(struct s2n_connection));
179
180 conn->mode = mode;
181 conn->initial.cipher_suite = &s2n_null_cipher_suite;
182 conn->secure.cipher_suite = &s2n_null_cipher_suite;
183 conn->server = &conn->initial;
184 conn->client = &conn->initial;
185 conn->max_outgoing_fragment_length = S2N_DEFAULT_FRAGMENT_LENGTH;
186 conn->handshake.end_of_messages = APPLICATION_DATA;
187 s2n_connection_set_config(conn, config);
188
189 return 0;
190 }
191
s2n_connection_wipe_all_keyshares(struct s2n_connection * conn)192 S2N_RESULT s2n_connection_wipe_all_keyshares(struct s2n_connection *conn)
193 {
194 RESULT_ENSURE_REF(conn);
195
196 RESULT_GUARD_POSIX(s2n_ecc_evp_params_free(&conn->kex_params.server_ecc_evp_params));
197 RESULT_GUARD_POSIX(s2n_ecc_evp_params_free(&conn->kex_params.client_ecc_evp_params));
198
199 RESULT_GUARD_POSIX(s2n_kem_group_free(&conn->kex_params.server_kem_group_params));
200 RESULT_GUARD_POSIX(s2n_kem_group_free(&conn->kex_params.client_kem_group_params));
201
202 return S2N_RESULT_OK;
203 }
204
s2n_connection_wipe_keys(struct s2n_connection * conn)205 static int s2n_connection_wipe_keys(struct s2n_connection *conn)
206 {
207 /* Destroy any keys - we call destroy on the object as that is where
208 * keys are allocated. */
209 if (conn->secure.cipher_suite
210 && conn->secure.cipher_suite->record_alg
211 && conn->secure.cipher_suite->record_alg->cipher
212 && conn->secure.cipher_suite->record_alg->cipher->destroy_key) {
213 POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->destroy_key(&conn->secure.client_key));
214 POSIX_GUARD(conn->secure.cipher_suite->record_alg->cipher->destroy_key(&conn->secure.server_key));
215 }
216
217 /* Free any server key received (we may not have completed a
218 * handshake, so this may not have been free'd yet) */
219 POSIX_GUARD(s2n_pkey_free(&conn->handshake_params.server_public_key));
220 POSIX_GUARD(s2n_pkey_zero_init(&conn->handshake_params.server_public_key));
221 POSIX_GUARD(s2n_pkey_free(&conn->handshake_params.client_public_key));
222 POSIX_GUARD(s2n_pkey_zero_init(&conn->handshake_params.client_public_key));
223 s2n_x509_validator_wipe(&conn->x509_validator);
224 POSIX_GUARD(s2n_dh_params_free(&conn->kex_params.server_dh_params));
225 POSIX_GUARD_RESULT(s2n_connection_wipe_all_keyshares(conn));
226 POSIX_GUARD(s2n_kem_free(&conn->kex_params.kem_params));
227 POSIX_GUARD(s2n_free(&conn->handshake_params.client_cert_chain));
228 POSIX_GUARD(s2n_free(&conn->ct_response));
229
230 return 0;
231 }
232
s2n_connection_reset_hmacs(struct s2n_connection * conn)233 static int s2n_connection_reset_hmacs(struct s2n_connection *conn)
234 {
235 /* Reset all of the Connection's HMAC states */
236 POSIX_GUARD(s2n_hmac_reset(&conn->initial.client_record_mac));
237 POSIX_GUARD(s2n_hmac_reset(&conn->initial.server_record_mac));
238 POSIX_GUARD(s2n_hmac_reset(&conn->secure.client_record_mac));
239 POSIX_GUARD(s2n_hmac_reset(&conn->secure.server_record_mac));
240
241 return 0;
242 }
243
s2n_connection_free_managed_recv_io(struct s2n_connection * conn)244 static int s2n_connection_free_managed_recv_io(struct s2n_connection *conn)
245 {
246 POSIX_ENSURE_REF(conn);
247
248 if (conn->managed_recv_io) {
249 POSIX_GUARD(s2n_free_object((uint8_t **)&conn->recv_io_context, sizeof(struct s2n_socket_read_io_context)));
250 conn->managed_recv_io = false;
251 conn->recv = NULL;
252 }
253 return S2N_SUCCESS;
254 }
255
s2n_connection_free_managed_send_io(struct s2n_connection * conn)256 static int s2n_connection_free_managed_send_io(struct s2n_connection *conn)
257 {
258 POSIX_ENSURE_REF(conn);
259
260 if (conn->managed_send_io) {
261 POSIX_GUARD(s2n_free_object((uint8_t **)&conn->send_io_context, sizeof(struct s2n_socket_write_io_context)));
262 conn->managed_send_io = false;
263 conn->send = NULL;
264 }
265 return S2N_SUCCESS;
266 }
267
s2n_connection_free_managed_io(struct s2n_connection * conn)268 static int s2n_connection_free_managed_io(struct s2n_connection *conn)
269 {
270 POSIX_GUARD(s2n_connection_free_managed_recv_io(conn));
271 POSIX_GUARD(s2n_connection_free_managed_send_io(conn));
272 return S2N_SUCCESS;
273 }
274
s2n_connection_wipe_io(struct s2n_connection * conn)275 static int s2n_connection_wipe_io(struct s2n_connection *conn)
276 {
277 if (s2n_connection_is_managed_corked(conn) && conn->recv){
278 POSIX_GUARD(s2n_socket_read_restore(conn));
279 }
280 if (s2n_connection_is_managed_corked(conn) && conn->send){
281 POSIX_GUARD(s2n_socket_write_restore(conn));
282 }
283
284 /* Remove all I/O-related members */
285 POSIX_GUARD(s2n_connection_free_managed_io(conn));
286
287 return 0;
288 }
289
s2n_connection_free_hmacs(struct s2n_connection * conn)290 static int s2n_connection_free_hmacs(struct s2n_connection *conn)
291 {
292 /* Free all of the Connection's HMAC states */
293 POSIX_GUARD(s2n_hmac_free(&conn->initial.client_record_mac));
294 POSIX_GUARD(s2n_hmac_free(&conn->initial.server_record_mac));
295 POSIX_GUARD(s2n_hmac_free(&conn->secure.client_record_mac));
296 POSIX_GUARD(s2n_hmac_free(&conn->secure.server_record_mac));
297
298 return 0;
299 }
300
s2n_default_verify_host(const char * host_name,size_t len,void * data)301 static uint8_t s2n_default_verify_host(const char *host_name, size_t len, void *data)
302 {
303 /* if present, match server_name of the connection using rules
304 * outlined in RFC6125 6.4. */
305
306 struct s2n_connection *conn = data;
307
308 if (conn->server_name[0] == '\0') {
309 return 0;
310 }
311
312 /* complete match */
313 if (strlen(conn->server_name) == len &&
314 strncasecmp(conn->server_name, host_name, len) == 0) {
315 return 1;
316 }
317
318 /* match 1 level of wildcard */
319 if (len > 2 && host_name[0] == '*' && host_name[1] == '.') {
320 const char *suffix = strchr(conn->server_name, '.');
321
322 if (suffix == NULL) {
323 return 0;
324 }
325
326 if (strlen(suffix) == len - 1 &&
327 strncasecmp(suffix, host_name + 1, len - 1) == 0) {
328 return 1;
329 }
330 }
331
332 return 0;
333 }
334
s2n_connection_free(struct s2n_connection * conn)335 int s2n_connection_free(struct s2n_connection *conn)
336 {
337 POSIX_GUARD(s2n_connection_wipe_keys(conn));
338 POSIX_GUARD(s2n_connection_free_keys(conn));
339 POSIX_GUARD_RESULT(s2n_psk_parameters_wipe(&conn->psk_params));
340
341 POSIX_GUARD_RESULT(s2n_prf_free(conn));
342 POSIX_GUARD_RESULT(s2n_handshake_hashes_free(&conn->handshake.hashes));
343
344 POSIX_GUARD(s2n_connection_reset_hmacs(conn));
345 POSIX_GUARD(s2n_connection_free_hmacs(conn));
346
347 POSIX_GUARD(s2n_connection_free_managed_io(conn));
348
349 POSIX_GUARD(s2n_free(&conn->client_ticket));
350 POSIX_GUARD(s2n_free(&conn->status_response));
351 POSIX_GUARD(s2n_free(&conn->our_quic_transport_parameters));
352 POSIX_GUARD(s2n_free(&conn->peer_quic_transport_parameters));
353 POSIX_GUARD(s2n_free(&conn->server_early_data_context));
354 POSIX_GUARD(s2n_free(&conn->tls13_ticket_fields.session_secret));
355 POSIX_GUARD(s2n_stuffer_free(&conn->in));
356 POSIX_GUARD(s2n_stuffer_free(&conn->out));
357 POSIX_GUARD(s2n_stuffer_free(&conn->handshake.io));
358 s2n_x509_validator_wipe(&conn->x509_validator);
359 POSIX_GUARD(s2n_client_hello_free(&conn->client_hello));
360 POSIX_GUARD(s2n_free(&conn->application_protocols_overridden));
361 POSIX_GUARD(s2n_stuffer_free(&conn->cookie_stuffer));
362 POSIX_GUARD(s2n_free_object((uint8_t **)&conn, sizeof(struct s2n_connection)));
363
364 return 0;
365 }
366
s2n_connection_set_config(struct s2n_connection * conn,struct s2n_config * config)367 int s2n_connection_set_config(struct s2n_connection *conn, struct s2n_config *config)
368 {
369 POSIX_ENSURE_REF(conn);
370 POSIX_ENSURE_REF(config);
371
372 if (conn->config == config) {
373 return 0;
374 }
375
376 /* We only support one client certificate */
377 if (s2n_config_get_num_default_certs(config) > 1 && conn->mode == S2N_CLIENT) {
378 POSIX_BAIL(S2N_ERR_TOO_MANY_CERTIFICATES);
379 }
380
381 s2n_x509_validator_wipe(&conn->x509_validator);
382
383 s2n_cert_auth_type auth_type = config->client_cert_auth_type;
384
385 if (conn->client_cert_auth_type_overridden) {
386 auth_type = conn->client_cert_auth_type;
387 }
388
389 int8_t dont_need_x509_validation = (conn->mode == S2N_SERVER) && (auth_type == S2N_CERT_AUTH_NONE);
390
391 if (config->disable_x509_validation || dont_need_x509_validation) {
392 POSIX_GUARD(s2n_x509_validator_init_no_x509_validation(&conn->x509_validator));
393 }
394 else {
395 POSIX_GUARD(s2n_x509_validator_init(&conn->x509_validator, &config->trust_store, config->check_ocsp));
396 if (!conn->verify_host_fn_overridden) {
397 if (config->verify_host != NULL) {
398 conn->verify_host_fn = config->verify_host;
399 conn->data_for_verify_host = config->data_for_verify_host;
400 } else {
401 conn->verify_host_fn = s2n_default_verify_host;
402 conn->data_for_verify_host = conn;
403 }
404 }
405
406 if (config->max_verify_cert_chain_depth_set) {
407 POSIX_GUARD(s2n_x509_validator_set_max_chain_depth(&conn->x509_validator, config->max_verify_cert_chain_depth));
408 }
409 }
410 conn->tickets_to_send = config->initial_tickets_to_send;
411
412 if (conn->psk_params.psk_list.len == 0 && !conn->psk_mode_overridden) {
413 POSIX_GUARD(s2n_connection_set_psk_mode(conn, config->psk_mode));
414 conn->psk_mode_overridden = false;
415 }
416
417 /* If at least one certificate does not have a private key configured,
418 * the config must provide an async pkey callback.
419 * The handshake could still fail if the callback doesn't offload the
420 * signature, but this at least catches configuration mistakes.
421 */
422 if (config->no_signing_key) {
423 POSIX_ENSURE(config->async_pkey_cb, S2N_ERR_NO_PRIVATE_KEY);
424 }
425
426 conn->config = config;
427 return S2N_SUCCESS;
428 }
429
s2n_connection_server_name_extension_used(struct s2n_connection * conn)430 int s2n_connection_server_name_extension_used(struct s2n_connection *conn)
431 {
432
433 POSIX_ENSURE_REF(conn);
434 POSIX_ENSURE(conn->mode == S2N_SERVER, S2N_ERR_INVALID_STATE);
435 POSIX_ENSURE(!(conn->handshake.client_hello_received), S2N_ERR_INVALID_STATE);
436
437 conn->server_name_used = 1;
438 return S2N_SUCCESS;
439 }
440
s2n_connection_set_ctx(struct s2n_connection * conn,void * ctx)441 int s2n_connection_set_ctx(struct s2n_connection *conn, void *ctx)
442 {
443 conn->context = ctx;
444 return 0;
445 }
446
s2n_connection_get_ctx(struct s2n_connection * conn)447 void *s2n_connection_get_ctx(struct s2n_connection *conn)
448 {
449 return conn->context;
450 }
451
s2n_connection_release_buffers(struct s2n_connection * conn)452 int s2n_connection_release_buffers(struct s2n_connection *conn)
453 {
454 POSIX_ENSURE_REF(conn);
455 POSIX_PRECONDITION(s2n_stuffer_validate(&conn->out));
456 POSIX_PRECONDITION(s2n_stuffer_validate(&conn->in));
457
458 POSIX_ENSURE(s2n_stuffer_is_consumed(&conn->out), S2N_ERR_STUFFER_HAS_UNPROCESSED_DATA);
459 POSIX_GUARD(s2n_stuffer_resize(&conn->out, 0));
460
461 POSIX_ENSURE(s2n_stuffer_is_consumed(&conn->in), S2N_ERR_STUFFER_HAS_UNPROCESSED_DATA);
462 POSIX_GUARD(s2n_stuffer_resize(&conn->in, 0));
463
464 POSIX_POSTCONDITION(s2n_stuffer_validate(&conn->out));
465 POSIX_POSTCONDITION(s2n_stuffer_validate(&conn->in));
466 return S2N_SUCCESS;
467 }
468
s2n_connection_free_handshake(struct s2n_connection * conn)469 int s2n_connection_free_handshake(struct s2n_connection *conn)
470 {
471 /* We are done with the handshake */
472 POSIX_GUARD_RESULT(s2n_handshake_hashes_free(&conn->handshake.hashes));
473 POSIX_GUARD_RESULT(s2n_prf_free(conn));
474
475 /* Wipe the buffers we are going to free */
476 POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
477 POSIX_GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
478
479 /* Truncate buffers to save memory, we are done with the handshake */
480 POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, 0));
481 POSIX_GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
482
483 /* We can free extension data we no longer need */
484 POSIX_GUARD(s2n_free(&conn->client_ticket));
485 POSIX_GUARD(s2n_free(&conn->status_response));
486 POSIX_GUARD(s2n_free(&conn->our_quic_transport_parameters));
487 POSIX_GUARD(s2n_free(&conn->application_protocols_overridden));
488 POSIX_GUARD(s2n_stuffer_free(&conn->cookie_stuffer));
489
490 return 0;
491 }
492
s2n_connection_wipe(struct s2n_connection * conn)493 int s2n_connection_wipe(struct s2n_connection *conn)
494 {
495 /* First make a copy of everything we'd like to save, which isn't very much. */
496 int mode = conn->mode;
497 struct s2n_config *config = conn->config;
498 struct s2n_stuffer alert_in = {0};
499 struct s2n_stuffer reader_alert_out = {0};
500 struct s2n_stuffer writer_alert_out = {0};
501 struct s2n_stuffer client_ticket_to_decrypt = {0};
502 struct s2n_stuffer handshake_io = {0};
503 struct s2n_stuffer client_hello_raw_message = {0};
504 struct s2n_stuffer header_in = {0};
505 struct s2n_stuffer in = {0};
506 struct s2n_stuffer out = {0};
507 /* Session keys will be wiped. Preserve structs to avoid reallocation */
508 struct s2n_session_key initial_client_key = {0};
509 struct s2n_session_key initial_server_key = {0};
510 struct s2n_session_key secure_client_key = {0};
511 struct s2n_session_key secure_server_key = {0};
512 /* Parts of the hmac states will be wiped. Preserve structs to avoid reallocation */
513 struct s2n_connection_hmac_handles hmac_handles = {0};
514
515 /* Some required structures might have been freed to conserve memory between handshakes.
516 * Restore them.
517 */
518
519 if (!conn->handshake.hashes) {
520 POSIX_GUARD_RESULT(s2n_handshake_hashes_new(&conn->handshake.hashes));
521 }
522 POSIX_GUARD_RESULT(s2n_handshake_hashes_wipe(conn->handshake.hashes));
523 struct s2n_handshake_hashes *handshake_hashes = conn->handshake.hashes;
524
525 if (!conn->prf_space) {
526 POSIX_GUARD_RESULT(s2n_prf_new(conn));
527 }
528 POSIX_GUARD_RESULT(s2n_prf_wipe(conn));
529 struct s2n_prf_working_space *prf_workspace = conn->prf_space;
530
531 /* Wipe all of the sensitive stuff */
532 POSIX_GUARD(s2n_connection_wipe_keys(conn));
533 POSIX_GUARD(s2n_connection_reset_hmacs(conn));
534 POSIX_GUARD(s2n_stuffer_wipe(&conn->alert_in));
535 POSIX_GUARD(s2n_stuffer_wipe(&conn->reader_alert_out));
536 POSIX_GUARD(s2n_stuffer_wipe(&conn->writer_alert_out));
537 POSIX_GUARD(s2n_stuffer_wipe(&conn->client_ticket_to_decrypt));
538 POSIX_GUARD(s2n_stuffer_wipe(&conn->handshake.io));
539 POSIX_GUARD(s2n_stuffer_wipe(&conn->client_hello.raw_message));
540 POSIX_GUARD(s2n_stuffer_wipe(&conn->header_in));
541 POSIX_GUARD(s2n_stuffer_wipe(&conn->in));
542 POSIX_GUARD(s2n_stuffer_wipe(&conn->out));
543
544 POSIX_GUARD_RESULT(s2n_psk_parameters_wipe(&conn->psk_params));
545
546 /* Wipe the I/O-related info and restore the original socket if necessary */
547 POSIX_GUARD(s2n_connection_wipe_io(conn));
548
549 POSIX_GUARD(s2n_free(&conn->client_ticket));
550 POSIX_GUARD(s2n_free(&conn->status_response));
551 POSIX_GUARD(s2n_free(&conn->application_protocols_overridden));
552 POSIX_GUARD(s2n_free(&conn->our_quic_transport_parameters));
553 POSIX_GUARD(s2n_free(&conn->peer_quic_transport_parameters));
554 POSIX_GUARD(s2n_free(&conn->server_early_data_context));
555 POSIX_GUARD(s2n_free(&conn->tls13_ticket_fields.session_secret));
556
557 /* Allocate memory for handling handshakes */
558 POSIX_GUARD(s2n_stuffer_resize(&conn->handshake.io, S2N_LARGE_RECORD_LENGTH));
559
560 /* Truncate the message buffers to save memory, we will dynamically resize it as needed */
561 POSIX_GUARD(s2n_stuffer_resize(&conn->client_hello.raw_message, 0));
562 POSIX_GUARD(s2n_stuffer_resize(&conn->in, 0));
563 POSIX_GUARD(s2n_stuffer_resize(&conn->out, 0));
564
565 /* Remove context associated with connection */
566 conn->context = NULL;
567 conn->verify_host_fn_overridden = 0;
568 conn->verify_host_fn = NULL;
569 conn->data_for_verify_host = NULL;
570
571 /* Clone the stuffers */
572 /* ignore gcc 4.7 address warnings because dest is allocated on the stack */
573 /* pragma gcc diagnostic was added in gcc 4.6 */
574 #if S2N_GCC_VERSION_AT_LEAST(4,6,0)
575 #pragma GCC diagnostic push
576 #pragma GCC diagnostic ignored "-Waddress"
577 #endif
578 POSIX_CHECKED_MEMCPY(&alert_in, &conn->alert_in, sizeof(struct s2n_stuffer));
579 POSIX_CHECKED_MEMCPY(&reader_alert_out, &conn->reader_alert_out, sizeof(struct s2n_stuffer));
580 POSIX_CHECKED_MEMCPY(&writer_alert_out, &conn->writer_alert_out, sizeof(struct s2n_stuffer));
581 POSIX_CHECKED_MEMCPY(&client_ticket_to_decrypt, &conn->client_ticket_to_decrypt, sizeof(struct s2n_stuffer));
582 POSIX_CHECKED_MEMCPY(&handshake_io, &conn->handshake.io, sizeof(struct s2n_stuffer));
583 POSIX_CHECKED_MEMCPY(&client_hello_raw_message, &conn->client_hello.raw_message, sizeof(struct s2n_stuffer));
584 POSIX_CHECKED_MEMCPY(&header_in, &conn->header_in, sizeof(struct s2n_stuffer));
585 POSIX_CHECKED_MEMCPY(&in, &conn->in, sizeof(struct s2n_stuffer));
586 POSIX_CHECKED_MEMCPY(&out, &conn->out, sizeof(struct s2n_stuffer));
587 POSIX_CHECKED_MEMCPY(&initial_client_key, &conn->initial.client_key, sizeof(struct s2n_session_key));
588 POSIX_CHECKED_MEMCPY(&initial_server_key, &conn->initial.server_key, sizeof(struct s2n_session_key));
589 POSIX_CHECKED_MEMCPY(&secure_client_key, &conn->secure.client_key, sizeof(struct s2n_session_key));
590 POSIX_CHECKED_MEMCPY(&secure_server_key, &conn->secure.server_key, sizeof(struct s2n_session_key));
591 POSIX_GUARD(s2n_connection_save_hmac_state(&hmac_handles, conn));
592 #if S2N_GCC_VERSION_AT_LEAST(4,6,0)
593 #pragma GCC diagnostic pop
594 #endif
595
596 POSIX_GUARD(s2n_connection_zero(conn, mode, config));
597
598 POSIX_CHECKED_MEMCPY(&conn->alert_in, &alert_in, sizeof(struct s2n_stuffer));
599 POSIX_CHECKED_MEMCPY(&conn->reader_alert_out, &reader_alert_out, sizeof(struct s2n_stuffer));
600 POSIX_CHECKED_MEMCPY(&conn->writer_alert_out, &writer_alert_out, sizeof(struct s2n_stuffer));
601 POSIX_CHECKED_MEMCPY(&conn->client_ticket_to_decrypt, &client_ticket_to_decrypt, sizeof(struct s2n_stuffer));
602 POSIX_CHECKED_MEMCPY(&conn->handshake.io, &handshake_io, sizeof(struct s2n_stuffer));
603 POSIX_CHECKED_MEMCPY(&conn->client_hello.raw_message, &client_hello_raw_message, sizeof(struct s2n_stuffer));
604 POSIX_CHECKED_MEMCPY(&conn->header_in, &header_in, sizeof(struct s2n_stuffer));
605 POSIX_CHECKED_MEMCPY(&conn->in, &in, sizeof(struct s2n_stuffer));
606 POSIX_CHECKED_MEMCPY(&conn->out, &out, sizeof(struct s2n_stuffer));
607 POSIX_CHECKED_MEMCPY(&conn->initial.client_key, &initial_client_key, sizeof(struct s2n_session_key));
608 POSIX_CHECKED_MEMCPY(&conn->initial.server_key, &initial_server_key, sizeof(struct s2n_session_key));
609 POSIX_CHECKED_MEMCPY(&conn->secure.client_key, &secure_client_key, sizeof(struct s2n_session_key));
610 POSIX_CHECKED_MEMCPY(&conn->secure.server_key, &secure_server_key, sizeof(struct s2n_session_key));
611 POSIX_GUARD(s2n_connection_restore_hmac_state(conn, &hmac_handles));
612 conn->handshake.hashes = handshake_hashes;
613 conn->prf_space = prf_workspace;
614
615 /* Re-initialize hash and hmac states */
616 POSIX_GUARD(s2n_connection_init_hmacs(conn));
617
618 POSIX_GUARD_RESULT(s2n_psk_parameters_init(&conn->psk_params));
619 conn->server_keying_material_lifetime = ONE_WEEK_IN_SEC;
620
621 /* Require all handshakes hashes. This set can be reduced as the handshake progresses. */
622 POSIX_GUARD(s2n_handshake_require_all_hashes(&conn->handshake));
623
624 if (conn->mode == S2N_SERVER) {
625 /* Start with the highest protocol version so that the highest common protocol version can be selected */
626 /* during handshake. */
627 conn->server_protocol_version = s2n_highest_protocol_version;
628 conn->client_protocol_version = s2n_unknown_protocol_version;
629 conn->actual_protocol_version = s2n_unknown_protocol_version;
630 }
631 else {
632 /* For clients, also set actual_protocol_version. Record generation uses that value for the initial */
633 /* ClientHello record version. Not all servers ignore the record version in ClientHello. */
634 conn->server_protocol_version = s2n_unknown_protocol_version;
635 conn->client_protocol_version = s2n_highest_protocol_version;
636 conn->actual_protocol_version = s2n_highest_protocol_version;
637 }
638
639 return 0;
640 }
641
s2n_connection_set_recv_ctx(struct s2n_connection * conn,void * ctx)642 int s2n_connection_set_recv_ctx(struct s2n_connection *conn, void *ctx)
643 {
644 POSIX_ENSURE_REF(conn);
645 POSIX_GUARD(s2n_connection_free_managed_recv_io(conn));
646 conn->recv_io_context = ctx;
647 return S2N_SUCCESS;
648 }
649
s2n_connection_set_send_ctx(struct s2n_connection * conn,void * ctx)650 int s2n_connection_set_send_ctx(struct s2n_connection *conn, void *ctx)
651 {
652 POSIX_ENSURE_REF(conn);
653 POSIX_GUARD(s2n_connection_free_managed_send_io(conn));
654 conn->send_io_context = ctx;
655 return S2N_SUCCESS;
656 }
657
s2n_connection_set_recv_cb(struct s2n_connection * conn,s2n_recv_fn recv)658 int s2n_connection_set_recv_cb(struct s2n_connection *conn, s2n_recv_fn recv)
659 {
660 POSIX_ENSURE_REF(conn);
661 POSIX_GUARD(s2n_connection_free_managed_recv_io(conn));
662 conn->recv = recv;
663 return S2N_SUCCESS;
664 }
665
s2n_connection_set_send_cb(struct s2n_connection * conn,s2n_send_fn send)666 int s2n_connection_set_send_cb(struct s2n_connection *conn, s2n_send_fn send)
667 {
668 POSIX_ENSURE_REF(conn);
669 POSIX_GUARD(s2n_connection_free_managed_send_io(conn));
670 conn->send = send;
671 return S2N_SUCCESS;
672 }
673
s2n_connection_get_client_cert_chain(struct s2n_connection * conn,uint8_t ** der_cert_chain_out,uint32_t * cert_chain_len)674 int s2n_connection_get_client_cert_chain(struct s2n_connection *conn, uint8_t **der_cert_chain_out, uint32_t *cert_chain_len)
675 {
676 POSIX_ENSURE_REF(conn);
677 POSIX_ENSURE_REF(der_cert_chain_out);
678 POSIX_ENSURE_REF(cert_chain_len);
679 POSIX_ENSURE_REF(conn->handshake_params.client_cert_chain.data);
680
681 *der_cert_chain_out = conn->handshake_params.client_cert_chain.data;
682 *cert_chain_len = conn->handshake_params.client_cert_chain.size;
683
684 return 0;
685 }
686
s2n_connection_get_cipher_preferences(struct s2n_connection * conn,const struct s2n_cipher_preferences ** cipher_preferences)687 int s2n_connection_get_cipher_preferences(struct s2n_connection *conn, const struct s2n_cipher_preferences **cipher_preferences)
688 {
689 POSIX_ENSURE_REF(conn);
690 POSIX_ENSURE_REF(conn->config);
691 POSIX_ENSURE_REF(cipher_preferences);
692
693 if (conn->security_policy_override != NULL) {
694 *cipher_preferences = conn->security_policy_override->cipher_preferences;
695 } else if (conn->config->security_policy != NULL) {
696 *cipher_preferences = conn->config->security_policy->cipher_preferences;
697 } else {
698 POSIX_BAIL(S2N_ERR_INVALID_CIPHER_PREFERENCES);
699 }
700
701 POSIX_ENSURE_REF(*cipher_preferences);
702 return 0;
703 }
704
s2n_connection_get_security_policy(struct s2n_connection * conn,const struct s2n_security_policy ** security_policy)705 int s2n_connection_get_security_policy(struct s2n_connection *conn, const struct s2n_security_policy **security_policy)
706 {
707 POSIX_ENSURE_REF(conn);
708 POSIX_ENSURE_REF(conn->config);
709 POSIX_ENSURE_REF(security_policy);
710
711 if (conn->security_policy_override != NULL) {
712 *security_policy = conn->security_policy_override;
713 } else if (conn->config->security_policy != NULL) {
714 *security_policy = conn->config->security_policy;
715 } else {
716 POSIX_BAIL(S2N_ERR_INVALID_SECURITY_POLICY);
717 }
718
719 POSIX_ENSURE_REF(*security_policy);
720 return 0;
721 }
722
s2n_connection_get_kem_preferences(struct s2n_connection * conn,const struct s2n_kem_preferences ** kem_preferences)723 int s2n_connection_get_kem_preferences(struct s2n_connection *conn, const struct s2n_kem_preferences **kem_preferences)
724 {
725 POSIX_ENSURE_REF(conn);
726 POSIX_ENSURE_REF(conn->config);
727 POSIX_ENSURE_REF(kem_preferences);
728
729 if (conn->security_policy_override != NULL) {
730 *kem_preferences = conn->security_policy_override->kem_preferences;
731 } else if (conn->config->security_policy != NULL) {
732 *kem_preferences = conn->config->security_policy->kem_preferences;
733 } else {
734 POSIX_BAIL(S2N_ERR_INVALID_KEM_PREFERENCES);
735 }
736
737 POSIX_ENSURE_REF(*kem_preferences);
738 return 0;
739 }
740
s2n_connection_get_signature_preferences(struct s2n_connection * conn,const struct s2n_signature_preferences ** signature_preferences)741 int s2n_connection_get_signature_preferences(struct s2n_connection *conn, const struct s2n_signature_preferences **signature_preferences)
742 {
743 POSIX_ENSURE_REF(conn);
744 POSIX_ENSURE_REF(conn->config);
745 POSIX_ENSURE_REF(signature_preferences);
746
747 if (conn->security_policy_override != NULL) {
748 *signature_preferences = conn->security_policy_override->signature_preferences;
749 } else if (conn->config->security_policy != NULL) {
750 *signature_preferences = conn->config->security_policy->signature_preferences;
751 } else {
752 POSIX_BAIL(S2N_ERR_INVALID_SIGNATURE_ALGORITHMS_PREFERENCES);
753 }
754
755 POSIX_ENSURE_REF(*signature_preferences);
756 return 0;
757
758 }
759
s2n_connection_get_ecc_preferences(struct s2n_connection * conn,const struct s2n_ecc_preferences ** ecc_preferences)760 int s2n_connection_get_ecc_preferences(struct s2n_connection *conn, const struct s2n_ecc_preferences **ecc_preferences)
761 {
762 POSIX_ENSURE_REF(conn);
763 POSIX_ENSURE_REF(conn->config);
764 POSIX_ENSURE_REF(ecc_preferences);
765
766 if (conn->security_policy_override != NULL) {
767 *ecc_preferences = conn->security_policy_override->ecc_preferences;
768 } else if (conn->config->security_policy != NULL) {
769 *ecc_preferences = conn->config->security_policy->ecc_preferences;
770 } else {
771 POSIX_BAIL(S2N_ERR_INVALID_ECC_PREFERENCES);
772 }
773
774 POSIX_ENSURE_REF(*ecc_preferences);
775 return 0;
776
777 }
778
s2n_connection_get_protocol_preferences(struct s2n_connection * conn,struct s2n_blob ** protocol_preferences)779 int s2n_connection_get_protocol_preferences(struct s2n_connection *conn, struct s2n_blob **protocol_preferences)
780 {
781 POSIX_ENSURE_REF(conn);
782 POSIX_ENSURE_REF(protocol_preferences);
783
784 *protocol_preferences = NULL;
785 if (conn->application_protocols_overridden.size > 0) {
786 *protocol_preferences = &conn->application_protocols_overridden;
787 } else {
788 *protocol_preferences = &conn->config->application_protocols;
789 }
790
791 POSIX_ENSURE_REF(*protocol_preferences);
792 return 0;
793 }
794
s2n_connection_get_client_auth_type(struct s2n_connection * conn,s2n_cert_auth_type * client_cert_auth_type)795 int s2n_connection_get_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type *client_cert_auth_type)
796 {
797 POSIX_ENSURE_REF(conn);
798 POSIX_ENSURE_REF(client_cert_auth_type);
799
800 if (conn->client_cert_auth_type_overridden) {
801 *client_cert_auth_type = conn->client_cert_auth_type;
802 } else {
803 POSIX_ENSURE_REF(conn->config);
804 *client_cert_auth_type = conn->config->client_cert_auth_type;
805 }
806
807 return 0;
808 }
809
s2n_connection_set_client_auth_type(struct s2n_connection * conn,s2n_cert_auth_type client_cert_auth_type)810 int s2n_connection_set_client_auth_type(struct s2n_connection *conn, s2n_cert_auth_type client_cert_auth_type)
811 {
812 conn->client_cert_auth_type_overridden = 1;
813 conn->client_cert_auth_type = client_cert_auth_type;
814 return 0;
815 }
816
s2n_connection_set_read_fd(struct s2n_connection * conn,int rfd)817 int s2n_connection_set_read_fd(struct s2n_connection *conn, int rfd)
818 {
819 struct s2n_blob ctx_mem = {0};
820 struct s2n_socket_read_io_context *peer_socket_ctx;
821
822 POSIX_ENSURE_REF(conn);
823 POSIX_GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_read_io_context)));
824 POSIX_GUARD(s2n_blob_zero(&ctx_mem));
825
826 peer_socket_ctx = (struct s2n_socket_read_io_context *)(void *)ctx_mem.data;
827 peer_socket_ctx->fd = rfd;
828
829 POSIX_GUARD(s2n_connection_set_recv_cb(conn, s2n_socket_read));
830 POSIX_GUARD(s2n_connection_set_recv_ctx(conn, peer_socket_ctx));
831 conn->managed_recv_io = true;
832
833 /* This is only needed if the user is using corked io.
834 * Take the snapshot in case optimized io is enabled after setting the fd.
835 */
836 POSIX_GUARD(s2n_socket_read_snapshot(conn));
837
838 return 0;
839 }
840
s2n_connection_get_read_fd(struct s2n_connection * conn,int * readfd)841 int s2n_connection_get_read_fd(struct s2n_connection *conn, int *readfd)
842 {
843 POSIX_ENSURE_REF(conn);
844 POSIX_ENSURE_REF(readfd);
845 POSIX_ENSURE((conn->managed_recv_io && conn->recv_io_context), S2N_ERR_INVALID_STATE);
846
847 const struct s2n_socket_read_io_context *peer_socket_ctx = conn->recv_io_context;
848 *readfd = peer_socket_ctx->fd;
849 return S2N_SUCCESS;
850 }
851
s2n_connection_set_write_fd(struct s2n_connection * conn,int wfd)852 int s2n_connection_set_write_fd(struct s2n_connection *conn, int wfd)
853 {
854 struct s2n_blob ctx_mem = {0};
855 struct s2n_socket_write_io_context *peer_socket_ctx;
856
857 POSIX_ENSURE_REF(conn);
858 POSIX_GUARD(s2n_alloc(&ctx_mem, sizeof(struct s2n_socket_write_io_context)));
859
860 peer_socket_ctx = (struct s2n_socket_write_io_context *)(void *)ctx_mem.data;
861 peer_socket_ctx->fd = wfd;
862
863 POSIX_GUARD(s2n_connection_set_send_cb(conn, s2n_socket_write));
864 POSIX_GUARD(s2n_connection_set_send_ctx(conn, peer_socket_ctx));
865 conn->managed_send_io = true;
866
867 /* This is only needed if the user is using corked io.
868 * Take the snapshot in case optimized io is enabled after setting the fd.
869 */
870 POSIX_GUARD(s2n_socket_write_snapshot(conn));
871
872 uint8_t ipv6;
873 if (0 == s2n_socket_is_ipv6(wfd, &ipv6)) {
874 conn->ipv6 = (ipv6 ? 1 : 0);
875 }
876
877 conn->write_fd_broken = 0;
878
879 return 0;
880 }
881
s2n_connection_get_write_fd(struct s2n_connection * conn,int * writefd)882 int s2n_connection_get_write_fd(struct s2n_connection *conn, int *writefd)
883 {
884 POSIX_ENSURE_REF(conn);
885 POSIX_ENSURE_REF(writefd);
886 POSIX_ENSURE((conn->managed_send_io && conn->send_io_context), S2N_ERR_INVALID_STATE);
887
888 const struct s2n_socket_write_io_context *peer_socket_ctx = conn->send_io_context;
889 *writefd = peer_socket_ctx->fd;
890 return S2N_SUCCESS;
891 }
s2n_connection_set_fd(struct s2n_connection * conn,int fd)892 int s2n_connection_set_fd(struct s2n_connection *conn, int fd)
893 {
894 POSIX_GUARD(s2n_connection_set_read_fd(conn, fd));
895 POSIX_GUARD(s2n_connection_set_write_fd(conn, fd));
896 return 0;
897 }
898
s2n_connection_use_corked_io(struct s2n_connection * conn)899 int s2n_connection_use_corked_io(struct s2n_connection *conn)
900 {
901 POSIX_ENSURE_REF(conn);
902
903 /* Caller shouldn't be trying to set s2n IO corked on non-s2n-managed IO */
904 POSIX_ENSURE(conn->managed_send_io, S2N_ERR_CORK_SET_ON_UNMANAGED);
905 conn->corked_io = 1;
906
907 return 0;
908 }
909
s2n_connection_get_wire_bytes_in(struct s2n_connection * conn)910 uint64_t s2n_connection_get_wire_bytes_in(struct s2n_connection *conn)
911 {
912 return conn->wire_bytes_in;
913 }
914
s2n_connection_get_wire_bytes_out(struct s2n_connection * conn)915 uint64_t s2n_connection_get_wire_bytes_out(struct s2n_connection *conn)
916 {
917 return conn->wire_bytes_out;
918 }
919
s2n_connection_get_cipher(struct s2n_connection * conn)920 const char *s2n_connection_get_cipher(struct s2n_connection *conn)
921 {
922 PTR_ENSURE_REF(conn);
923 PTR_ENSURE_REF(conn->secure.cipher_suite);
924
925 return conn->secure.cipher_suite->name;
926 }
927
s2n_connection_get_cipher_iana_value(struct s2n_connection * conn,uint8_t * first,uint8_t * second)928 int s2n_connection_get_cipher_iana_value(struct s2n_connection *conn, uint8_t *first, uint8_t *second)
929 {
930 POSIX_ENSURE_REF(conn);
931 POSIX_ENSURE_REF(conn->secure.cipher_suite);
932 POSIX_ENSURE_MUT(first);
933 POSIX_ENSURE_MUT(second);
934
935 /* ensure we've negotiated a cipher suite */
936 POSIX_ENSURE(
937 memcmp(
938 conn->secure.cipher_suite->iana_value,
939 s2n_null_cipher_suite.iana_value,
940 sizeof(s2n_null_cipher_suite.iana_value)
941 ) != 0,
942 S2N_ERR_INVALID_STATE
943 );
944
945 const uint8_t *iana_value = conn->secure.cipher_suite->iana_value;
946 *first = iana_value[0];
947 *second = iana_value[1];
948
949 return S2N_SUCCESS;
950 }
951
s2n_connection_get_curve(struct s2n_connection * conn)952 const char *s2n_connection_get_curve(struct s2n_connection *conn)
953 {
954 PTR_ENSURE_REF(conn);
955
956 if (conn->kex_params.server_ecc_evp_params.negotiated_curve) {
957 /* TLS1.3 currently only uses ECC groups. */
958 if (conn->actual_protocol_version >= S2N_TLS13 || s2n_kex_includes(conn->secure.cipher_suite->key_exchange_alg, &s2n_ecdhe)) {
959 return conn->kex_params.server_ecc_evp_params.negotiated_curve->name;
960 }
961 }
962
963 return "NONE";
964 }
965
s2n_connection_get_kem_name(struct s2n_connection * conn)966 const char *s2n_connection_get_kem_name(struct s2n_connection *conn)
967 {
968 PTR_ENSURE_REF(conn);
969
970 if (!conn->kex_params.kem_params.kem) {
971 return "NONE";
972 }
973
974 return conn->kex_params.kem_params.kem->name;
975 }
976
s2n_connection_get_kem_group_name(struct s2n_connection * conn)977 const char *s2n_connection_get_kem_group_name(struct s2n_connection *conn)
978 {
979 PTR_ENSURE_REF(conn);
980
981 if (conn->actual_protocol_version < S2N_TLS13 || !conn->kex_params.client_kem_group_params.kem_group) {
982 return "NONE";
983 }
984
985 return conn->kex_params.client_kem_group_params.kem_group->name;
986 }
987
s2n_connection_get_client_protocol_version(struct s2n_connection * conn)988 int s2n_connection_get_client_protocol_version(struct s2n_connection *conn)
989 {
990 POSIX_ENSURE_REF(conn);
991
992 return conn->client_protocol_version;
993 }
994
s2n_connection_get_server_protocol_version(struct s2n_connection * conn)995 int s2n_connection_get_server_protocol_version(struct s2n_connection *conn)
996 {
997 POSIX_ENSURE_REF(conn);
998
999 return conn->server_protocol_version;
1000 }
1001
s2n_connection_get_actual_protocol_version(struct s2n_connection * conn)1002 int s2n_connection_get_actual_protocol_version(struct s2n_connection *conn)
1003 {
1004 POSIX_ENSURE_REF(conn);
1005
1006 return conn->actual_protocol_version;
1007 }
1008
s2n_connection_get_client_hello_version(struct s2n_connection * conn)1009 int s2n_connection_get_client_hello_version(struct s2n_connection *conn)
1010 {
1011 POSIX_ENSURE_REF(conn);
1012
1013 return conn->client_hello_version;
1014 }
1015
s2n_connection_client_cert_used(struct s2n_connection * conn)1016 int s2n_connection_client_cert_used(struct s2n_connection *conn)
1017 {
1018 POSIX_ENSURE_REF(conn);
1019
1020 if (IS_CLIENT_AUTH_HANDSHAKE(conn) && is_handshake_complete(conn)) {
1021 if (IS_CLIENT_AUTH_NO_CERT(conn)) {
1022 return 0;
1023 }
1024 return 1;
1025 }
1026 return 0;
1027 }
1028
s2n_connection_get_alert(struct s2n_connection * conn)1029 int s2n_connection_get_alert(struct s2n_connection *conn)
1030 {
1031 POSIX_ENSURE_REF(conn);
1032
1033 S2N_ERROR_IF(s2n_stuffer_data_available(&conn->alert_in) != 2, S2N_ERR_NO_ALERT);
1034
1035 uint8_t alert_code = 0;
1036 POSIX_GUARD(s2n_stuffer_read_uint8(&conn->alert_in, &alert_code));
1037 POSIX_GUARD(s2n_stuffer_read_uint8(&conn->alert_in, &alert_code));
1038
1039 return alert_code;
1040 }
1041
s2n_set_server_name(struct s2n_connection * conn,const char * server_name)1042 int s2n_set_server_name(struct s2n_connection *conn, const char *server_name)
1043 {
1044 POSIX_ENSURE_REF(conn);
1045 POSIX_ENSURE_REF(server_name);
1046
1047 S2N_ERROR_IF(conn->mode != S2N_CLIENT, S2N_ERR_CLIENT_MODE);
1048
1049 int len = strlen(server_name);
1050 S2N_ERROR_IF(len > S2N_MAX_SERVER_NAME, S2N_ERR_SERVER_NAME_TOO_LONG);
1051
1052 POSIX_CHECKED_MEMCPY(conn->server_name, server_name, len);
1053
1054 return 0;
1055 }
1056
s2n_get_server_name(struct s2n_connection * conn)1057 const char *s2n_get_server_name(struct s2n_connection *conn)
1058 {
1059 PTR_ENSURE_REF(conn);
1060
1061 if (conn->server_name[0]) {
1062 return conn->server_name;
1063 }
1064
1065 PTR_GUARD_POSIX(s2n_extension_process(&s2n_client_server_name_extension, conn, &conn->client_hello.extensions));
1066
1067 if (!conn->server_name[0]) {
1068 return NULL;
1069 }
1070
1071 return conn->server_name;
1072 }
1073
s2n_get_application_protocol(struct s2n_connection * conn)1074 const char *s2n_get_application_protocol(struct s2n_connection *conn)
1075 {
1076 PTR_ENSURE_REF(conn);
1077
1078 if (strlen(conn->application_protocol) == 0) {
1079 return NULL;
1080 }
1081
1082 return conn->application_protocol;
1083 }
1084
s2n_connection_get_session_id_length(struct s2n_connection * conn)1085 int s2n_connection_get_session_id_length(struct s2n_connection *conn)
1086 {
1087 POSIX_ENSURE_REF(conn);
1088 /* Stateful session resumption in TLS1.3 using session id is not yet supported. */
1089 if (conn->actual_protocol_version >= S2N_TLS13) {
1090 return 0;
1091 }
1092 return conn->session_id_len;
1093 }
1094
s2n_connection_get_session_id(struct s2n_connection * conn,uint8_t * session_id,size_t max_length)1095 int s2n_connection_get_session_id(struct s2n_connection *conn, uint8_t *session_id, size_t max_length)
1096 {
1097 POSIX_ENSURE_REF(conn);
1098 POSIX_ENSURE_REF(session_id);
1099
1100 int session_id_len = s2n_connection_get_session_id_length(conn);
1101
1102 S2N_ERROR_IF(session_id_len > max_length, S2N_ERR_SESSION_ID_TOO_LONG);
1103
1104 POSIX_CHECKED_MEMCPY(session_id, conn->session_id, session_id_len);
1105
1106 return session_id_len;
1107 }
1108
s2n_connection_set_blinding(struct s2n_connection * conn,s2n_blinding blinding)1109 int s2n_connection_set_blinding(struct s2n_connection *conn, s2n_blinding blinding)
1110 {
1111 POSIX_ENSURE_REF(conn);
1112 conn->blinding = blinding;
1113
1114 return 0;
1115 }
1116
1117 #define ONE_S INT64_C(1000000000)
1118 #define TEN_S INT64_C(10000000000)
1119
s2n_connection_get_delay(struct s2n_connection * conn)1120 uint64_t s2n_connection_get_delay(struct s2n_connection *conn)
1121 {
1122 if (!conn->delay) {
1123 return 0;
1124 }
1125
1126 uint64_t elapsed;
1127 /* This will cast -1 to max uint64_t */
1128 POSIX_GUARD_RESULT(s2n_timer_elapsed(conn->config, &conn->write_timer, &elapsed));
1129
1130 if (elapsed > conn->delay) {
1131 return 0;
1132 }
1133
1134 return conn->delay - elapsed;
1135 }
1136
s2n_connection_apply_error_blinding(struct s2n_connection ** conn)1137 S2N_CLEANUP_RESULT s2n_connection_apply_error_blinding(struct s2n_connection **conn)
1138 {
1139 RESULT_ENSURE_REF(conn);
1140 if (*conn == NULL) {
1141 return S2N_RESULT_OK;
1142 }
1143
1144 int error_code = s2n_errno;
1145 int error_type = s2n_error_get_type(error_code);
1146
1147 switch(error_type) {
1148 case S2N_ERR_T_OK:
1149 /* Ignore no error */
1150 return S2N_RESULT_OK;
1151 case S2N_ERR_T_BLOCKED:
1152 /* All blocking errors are retriable and should trigger no further action. */
1153 return S2N_RESULT_OK;
1154 default:
1155 break;
1156 }
1157
1158 switch(error_code) {
1159 /* Don't invoke blinding on some of the common errors.
1160 *
1161 * Be careful adding new errors here. Disabling blinding for an
1162 * error that can be triggered by secret / encrypted values can
1163 * potentially lead to a side channel attack.
1164 *
1165 * We may want to someday add an explicit error type for these errors.
1166 */
1167 case S2N_ERR_CANCELLED:
1168 case S2N_ERR_CIPHER_NOT_SUPPORTED:
1169 case S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED:
1170 (*conn)->closed = 1;
1171 break;
1172 default:
1173 /* Apply blinding to all other errors */
1174 RESULT_GUARD_POSIX(s2n_connection_kill(*conn));
1175 break;
1176 }
1177
1178 return S2N_RESULT_OK;
1179 }
1180
s2n_connection_kill(struct s2n_connection * conn)1181 int s2n_connection_kill(struct s2n_connection *conn)
1182 {
1183 POSIX_ENSURE_REF(conn);
1184
1185 conn->closed = 1;
1186
1187 /* Delay between 10 and 30 seconds in nanoseconds */
1188 int64_t min = TEN_S, max = 3 * TEN_S;
1189
1190 /* Keep track of the delay so that it can be enforced */
1191 uint64_t rand_delay = 0;
1192 POSIX_GUARD_RESULT(s2n_public_random(max - min, &rand_delay));
1193
1194 conn->delay = min + rand_delay;
1195
1196 /* Restart the write timer */
1197 POSIX_GUARD_RESULT(s2n_timer_start(conn->config, &conn->write_timer));
1198
1199 if (conn->blinding == S2N_BUILT_IN_BLINDING) {
1200 struct timespec sleep_time = {.tv_sec = conn->delay / ONE_S,.tv_nsec = conn->delay % ONE_S };
1201 int r;
1202
1203 do {
1204 r = nanosleep(&sleep_time, &sleep_time);
1205 }
1206 while (r != 0);
1207 }
1208
1209 return 0;
1210 }
1211
s2n_connection_get_ocsp_response(struct s2n_connection * conn,uint32_t * length)1212 const uint8_t *s2n_connection_get_ocsp_response(struct s2n_connection *conn, uint32_t * length)
1213 {
1214 PTR_ENSURE_REF(conn);
1215 PTR_ENSURE_REF(length);
1216
1217 *length = conn->status_response.size;
1218 return conn->status_response.data;
1219 }
1220
s2n_connection_set_max_fragment_length(struct s2n_connection * conn,uint16_t max_frag_length)1221 S2N_RESULT s2n_connection_set_max_fragment_length(struct s2n_connection *conn, uint16_t max_frag_length)
1222 {
1223 RESULT_ENSURE_REF(conn);
1224
1225 if (conn->negotiated_mfl_code) {
1226 /* Respect the upper limit agreed on with the peer */
1227 RESULT_ENSURE_LT(conn->negotiated_mfl_code, s2n_array_len(mfl_code_to_length));
1228 conn->max_outgoing_fragment_length = MIN(mfl_code_to_length[conn->negotiated_mfl_code], max_frag_length);
1229 } else {
1230 conn->max_outgoing_fragment_length = max_frag_length;
1231 }
1232
1233 /* If no buffer has been initialized yet, no need to resize.
1234 * The standard I/O logic will handle initializing the buffer.
1235 */
1236 if (s2n_stuffer_is_freed(&conn->out)) {
1237 return S2N_RESULT_OK;
1238 }
1239
1240 uint16_t max_wire_record_size = 0;
1241 RESULT_GUARD(s2n_record_max_write_size(conn, conn->max_outgoing_fragment_length, &max_wire_record_size));
1242 if ((conn->out.blob.size < max_wire_record_size)) {
1243 RESULT_GUARD_POSIX(s2n_realloc(&conn->out.blob, max_wire_record_size));
1244 }
1245
1246 return S2N_RESULT_OK;
1247 }
1248
s2n_connection_prefer_throughput(struct s2n_connection * conn)1249 int s2n_connection_prefer_throughput(struct s2n_connection *conn)
1250 {
1251 POSIX_GUARD_RESULT(s2n_connection_set_max_fragment_length(conn, S2N_LARGE_FRAGMENT_LENGTH));
1252 return S2N_SUCCESS;
1253 }
1254
s2n_connection_prefer_low_latency(struct s2n_connection * conn)1255 int s2n_connection_prefer_low_latency(struct s2n_connection *conn)
1256 {
1257 POSIX_GUARD_RESULT(s2n_connection_set_max_fragment_length(conn, S2N_SMALL_FRAGMENT_LENGTH));
1258 return S2N_SUCCESS;
1259 }
1260
s2n_connection_set_dynamic_record_threshold(struct s2n_connection * conn,uint32_t resize_threshold,uint16_t timeout_threshold)1261 int s2n_connection_set_dynamic_record_threshold(struct s2n_connection *conn, uint32_t resize_threshold, uint16_t timeout_threshold)
1262 {
1263 POSIX_ENSURE_REF(conn);
1264 S2N_ERROR_IF(resize_threshold > S2N_TLS_MAX_RESIZE_THRESHOLD, S2N_ERR_INVALID_DYNAMIC_THRESHOLD);
1265
1266 conn->dynamic_record_resize_threshold = resize_threshold;
1267 conn->dynamic_record_timeout_threshold = timeout_threshold;
1268 return 0;
1269 }
1270
s2n_connection_set_verify_host_callback(struct s2n_connection * conn,s2n_verify_host_fn verify_host_fn,void * data)1271 int s2n_connection_set_verify_host_callback(struct s2n_connection *conn, s2n_verify_host_fn verify_host_fn, void *data) {
1272 POSIX_ENSURE_REF(conn);
1273
1274 conn->verify_host_fn = verify_host_fn;
1275 conn->data_for_verify_host = data;
1276 conn->verify_host_fn_overridden = 1;
1277
1278 return 0;
1279 }
1280
s2n_connection_recv_stuffer(struct s2n_stuffer * stuffer,struct s2n_connection * conn,uint32_t len)1281 int s2n_connection_recv_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len)
1282 {
1283 POSIX_ENSURE_REF(conn->recv);
1284 /* Make sure we have enough space to write */
1285 POSIX_GUARD(s2n_stuffer_reserve_space(stuffer, len));
1286
1287 int r = 0;
1288 do {
1289 errno = 0;
1290 r = conn->recv(conn->recv_io_context, stuffer->blob.data + stuffer->write_cursor, len);
1291 S2N_ERROR_IF(r < 0 && errno != EINTR, S2N_ERR_RECV_STUFFER_FROM_CONN);
1292 } while (r < 0);
1293
1294 /* Record just how many bytes we have written */
1295 POSIX_GUARD(s2n_stuffer_skip_write(stuffer, r));
1296 return r;
1297 }
1298
s2n_connection_send_stuffer(struct s2n_stuffer * stuffer,struct s2n_connection * conn,uint32_t len)1299 int s2n_connection_send_stuffer(struct s2n_stuffer *stuffer, struct s2n_connection *conn, uint32_t len)
1300 {
1301 POSIX_ENSURE_REF(conn);
1302 POSIX_ENSURE_REF(conn->send);
1303 if (conn->write_fd_broken) {
1304 POSIX_BAIL(S2N_ERR_SEND_STUFFER_TO_CONN);
1305 }
1306 /* Make sure we even have the data */
1307 S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) < len, S2N_ERR_STUFFER_OUT_OF_DATA);
1308
1309 int w = 0;
1310 do {
1311 errno = 0;
1312 w = conn->send(conn->send_io_context, stuffer->blob.data + stuffer->read_cursor, len);
1313 if (w < 0 && errno == EPIPE) {
1314 conn->write_fd_broken = 1;
1315 }
1316 S2N_ERROR_IF(w < 0 && errno != EINTR, S2N_ERR_SEND_STUFFER_TO_CONN);
1317 } while (w < 0);
1318
1319 POSIX_GUARD(s2n_stuffer_skip_read(stuffer, w));
1320 return w;
1321 }
1322
s2n_connection_is_managed_corked(const struct s2n_connection * s2n_connection)1323 int s2n_connection_is_managed_corked(const struct s2n_connection *s2n_connection)
1324 {
1325 POSIX_ENSURE_REF(s2n_connection);
1326
1327 return (s2n_connection->managed_send_io && s2n_connection->corked_io);
1328 }
1329
s2n_connection_get_sct_list(struct s2n_connection * conn,uint32_t * length)1330 const uint8_t *s2n_connection_get_sct_list(struct s2n_connection *conn, uint32_t *length)
1331 {
1332 if (!length) {
1333 return NULL;
1334 }
1335
1336 *length = conn->ct_response.size;
1337 return conn->ct_response.data;
1338 }
1339
s2n_connection_is_client_auth_enabled(struct s2n_connection * s2n_connection)1340 int s2n_connection_is_client_auth_enabled(struct s2n_connection *s2n_connection)
1341 {
1342 s2n_cert_auth_type auth_type;
1343 POSIX_GUARD(s2n_connection_get_client_auth_type(s2n_connection, &auth_type));
1344
1345 return (auth_type != S2N_CERT_AUTH_NONE);
1346 }
1347
s2n_connection_get_selected_cert(struct s2n_connection * conn)1348 struct s2n_cert_chain_and_key *s2n_connection_get_selected_cert(struct s2n_connection *conn)
1349 {
1350 PTR_ENSURE_REF(conn);
1351 return conn->handshake_params.our_chain_and_key;
1352 }
1353
s2n_connection_get_protocol_version(const struct s2n_connection * conn)1354 uint8_t s2n_connection_get_protocol_version(const struct s2n_connection *conn)
1355 {
1356 if (conn == NULL) {
1357 return S2N_UNKNOWN_PROTOCOL_VERSION;
1358 }
1359
1360 if (conn->actual_protocol_version != S2N_UNKNOWN_PROTOCOL_VERSION) {
1361 return conn->actual_protocol_version;
1362 }
1363
1364 if (conn->mode == S2N_CLIENT) {
1365 return conn->client_protocol_version;
1366 }
1367 return conn->server_protocol_version;
1368 }
1369
1370 DEFINE_POINTER_CLEANUP_FUNC(struct s2n_cert_chain *, s2n_cert_chain_free);
1371
s2n_connection_get_peer_cert_chain(const struct s2n_connection * conn,struct s2n_cert_chain_and_key * cert_chain_and_key)1372 int s2n_connection_get_peer_cert_chain(const struct s2n_connection *conn, struct s2n_cert_chain_and_key *cert_chain_and_key)
1373 {
1374 POSIX_ENSURE_REF(conn);
1375 POSIX_ENSURE_REF(cert_chain_and_key);
1376
1377 DEFER_CLEANUP(struct s2n_cert_chain *cert_chain = cert_chain_and_key->cert_chain, s2n_cert_chain_free_pointer);
1378 struct s2n_cert **insert = &cert_chain->head;
1379 POSIX_ENSURE(*insert == NULL, S2N_ERR_INVALID_ARGUMENT);
1380
1381 const struct s2n_x509_validator *validator = &conn->x509_validator;
1382 POSIX_ENSURE_REF(validator);
1383 POSIX_ENSURE(s2n_x509_validator_is_cert_chain_validated(validator), S2N_ERR_CERT_NOT_VALIDATED);
1384
1385 /* X509_STORE_CTX_get1_chain() returns a validated cert chain if a previous call to X509_verify_cert() was successful.
1386 * X509_STORE_CTX_get0_chain() is a better API because it doesn't return a copy. But it's not available for Openssl 1.0.2.
1387 * See the comments here:
1388 * https://www.openssl.org/docs/man1.0.2/man3/X509_STORE_CTX_get1_chain.html
1389 */
1390 DEFER_CLEANUP(STACK_OF(X509) *cert_chain_validated = X509_STORE_CTX_get1_chain(validator->store_ctx),
1391 s2n_openssl_x509_stack_pop_free);
1392 POSIX_ENSURE_REF(cert_chain_validated);
1393
1394 for (size_t cert_idx = 0; cert_idx < sk_X509_num(cert_chain_validated); cert_idx++) {
1395 X509 *cert = sk_X509_value(cert_chain_validated, cert_idx);
1396 POSIX_ENSURE_REF(cert);
1397 DEFER_CLEANUP(uint8_t *cert_data = NULL, s2n_crypto_free);
1398 int cert_size = i2d_X509(cert, &cert_data);
1399 POSIX_ENSURE_GT(cert_size, 0);
1400
1401 struct s2n_blob mem = { 0 };
1402 POSIX_GUARD(s2n_alloc(&mem, sizeof(struct s2n_cert)));
1403
1404 struct s2n_cert *new_node = (struct s2n_cert *)(void *)mem.data;
1405 POSIX_ENSURE_REF(new_node);
1406
1407 new_node->next = NULL;
1408 *insert = new_node;
1409 insert = &new_node->next;
1410
1411 POSIX_GUARD(s2n_alloc(&new_node->raw, cert_size));
1412 POSIX_CHECKED_MEMCPY(new_node->raw.data, cert_data, cert_size);
1413 }
1414
1415 ZERO_TO_DISABLE_DEFER_CLEANUP(cert_chain);
1416
1417 return S2N_SUCCESS;
1418 }
1419
s2n_signature_scheme_to_tls_iana(struct s2n_signature_scheme * sig_scheme,s2n_tls_hash_algorithm * converted_scheme)1420 static S2N_RESULT s2n_signature_scheme_to_tls_iana(struct s2n_signature_scheme *sig_scheme, s2n_tls_hash_algorithm *converted_scheme)
1421 {
1422 RESULT_ENSURE_REF(sig_scheme);
1423 RESULT_ENSURE_REF(converted_scheme);
1424
1425 switch (sig_scheme->hash_alg) {
1426 case S2N_HASH_MD5:
1427 *converted_scheme = S2N_TLS_HASH_MD5;
1428 break;
1429 case S2N_HASH_SHA1:
1430 *converted_scheme = S2N_TLS_HASH_SHA1;
1431 break;
1432 case S2N_HASH_SHA224:
1433 *converted_scheme = S2N_TLS_HASH_SHA224;
1434 break;
1435 case S2N_HASH_SHA256:
1436 *converted_scheme = S2N_TLS_HASH_SHA256;
1437 break;
1438 case S2N_HASH_SHA384:
1439 *converted_scheme = S2N_TLS_HASH_SHA384;
1440 break;
1441 case S2N_HASH_SHA512:
1442 *converted_scheme = S2N_TLS_HASH_SHA512;
1443 break;
1444 case S2N_HASH_MD5_SHA1:
1445 *converted_scheme = S2N_TLS_HASH_MD5_SHA1;
1446 break;
1447 default:
1448 *converted_scheme = S2N_TLS_HASH_NONE;
1449 break;
1450 }
1451
1452 return S2N_RESULT_OK;
1453 }
1454
s2n_connection_get_selected_digest_algorithm(struct s2n_connection * conn,s2n_tls_hash_algorithm * converted_scheme)1455 int s2n_connection_get_selected_digest_algorithm(struct s2n_connection *conn, s2n_tls_hash_algorithm *converted_scheme)
1456 {
1457 POSIX_ENSURE_REF(conn);
1458 POSIX_ENSURE_REF(converted_scheme);
1459
1460 POSIX_GUARD_RESULT(s2n_signature_scheme_to_tls_iana(&conn->handshake_params.conn_sig_scheme, converted_scheme));
1461
1462 return S2N_SUCCESS;
1463 }
1464
s2n_connection_get_selected_client_cert_digest_algorithm(struct s2n_connection * conn,s2n_tls_hash_algorithm * converted_scheme)1465 int s2n_connection_get_selected_client_cert_digest_algorithm(struct s2n_connection *conn, s2n_tls_hash_algorithm *converted_scheme)
1466 {
1467 POSIX_ENSURE_REF(conn);
1468 POSIX_ENSURE_REF(converted_scheme);
1469
1470 POSIX_GUARD_RESULT(s2n_signature_scheme_to_tls_iana(&conn->handshake_params.client_cert_sig_scheme, converted_scheme));
1471 return S2N_SUCCESS;
1472 }
1473
s2n_signature_scheme_to_signature_algorithm(struct s2n_signature_scheme * sig_scheme,s2n_tls_signature_algorithm * converted_scheme)1474 static S2N_RESULT s2n_signature_scheme_to_signature_algorithm(struct s2n_signature_scheme *sig_scheme, s2n_tls_signature_algorithm *converted_scheme)
1475 {
1476 RESULT_ENSURE_REF(sig_scheme);
1477 RESULT_ENSURE_REF(converted_scheme);
1478
1479 switch (sig_scheme->sig_alg) {
1480 case S2N_SIGNATURE_RSA:
1481 *converted_scheme = S2N_TLS_SIGNATURE_RSA;
1482 break;
1483 case S2N_SIGNATURE_ECDSA:
1484 *converted_scheme = S2N_TLS_SIGNATURE_ECDSA;
1485 break;
1486 case S2N_SIGNATURE_RSA_PSS_RSAE:
1487 *converted_scheme = S2N_TLS_SIGNATURE_RSA_PSS_RSAE;
1488 break;
1489 case S2N_SIGNATURE_RSA_PSS_PSS:
1490 *converted_scheme = S2N_TLS_SIGNATURE_RSA_PSS_PSS;
1491 break;
1492 default:
1493 *converted_scheme = S2N_TLS_SIGNATURE_ANONYMOUS;
1494 break;
1495 }
1496
1497 return S2N_RESULT_OK;
1498 }
1499
s2n_connection_get_selected_signature_algorithm(struct s2n_connection * conn,s2n_tls_signature_algorithm * converted_scheme)1500 int s2n_connection_get_selected_signature_algorithm(struct s2n_connection *conn, s2n_tls_signature_algorithm *converted_scheme)
1501 {
1502 POSIX_ENSURE_REF(conn);
1503 POSIX_ENSURE_REF(converted_scheme);
1504
1505 POSIX_GUARD_RESULT(s2n_signature_scheme_to_signature_algorithm(&conn->handshake_params.conn_sig_scheme, converted_scheme));
1506
1507 return S2N_SUCCESS;
1508 }
1509
s2n_connection_get_selected_client_cert_signature_algorithm(struct s2n_connection * conn,s2n_tls_signature_algorithm * converted_scheme)1510 int s2n_connection_get_selected_client_cert_signature_algorithm(struct s2n_connection *conn, s2n_tls_signature_algorithm *converted_scheme)
1511 {
1512 POSIX_ENSURE_REF(conn);
1513 POSIX_ENSURE_REF(converted_scheme);
1514
1515 POSIX_GUARD_RESULT(s2n_signature_scheme_to_signature_algorithm(&conn->handshake_params.client_cert_sig_scheme, converted_scheme));
1516
1517 return S2N_SUCCESS;
1518 }
1519