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