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 <strings.h>
17 #include <time.h>
18 
19 #include "error/s2n_errno.h"
20 
21 #include "crypto/s2n_certificate.h"
22 #include "crypto/s2n_fips.h"
23 
24 #include "tls/s2n_cipher_preferences.h"
25 #include "tls/s2n_security_policies.h"
26 #include "tls/s2n_tls13.h"
27 #include "utils/s2n_safety.h"
28 #include "crypto/s2n_hkdf.h"
29 #include "utils/s2n_map.h"
30 #include "utils/s2n_blob.h"
31 
32 #if defined(CLOCK_MONOTONIC_RAW)
33 #define S2N_CLOCK_HW CLOCK_MONOTONIC_RAW
34 #else
35 #define S2N_CLOCK_HW CLOCK_MONOTONIC
36 #endif
37 
38 #define S2N_CLOCK_SYS CLOCK_REALTIME
39 
monotonic_clock(void * data,uint64_t * nanoseconds)40 static int monotonic_clock(void *data, uint64_t *nanoseconds)
41 {
42     struct timespec current_time = {0};
43 
44     POSIX_GUARD(clock_gettime(S2N_CLOCK_HW, &current_time));
45 
46     *nanoseconds = (uint64_t)current_time.tv_sec * 1000000000ull;
47     *nanoseconds += current_time.tv_nsec;
48 
49     return 0;
50 }
51 
wall_clock(void * data,uint64_t * nanoseconds)52 static int wall_clock(void *data, uint64_t *nanoseconds)
53 {
54     struct timespec current_time = {0};
55 
56     POSIX_GUARD(clock_gettime(S2N_CLOCK_SYS, &current_time));
57 
58     *nanoseconds = (uint64_t)current_time.tv_sec * 1000000000ull;
59     *nanoseconds += current_time.tv_nsec;
60 
61     return 0;
62 }
63 
64 static struct s2n_config s2n_default_config = {0};
65 static struct s2n_config s2n_default_fips_config = {0};
66 static struct s2n_config s2n_default_tls13_config = {0};
67 
s2n_config_setup_default(struct s2n_config * config)68 static int s2n_config_setup_default(struct s2n_config *config)
69 {
70     POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default"));
71     return S2N_SUCCESS;
72 }
73 
s2n_config_setup_tls13(struct s2n_config * config)74 static int s2n_config_setup_tls13(struct s2n_config *config)
75 {
76     POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default_tls13"));
77     return S2N_SUCCESS;
78 }
79 
s2n_config_setup_fips(struct s2n_config * config)80 static int s2n_config_setup_fips(struct s2n_config *config)
81 {
82     POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default_fips"));
83     return S2N_SUCCESS;
84 }
85 
s2n_config_init(struct s2n_config * config)86 static int s2n_config_init(struct s2n_config *config)
87 {
88     config->status_request_type = S2N_STATUS_REQUEST_NONE;
89     config->wall_clock = wall_clock;
90     config->monotonic_clock = monotonic_clock;
91     config->ct_type = S2N_CT_SUPPORT_NONE;
92     config->mfl_code = S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
93     config->alert_behavior = S2N_ALERT_FAIL_ON_WARNINGS;
94     config->session_state_lifetime_in_nanos = S2N_STATE_LIFETIME_IN_NANOS;
95     config->encrypt_decrypt_key_lifetime_in_nanos = S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS;
96     config->decrypt_key_lifetime_in_nanos = S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS;
97     config->async_pkey_validation_mode = S2N_ASYNC_PKEY_VALIDATION_FAST;
98 
99     /* By default, only the client will authenticate the Server's Certificate. The Server does not request or
100      * authenticate any client certificates. */
101     config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
102     config->check_ocsp = 1;
103 
104     config->client_hello_cb_mode = S2N_CLIENT_HELLO_CB_BLOCKING;
105 
106     POSIX_GUARD(s2n_config_setup_default(config));
107     if (s2n_use_default_tls13_config()) {
108         POSIX_GUARD(s2n_config_setup_tls13(config));
109     } else if (s2n_is_in_fips_mode()) {
110         POSIX_GUARD(s2n_config_setup_fips(config));
111     }
112 
113     POSIX_GUARD_PTR(config->domain_name_to_cert_map = s2n_map_new_with_initial_capacity(1));
114     POSIX_GUARD_RESULT(s2n_map_complete(config->domain_name_to_cert_map));
115 
116     s2n_x509_trust_store_init_empty(&config->trust_store);
117     POSIX_GUARD(s2n_x509_trust_store_from_system_defaults(&config->trust_store));
118 
119     return 0;
120 }
121 
s2n_config_cleanup(struct s2n_config * config)122 static int s2n_config_cleanup(struct s2n_config *config)
123 {
124     s2n_x509_trust_store_wipe(&config->trust_store);
125     config->check_ocsp = 0;
126 
127     POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
128     POSIX_GUARD(s2n_config_free_cert_chain_and_key(config));
129     POSIX_GUARD(s2n_config_free_dhparams(config));
130     POSIX_GUARD(s2n_free(&config->application_protocols));
131     POSIX_GUARD_RESULT(s2n_map_free(config->domain_name_to_cert_map));
132 
133     return 0;
134 }
135 
s2n_config_update_domain_name_to_cert_map(struct s2n_config * config,struct s2n_blob * name,struct s2n_cert_chain_and_key * cert_key_pair)136 static int s2n_config_update_domain_name_to_cert_map(struct s2n_config *config,
137                                                      struct s2n_blob *name,
138                                                      struct s2n_cert_chain_and_key *cert_key_pair)
139 {
140     POSIX_ENSURE_REF(config);
141     POSIX_ENSURE_REF(name);
142 
143     struct s2n_map *domain_name_to_cert_map = config->domain_name_to_cert_map;
144     /* s2n_map does not allow zero-size key */
145     if (name->size == 0) {
146         return 0;
147     }
148     s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
149     struct s2n_blob s2n_map_value = { 0 };
150     bool key_found = false;
151     POSIX_GUARD_RESULT(s2n_map_lookup(domain_name_to_cert_map, name, &s2n_map_value, &key_found));
152     if (!key_found) {
153         struct certs_by_type value = {{ 0 }};
154         value.certs[cert_type] = cert_key_pair;
155         s2n_map_value.data = (uint8_t *) &value;
156         s2n_map_value.size = sizeof(struct certs_by_type);
157 
158         POSIX_GUARD_RESULT(s2n_map_unlock(domain_name_to_cert_map));
159         POSIX_GUARD_RESULT(s2n_map_add(domain_name_to_cert_map, name, &s2n_map_value));
160         POSIX_GUARD_RESULT(s2n_map_complete(domain_name_to_cert_map));
161     } else {
162         struct certs_by_type *value = (void *) s2n_map_value.data;;
163         if (value->certs[cert_type] == NULL) {
164             value->certs[cert_type] = cert_key_pair;
165         } else if (config->cert_tiebreak_cb) {
166             /* There's an existing certificate for this (domain_name, auth_method).
167              * Run the application's tiebreaking callback to decide which cert should be used.
168              * An application may have some context specific logic to resolve ties that are based
169              * on factors like trust, expiry, etc.
170              */
171             struct s2n_cert_chain_and_key *winner = config->cert_tiebreak_cb(
172                     value->certs[cert_type],
173                     cert_key_pair,
174                     name->data,
175                     name->size);
176             if (winner) {
177                 value->certs[cert_type] = winner;
178             }
179         }
180     }
181 
182     return 0;
183 }
184 
s2n_config_build_domain_name_to_cert_map(struct s2n_config * config,struct s2n_cert_chain_and_key * cert_key_pair)185 static int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
186 {
187 
188     uint32_t cn_len = 0;
189     POSIX_GUARD_RESULT(s2n_array_num_elements(cert_key_pair->cn_names, &cn_len));
190     uint32_t san_len = 0;
191     POSIX_GUARD_RESULT(s2n_array_num_elements(cert_key_pair->san_names, &san_len));
192 
193     if (san_len == 0) {
194         for (uint32_t i = 0; i < cn_len; i++) {
195             struct s2n_blob *cn_name = NULL;
196             POSIX_GUARD_RESULT(s2n_array_get(cert_key_pair->cn_names, i, (void **)&cn_name));
197             POSIX_GUARD(s2n_config_update_domain_name_to_cert_map(config, cn_name, cert_key_pair));
198         }
199     } else {
200         for (uint32_t i = 0; i < san_len; i++) {
201             struct s2n_blob *san_name = NULL;
202             POSIX_GUARD_RESULT(s2n_array_get(cert_key_pair->san_names, i, (void **)&san_name));
203             POSIX_GUARD(s2n_config_update_domain_name_to_cert_map(config, san_name, cert_key_pair));
204         }
205     }
206 
207     return 0;
208 }
209 
s2n_fetch_default_config(void)210 struct s2n_config *s2n_fetch_default_config(void)
211 {
212     if (s2n_use_default_tls13_config()) {
213         return &s2n_default_tls13_config;
214     }
215     if (s2n_is_in_fips_mode()) {
216         return &s2n_default_fips_config;
217     }
218     return &s2n_default_config;
219 }
220 
s2n_config_set_unsafe_for_testing(struct s2n_config * config)221 int s2n_config_set_unsafe_for_testing(struct s2n_config *config)
222 {
223     S2N_ERROR_IF(!S2N_IN_TEST, S2N_ERR_NOT_IN_UNIT_TEST);
224     config->client_cert_auth_type = S2N_CERT_AUTH_NONE;
225     config->check_ocsp = 0;
226     config->disable_x509_validation = 1;
227 
228     return S2N_SUCCESS;
229 }
230 
s2n_config_defaults_init(void)231 int s2n_config_defaults_init(void)
232 {
233     /* Set up default */
234     POSIX_GUARD(s2n_config_init(&s2n_default_config));
235     POSIX_GUARD(s2n_config_setup_default(&s2n_default_config));
236 
237     /* Set up fips defaults */
238     POSIX_GUARD(s2n_config_init(&s2n_default_fips_config));
239     POSIX_GUARD(s2n_config_setup_fips(&s2n_default_fips_config));
240 
241     /* Set up TLS 1.3 defaults */
242     POSIX_GUARD(s2n_config_init(&s2n_default_tls13_config));
243     POSIX_GUARD(s2n_config_setup_tls13(&s2n_default_tls13_config));
244 
245     return S2N_SUCCESS;
246 }
247 
s2n_wipe_static_configs(void)248 void s2n_wipe_static_configs(void)
249 {
250     s2n_config_cleanup(&s2n_default_config);
251     s2n_config_cleanup(&s2n_default_fips_config);
252     s2n_config_cleanup(&s2n_default_tls13_config);
253 }
254 
s2n_config_new(void)255 struct s2n_config *s2n_config_new(void)
256 {
257     struct s2n_blob allocator = {0};
258     struct s2n_config *new_config;
259 
260     PTR_GUARD_POSIX(s2n_alloc(&allocator, sizeof(struct s2n_config)));
261     PTR_GUARD_POSIX(s2n_blob_zero(&allocator));
262 
263     new_config = (struct s2n_config *)(void *)allocator.data;
264     if (s2n_config_init(new_config) != S2N_SUCCESS) {
265         s2n_free(&allocator);
266         return NULL;
267     }
268 
269     return new_config;
270 }
271 
s2n_config_store_ticket_key_comparator(const void * a,const void * b)272 static int s2n_config_store_ticket_key_comparator(const void *a, const void *b)
273 {
274     if (((const struct s2n_ticket_key *) a)->intro_timestamp >= ((const struct s2n_ticket_key *) b)->intro_timestamp) {
275         return S2N_GREATER_OR_EQUAL;
276     } else {
277         return S2N_LESS_THAN;
278     }
279 }
280 
s2n_verify_unique_ticket_key_comparator(const void * a,const void * b)281 static int s2n_verify_unique_ticket_key_comparator(const void *a, const void *b)
282 {
283     return memcmp(a, b, SHA_DIGEST_LENGTH);
284 }
285 
s2n_config_init_session_ticket_keys(struct s2n_config * config)286 int s2n_config_init_session_ticket_keys(struct s2n_config *config)
287 {
288     if (config->ticket_keys == NULL) {
289       POSIX_ENSURE_REF(config->ticket_keys = s2n_set_new(sizeof(struct s2n_ticket_key), s2n_config_store_ticket_key_comparator));
290     }
291 
292     if (config->ticket_key_hashes == NULL) {
293       POSIX_ENSURE_REF(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
294     }
295 
296     return 0;
297 }
298 
s2n_config_free_session_ticket_keys(struct s2n_config * config)299 int s2n_config_free_session_ticket_keys(struct s2n_config *config)
300 {
301     if (config->ticket_keys != NULL) {
302         POSIX_GUARD_RESULT(s2n_set_free_p(&config->ticket_keys));
303     }
304 
305     if (config->ticket_key_hashes != NULL) {
306         POSIX_GUARD_RESULT(s2n_set_free_p(&config->ticket_key_hashes));
307     }
308 
309     return 0;
310 }
311 
s2n_config_free_cert_chain_and_key(struct s2n_config * config)312 int s2n_config_free_cert_chain_and_key(struct s2n_config *config)
313 {
314     /* Free the cert_chain_and_key since the application has no reference
315      * to it. This is necessary until s2n_config_add_cert_chain_and_key is deprecated. */
316     if (config->cert_allocated) {
317         for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
318             s2n_cert_chain_and_key_free(config->default_certs_by_type.certs[i]);
319         }
320     }
321 
322     return 0;
323 }
324 
s2n_config_free_dhparams(struct s2n_config * config)325 int s2n_config_free_dhparams(struct s2n_config *config)
326 {
327     if (config->dhparams) {
328         POSIX_GUARD(s2n_dh_params_free(config->dhparams));
329     }
330 
331     POSIX_GUARD(s2n_free_object((uint8_t **)&config->dhparams, sizeof(struct s2n_dh_params)));
332     return 0;
333 }
334 
s2n_config_free(struct s2n_config * config)335 int s2n_config_free(struct s2n_config *config)
336 {
337     s2n_config_cleanup(config);
338 
339     POSIX_GUARD(s2n_free_object((uint8_t **)&config, sizeof(struct s2n_config)));
340     return 0;
341 }
342 
s2n_config_get_client_auth_type(struct s2n_config * config,s2n_cert_auth_type * client_auth_type)343 int s2n_config_get_client_auth_type(struct s2n_config *config, s2n_cert_auth_type *client_auth_type)
344 {
345     POSIX_ENSURE_REF(config);
346     POSIX_ENSURE_REF(client_auth_type);
347     *client_auth_type = config->client_cert_auth_type;
348     return 0;
349 }
350 
s2n_config_set_client_auth_type(struct s2n_config * config,s2n_cert_auth_type client_auth_type)351 int s2n_config_set_client_auth_type(struct s2n_config *config, s2n_cert_auth_type client_auth_type)
352 {
353     POSIX_ENSURE_REF(config);
354     config->client_cert_auth_type = client_auth_type;
355     return 0;
356 }
357 
s2n_config_set_ct_support_level(struct s2n_config * config,s2n_ct_support_level type)358 int s2n_config_set_ct_support_level(struct s2n_config *config, s2n_ct_support_level type)
359 {
360     POSIX_ENSURE_REF(config);
361     config->ct_type = type;
362 
363     return 0;
364 }
365 
s2n_config_set_alert_behavior(struct s2n_config * config,s2n_alert_behavior alert_behavior)366 int s2n_config_set_alert_behavior(struct s2n_config *config, s2n_alert_behavior alert_behavior)
367 {
368     POSIX_ENSURE_REF(config);
369 
370     switch (alert_behavior) {
371         case S2N_ALERT_FAIL_ON_WARNINGS:
372         case S2N_ALERT_IGNORE_WARNINGS:
373             config->alert_behavior = alert_behavior;
374             break;
375         default:
376             POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
377     }
378 
379     return 0;
380 }
381 
s2n_config_set_verify_host_callback(struct s2n_config * config,s2n_verify_host_fn verify_host_fn,void * data)382 int s2n_config_set_verify_host_callback(struct s2n_config *config, s2n_verify_host_fn verify_host_fn, void *data)
383 {
384     POSIX_ENSURE_REF(config);
385     config->verify_host = verify_host_fn;
386     config->data_for_verify_host = data;
387     return 0;
388 }
389 
s2n_config_set_check_stapled_ocsp_response(struct s2n_config * config,uint8_t check_ocsp)390 int s2n_config_set_check_stapled_ocsp_response(struct s2n_config *config, uint8_t check_ocsp)
391 {
392     POSIX_ENSURE_REF(config);
393     S2N_ERROR_IF(check_ocsp && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
394     config->check_ocsp = check_ocsp;
395     return 0;
396 }
397 
s2n_config_disable_x509_verification(struct s2n_config * config)398 int s2n_config_disable_x509_verification(struct s2n_config *config)
399 {
400     POSIX_ENSURE_REF(config);
401     s2n_x509_trust_store_wipe(&config->trust_store);
402     config->disable_x509_validation = 1;
403     return 0;
404 }
405 
s2n_config_set_max_cert_chain_depth(struct s2n_config * config,uint16_t max_depth)406 int s2n_config_set_max_cert_chain_depth(struct s2n_config *config, uint16_t max_depth)
407 {
408     POSIX_ENSURE_REF(config);
409     S2N_ERROR_IF(max_depth == 0, S2N_ERR_INVALID_ARGUMENT);
410 
411     config->max_verify_cert_chain_depth = max_depth;
412     config->max_verify_cert_chain_depth_set = 1;
413     return 0;
414 }
415 
416 
s2n_config_set_status_request_type(struct s2n_config * config,s2n_status_request_type type)417 int s2n_config_set_status_request_type(struct s2n_config *config, s2n_status_request_type type)
418 {
419     S2N_ERROR_IF(type == S2N_STATUS_REQUEST_OCSP && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
420 
421     POSIX_ENSURE_REF(config);
422     config->status_request_type = type;
423 
424     return 0;
425 }
426 
s2n_config_wipe_trust_store(struct s2n_config * config)427 int s2n_config_wipe_trust_store(struct s2n_config *config)
428 {
429     POSIX_ENSURE_REF(config);
430 
431     s2n_x509_trust_store_wipe(&config->trust_store);
432 
433     return S2N_SUCCESS;
434 }
435 
s2n_config_add_pem_to_trust_store(struct s2n_config * config,const char * pem)436 int s2n_config_add_pem_to_trust_store(struct s2n_config *config, const char *pem)
437 {
438     POSIX_ENSURE_REF(config);
439     POSIX_ENSURE_REF(pem);
440 
441     POSIX_GUARD(s2n_x509_trust_store_add_pem(&config->trust_store, pem));
442 
443     return 0;
444 }
445 
s2n_config_set_verification_ca_location(struct s2n_config * config,const char * ca_pem_filename,const char * ca_dir)446 int s2n_config_set_verification_ca_location(struct s2n_config *config, const char *ca_pem_filename, const char *ca_dir)
447 {
448     POSIX_ENSURE_REF(config);
449     int err_code = s2n_x509_trust_store_from_ca_file(&config->trust_store, ca_pem_filename, ca_dir);
450 
451     if (!err_code) {
452         config->status_request_type = s2n_x509_ocsp_stapling_supported() ? S2N_STATUS_REQUEST_OCSP : S2N_STATUS_REQUEST_NONE;
453     }
454 
455     return err_code;
456 }
457 
458 /* Deprecated. Superseded by s2n_config_add_cert_chain_and_key_to_store */
s2n_config_add_cert_chain_and_key(struct s2n_config * config,const char * cert_chain_pem,const char * private_key_pem)459 int s2n_config_add_cert_chain_and_key(struct s2n_config *config, const char *cert_chain_pem, const char *private_key_pem)
460 {
461     struct s2n_cert_chain_and_key *chain_and_key;
462     POSIX_ENSURE_REF(chain_and_key = s2n_cert_chain_and_key_new());
463     POSIX_GUARD(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain_pem, private_key_pem));
464     POSIX_GUARD(s2n_config_add_cert_chain_and_key_to_store(config, chain_and_key));
465     config->cert_allocated = 1;
466 
467     return 0;
468 }
469 
s2n_config_add_cert_chain_and_key_to_store(struct s2n_config * config,struct s2n_cert_chain_and_key * cert_key_pair)470 int s2n_config_add_cert_chain_and_key_to_store(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
471 {
472     POSIX_ENSURE_REF(config->domain_name_to_cert_map);
473     POSIX_ENSURE_REF(cert_key_pair);
474     s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
475     config->is_rsa_cert_configured |= (cert_type == S2N_PKEY_TYPE_RSA);
476     POSIX_GUARD(s2n_config_build_domain_name_to_cert_map(config, cert_key_pair));
477 
478     if (!config->default_certs_are_explicit) {
479         /* Attempt to auto set default based on ordering. ie: first RSA cert is the default, first ECDSA cert is the
480          * default, etc. */
481         if (config->default_certs_by_type.certs[cert_type] == NULL) {
482             config->default_certs_by_type.certs[cert_type] = cert_key_pair;
483         }
484     }
485 
486     if (s2n_pkey_check_key_exists(cert_key_pair->private_key) != S2N_SUCCESS) {
487         config->no_signing_key = true;
488     }
489 
490     return S2N_SUCCESS;
491 }
492 
s2n_config_set_async_pkey_callback(struct s2n_config * config,s2n_async_pkey_fn fn)493 int s2n_config_set_async_pkey_callback(struct s2n_config *config, s2n_async_pkey_fn fn)
494 {
495     POSIX_ENSURE_REF(config);
496 
497     config->async_pkey_cb = fn;
498 
499     return S2N_SUCCESS;
500 }
501 
s2n_config_clear_default_certificates(struct s2n_config * config)502 int s2n_config_clear_default_certificates(struct s2n_config *config)
503 {
504     POSIX_ENSURE_REF(config);
505     for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
506         config->default_certs_by_type.certs[i] = NULL;
507     }
508     return 0;
509 }
510 
s2n_config_set_cert_chain_and_key_defaults(struct s2n_config * config,struct s2n_cert_chain_and_key ** cert_key_pairs,uint32_t num_cert_key_pairs)511 int s2n_config_set_cert_chain_and_key_defaults(struct s2n_config *config,
512                                                struct s2n_cert_chain_and_key **cert_key_pairs,
513                                                uint32_t num_cert_key_pairs)
514 {
515     POSIX_ENSURE_REF(config);
516     POSIX_ENSURE_REF(cert_key_pairs);
517     S2N_ERROR_IF(num_cert_key_pairs < 1 || num_cert_key_pairs > S2N_CERT_TYPE_COUNT,
518             S2N_ERR_NUM_DEFAULT_CERTIFICATES);
519 
520     /* Validate certs being set before clearing auto-chosen defaults or previously set defaults */
521     struct certs_by_type new_defaults = {{ 0 }};
522     for (uint32_t i = 0; i < num_cert_key_pairs; i++) {
523         POSIX_ENSURE_REF(cert_key_pairs[i]);
524         s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
525         S2N_ERROR_IF(new_defaults.certs[cert_type] != NULL, S2N_ERR_MULTIPLE_DEFAULT_CERTIFICATES_PER_AUTH_TYPE);
526         new_defaults.certs[cert_type] = cert_key_pairs[i];
527     }
528 
529     POSIX_GUARD(s2n_config_clear_default_certificates(config));
530     for (uint32_t i = 0; i < num_cert_key_pairs; i++) {
531         s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
532         config->is_rsa_cert_configured |= (cert_type == S2N_PKEY_TYPE_RSA);
533         config->default_certs_by_type.certs[cert_type] = cert_key_pairs[i];
534     }
535 
536     config->default_certs_are_explicit = 1;
537     return 0;
538 }
539 
s2n_config_add_dhparams(struct s2n_config * config,const char * dhparams_pem)540 int s2n_config_add_dhparams(struct s2n_config *config, const char *dhparams_pem)
541 {
542     DEFER_CLEANUP(struct s2n_stuffer dhparams_in_stuffer = {0}, s2n_stuffer_free);
543     DEFER_CLEANUP(struct s2n_stuffer dhparams_out_stuffer = {0}, s2n_stuffer_free);
544     struct s2n_blob dhparams_blob = {0};
545     struct s2n_blob mem = {0};
546 
547     /* Allocate the memory for the chain and key struct */
548     POSIX_GUARD(s2n_alloc(&mem, sizeof(struct s2n_dh_params)));
549     config->dhparams = (struct s2n_dh_params *)(void *)mem.data;
550 
551     if (s2n_stuffer_alloc_ro_from_string(&dhparams_in_stuffer, dhparams_pem) != S2N_SUCCESS) {
552         s2n_free(&mem);
553         S2N_ERROR_PRESERVE_ERRNO();
554     }
555     if (s2n_stuffer_growable_alloc(&dhparams_out_stuffer, strlen(dhparams_pem)) != S2N_SUCCESS) {
556         s2n_free(&mem);
557         S2N_ERROR_PRESERVE_ERRNO();
558     }
559 
560     /* Convert pem to asn1 and asn1 to the private key */
561     POSIX_GUARD(s2n_stuffer_dhparams_from_pem(&dhparams_in_stuffer, &dhparams_out_stuffer));
562 
563     dhparams_blob.size = s2n_stuffer_data_available(&dhparams_out_stuffer);
564     dhparams_blob.data = s2n_stuffer_raw_read(&dhparams_out_stuffer, dhparams_blob.size);
565     POSIX_ENSURE_REF(dhparams_blob.data);
566 
567     POSIX_GUARD(s2n_pkcs3_to_dh_params(config->dhparams, &dhparams_blob));
568 
569     return 0;
570 }
571 
s2n_config_set_wall_clock(struct s2n_config * config,s2n_clock_time_nanoseconds clock_fn,void * ctx)572 extern int s2n_config_set_wall_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
573 {
574     POSIX_ENSURE_REF(clock_fn);
575 
576     config->wall_clock = clock_fn;
577     config->sys_clock_ctx = ctx;
578 
579     return 0;
580 }
581 
s2n_config_set_monotonic_clock(struct s2n_config * config,s2n_clock_time_nanoseconds clock_fn,void * ctx)582 extern int s2n_config_set_monotonic_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
583 {
584     POSIX_ENSURE_REF(clock_fn);
585 
586     config->monotonic_clock = clock_fn;
587     config->monotonic_clock_ctx = ctx;
588 
589     return 0;
590 }
591 
s2n_config_set_cache_store_callback(struct s2n_config * config,s2n_cache_store_callback cache_store_callback,void * data)592 int s2n_config_set_cache_store_callback(struct s2n_config *config, s2n_cache_store_callback cache_store_callback, void *data)
593 {
594     POSIX_ENSURE_REF(cache_store_callback);
595 
596     config->cache_store = cache_store_callback;
597     config->cache_store_data = data;
598 
599     return 0;
600 }
601 
s2n_config_set_cache_retrieve_callback(struct s2n_config * config,s2n_cache_retrieve_callback cache_retrieve_callback,void * data)602 int s2n_config_set_cache_retrieve_callback(struct s2n_config *config, s2n_cache_retrieve_callback cache_retrieve_callback, void *data)
603 {
604     POSIX_ENSURE_REF(cache_retrieve_callback);
605 
606     config->cache_retrieve = cache_retrieve_callback;
607     config->cache_retrieve_data = data;
608 
609     return 0;
610 }
611 
s2n_config_set_cache_delete_callback(struct s2n_config * config,s2n_cache_delete_callback cache_delete_callback,void * data)612 int s2n_config_set_cache_delete_callback(struct s2n_config *config, s2n_cache_delete_callback cache_delete_callback, void *data)
613 {
614     POSIX_ENSURE_REF(cache_delete_callback);
615 
616     config->cache_delete = cache_delete_callback;
617     config->cache_delete_data = data;
618 
619     return 0;
620 }
621 
s2n_config_set_extension_data(struct s2n_config * config,s2n_tls_extension_type type,const uint8_t * data,uint32_t length)622 int s2n_config_set_extension_data(struct s2n_config *config, s2n_tls_extension_type type, const uint8_t *data, uint32_t length)
623 {
624     POSIX_ENSURE_REF(config);
625 
626     if (s2n_config_get_num_default_certs(config) == 0) {
627         POSIX_BAIL(S2N_ERR_UPDATING_EXTENSION);
628     }
629     struct s2n_cert_chain_and_key *config_chain_and_key = s2n_config_get_single_default_cert(config);
630     POSIX_ENSURE_REF(config_chain_and_key);
631 
632     switch (type) {
633         case S2N_EXTENSION_CERTIFICATE_TRANSPARENCY:
634             {
635                 POSIX_GUARD(s2n_cert_chain_and_key_set_sct_list(config_chain_and_key, data, length));
636             } break;
637         case S2N_EXTENSION_OCSP_STAPLING:
638             {
639                 POSIX_GUARD(s2n_cert_chain_and_key_set_ocsp_data(config_chain_and_key, data, length));
640             } break;
641         default:
642             POSIX_BAIL(S2N_ERR_UNRECOGNIZED_EXTENSION);
643     }
644 
645     return 0;
646 }
647 
s2n_config_set_client_hello_cb(struct s2n_config * config,s2n_client_hello_fn client_hello_cb,void * ctx)648 int s2n_config_set_client_hello_cb(struct s2n_config *config, s2n_client_hello_fn client_hello_cb, void *ctx)
649 {
650     POSIX_ENSURE_REF(config);
651 
652     config->client_hello_cb = client_hello_cb;
653     config->client_hello_cb_ctx = ctx;
654     return 0;
655 }
656 
s2n_config_set_client_hello_cb_mode(struct s2n_config * config,s2n_client_hello_cb_mode cb_mode)657 int s2n_config_set_client_hello_cb_mode(struct s2n_config *config, s2n_client_hello_cb_mode cb_mode)
658 {
659     POSIX_ENSURE_REF(config);
660     POSIX_ENSURE(cb_mode == S2N_CLIENT_HELLO_CB_BLOCKING ||
661             cb_mode == S2N_CLIENT_HELLO_CB_NONBLOCKING, S2N_ERR_INVALID_STATE);
662 
663     config->client_hello_cb_mode = cb_mode;
664     return S2N_SUCCESS;
665 }
666 
s2n_config_send_max_fragment_length(struct s2n_config * config,s2n_max_frag_len mfl_code)667 int s2n_config_send_max_fragment_length(struct s2n_config *config, s2n_max_frag_len mfl_code)
668 {
669     POSIX_ENSURE_REF(config);
670 
671     S2N_ERROR_IF(mfl_code > S2N_TLS_MAX_FRAG_LEN_4096, S2N_ERR_INVALID_MAX_FRAG_LEN);
672 
673     config->mfl_code = mfl_code;
674 
675     return 0;
676 }
677 
s2n_config_accept_max_fragment_length(struct s2n_config * config)678 int s2n_config_accept_max_fragment_length(struct s2n_config *config)
679 {
680     POSIX_ENSURE_REF(config);
681 
682     config->accept_mfl = 1;
683 
684     return 0;
685 }
686 
s2n_config_set_session_state_lifetime(struct s2n_config * config,uint64_t lifetime_in_secs)687 int s2n_config_set_session_state_lifetime(struct s2n_config *config,
688                                           uint64_t lifetime_in_secs)
689 {
690     POSIX_ENSURE_REF(config);
691 
692     config->session_state_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
693     return 0;
694 }
695 
s2n_config_set_session_tickets_onoff(struct s2n_config * config,uint8_t enabled)696 int s2n_config_set_session_tickets_onoff(struct s2n_config *config, uint8_t enabled)
697 {
698     POSIX_ENSURE_REF(config);
699 
700     if (config->use_tickets == enabled) {
701         return 0;
702     }
703 
704     config->use_tickets = enabled;
705 
706     if (config->initial_tickets_to_send == 0) {
707         /* Normally initial_tickets_to_send is set via s2n_config_set_initial_ticket_count.
708          * However, s2n_config_set_initial_ticket_count calls this method.
709          * So we set initial_tickets_to_send directly to avoid infinite recursion. */
710         config->initial_tickets_to_send = 1;
711     }
712 
713     /* session ticket || session id is enabled */
714     if (enabled) {
715         POSIX_GUARD(s2n_config_init_session_ticket_keys(config));
716     } else if (!config->use_session_cache) {
717         POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
718     }
719 
720     return 0;
721 }
722 
s2n_config_set_session_cache_onoff(struct s2n_config * config,uint8_t enabled)723 int s2n_config_set_session_cache_onoff(struct s2n_config *config, uint8_t enabled)
724 {
725     POSIX_ENSURE_REF(config);
726     if (enabled && config->cache_store && config->cache_retrieve && config->cache_delete) {
727         POSIX_GUARD(s2n_config_init_session_ticket_keys(config));
728         config->use_session_cache = 1;
729     }
730     else {
731         if (!config->use_tickets) {
732             POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
733         }
734         config->use_session_cache = 0;
735     }
736     return 0;
737 }
738 
s2n_config_set_ticket_encrypt_decrypt_key_lifetime(struct s2n_config * config,uint64_t lifetime_in_secs)739 int s2n_config_set_ticket_encrypt_decrypt_key_lifetime(struct s2n_config *config,
740                                                        uint64_t lifetime_in_secs)
741 {
742     POSIX_ENSURE_REF(config);
743 
744     config->encrypt_decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
745     return 0;
746 }
747 
s2n_config_set_ticket_decrypt_key_lifetime(struct s2n_config * config,uint64_t lifetime_in_secs)748 int s2n_config_set_ticket_decrypt_key_lifetime(struct s2n_config *config,
749                                                uint64_t lifetime_in_secs)
750 {
751     POSIX_ENSURE_REF(config);
752 
753     config->decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
754     return 0;
755 }
756 
s2n_config_add_ticket_crypto_key(struct s2n_config * config,const uint8_t * name,uint32_t name_len,uint8_t * key,uint32_t key_len,uint64_t intro_time_in_seconds_from_epoch)757 int s2n_config_add_ticket_crypto_key(struct s2n_config *config,
758                                      const uint8_t *name, uint32_t name_len,
759                                      uint8_t *key, uint32_t key_len,
760                                      uint64_t intro_time_in_seconds_from_epoch)
761 {
762     POSIX_ENSURE_REF(config);
763     POSIX_ENSURE_REF(name);
764     POSIX_ENSURE_REF(key);
765 
766     /* both session ticket and session cache encryption/decryption can use the same key mechanism */
767     if (!config->use_tickets && !config->use_session_cache) {
768         return 0;
769     }
770 
771     POSIX_GUARD(s2n_config_wipe_expired_ticket_crypto_keys(config, -1));
772 
773     S2N_ERROR_IF(key_len == 0, S2N_ERR_INVALID_TICKET_KEY_LENGTH);
774 
775     uint32_t ticket_keys_len = 0;
776     POSIX_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
777     S2N_ERROR_IF(ticket_keys_len >= S2N_MAX_TICKET_KEYS, S2N_ERR_TICKET_KEY_LIMIT);
778 
779     S2N_ERROR_IF(name_len == 0 || name_len > S2N_TICKET_KEY_NAME_LEN || s2n_find_ticket_key(config, name), S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
780 
781     uint8_t output_pad[S2N_AES256_KEY_LEN + S2N_TICKET_AAD_IMPLICIT_LEN];
782     struct s2n_blob out_key = { .data = output_pad, .size = sizeof(output_pad) };
783     struct s2n_blob in_key = { .data = key, .size = key_len };
784     struct s2n_blob salt = { .size = 0 };
785     struct s2n_blob info = { .size = 0 };
786 
787     struct s2n_ticket_key *session_ticket_key;
788     DEFER_CLEANUP(struct s2n_blob allocator = {0}, s2n_free);
789     POSIX_GUARD(s2n_alloc(&allocator, sizeof(struct s2n_ticket_key)));
790     session_ticket_key = (struct s2n_ticket_key *) (void *) allocator.data;
791 
792     DEFER_CLEANUP(struct s2n_hmac_state hmac = {0}, s2n_hmac_free);
793 
794     POSIX_GUARD(s2n_hmac_new(&hmac));
795     POSIX_GUARD(s2n_hkdf(&hmac, S2N_HMAC_SHA256, &salt, &in_key, &info, &out_key));
796 
797     DEFER_CLEANUP(struct s2n_hash_state hash = {0}, s2n_hash_free);
798     uint8_t hash_output[SHA_DIGEST_LENGTH];
799 
800     POSIX_GUARD(s2n_hash_new(&hash));
801     POSIX_GUARD(s2n_hash_init(&hash, S2N_HASH_SHA1));
802     POSIX_GUARD(s2n_hash_update(&hash, out_key.data, out_key.size));
803     POSIX_GUARD(s2n_hash_digest(&hash, hash_output, SHA_DIGEST_LENGTH));
804 
805     POSIX_GUARD_RESULT(s2n_set_len(config->ticket_keys, &ticket_keys_len));
806     if (ticket_keys_len >= S2N_MAX_TICKET_KEY_HASHES) {
807         POSIX_GUARD_RESULT(s2n_set_free_p(&config->ticket_key_hashes));
808         POSIX_ENSURE_REF(config->ticket_key_hashes = s2n_set_new(SHA_DIGEST_LENGTH, s2n_verify_unique_ticket_key_comparator));
809     }
810 
811     /* Insert hash key into a sorted array at known index */
812     POSIX_GUARD_RESULT(s2n_set_add(config->ticket_key_hashes, hash_output));
813 
814     POSIX_CHECKED_MEMCPY(session_ticket_key->key_name, name, S2N_TICKET_KEY_NAME_LEN);
815     POSIX_CHECKED_MEMCPY(session_ticket_key->aes_key, out_key.data, S2N_AES256_KEY_LEN);
816     out_key.data = output_pad + S2N_AES256_KEY_LEN;
817     POSIX_CHECKED_MEMCPY(session_ticket_key->implicit_aad, out_key.data, S2N_TICKET_AAD_IMPLICIT_LEN);
818 
819     if (intro_time_in_seconds_from_epoch == 0) {
820         uint64_t now;
821         POSIX_GUARD(config->wall_clock(config->sys_clock_ctx, &now));
822         session_ticket_key->intro_timestamp = now;
823     } else {
824         session_ticket_key->intro_timestamp = (intro_time_in_seconds_from_epoch * ONE_SEC_IN_NANOS);
825     }
826 
827     POSIX_GUARD(s2n_config_store_ticket_key(config, session_ticket_key));
828 
829     return 0;
830 }
831 
s2n_config_set_cert_tiebreak_callback(struct s2n_config * config,s2n_cert_tiebreak_callback cert_tiebreak_cb)832 int s2n_config_set_cert_tiebreak_callback(struct s2n_config *config, s2n_cert_tiebreak_callback cert_tiebreak_cb)
833 {
834     config->cert_tiebreak_cb = cert_tiebreak_cb;
835     return 0;
836 }
837 
s2n_config_get_single_default_cert(struct s2n_config * config)838 struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config)
839 {
840     PTR_ENSURE_REF(config);
841     struct s2n_cert_chain_and_key *cert = NULL;
842 
843     for (int i = S2N_CERT_TYPE_COUNT - 1; i >= 0; i--) {
844         if (config->default_certs_by_type.certs[i] != NULL) {
845             cert = config->default_certs_by_type.certs[i];
846         }
847     }
848     return cert;
849 }
850 
s2n_config_get_num_default_certs(struct s2n_config * config)851 int s2n_config_get_num_default_certs(struct s2n_config *config)
852 {
853     POSIX_ENSURE_REF(config);
854     int num_certs = 0;
855     for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
856         if (config->default_certs_by_type.certs[i] != NULL) {
857             num_certs++;
858         }
859     }
860 
861     return num_certs;
862 }
863 
s2n_config_enable_cert_req_dss_legacy_compat(struct s2n_config * config)864 int s2n_config_enable_cert_req_dss_legacy_compat(struct s2n_config *config)
865 {
866     POSIX_ENSURE_REF(config);
867     config->cert_req_dss_legacy_compat_enabled = 1;
868     return S2N_SUCCESS;
869 }
870 
s2n_config_set_psk_selection_callback(struct s2n_config * config,s2n_psk_selection_callback cb,void * context)871 int s2n_config_set_psk_selection_callback(struct s2n_config *config, s2n_psk_selection_callback cb, void *context)
872 {
873     POSIX_ENSURE_REF(config);
874     config->psk_selection_cb = cb;
875     config->psk_selection_ctx = context;
876     return S2N_SUCCESS;
877 }
878 
s2n_config_set_key_log_cb(struct s2n_config * config,s2n_key_log_fn callback,void * ctx)879 int s2n_config_set_key_log_cb(struct s2n_config *config, s2n_key_log_fn callback, void *ctx) {
880     POSIX_ENSURE_MUT(config);
881 
882     config->key_log_cb = callback;
883     config->key_log_ctx = ctx;
884 
885     return S2N_SUCCESS;
886 }
887 
s2n_config_set_async_pkey_validation_mode(struct s2n_config * config,s2n_async_pkey_validation_mode mode)888 int s2n_config_set_async_pkey_validation_mode(struct s2n_config *config, s2n_async_pkey_validation_mode mode) {
889     POSIX_ENSURE_REF(config);
890 
891     switch(mode) {
892         case S2N_ASYNC_PKEY_VALIDATION_FAST:
893         case S2N_ASYNC_PKEY_VALIDATION_STRICT:
894             config->async_pkey_validation_mode = mode;
895             return S2N_SUCCESS;
896     }
897 
898     POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
899 }
900