LCOV - code coverage report
Current view: top level - tls - s2n_config.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 745 821 90.7 %
Date: 2025-08-15 07:28:39 Functions: 80 83 96.4 %
Branches: 395 844 46.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License").
       5                 :            :  * You may not use this file except in compliance with the License.
       6                 :            :  * A copy of the License is located at
       7                 :            :  *
       8                 :            :  *  http://aws.amazon.com/apache2.0
       9                 :            :  *
      10                 :            :  * or in the "license" file accompanying this file. This file is distributed
      11                 :            :  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
      12                 :            :  * express or implied. See the License for the specific language governing
      13                 :            :  * permissions and limitations under the License.
      14                 :            :  */
      15                 :            : 
      16                 :            : #ifndef _S2N_PRELUDE_INCLUDED
      17                 :            :     /* make sure s2n_prelude.h is includes as part of the compiler flags, if not then fail the build */
      18                 :            :     #error "Expected s2n_prelude.h to be included as part of the compiler flags"
      19                 :            : #endif
      20                 :            : 
      21                 :            : #include <strings.h>
      22                 :            : #include <time.h>
      23                 :            : 
      24                 :            : #include "api/unstable/custom_x509_extensions.h"
      25                 :            : #include "api/unstable/npn.h"
      26                 :            : #include "crypto/s2n_certificate.h"
      27                 :            : #include "crypto/s2n_fips.h"
      28                 :            : #include "crypto/s2n_hkdf.h"
      29                 :            : #include "crypto/s2n_libcrypto.h"
      30                 :            : #include "crypto/s2n_pq.h"
      31                 :            : #include "error/s2n_errno.h"
      32                 :            : #include "tls/s2n_cipher_preferences.h"
      33                 :            : #include "tls/s2n_internal.h"
      34                 :            : #include "tls/s2n_ktls.h"
      35                 :            : #include "tls/s2n_security_policies.h"
      36                 :            : #include "tls/s2n_tls13.h"
      37                 :            : #include "utils/s2n_blob.h"
      38                 :            : #include "utils/s2n_map.h"
      39                 :            : #include "utils/s2n_safety.h"
      40                 :            : 
      41                 :            : #if defined(CLOCK_MONOTONIC_RAW)
      42                 :            :     #define S2N_CLOCK_HW CLOCK_MONOTONIC_RAW
      43                 :            : #else
      44                 :            :     #define S2N_CLOCK_HW CLOCK_MONOTONIC
      45                 :            : #endif
      46                 :            : 
      47                 :            : #define S2N_CLOCK_SYS CLOCK_REALTIME
      48                 :            : 
      49                 :            : static int monotonic_clock(void *data, uint64_t *nanoseconds)
      50                 :     131872 : {
      51                 :     131872 :     struct timespec current_time = { 0 };
      52                 :            : 
      53         [ -  + ]:     131872 :     POSIX_GUARD(clock_gettime(S2N_CLOCK_HW, &current_time));
      54                 :            : 
      55                 :     131872 :     *nanoseconds = (uint64_t) current_time.tv_sec * 1000000000ull;
      56                 :     131872 :     *nanoseconds += current_time.tv_nsec;
      57                 :            : 
      58                 :     131872 :     return 0;
      59                 :     131872 : }
      60                 :            : 
      61                 :            : static int wall_clock(void *data, uint64_t *nanoseconds)
      62                 :       4072 : {
      63                 :       4072 :     struct timespec current_time = { 0 };
      64                 :            : 
      65         [ -  + ]:       4072 :     POSIX_GUARD(clock_gettime(S2N_CLOCK_SYS, &current_time));
      66                 :            : 
      67                 :       4072 :     *nanoseconds = (uint64_t) current_time.tv_sec * 1000000000ull;
      68                 :       4072 :     *nanoseconds += current_time.tv_nsec;
      69                 :            : 
      70                 :       4072 :     return 0;
      71                 :       4072 : }
      72                 :            : 
      73                 :            : static struct s2n_config s2n_default_config = { 0 };
      74                 :            : static struct s2n_config s2n_default_fips_config = { 0 };
      75                 :            : static struct s2n_config s2n_default_tls13_config = { 0 };
      76                 :            : 
      77                 :            : static int s2n_config_setup_default(struct s2n_config *config)
      78                 :       3202 : {
      79         [ -  + ]:       3202 :     POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default"));
      80                 :       3202 :     return S2N_SUCCESS;
      81                 :       3202 : }
      82                 :            : 
      83                 :            : static int s2n_config_setup_tls13(struct s2n_config *config)
      84                 :        767 : {
      85         [ -  + ]:        767 :     POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default_tls13"));
      86                 :        767 :     return S2N_SUCCESS;
      87                 :        767 : }
      88                 :            : 
      89                 :            : static int s2n_config_setup_fips(struct s2n_config *config)
      90                 :          0 : {
      91         [ #  # ]:          0 :     POSIX_GUARD(s2n_config_set_cipher_preferences(config, "default_fips"));
      92                 :          0 :     return S2N_SUCCESS;
      93                 :          0 : }
      94                 :            : 
      95                 :            : static int s2n_config_init(struct s2n_config *config)
      96                 :       2657 : {
      97                 :       2657 :     config->wall_clock = wall_clock;
      98                 :       2657 :     config->monotonic_clock = monotonic_clock;
      99                 :       2657 :     config->ct_type = S2N_CT_SUPPORT_NONE;
     100                 :       2657 :     config->mfl_code = S2N_TLS_MAX_FRAG_LEN_EXT_NONE;
     101                 :       2657 :     config->alert_behavior = S2N_ALERT_FAIL_ON_WARNINGS;
     102                 :       2657 :     config->session_state_lifetime_in_nanos = S2N_STATE_LIFETIME_IN_NANOS;
     103                 :       2657 :     config->encrypt_decrypt_key_lifetime_in_nanos = S2N_TICKET_ENCRYPT_DECRYPT_KEY_LIFETIME_IN_NANOS;
     104                 :       2657 :     config->decrypt_key_lifetime_in_nanos = S2N_TICKET_DECRYPT_KEY_LIFETIME_IN_NANOS;
     105                 :       2657 :     config->async_pkey_validation_mode = S2N_ASYNC_PKEY_VALIDATION_FAST;
     106                 :       2657 :     config->check_ocsp = 1;
     107                 :            : 
     108                 :       2657 :     config->client_hello_cb_mode = S2N_CLIENT_HELLO_CB_BLOCKING;
     109                 :            : 
     110         [ -  + ]:       2657 :     POSIX_GUARD(s2n_config_setup_default(config));
     111         [ +  + ]:       2657 :     if (s2n_use_default_tls13_config()) {
     112         [ -  + ]:        222 :         POSIX_GUARD(s2n_config_setup_tls13(config));
     113         [ -  + ]:       2435 :     } else if (s2n_is_in_fips_mode()) {
     114         [ #  # ]:          0 :         POSIX_GUARD(s2n_config_setup_fips(config));
     115                 :          0 :     }
     116                 :            : 
     117         [ -  + ]:       2657 :     POSIX_GUARD_PTR(config->domain_name_to_cert_map = s2n_map_new_with_initial_capacity(1));
     118         [ -  + ]:       2657 :     POSIX_GUARD_RESULT(s2n_map_complete(config->domain_name_to_cert_map));
     119                 :            : 
     120                 :       2657 :     s2n_x509_trust_store_init_empty(&config->trust_store);
     121                 :            : 
     122                 :       2657 :     return 0;
     123                 :       2657 : }
     124                 :            : 
     125                 :            : static int s2n_config_cleanup(struct s2n_config *config)
     126                 :       3295 : {
     127                 :       3295 :     s2n_x509_trust_store_wipe(&config->trust_store);
     128                 :       3295 :     config->check_ocsp = 0;
     129                 :            : 
     130         [ -  + ]:       3295 :     if (config->custom_x509_extension_oids) {
     131                 :          0 :         sk_ASN1_OBJECT_pop_free(config->custom_x509_extension_oids, ASN1_OBJECT_free);
     132                 :          0 :         config->custom_x509_extension_oids = NULL;
     133                 :          0 :     }
     134                 :            : 
     135         [ -  + ]:       3295 :     POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
     136         [ -  + ]:       3295 :     POSIX_GUARD(s2n_config_free_cert_chain_and_key(config));
     137         [ -  + ]:       3295 :     POSIX_GUARD(s2n_config_free_dhparams(config));
     138         [ +  + ]:       3295 :     POSIX_GUARD(s2n_free(&config->application_protocols));
     139         [ -  + ]:       3202 :     POSIX_GUARD(s2n_free(&config->cert_authorities));
     140         [ -  + ]:       3202 :     POSIX_GUARD_RESULT(s2n_map_free(config->domain_name_to_cert_map));
     141                 :            : 
     142 [ -  + ][ #  # ]:       3202 :     POSIX_CHECKED_MEMSET(config, 0, sizeof(struct s2n_config));
                 [ +  - ]
     143                 :            : 
     144                 :       3202 :     return 0;
     145                 :       3202 : }
     146                 :            : 
     147                 :            : static int s2n_config_update_domain_name_to_cert_map(struct s2n_config *config,
     148                 :            :         struct s2n_blob *name,
     149                 :            :         struct s2n_cert_chain_and_key *cert_key_pair)
     150                 :        950 : {
     151 [ #  # ][ -  + ]:        950 :     POSIX_ENSURE_REF(config);
     152 [ -  + ][ #  # ]:        950 :     POSIX_ENSURE_REF(name);
     153                 :            : 
     154                 :        950 :     struct s2n_map *domain_name_to_cert_map = config->domain_name_to_cert_map;
     155                 :            :     /* s2n_map does not allow zero-size key */
     156         [ -  + ]:        950 :     if (name->size == 0) {
     157                 :          0 :         return 0;
     158                 :          0 :     }
     159                 :        950 :     s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
     160                 :        950 :     struct s2n_blob s2n_map_value = { 0 };
     161                 :        950 :     bool key_found = false;
     162         [ -  + ]:        950 :     POSIX_GUARD_RESULT(s2n_map_lookup(domain_name_to_cert_map, name, &s2n_map_value, &key_found));
     163         [ +  + ]:        950 :     if (!key_found) {
     164                 :        848 :         struct certs_by_type value = { { 0 } };
     165                 :        848 :         value.certs[cert_type] = cert_key_pair;
     166                 :        848 :         s2n_map_value.data = (uint8_t *) &value;
     167                 :        848 :         s2n_map_value.size = sizeof(struct certs_by_type);
     168                 :            : 
     169         [ -  + ]:        848 :         POSIX_GUARD_RESULT(s2n_map_unlock(domain_name_to_cert_map));
     170         [ -  + ]:        848 :         POSIX_GUARD_RESULT(s2n_map_add(domain_name_to_cert_map, name, &s2n_map_value));
     171         [ -  + ]:        848 :         POSIX_GUARD_RESULT(s2n_map_complete(domain_name_to_cert_map));
     172                 :        848 :     } else {
     173                 :        102 :         struct certs_by_type *value = (void *) s2n_map_value.data;
     174         [ -  + ]:        102 :         if (value->certs[cert_type] == NULL) {
     175                 :          0 :             value->certs[cert_type] = cert_key_pair;
     176         [ +  + ]:        102 :         } else if (config->cert_tiebreak_cb) {
     177                 :            :             /* There's an existing certificate for this (domain_name, auth_method).
     178                 :            :              * Run the application's tiebreaking callback to decide which cert should be used.
     179                 :            :              * An application may have some context specific logic to resolve ties that are based
     180                 :            :              * on factors like trust, expiry, etc.
     181                 :            :              */
     182                 :         99 :             struct s2n_cert_chain_and_key *winner = config->cert_tiebreak_cb(
     183                 :         99 :                     value->certs[cert_type],
     184                 :         99 :                     cert_key_pair,
     185                 :         99 :                     name->data,
     186                 :         99 :                     name->size);
     187         [ +  - ]:         99 :             if (winner) {
     188                 :         99 :                 value->certs[cert_type] = winner;
     189                 :         99 :             }
     190                 :         99 :         }
     191                 :        102 :     }
     192                 :            : 
     193                 :        950 :     return 0;
     194                 :        950 : }
     195                 :            : 
     196                 :            : int s2n_config_build_domain_name_to_cert_map(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
     197                 :        949 : {
     198                 :        949 :     uint32_t cn_len = 0;
     199         [ -  + ]:        949 :     POSIX_GUARD_RESULT(s2n_array_num_elements(cert_key_pair->cn_names, &cn_len));
     200                 :        949 :     uint32_t san_len = 0;
     201         [ -  + ]:        949 :     POSIX_GUARD_RESULT(s2n_array_num_elements(cert_key_pair->san_names, &san_len));
     202                 :            : 
     203         [ +  + ]:        949 :     if (san_len == 0) {
     204         [ +  + ]:        158 :         for (uint32_t i = 0; i < cn_len; i++) {
     205                 :         79 :             struct s2n_blob *cn_name = NULL;
     206         [ -  + ]:         79 :             POSIX_GUARD_RESULT(s2n_array_get(cert_key_pair->cn_names, i, (void **) &cn_name));
     207         [ -  + ]:         79 :             POSIX_GUARD(s2n_config_update_domain_name_to_cert_map(config, cn_name, cert_key_pair));
     208                 :         79 :         }
     209                 :        870 :     } else {
     210         [ +  + ]:       1741 :         for (uint32_t i = 0; i < san_len; i++) {
     211                 :        871 :             struct s2n_blob *san_name = NULL;
     212         [ -  + ]:        871 :             POSIX_GUARD_RESULT(s2n_array_get(cert_key_pair->san_names, i, (void **) &san_name));
     213         [ -  + ]:        871 :             POSIX_GUARD(s2n_config_update_domain_name_to_cert_map(config, san_name, cert_key_pair));
     214                 :        871 :         }
     215                 :        870 :     }
     216                 :            : 
     217                 :        949 :     return 0;
     218                 :        949 : }
     219                 :            : 
     220                 :            : struct s2n_config *s2n_fetch_default_config(void)
     221                 :     125242 : {
     222         [ +  + ]:     125242 :     if (s2n_use_default_tls13_config()) {
     223                 :        637 :         return &s2n_default_tls13_config;
     224                 :        637 :     }
     225         [ -  + ]:     124605 :     if (s2n_is_in_fips_mode()) {
     226                 :          0 :         return &s2n_default_fips_config;
     227                 :          0 :     }
     228                 :     124605 :     return &s2n_default_config;
     229                 :     124605 : }
     230                 :            : 
     231                 :            : int s2n_config_set_unsafe_for_testing(struct s2n_config *config)
     232                 :        335 : {
     233 [ -  + ][ #  # ]:        335 :     POSIX_ENSURE(s2n_in_test(), S2N_ERR_NOT_IN_TEST);
     234                 :        335 :     config->check_ocsp = 0;
     235                 :        335 :     config->disable_x509_validation = 1;
     236                 :            : 
     237                 :        335 :     return S2N_SUCCESS;
     238                 :        335 : }
     239                 :            : 
     240                 :            : int s2n_config_defaults_init(void)
     241                 :        545 : {
     242                 :            :     /* Set up fips defaults */
     243         [ -  + ]:        545 :     if (s2n_is_in_fips_mode()) {
     244         [ #  # ]:          0 :         POSIX_GUARD(s2n_config_init(&s2n_default_fips_config));
     245         [ #  # ]:          0 :         POSIX_GUARD(s2n_config_setup_fips(&s2n_default_fips_config));
     246         [ #  # ]:          0 :         POSIX_GUARD(s2n_config_load_system_certs(&s2n_default_fips_config));
     247                 :        545 :     } else {
     248                 :            :         /* Set up default */
     249         [ -  + ]:        545 :         POSIX_GUARD(s2n_config_init(&s2n_default_config));
     250         [ -  + ]:        545 :         POSIX_GUARD(s2n_config_setup_default(&s2n_default_config));
     251         [ -  + ]:        545 :         POSIX_GUARD(s2n_config_load_system_certs(&s2n_default_config));
     252                 :        545 :     }
     253                 :            : 
     254                 :            :     /* TLS 1.3 default config is only used in tests so avoid initialization costs in applications */
     255         [ -  + ]:        545 :     POSIX_GUARD(s2n_config_init(&s2n_default_tls13_config));
     256         [ -  + ]:        545 :     POSIX_GUARD(s2n_config_setup_tls13(&s2n_default_tls13_config));
     257                 :            : 
     258                 :        545 :     return S2N_SUCCESS;
     259                 :        545 : }
     260                 :            : 
     261                 :            : void s2n_wipe_static_configs(void)
     262                 :        576 : {
     263                 :        576 :     s2n_config_cleanup(&s2n_default_fips_config);
     264                 :        576 :     s2n_config_cleanup(&s2n_default_config);
     265                 :        576 :     s2n_config_cleanup(&s2n_default_tls13_config);
     266                 :        576 : }
     267                 :            : 
     268                 :            : int s2n_config_load_system_certs(struct s2n_config *config)
     269                 :       2185 : {
     270 [ +  + ][ +  - ]:       2185 :     POSIX_ENSURE_REF(config);
     271                 :            : 
     272                 :       2184 :     struct s2n_x509_trust_store *store = &config->trust_store;
     273 [ +  + ][ +  - ]:       2184 :     POSIX_ENSURE(!store->loaded_system_certs, S2N_ERR_X509_TRUST_STORE);
     274                 :            : 
     275         [ +  + ]:       2104 :     if (!store->trust_store) {
     276                 :       2103 :         store->trust_store = X509_STORE_new();
     277 [ -  + ][ #  # ]:       2103 :         POSIX_ENSURE_REF(store->trust_store);
     278                 :       2103 :     }
     279                 :            : 
     280                 :       2104 :     int err_code = X509_STORE_set_default_paths(store->trust_store);
     281         [ -  + ]:       2104 :     if (!err_code) {
     282                 :          0 :         s2n_x509_trust_store_wipe(store);
     283         [ #  # ]:          0 :         POSIX_BAIL(S2N_ERR_X509_TRUST_STORE);
     284                 :          0 :     }
     285                 :       2104 :     store->loaded_system_certs = true;
     286                 :            : 
     287                 :       2104 :     return S2N_SUCCESS;
     288                 :       2104 : }
     289                 :            : 
     290                 :            : struct s2n_config *s2n_config_new_minimal(void)
     291                 :       1567 : {
     292                 :       1567 :     struct s2n_blob allocator = { 0 };
     293                 :       1567 :     struct s2n_config *new_config = NULL;
     294                 :            : 
     295         [ -  + ]:       1567 :     PTR_GUARD_POSIX(s2n_alloc(&allocator, sizeof(struct s2n_config)));
     296         [ -  + ]:       1567 :     PTR_GUARD_POSIX(s2n_blob_zero(&allocator));
     297                 :            : 
     298                 :       1567 :     new_config = (struct s2n_config *) (void *) allocator.data;
     299         [ -  + ]:       1567 :     if (s2n_config_init(new_config) != S2N_SUCCESS) {
     300                 :          0 :         s2n_free(&allocator);
     301                 :          0 :         return NULL;
     302                 :          0 :     }
     303                 :            : 
     304                 :       1567 :     return new_config;
     305                 :       1567 : }
     306                 :            : 
     307                 :            : struct s2n_config *s2n_config_new(void)
     308                 :       1537 : {
     309                 :       1537 :     struct s2n_config *new_config = s2n_config_new_minimal();
     310 [ -  + ][ #  # ]:       1537 :     PTR_ENSURE_REF(new_config);
     311                 :            : 
     312                 :            :     /* For backwards compatibility, s2n_config_new loads system certs by default. */
     313         [ -  + ]:       1537 :     PTR_GUARD_POSIX(s2n_config_load_system_certs(new_config));
     314                 :            : 
     315                 :       1537 :     return new_config;
     316                 :       1537 : }
     317                 :            : 
     318                 :            : int s2n_config_init_session_ticket_keys(struct s2n_config *config)
     319                 :        136 : {
     320         [ +  + ]:        136 :     if (config->ticket_keys == NULL) {
     321 [ -  + ][ #  # ]:        135 :         POSIX_ENSURE_REF(config->ticket_keys = s2n_array_new_with_capacity(sizeof(struct s2n_ticket_key), S2N_MAX_TICKET_KEYS));
     322                 :        135 :     }
     323                 :            : 
     324                 :        136 :     return 0;
     325                 :        136 : }
     326                 :            : 
     327                 :            : int s2n_config_free_session_ticket_keys(struct s2n_config *config)
     328                 :       3299 : {
     329         [ +  + ]:       3299 :     if (config->ticket_keys != NULL) {
     330         [ -  + ]:        135 :         POSIX_GUARD_RESULT(s2n_array_free_p(&config->ticket_keys));
     331                 :        135 :     }
     332                 :            : 
     333                 :       3299 :     return 0;
     334                 :       3299 : }
     335                 :            : 
     336                 :            : int s2n_config_free_cert_chain_and_key(struct s2n_config *config)
     337                 :       3303 : {
     338                 :            :     /* We track certificate ownership on the config itself because a config
     339                 :            :      * CANNOT use a combination of owned and unowned chains.
     340                 :            :      * If it does, and the unowned chains are freed before the config is,
     341                 :            :      * then iterating over the chains to determine which are owned and need to be freed
     342                 :            :      * will mean also reading the invalid, freed memory of any unowned certificates.
     343                 :            :      * As of now, some tests free chains before the config, so that pattern may also
     344                 :            :      * appear in application code.
     345                 :            :      */
     346         [ +  + ]:       3303 :     if (config->cert_ownership != S2N_LIB_OWNED) {
     347                 :       3290 :         return S2N_SUCCESS;
     348                 :       3290 :     }
     349                 :            : 
     350                 :            :     /* Free the cert_chain_and_key since the application has no reference
     351                 :            :      * to it. This is necessary until s2n_config_add_cert_chain_and_key is deprecated. */
     352         [ +  + ]:         65 :     for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
     353                 :         52 :         s2n_cert_chain_and_key_free(config->default_certs_by_type.certs[i]);
     354                 :         52 :         config->default_certs_by_type.certs[i] = NULL;
     355                 :         52 :     }
     356                 :            : 
     357                 :         13 :     config->cert_ownership = S2N_NOT_OWNED;
     358                 :         13 :     return S2N_SUCCESS;
     359                 :       3303 : }
     360                 :            : 
     361                 :            : int s2n_config_free_dhparams(struct s2n_config *config)
     362                 :       3295 : {
     363         [ +  + ]:       3295 :     if (config->dhparams) {
     364         [ -  + ]:         81 :         POSIX_GUARD(s2n_dh_params_free(config->dhparams));
     365                 :         81 :     }
     366                 :            : 
     367         [ -  + ]:       3295 :     POSIX_GUARD(s2n_free_object((uint8_t **) &config->dhparams, sizeof(struct s2n_dh_params)));
     368                 :       3295 :     return 0;
     369                 :       3295 : }
     370                 :            : 
     371                 :            : S2N_CLEANUP_RESULT s2n_config_ptr_free(struct s2n_config **config)
     372                 :        945 : {
     373 [ #  # ][ -  + ]:        945 :     RESULT_ENSURE_REF(config);
     374         [ -  + ]:        945 :     RESULT_GUARD_POSIX(s2n_config_free(*config));
     375                 :        945 :     *config = NULL;
     376                 :        945 :     return S2N_RESULT_OK;
     377                 :        945 : }
     378                 :            : 
     379                 :            : int s2n_config_free(struct s2n_config *config)
     380                 :       1567 : {
     381                 :       1567 :     s2n_config_cleanup(config);
     382                 :            : 
     383         [ -  + ]:       1567 :     POSIX_GUARD(s2n_free_object((uint8_t **) &config, sizeof(struct s2n_config)));
     384                 :       1567 :     return 0;
     385                 :       1567 : }
     386                 :            : 
     387                 :            : int s2n_config_get_client_auth_type(struct s2n_config *config, s2n_cert_auth_type *client_auth_type)
     388                 :          0 : {
     389 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE_REF(config);
     390 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE_REF(client_auth_type);
     391                 :          0 :     *client_auth_type = config->client_cert_auth_type;
     392                 :          0 :     return 0;
     393                 :          0 : }
     394                 :            : 
     395                 :            : int s2n_config_set_client_auth_type(struct s2n_config *config, s2n_cert_auth_type client_auth_type)
     396                 :         68 : {
     397 [ -  + ][ #  # ]:         68 :     POSIX_ENSURE_REF(config);
     398                 :         68 :     config->client_cert_auth_type_overridden = 1;
     399                 :         68 :     config->client_cert_auth_type = client_auth_type;
     400                 :         68 :     return 0;
     401                 :         68 : }
     402                 :            : 
     403                 :            : int s2n_config_set_ct_support_level(struct s2n_config *config, s2n_ct_support_level type)
     404                 :          6 : {
     405 [ #  # ][ -  + ]:          6 :     POSIX_ENSURE_REF(config);
     406                 :          6 :     config->ct_type = type;
     407                 :            : 
     408                 :          6 :     return 0;
     409                 :          6 : }
     410                 :            : 
     411                 :            : int s2n_config_set_alert_behavior(struct s2n_config *config, s2n_alert_behavior alert_behavior)
     412                 :          6 : {
     413 [ -  + ][ #  # ]:          6 :     POSIX_ENSURE_REF(config);
     414                 :            : 
     415                 :          6 :     switch (alert_behavior) {
     416         [ +  + ]:          1 :         case S2N_ALERT_FAIL_ON_WARNINGS:
     417         [ +  + ]:          6 :         case S2N_ALERT_IGNORE_WARNINGS:
     418                 :          6 :             config->alert_behavior = alert_behavior;
     419                 :          6 :             break;
     420         [ -  + ]:          0 :         default:
     421         [ #  # ]:          0 :             POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
     422                 :          6 :     }
     423                 :            : 
     424                 :          6 :     return 0;
     425                 :          6 : }
     426                 :            : 
     427                 :            : int s2n_config_set_verify_host_callback(struct s2n_config *config, s2n_verify_host_fn verify_host_fn, void *data)
     428                 :         29 : {
     429 [ -  + ][ #  # ]:         29 :     POSIX_ENSURE_REF(config);
     430                 :         29 :     config->verify_host_fn = verify_host_fn;
     431                 :         29 :     config->data_for_verify_host = data;
     432                 :         29 :     return 0;
     433                 :         29 : }
     434                 :            : 
     435                 :            : int s2n_config_set_check_stapled_ocsp_response(struct s2n_config *config, uint8_t check_ocsp)
     436                 :         25 : {
     437 [ -  + ][ #  # ]:         25 :     POSIX_ENSURE_REF(config);
     438 [ #  # ][ -  + ]:         25 :     S2N_ERROR_IF(check_ocsp && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
                 [ #  # ]
     439                 :         25 :     config->check_ocsp = check_ocsp;
     440                 :         25 :     return 0;
     441                 :         25 : }
     442                 :            : 
     443                 :            : int s2n_config_disable_x509_time_verification(struct s2n_config *config)
     444                 :         11 : {
     445 [ +  + ][ +  - ]:         11 :     POSIX_ENSURE_REF(config);
     446                 :         10 :     config->disable_x509_time_validation = true;
     447                 :         10 :     return S2N_SUCCESS;
     448                 :         11 : }
     449                 :            : 
     450                 :            : int s2n_config_disable_x509_verification(struct s2n_config *config)
     451                 :        173 : {
     452 [ #  # ][ -  + ]:        173 :     POSIX_ENSURE_REF(config);
     453                 :        173 :     s2n_x509_trust_store_wipe(&config->trust_store);
     454                 :        173 :     config->disable_x509_validation = 1;
     455                 :        173 :     return 0;
     456                 :        173 : }
     457                 :            : 
     458                 :            : int s2n_config_set_max_cert_chain_depth(struct s2n_config *config, uint16_t max_depth)
     459                 :          0 : {
     460 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE_REF(config);
     461 [ #  # ][ #  # ]:          0 :     S2N_ERROR_IF(max_depth == 0, S2N_ERR_INVALID_ARGUMENT);
     462                 :            : 
     463                 :          0 :     config->max_verify_cert_chain_depth = max_depth;
     464                 :          0 :     config->max_verify_cert_chain_depth_set = 1;
     465                 :          0 :     return 0;
     466                 :          0 : }
     467                 :            : 
     468                 :            : int s2n_config_set_status_request_type(struct s2n_config *config, s2n_status_request_type type)
     469                 :         30 : {
     470 [ +  + ][ -  + ]:         30 :     S2N_ERROR_IF(type == S2N_STATUS_REQUEST_OCSP && !s2n_x509_ocsp_stapling_supported(), S2N_ERR_OCSP_NOT_SUPPORTED);
                 [ #  # ]
     471                 :            : 
     472 [ #  # ][ -  + ]:         30 :     POSIX_ENSURE_REF(config);
     473                 :         30 :     config->ocsp_status_requested_by_user = (type == S2N_STATUS_REQUEST_OCSP);
     474                 :            : 
     475                 :            :     /* Reset the ocsp_status_requested_by_s2n flag if OCSP status requests were disabled. */
     476         [ +  + ]:         30 :     if (type == S2N_STATUS_REQUEST_NONE) {
     477                 :          8 :         config->ocsp_status_requested_by_s2n = false;
     478                 :          8 :     }
     479                 :            : 
     480                 :         30 :     return 0;
     481                 :         30 : }
     482                 :            : 
     483                 :            : int s2n_config_wipe_trust_store(struct s2n_config *config)
     484                 :         28 : {
     485 [ #  # ][ -  + ]:         28 :     POSIX_ENSURE_REF(config);
     486                 :            : 
     487                 :         28 :     s2n_x509_trust_store_wipe(&config->trust_store);
     488                 :            : 
     489                 :         28 :     return S2N_SUCCESS;
     490                 :         28 : }
     491                 :            : 
     492                 :            : int s2n_config_add_pem_to_trust_store(struct s2n_config *config, const char *pem)
     493                 :         24 : {
     494 [ -  + ][ #  # ]:         24 :     POSIX_ENSURE_REF(config);
     495 [ #  # ][ -  + ]:         24 :     POSIX_ENSURE_REF(pem);
     496                 :            : 
     497         [ +  + ]:         24 :     POSIX_GUARD(s2n_x509_trust_store_add_pem(&config->trust_store, pem));
     498                 :            : 
     499                 :         23 :     return 0;
     500                 :         24 : }
     501                 :            : 
     502                 :            : int s2n_config_set_verification_ca_location(struct s2n_config *config, const char *ca_pem_filename, const char *ca_dir)
     503                 :        119 : {
     504 [ -  + ][ #  # ]:        119 :     POSIX_ENSURE_REF(config);
     505                 :        119 :     int err_code = s2n_x509_trust_store_from_ca_file(&config->trust_store, ca_pem_filename, ca_dir);
     506                 :            : 
     507         [ +  - ]:        119 :     if (!err_code) {
     508         [ +  - ]:        119 :         config->ocsp_status_requested_by_s2n = s2n_x509_ocsp_stapling_supported() ? S2N_STATUS_REQUEST_OCSP : S2N_STATUS_REQUEST_NONE;
     509                 :        119 :     }
     510                 :            : 
     511                 :        119 :     return err_code;
     512                 :        119 : }
     513                 :            : 
     514                 :            : static int s2n_config_add_cert_chain_and_key_impl(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
     515                 :        949 : {
     516 [ #  # ][ -  + ]:        949 :     POSIX_ENSURE_REF(config->domain_name_to_cert_map);
     517 [ -  + ][ #  # ]:        949 :     POSIX_ENSURE_REF(cert_key_pair);
     518                 :            : 
     519         [ +  + ]:        949 :     POSIX_GUARD_RESULT(s2n_security_policy_validate_certificate_chain(config->security_policy, cert_key_pair));
     520                 :            : 
     521                 :        948 :     s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pair);
     522                 :        948 :     config->is_rsa_cert_configured |= (cert_type == S2N_PKEY_TYPE_RSA);
     523                 :            : 
     524         [ -  + ]:        948 :     POSIX_GUARD(s2n_config_build_domain_name_to_cert_map(config, cert_key_pair));
     525                 :            : 
     526         [ +  - ]:        948 :     if (!config->default_certs_are_explicit) {
     527 [ -  + ][ #  # ]:        948 :         POSIX_ENSURE(cert_type >= 0, S2N_ERR_CERT_TYPE_UNSUPPORTED);
     528 [ -  + ][ #  # ]:        948 :         POSIX_ENSURE(cert_type < S2N_CERT_TYPE_COUNT, S2N_ERR_CERT_TYPE_UNSUPPORTED);
     529                 :            :         /* Attempt to auto set default based on ordering. ie: first RSA cert is the default, first ECDSA cert is the
     530                 :            :          * default, etc. */
     531         [ +  + ]:        948 :         if (config->default_certs_by_type.certs[cert_type] == NULL) {
     532                 :        837 :             config->default_certs_by_type.certs[cert_type] = cert_key_pair;
     533                 :        837 :         } else {
     534                 :            :             /* Because library-owned certificates are tracked and cleaned up via the
     535                 :            :              * default_certs_by_type mapping, library-owned chains MUST be set as the default
     536                 :            :              * to avoid a memory leak. If they're not the default, they're not freed.
     537                 :            :              */
     538 [ +  + ][ +  - ]:        111 :             POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED,
     539                 :        111 :                     S2N_ERR_MULTIPLE_DEFAULT_CERTIFICATES_PER_AUTH_TYPE);
     540                 :        111 :         }
     541                 :        948 :     }
     542                 :            : 
     543         [ +  + ]:        947 :     if (s2n_pkey_check_key_exists(cert_key_pair->private_key) != S2N_SUCCESS) {
     544                 :          5 :         config->no_signing_key = true;
     545                 :          5 :     }
     546                 :            : 
     547                 :        947 :     return S2N_SUCCESS;
     548                 :        948 : }
     549                 :            : 
     550                 :            : S2N_RESULT s2n_config_validate_loaded_certificates(const struct s2n_config *config,
     551                 :            :         const struct s2n_security_policy *security_policy)
     552                 :       5939 : {
     553 [ -  + ][ #  # ]:       5939 :     RESULT_ENSURE_REF(config);
     554 [ #  # ][ -  + ]:       5939 :     RESULT_ENSURE_REF(security_policy);
     555                 :            : 
     556         [ +  + ]:       5939 :     if (security_policy->certificate_key_preferences == NULL
     557         [ +  + ]:       5939 :             && security_policy->certificate_signature_preferences == NULL) {
     558                 :       3919 :         return S2N_RESULT_OK;
     559                 :       3919 :     }
     560                 :            : 
     561                 :            :     /* Duplicates a check in s2n_security_policy_validate_certificate_chain.
     562                 :            :      * If a large number of certificates are configured, even iterating
     563                 :            :      * over the chains to call s2n_security_policy_validate_certificate_chain
     564                 :            :      * could be prohibitively expensive.
     565                 :            :      */
     566         [ +  + ]:       2020 :     if (!security_policy->certificate_preferences_apply_locally) {
     567                 :       2005 :         return S2N_RESULT_OK;
     568                 :       2005 :     }
     569                 :            : 
     570                 :            :     /* validate the default certs */
     571         [ +  + ]:         61 :     for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
     572                 :         50 :         struct s2n_cert_chain_and_key *cert = config->default_certs_by_type.certs[i];
     573         [ +  + ]:         50 :         if (cert == NULL) {
     574                 :         37 :             continue;
     575                 :         37 :         }
     576         [ +  + ]:         13 :         RESULT_GUARD(s2n_security_policy_validate_certificate_chain(security_policy, cert));
     577                 :         13 :     }
     578                 :            : 
     579                 :            :     /* validate the certs in the domain map */
     580         [ -  + ]:         11 :     if (config->domain_name_to_cert_map == NULL) {
     581                 :          0 :         return S2N_RESULT_OK;
     582                 :          0 :     }
     583                 :            : 
     584                 :         11 :     struct s2n_map_iterator iter = { 0 };
     585         [ +  + ]:         11 :     RESULT_GUARD(s2n_map_iterator_init(&iter, config->domain_name_to_cert_map));
     586                 :            : 
     587         [ +  + ]:         18 :     while (s2n_map_iterator_has_next(&iter)) {
     588                 :          9 :         struct s2n_blob value = { 0 };
     589         [ -  + ]:          9 :         RESULT_GUARD(s2n_map_iterator_next(&iter, &value));
     590                 :            : 
     591                 :          9 :         struct certs_by_type *domain_certs = (void *) value.data;
     592         [ +  + ]:         42 :         for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
     593                 :         34 :             struct s2n_cert_chain_and_key *cert = domain_certs->certs[i];
     594         [ +  + ]:         34 :             if (cert == NULL) {
     595                 :         25 :                 continue;
     596                 :         25 :             }
     597         [ +  + ]:          9 :             RESULT_GUARD(s2n_security_policy_validate_certificate_chain(security_policy, cert));
     598                 :          9 :         }
     599                 :          9 :     }
     600                 :          9 :     return S2N_RESULT_OK;
     601                 :         10 : }
     602                 :            : 
     603                 :            : /* Deprecated. Superseded by s2n_config_add_cert_chain_and_key_to_store */
     604                 :            : int s2n_config_add_cert_chain_and_key(struct s2n_config *config, const char *cert_chain_pem, const char *private_key_pem)
     605                 :         14 : {
     606 [ -  + ][ #  # ]:         14 :     POSIX_ENSURE_REF(config);
     607 [ +  - ][ +  + ]:         14 :     POSIX_ENSURE(config->cert_ownership != S2N_APP_OWNED, S2N_ERR_CERT_OWNERSHIP);
     608                 :            : 
     609                 :         13 :     DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = s2n_cert_chain_and_key_new(),
     610                 :         13 :             s2n_cert_chain_and_key_ptr_free);
     611 [ #  # ][ -  + ]:         13 :     POSIX_ENSURE_REF(chain_and_key);
     612         [ -  + ]:         13 :     POSIX_GUARD(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain_pem, private_key_pem));
     613         [ +  + ]:         13 :     POSIX_GUARD(s2n_config_add_cert_chain_and_key_impl(config, chain_and_key));
     614                 :         12 :     config->cert_ownership = S2N_LIB_OWNED;
     615                 :            : 
     616                 :         12 :     ZERO_TO_DISABLE_DEFER_CLEANUP(chain_and_key);
     617                 :         12 :     return S2N_SUCCESS;
     618                 :         13 : }
     619                 :            : 
     620                 :            : /* Only used in the Rust bindings. Superseded by s2n_config_add_cert_chain_and_key_to_store */
     621                 :            : int s2n_config_add_cert_chain(struct s2n_config *config,
     622                 :            :         uint8_t *cert_chain_pem, uint32_t cert_chain_pem_size)
     623                 :          1 : {
     624 [ #  # ][ -  + ]:          1 :     POSIX_ENSURE_REF(config);
     625 [ #  # ][ -  + ]:          1 :     POSIX_ENSURE(config->cert_ownership != S2N_APP_OWNED, S2N_ERR_CERT_OWNERSHIP);
     626                 :            : 
     627                 :          1 :     DEFER_CLEANUP(struct s2n_cert_chain_and_key *chain_and_key = s2n_cert_chain_and_key_new(),
     628                 :          1 :             s2n_cert_chain_and_key_ptr_free);
     629 [ #  # ][ -  + ]:          1 :     POSIX_ENSURE_REF(chain_and_key);
     630         [ -  + ]:          1 :     POSIX_GUARD(s2n_cert_chain_and_key_load_public_pem_bytes(chain_and_key,
     631                 :          1 :             cert_chain_pem, cert_chain_pem_size));
     632         [ -  + ]:          1 :     POSIX_GUARD(s2n_config_add_cert_chain_and_key_impl(config, chain_and_key));
     633                 :          1 :     config->cert_ownership = S2N_LIB_OWNED;
     634                 :            : 
     635                 :          1 :     ZERO_TO_DISABLE_DEFER_CLEANUP(chain_and_key);
     636                 :          1 :     return S2N_SUCCESS;
     637                 :          1 : }
     638                 :            : 
     639                 :            : int s2n_config_add_cert_chain_and_key_to_store(struct s2n_config *config, struct s2n_cert_chain_and_key *cert_key_pair)
     640                 :        936 : {
     641 [ -  + ][ #  # ]:        936 :     POSIX_ENSURE_REF(config);
     642 [ +  - ][ +  + ]:        936 :     POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
     643                 :            : 
     644 [ #  # ][ -  + ]:        935 :     POSIX_ENSURE_REF(cert_key_pair);
     645         [ +  + ]:        935 :     POSIX_GUARD(s2n_config_add_cert_chain_and_key_impl(config, cert_key_pair));
     646                 :        934 :     config->cert_ownership = S2N_APP_OWNED;
     647                 :            : 
     648                 :        934 :     return S2N_SUCCESS;
     649                 :        935 : }
     650                 :            : 
     651                 :            : int s2n_config_set_async_pkey_callback(struct s2n_config *config, s2n_async_pkey_fn fn)
     652                 :         34 : {
     653 [ #  # ][ -  + ]:         34 :     POSIX_ENSURE_REF(config);
     654                 :            : 
     655                 :         34 :     config->async_pkey_cb = fn;
     656                 :            : 
     657                 :         34 :     return S2N_SUCCESS;
     658                 :         34 : }
     659                 :            : 
     660                 :            : static int s2n_config_clear_default_certificates(struct s2n_config *config)
     661                 :          5 : {
     662 [ #  # ][ -  + ]:          5 :     POSIX_ENSURE_REF(config);
     663                 :            : 
     664                 :            :     /* Clearing library-owned chains would lead to a memory leak.
     665                 :            :      * See s2n_config_free_cert_chain_and_key.
     666                 :            :      */
     667 [ -  + ][ #  # ]:          5 :     POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
     668                 :            : 
     669         [ +  + ]:         25 :     for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
     670                 :         20 :         config->default_certs_by_type.certs[i] = NULL;
     671                 :         20 :     }
     672                 :          5 :     config->cert_ownership = S2N_NOT_OWNED;
     673                 :          5 :     return 0;
     674                 :          5 : }
     675                 :            : 
     676                 :            : int s2n_config_set_cert_chain_and_key_defaults(struct s2n_config *config,
     677                 :            :         struct s2n_cert_chain_and_key **cert_key_pairs,
     678                 :            :         uint32_t num_cert_key_pairs)
     679                 :          9 : {
     680 [ -  + ][ #  # ]:          9 :     POSIX_ENSURE_REF(config);
     681 [ +  + ][ +  - ]:          9 :     POSIX_ENSURE_REF(cert_key_pairs);
     682 [ -  + ][ +  + ]:          8 :     S2N_ERROR_IF(num_cert_key_pairs < 1 || num_cert_key_pairs > S2N_CERT_TYPE_COUNT,
                 [ +  - ]
     683                 :          8 :             S2N_ERR_NUM_DEFAULT_CERTIFICATES);
     684                 :            : 
     685                 :            :     /* This method will set application-owned chains, so we must not already be using
     686                 :            :      * any library owned chains. See s2n_config_free_cert_chain_and_key.
     687                 :            :      */
     688 [ +  - ][ +  + ]:          7 :     POSIX_ENSURE(config->cert_ownership != S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
     689                 :            : 
     690                 :            :     /* Validate certs being set before clearing auto-chosen defaults or previously set defaults */
     691                 :          6 :     struct certs_by_type new_defaults = { { 0 } };
     692         [ +  + ]:         13 :     for (size_t i = 0; i < num_cert_key_pairs; i++) {
     693 [ -  + ][ #  # ]:          8 :         POSIX_ENSURE_REF(cert_key_pairs[i]);
     694                 :          8 :         s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
     695 [ +  + ][ +  - ]:          8 :         S2N_ERROR_IF(new_defaults.certs[cert_type] != NULL, S2N_ERR_MULTIPLE_DEFAULT_CERTIFICATES_PER_AUTH_TYPE);
     696                 :          7 :         new_defaults.certs[cert_type] = cert_key_pairs[i];
     697                 :          7 :     }
     698                 :            : 
     699         [ -  + ]:          5 :     POSIX_GUARD(s2n_config_clear_default_certificates(config));
     700         [ +  + ]:         11 :     for (size_t i = 0; i < num_cert_key_pairs; i++) {
     701                 :          6 :         s2n_pkey_type cert_type = s2n_cert_chain_and_key_get_pkey_type(cert_key_pairs[i]);
     702                 :          6 :         config->is_rsa_cert_configured |= (cert_type == S2N_PKEY_TYPE_RSA);
     703                 :          6 :         config->default_certs_by_type.certs[cert_type] = cert_key_pairs[i];
     704                 :          6 :     }
     705                 :            : 
     706                 :          5 :     config->default_certs_are_explicit = 1;
     707                 :          5 :     config->cert_ownership = S2N_APP_OWNED;
     708                 :          5 :     return 0;
     709                 :          5 : }
     710                 :            : 
     711                 :            : int s2n_config_add_dhparams(struct s2n_config *config, const char *dhparams_pem)
     712                 :         81 : {
     713                 :         81 :     DEFER_CLEANUP(struct s2n_stuffer dhparams_in_stuffer = { 0 }, s2n_stuffer_free);
     714                 :         81 :     DEFER_CLEANUP(struct s2n_stuffer dhparams_out_stuffer = { 0 }, s2n_stuffer_free);
     715                 :         81 :     struct s2n_blob dhparams_blob = { 0 };
     716                 :         81 :     struct s2n_blob mem = { 0 };
     717                 :            : 
     718                 :            :     /* Allocate the memory for the chain and key struct */
     719         [ -  + ]:         81 :     POSIX_GUARD(s2n_alloc(&mem, sizeof(struct s2n_dh_params)));
     720                 :         81 :     config->dhparams = (struct s2n_dh_params *) (void *) mem.data;
     721                 :            : 
     722         [ -  + ]:         81 :     if (s2n_stuffer_alloc_ro_from_string(&dhparams_in_stuffer, dhparams_pem) != S2N_SUCCESS) {
     723                 :          0 :         s2n_free(&mem);
     724                 :          0 :         S2N_ERROR_PRESERVE_ERRNO();
     725                 :          0 :     }
     726         [ -  + ]:         81 :     if (s2n_stuffer_growable_alloc(&dhparams_out_stuffer, strlen(dhparams_pem)) != S2N_SUCCESS) {
     727                 :          0 :         s2n_free(&mem);
     728                 :          0 :         S2N_ERROR_PRESERVE_ERRNO();
     729                 :          0 :     }
     730                 :            : 
     731                 :            :     /* Convert pem to asn1 and asn1 to the private key */
     732         [ -  + ]:         81 :     POSIX_GUARD(s2n_stuffer_dhparams_from_pem(&dhparams_in_stuffer, &dhparams_out_stuffer));
     733                 :            : 
     734                 :         81 :     dhparams_blob.size = s2n_stuffer_data_available(&dhparams_out_stuffer);
     735                 :         81 :     dhparams_blob.data = s2n_stuffer_raw_read(&dhparams_out_stuffer, dhparams_blob.size);
     736 [ #  # ][ -  + ]:         81 :     POSIX_ENSURE_REF(dhparams_blob.data);
     737                 :            : 
     738         [ -  + ]:         81 :     POSIX_GUARD(s2n_pkcs3_to_dh_params(config->dhparams, &dhparams_blob));
     739                 :            : 
     740                 :         81 :     return 0;
     741                 :         81 : }
     742                 :            : 
     743                 :            : int s2n_config_set_wall_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
     744                 :         65 : {
     745 [ #  # ][ -  + ]:         65 :     POSIX_ENSURE_REF(clock_fn);
     746                 :            : 
     747                 :         65 :     config->wall_clock = clock_fn;
     748                 :         65 :     config->sys_clock_ctx = ctx;
     749                 :            : 
     750                 :         65 :     return 0;
     751                 :         65 : }
     752                 :            : 
     753                 :            : int s2n_config_set_monotonic_clock(struct s2n_config *config, s2n_clock_time_nanoseconds clock_fn, void *ctx)
     754                 :          1 : {
     755 [ #  # ][ -  + ]:          1 :     POSIX_ENSURE_REF(clock_fn);
     756                 :            : 
     757                 :          1 :     config->monotonic_clock = clock_fn;
     758                 :          1 :     config->monotonic_clock_ctx = ctx;
     759                 :            : 
     760                 :          1 :     return 0;
     761                 :          1 : }
     762                 :            : 
     763                 :            : int s2n_config_set_cache_store_callback(struct s2n_config *config, s2n_cache_store_callback cache_store_callback, void *data)
     764                 :          2 : {
     765 [ #  # ][ -  + ]:          2 :     POSIX_ENSURE_REF(cache_store_callback);
     766                 :            : 
     767                 :          2 :     config->cache_store = cache_store_callback;
     768                 :          2 :     config->cache_store_data = data;
     769                 :            : 
     770                 :          2 :     return 0;
     771                 :          2 : }
     772                 :            : 
     773                 :            : int s2n_config_set_cache_retrieve_callback(struct s2n_config *config, s2n_cache_retrieve_callback cache_retrieve_callback, void *data)
     774                 :          2 : {
     775 [ #  # ][ -  + ]:          2 :     POSIX_ENSURE_REF(cache_retrieve_callback);
     776                 :            : 
     777                 :          2 :     config->cache_retrieve = cache_retrieve_callback;
     778                 :          2 :     config->cache_retrieve_data = data;
     779                 :            : 
     780                 :          2 :     return 0;
     781                 :          2 : }
     782                 :            : 
     783                 :            : int s2n_config_set_cache_delete_callback(struct s2n_config *config, s2n_cache_delete_callback cache_delete_callback, void *data)
     784                 :          2 : {
     785 [ #  # ][ -  + ]:          2 :     POSIX_ENSURE_REF(cache_delete_callback);
     786                 :            : 
     787                 :          2 :     config->cache_delete = cache_delete_callback;
     788                 :          2 :     config->cache_delete_data = data;
     789                 :            : 
     790                 :          2 :     return 0;
     791                 :          2 : }
     792                 :            : 
     793                 :            : int s2n_config_set_extension_data(struct s2n_config *config, s2n_tls_extension_type type, const uint8_t *data, uint32_t length)
     794                 :          8 : {
     795 [ #  # ][ -  + ]:          8 :     POSIX_ENSURE_REF(config);
     796                 :            : 
     797         [ -  + ]:          8 :     if (s2n_config_get_num_default_certs(config) == 0) {
     798         [ #  # ]:          0 :         POSIX_BAIL(S2N_ERR_UPDATING_EXTENSION);
     799                 :          0 :     }
     800                 :          8 :     struct s2n_cert_chain_and_key *config_chain_and_key = s2n_config_get_single_default_cert(config);
     801 [ -  + ][ #  # ]:          8 :     POSIX_ENSURE_REF(config_chain_and_key);
     802 [ +  - ][ +  + ]:          8 :     POSIX_ENSURE(config->cert_ownership == S2N_LIB_OWNED, S2N_ERR_CERT_OWNERSHIP);
     803                 :            : 
     804                 :          7 :     switch (type) {
     805         [ +  + ]:          2 :         case S2N_EXTENSION_CERTIFICATE_TRANSPARENCY:
     806         [ -  + ]:          2 :             POSIX_GUARD(s2n_cert_chain_and_key_set_sct_list(config_chain_and_key, data, length));
     807                 :          2 :             break;
     808         [ +  + ]:          5 :         case S2N_EXTENSION_OCSP_STAPLING:
     809         [ -  + ]:          5 :             POSIX_GUARD(s2n_cert_chain_and_key_set_ocsp_data(config_chain_and_key, data, length));
     810                 :          5 :             break;
     811         [ -  + ]:          5 :         default:
     812         [ #  # ]:          0 :             POSIX_BAIL(S2N_ERR_UNRECOGNIZED_EXTENSION);
     813                 :          7 :     }
     814                 :            : 
     815                 :          7 :     return 0;
     816                 :          7 : }
     817                 :            : 
     818                 :            : int s2n_config_add_custom_x509_extension(struct s2n_config *config, uint8_t *extension_oid, uint32_t extension_oid_len)
     819                 :          3 : {
     820 [ +  + ][ +  - ]:          3 :     POSIX_ENSURE(config, S2N_ERR_INVALID_ARGUMENT);
     821 [ +  + ][ +  - ]:          2 :     POSIX_ENSURE(extension_oid, S2N_ERR_INVALID_ARGUMENT);
     822                 :            : 
     823 [ +  - ][ +  - ]:          1 :     POSIX_ENSURE(s2n_libcrypto_supports_custom_oid(), S2N_ERR_API_UNSUPPORTED_BY_LIBCRYPTO);
     824                 :            : 
     825         [ #  # ]:          0 :     if (config->custom_x509_extension_oids == NULL) {
     826                 :          0 :         config->custom_x509_extension_oids = sk_ASN1_OBJECT_new_null();
     827                 :          0 :     }
     828 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE_REF(config->custom_x509_extension_oids);
     829                 :            : 
     830                 :          0 :     DEFER_CLEANUP(struct s2n_blob oid_buffer = { 0 }, s2n_free);
     831         [ #  # ]:          0 :     POSIX_GUARD(s2n_alloc(&oid_buffer, extension_oid_len + 1));
     832                 :            : 
     833         [ #  # ]:          0 :     POSIX_GUARD(s2n_blob_zero(&oid_buffer));
     834 [ #  # ][ #  # ]:          0 :     POSIX_CHECKED_MEMCPY(oid_buffer.data, extension_oid, extension_oid_len);
                 [ #  # ]
     835                 :          0 :     oid_buffer.data[extension_oid_len] = '\0';
     836                 :            : 
     837                 :          0 :     const char *oid_string = (const char *) oid_buffer.data;
     838 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE_REF(oid_string);
     839                 :            : 
     840                 :          0 :     ASN1_OBJECT *critical_oid = OBJ_txt2obj(oid_string, 1);
     841 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE_REF(critical_oid);
     842 [ #  # ][ #  # ]:          0 :     POSIX_ENSURE(sk_ASN1_OBJECT_push(config->custom_x509_extension_oids, critical_oid) > 0, S2N_ERR_INTERNAL_LIBCRYPTO_ERROR);
     843                 :            : 
     844                 :          0 :     return S2N_SUCCESS;
     845                 :          0 : }
     846                 :            : 
     847                 :            : int s2n_config_set_cert_request_callback(struct s2n_config *config, s2n_cert_request_callback cert_request_cb, void *ctx)
     848                 :          3 : {
     849 [ +  + ][ +  - ]:          3 :     POSIX_ENSURE(config, S2N_ERR_INVALID_ARGUMENT);
     850                 :            : 
     851                 :          2 :     config->cert_request_cb = cert_request_cb;
     852                 :          2 :     config->cert_request_cb_ctx = ctx;
     853                 :            : 
     854                 :          2 :     return S2N_SUCCESS;
     855                 :          3 : }
     856                 :            : 
     857                 :            : int s2n_config_set_client_hello_cb(struct s2n_config *config, s2n_client_hello_fn client_hello_cb, void *ctx)
     858                 :        127 : {
     859 [ #  # ][ -  + ]:        127 :     POSIX_ENSURE_REF(config);
     860                 :            : 
     861                 :        127 :     config->client_hello_cb = client_hello_cb;
     862                 :        127 :     config->client_hello_cb_ctx = ctx;
     863                 :        127 :     return 0;
     864                 :        127 : }
     865                 :            : 
     866                 :            : int s2n_config_set_client_hello_cb_mode(struct s2n_config *config, s2n_client_hello_cb_mode cb_mode)
     867                 :         72 : {
     868 [ -  + ][ #  # ]:         72 :     POSIX_ENSURE_REF(config);
     869 [ #  # ][ +  + ]:         72 :     POSIX_ENSURE(cb_mode == S2N_CLIENT_HELLO_CB_BLOCKING || cb_mode == S2N_CLIENT_HELLO_CB_NONBLOCKING, S2N_ERR_INVALID_STATE);
                 [ +  - ]
     870                 :            : 
     871                 :         72 :     config->client_hello_cb_mode = cb_mode;
     872                 :         72 :     return S2N_SUCCESS;
     873                 :         72 : }
     874                 :            : 
     875                 :            : int s2n_config_send_max_fragment_length(struct s2n_config *config, s2n_max_frag_len mfl_code)
     876                 :        256 : {
     877 [ -  + ][ #  # ]:        256 :     POSIX_ENSURE_REF(config);
     878                 :            : 
     879 [ +  + ][ +  - ]:        256 :     S2N_ERROR_IF(mfl_code > S2N_TLS_MAX_FRAG_LEN_4096, S2N_ERR_INVALID_MAX_FRAG_LEN);
     880                 :            : 
     881                 :        255 :     config->mfl_code = mfl_code;
     882                 :            : 
     883                 :        255 :     return 0;
     884                 :        256 : }
     885                 :            : 
     886                 :            : int s2n_config_accept_max_fragment_length(struct s2n_config *config)
     887                 :         11 : {
     888 [ -  + ][ #  # ]:         11 :     POSIX_ENSURE_REF(config);
     889                 :            : 
     890                 :         11 :     config->accept_mfl = 1;
     891                 :            : 
     892                 :         11 :     return 0;
     893                 :         11 : }
     894                 :            : 
     895                 :            : int s2n_config_set_session_state_lifetime(struct s2n_config *config,
     896                 :            :         uint64_t lifetime_in_secs)
     897                 :         16 : {
     898 [ -  + ][ #  # ]:         16 :     POSIX_ENSURE_REF(config);
     899                 :            : 
     900                 :         16 :     config->session_state_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
     901                 :         16 :     return 0;
     902                 :         16 : }
     903                 :            : 
     904                 :            : int s2n_config_set_session_tickets_onoff(struct s2n_config *config, uint8_t enabled)
     905                 :        157 : {
     906 [ +  - ][ +  + ]:        157 :     POSIX_ENSURE_REF(config);
     907                 :            : 
     908         [ +  + ]:        155 :     if (config->use_tickets == enabled) {
     909                 :         17 :         return 0;
     910                 :         17 :     }
     911                 :            : 
     912                 :        138 :     config->use_tickets = enabled;
     913                 :            : 
     914         [ +  + ]:        138 :     if (config->initial_tickets_to_send == 0) {
     915                 :            :         /* Normally initial_tickets_to_send is set via s2n_config_set_initial_ticket_count.
     916                 :            :          * However, s2n_config_set_initial_ticket_count calls this method.
     917                 :            :          * So we set initial_tickets_to_send directly to avoid infinite recursion. */
     918                 :        130 :         config->initial_tickets_to_send = 1;
     919                 :        130 :     }
     920                 :            : 
     921                 :            :     /* session ticket || session id is enabled */
     922         [ +  + ]:        138 :     if (enabled) {
     923         [ -  + ]:        134 :         POSIX_GUARD(s2n_config_init_session_ticket_keys(config));
     924         [ +  - ]:        134 :     } else if (!config->use_session_cache) {
     925         [ -  + ]:          4 :         POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
     926                 :          4 :     }
     927                 :            : 
     928                 :        138 :     return 0;
     929                 :        138 : }
     930                 :            : 
     931                 :            : int s2n_config_set_session_cache_onoff(struct s2n_config *config, uint8_t enabled)
     932                 :          3 : {
     933 [ -  + ][ #  # ]:          3 :     POSIX_ENSURE_REF(config);
     934 [ +  - ][ +  + ]:          3 :     if (enabled && config->cache_store && config->cache_retrieve && config->cache_delete) {
         [ +  - ][ +  - ]
     935         [ -  + ]:          2 :         POSIX_GUARD(s2n_config_init_session_ticket_keys(config));
     936                 :          2 :         config->use_session_cache = 1;
     937                 :          2 :     } else {
     938         [ -  + ]:          1 :         if (!config->use_tickets) {
     939         [ #  # ]:          0 :             POSIX_GUARD(s2n_config_free_session_ticket_keys(config));
     940                 :          0 :         }
     941                 :          1 :         config->use_session_cache = 0;
     942                 :          1 :     }
     943                 :          3 :     return 0;
     944                 :          3 : }
     945                 :            : 
     946                 :            : int s2n_config_set_ticket_encrypt_decrypt_key_lifetime(struct s2n_config *config,
     947                 :            :         uint64_t lifetime_in_secs)
     948                 :          1 : {
     949 [ #  # ][ -  + ]:          1 :     POSIX_ENSURE_REF(config);
     950                 :            : 
     951                 :          1 :     config->encrypt_decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
     952                 :          1 :     return 0;
     953                 :          1 : }
     954                 :            : 
     955                 :            : int s2n_config_set_ticket_decrypt_key_lifetime(struct s2n_config *config,
     956                 :            :         uint64_t lifetime_in_secs)
     957                 :          1 : {
     958 [ -  + ][ #  # ]:          1 :     POSIX_ENSURE_REF(config);
     959                 :            : 
     960                 :          1 :     config->decrypt_key_lifetime_in_nanos = (lifetime_in_secs * ONE_SEC_IN_NANOS);
     961                 :          1 :     return 0;
     962                 :          1 : }
     963                 :            : 
     964                 :            : int s2n_config_add_ticket_crypto_key(struct s2n_config *config,
     965                 :            :         const uint8_t *name, uint32_t name_len,
     966                 :            :         uint8_t *key, uint32_t key_len,
     967                 :            :         uint64_t intro_time_in_seconds_from_epoch)
     968                 :        140 : {
     969 [ -  + ][ #  # ]:        140 :     POSIX_ENSURE_REF(config);
     970 [ -  + ][ #  # ]:        140 :     POSIX_ENSURE_REF(name);
     971 [ -  + ][ #  # ]:        140 :     POSIX_ENSURE_REF(key);
     972                 :            : 
     973                 :            :     /* both session ticket and session cache encryption/decryption can use the same key mechanism */
     974 [ +  + ][ -  + ]:        140 :     if (!config->use_tickets && !config->use_session_cache) {
     975                 :          0 :         return 0;
     976                 :          0 :     }
     977                 :            : 
     978         [ -  + ]:        140 :     POSIX_GUARD(s2n_config_wipe_expired_ticket_crypto_keys(config, -1));
     979                 :            : 
     980 [ +  + ][ +  - ]:        140 :     POSIX_ENSURE(key_len != 0, S2N_ERR_INVALID_TICKET_KEY_LENGTH);
     981                 :            : 
     982                 :        139 :     uint32_t ticket_keys_len = 0;
     983         [ -  + ]:        139 :     POSIX_GUARD_RESULT(s2n_array_num_elements(config->ticket_keys, &ticket_keys_len));
     984 [ +  + ][ +  - ]:        139 :     POSIX_ENSURE(ticket_keys_len < S2N_MAX_TICKET_KEYS, S2N_ERR_TICKET_KEY_LIMIT);
     985                 :            : 
     986 [ +  - ][ +  + ]:        138 :     POSIX_ENSURE(name_len != 0, S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
     987 [ +  + ][ +  - ]:        137 :     POSIX_ENSURE(name_len <= S2N_TICKET_KEY_NAME_LEN, S2N_ERR_INVALID_TICKET_KEY_NAME_OR_NAME_LENGTH);
     988                 :            : 
     989                 :            :     /* Copy the name into a zero-padded array. */
     990                 :            :     /* This ensures that all ticket names are equal in length, as the serialized name is fixed length */
     991                 :        136 :     uint8_t name_data[S2N_TICKET_KEY_NAME_LEN] = { 0 };
     992 [ -  + ][ #  # ]:        136 :     POSIX_CHECKED_MEMCPY(name_data, name, name_len);
                 [ +  - ]
     993                 :            : 
     994                 :        136 :     uint8_t output_pad[S2N_AES256_KEY_LEN + S2N_TICKET_AAD_IMPLICIT_LEN] = { 0 };
     995                 :        136 :     struct s2n_blob out_key = { 0 };
     996         [ -  + ]:        136 :     POSIX_GUARD(s2n_blob_init(&out_key, output_pad, s2n_array_len(output_pad)));
     997                 :        136 :     struct s2n_blob in_key = { 0 };
     998         [ -  + ]:        136 :     POSIX_GUARD(s2n_blob_init(&in_key, key, key_len));
     999                 :        136 :     struct s2n_blob salt = { 0 };
    1000         [ -  + ]:        136 :     POSIX_GUARD(s2n_blob_init(&salt, NULL, 0));
    1001                 :        136 :     struct s2n_blob info = { 0 };
    1002         [ -  + ]:        136 :     POSIX_GUARD(s2n_blob_init(&info, NULL, 0));
    1003                 :            : 
    1004                 :        136 :     struct s2n_ticket_key *session_ticket_key = { 0 };
    1005                 :        136 :     DEFER_CLEANUP(struct s2n_blob allocator = { 0 }, s2n_free);
    1006         [ -  + ]:        136 :     POSIX_GUARD(s2n_alloc(&allocator, sizeof(struct s2n_ticket_key)));
    1007                 :        136 :     session_ticket_key = (struct s2n_ticket_key *) (void *) allocator.data;
    1008                 :            : 
    1009                 :        136 :     DEFER_CLEANUP(struct s2n_hmac_state hmac = { 0 }, s2n_hmac_free);
    1010                 :            : 
    1011         [ -  + ]:        136 :     POSIX_GUARD(s2n_hmac_new(&hmac));
    1012         [ -  + ]:        136 :     POSIX_GUARD(s2n_hkdf(&hmac, S2N_HMAC_SHA256, &salt, &in_key, &info, &out_key));
    1013                 :            : 
    1014 [ -  + ][ #  # ]:        136 :     POSIX_CHECKED_MEMCPY(session_ticket_key->key_name, name_data, s2n_array_len(name_data));
                 [ +  - ]
    1015 [ -  + ][ #  # ]:        136 :     POSIX_CHECKED_MEMCPY(session_ticket_key->aes_key, out_key.data, S2N_AES256_KEY_LEN);
                 [ +  - ]
    1016                 :        136 :     out_key.data = output_pad + S2N_AES256_KEY_LEN;
    1017 [ #  # ][ -  + ]:        136 :     POSIX_CHECKED_MEMCPY(session_ticket_key->implicit_aad, out_key.data, S2N_TICKET_AAD_IMPLICIT_LEN);
                 [ +  - ]
    1018                 :            : 
    1019         [ +  + ]:        136 :     if (intro_time_in_seconds_from_epoch == 0) {
    1020                 :         86 :         uint64_t now = 0;
    1021         [ -  + ]:         86 :         POSIX_GUARD_RESULT(s2n_config_wall_clock(config, &now));
    1022                 :         86 :         session_ticket_key->intro_timestamp = now;
    1023                 :         86 :     } else {
    1024                 :         50 :         session_ticket_key->intro_timestamp = (intro_time_in_seconds_from_epoch * ONE_SEC_IN_NANOS);
    1025                 :         50 :     }
    1026                 :            : 
    1027         [ +  + ]:        136 :     POSIX_GUARD(s2n_config_store_ticket_key(config, session_ticket_key));
    1028                 :            : 
    1029                 :        132 :     return 0;
    1030                 :        136 : }
    1031                 :            : 
    1032                 :            : int s2n_config_require_ticket_forward_secrecy(struct s2n_config *config, bool enabled)
    1033                 :          4 : {
    1034 [ #  # ][ -  + ]:          4 :     POSIX_ENSURE_REF(config);
    1035                 :            : 
    1036                 :          4 :     config->ticket_forward_secrecy = enabled;
    1037                 :            : 
    1038                 :          4 :     return S2N_SUCCESS;
    1039                 :          4 : }
    1040                 :            : 
    1041                 :            : int s2n_config_set_cert_tiebreak_callback(struct s2n_config *config, s2n_cert_tiebreak_callback cert_tiebreak_cb)
    1042                 :          1 : {
    1043                 :          1 :     config->cert_tiebreak_cb = cert_tiebreak_cb;
    1044                 :          1 :     return 0;
    1045                 :          1 : }
    1046                 :            : 
    1047                 :            : struct s2n_cert_chain_and_key *s2n_config_get_single_default_cert(struct s2n_config *config)
    1048                 :        124 : {
    1049 [ -  + ][ #  # ]:        124 :     PTR_ENSURE_REF(config);
    1050                 :        124 :     struct s2n_cert_chain_and_key *cert = NULL;
    1051                 :            : 
    1052         [ +  + ]:        620 :     for (int i = S2N_CERT_TYPE_COUNT - 1; i >= 0; i--) {
    1053         [ +  + ]:        496 :         if (config->default_certs_by_type.certs[i] != NULL) {
    1054                 :        121 :             cert = config->default_certs_by_type.certs[i];
    1055                 :        121 :         }
    1056                 :        496 :     }
    1057                 :        124 :     return cert;
    1058                 :        124 : }
    1059                 :            : 
    1060                 :            : int s2n_config_get_num_default_certs(const struct s2n_config *config)
    1061                 :    3557884 : {
    1062 [ -  + ][ #  # ]:    3557884 :     POSIX_ENSURE_REF(config);
    1063                 :    3557884 :     int num_certs = 0;
    1064         [ +  + ]:   17789420 :     for (int i = 0; i < S2N_CERT_TYPE_COUNT; i++) {
    1065         [ +  + ]:   14231536 :         if (config->default_certs_by_type.certs[i] != NULL) {
    1066                 :      11079 :             num_certs++;
    1067                 :      11079 :         }
    1068                 :   14231536 :     }
    1069                 :            : 
    1070                 :    3557884 :     return num_certs;
    1071                 :    3557884 : }
    1072                 :            : 
    1073                 :            : int s2n_config_enable_cert_req_dss_legacy_compat(struct s2n_config *config)
    1074                 :          1 : {
    1075 [ -  + ][ #  # ]:          1 :     POSIX_ENSURE_REF(config);
    1076                 :          1 :     config->cert_req_dss_legacy_compat_enabled = 1;
    1077                 :          1 :     return S2N_SUCCESS;
    1078                 :          1 : }
    1079                 :            : 
    1080                 :            : int s2n_config_set_psk_selection_callback(struct s2n_config *config, s2n_psk_selection_callback cb, void *context)
    1081                 :          9 : {
    1082 [ +  + ][ +  - ]:          9 :     POSIX_ENSURE_REF(config);
    1083                 :          8 :     config->psk_selection_cb = cb;
    1084                 :          8 :     config->psk_selection_ctx = context;
    1085                 :          8 :     return S2N_SUCCESS;
    1086                 :          9 : }
    1087                 :            : 
    1088                 :            : int s2n_config_set_key_log_cb(struct s2n_config *config, s2n_key_log_fn callback, void *ctx)
    1089                 :          4 : {
    1090 [ -  + ][ #  # ]:          4 :     POSIX_ENSURE_MUT(config);
    1091                 :            : 
    1092                 :          4 :     config->key_log_cb = callback;
    1093                 :          4 :     config->key_log_ctx = ctx;
    1094                 :            : 
    1095                 :          4 :     return S2N_SUCCESS;
    1096                 :          4 : }
    1097                 :            : 
    1098                 :            : int s2n_config_set_async_pkey_validation_mode(struct s2n_config *config, s2n_async_pkey_validation_mode mode)
    1099                 :          4 : {
    1100 [ -  + ][ #  # ]:          4 :     POSIX_ENSURE_REF(config);
    1101                 :            : 
    1102         [ -  + ]:          4 :     switch (mode) {
    1103         [ -  + ]:          0 :         case S2N_ASYNC_PKEY_VALIDATION_FAST:
    1104         [ +  - ]:          4 :         case S2N_ASYNC_PKEY_VALIDATION_STRICT:
    1105                 :          4 :             config->async_pkey_validation_mode = mode;
    1106                 :          4 :             return S2N_SUCCESS;
    1107                 :          4 :     }
    1108                 :            : 
    1109         [ #  # ]:          0 :     POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
    1110                 :          0 : }
    1111                 :            : 
    1112                 :            : int s2n_config_set_ctx(struct s2n_config *config, void *ctx)
    1113                 :          1 : {
    1114 [ -  + ][ #  # ]:          1 :     POSIX_ENSURE_REF(config);
    1115                 :            : 
    1116                 :          1 :     config->context = ctx;
    1117                 :            : 
    1118                 :          1 :     return S2N_SUCCESS;
    1119                 :          1 : }
    1120                 :            : 
    1121                 :            : int s2n_config_get_ctx(struct s2n_config *config, void **ctx)
    1122                 :          2 : {
    1123 [ #  # ][ -  + ]:          2 :     POSIX_ENSURE_REF(config);
    1124 [ -  + ][ #  # ]:          2 :     POSIX_ENSURE_REF(ctx);
    1125                 :            : 
    1126                 :          2 :     *ctx = config->context;
    1127                 :            : 
    1128                 :          2 :     return S2N_SUCCESS;
    1129                 :          2 : }
    1130                 :            : 
    1131                 :            : int s2n_config_set_send_buffer_size(struct s2n_config *config, uint32_t size)
    1132                 :         11 : {
    1133 [ +  - ][ +  + ]:         11 :     POSIX_ENSURE_REF(config);
    1134 [ +  + ][ +  - ]:         10 :     POSIX_ENSURE(size >= S2N_MIN_SEND_BUFFER_SIZE, S2N_ERR_INVALID_ARGUMENT);
    1135                 :          8 :     config->send_buffer_size_override = size;
    1136                 :          8 :     return S2N_SUCCESS;
    1137                 :         10 : }
    1138                 :            : 
    1139                 :            : int s2n_config_set_verify_after_sign(struct s2n_config *config, s2n_verify_after_sign mode)
    1140                 :         25 : {
    1141 [ +  + ][ +  - ]:         25 :     POSIX_ENSURE_REF(config);
    1142                 :         24 :     switch (mode) {
    1143         [ +  + ]:          1 :         case S2N_VERIFY_AFTER_SIGN_DISABLED:
    1144                 :          1 :             config->verify_after_sign = false;
    1145                 :          1 :             break;
    1146         [ +  + ]:         21 :         case S2N_VERIFY_AFTER_SIGN_ENABLED:
    1147                 :         21 :             config->verify_after_sign = true;
    1148                 :         21 :             break;
    1149         [ +  + ]:          2 :         default:
    1150         [ +  - ]:          2 :             POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
    1151                 :         24 :     }
    1152                 :         22 :     return S2N_SUCCESS;
    1153                 :         24 : }
    1154                 :            : 
    1155                 :            : /*
    1156                 :            :  *= https://www.rfc-editor.org/rfc/rfc5746#5
    1157                 :            :  *# TLS implementations SHOULD provide a mechanism to disable and enable
    1158                 :            :  *# renegotiation.
    1159                 :            :  */
    1160                 :            : int s2n_config_set_renegotiate_request_cb(struct s2n_config *config, s2n_renegotiate_request_cb cb, void *ctx)
    1161                 :         18 : {
    1162 [ +  + ][ +  - ]:         18 :     POSIX_ENSURE_REF(config);
    1163                 :            : 
    1164                 :            :     /* This feature cannot be used with serialization currently */
    1165 [ +  - ][ +  + ]:         17 :     POSIX_ENSURE(config->serialized_connection_version == S2N_SERIALIZED_CONN_NONE, S2N_ERR_INVALID_STATE);
    1166                 :            : 
    1167                 :         16 :     config->renegotiate_request_cb = cb;
    1168                 :         16 :     config->renegotiate_request_ctx = ctx;
    1169                 :         16 :     return S2N_SUCCESS;
    1170                 :         17 : }
    1171                 :            : 
    1172                 :            : int s2n_config_set_npn(struct s2n_config *config, bool enable)
    1173                 :          3 : {
    1174 [ +  + ][ +  - ]:          3 :     POSIX_ENSURE_REF(config);
    1175                 :            : 
    1176                 :          2 :     config->npn_supported = enable;
    1177                 :            : 
    1178                 :          2 :     return S2N_SUCCESS;
    1179                 :          3 : }
    1180                 :            : 
    1181                 :            : /*
    1182                 :            :  * Wrapper for wall_clock callback. This wrapper will ensure right return of s2n_errno everytime wall_clock
    1183                 :            :  * callback is called.
    1184                 :            :  */
    1185                 :            : S2N_RESULT s2n_config_wall_clock(struct s2n_config *config, uint64_t *output)
    1186                 :       4176 : {
    1187 [ -  + ][ #  # ]:       4176 :     RESULT_ENSURE(config->wall_clock(config->sys_clock_ctx, output) >= S2N_SUCCESS, S2N_ERR_CANCELLED);
    1188                 :       4176 :     return S2N_RESULT_OK;
    1189                 :       4176 : }
    1190                 :            : 
    1191                 :            : int s2n_config_set_crl_lookup_cb(struct s2n_config *config, s2n_crl_lookup_callback cb, void *ctx)
    1192                 :         22 : {
    1193 [ +  - ][ +  + ]:         22 :     POSIX_ENSURE_REF(config);
    1194                 :         21 :     config->crl_lookup_cb = cb;
    1195                 :         21 :     config->crl_lookup_ctx = ctx;
    1196                 :         21 :     return S2N_SUCCESS;
    1197                 :         22 : }
    1198                 :            : 
    1199                 :            : int s2n_config_set_recv_multi_record(struct s2n_config *config, bool enabled)
    1200                 :          6 : {
    1201 [ -  + ][ #  # ]:          6 :     POSIX_ENSURE_REF(config);
    1202                 :            : 
    1203                 :          6 :     config->recv_multi_record = enabled;
    1204                 :            : 
    1205                 :          6 :     return S2N_SUCCESS;
    1206                 :          6 : }
    1207                 :            : 
    1208                 :            : int s2n_config_set_cert_validation_cb(struct s2n_config *config, s2n_cert_validation_callback cb, void *ctx)
    1209                 :         33 : {
    1210 [ +  - ][ +  + ]:         33 :     POSIX_ENSURE_REF(config);
    1211                 :            : 
    1212                 :         32 :     config->cert_validation_cb = cb;
    1213                 :         32 :     config->cert_validation_ctx = ctx;
    1214                 :            : 
    1215                 :         32 :     return S2N_SUCCESS;
    1216                 :         33 : }
    1217                 :            : 
    1218                 :            : int s2n_config_get_supported_groups(struct s2n_config *config, uint16_t *groups, uint16_t groups_count_max,
    1219                 :            :         uint16_t *groups_count_out)
    1220                 :        135 : {
    1221 [ +  + ][ +  - ]:        135 :     POSIX_ENSURE_REF(groups_count_out);
    1222                 :        134 :     *groups_count_out = 0;
    1223 [ +  - ][ +  + ]:        134 :     POSIX_ENSURE_REF(config);
    1224 [ +  + ][ +  - ]:        133 :     POSIX_ENSURE_REF(groups);
    1225                 :            : 
    1226                 :        132 :     const struct s2n_security_policy *security_policy = config->security_policy;
    1227 [ -  + ][ #  # ]:        132 :     POSIX_ENSURE_REF(security_policy);
    1228                 :        132 :     const struct s2n_kem_preferences *kem_preferences = security_policy->kem_preferences;
    1229 [ -  + ][ #  # ]:        132 :     POSIX_ENSURE_REF(kem_preferences);
    1230                 :        132 :     const struct s2n_ecc_preferences *ecc_preferences = security_policy->ecc_preferences;
    1231 [ -  + ][ #  # ]:        132 :     POSIX_ENSURE_REF(ecc_preferences);
    1232                 :            : 
    1233                 :        132 :     uint16_t groups_count = 0;
    1234         [ +  + ]:        294 :     for (uint8_t i = 0; i < kem_preferences->tls13_kem_group_count; i++) {
    1235                 :        162 :         const struct s2n_kem_group *kem_group = kem_preferences->tls13_kem_groups[i];
    1236 [ -  + ][ #  # ]:        162 :         POSIX_ENSURE_REF(kem_group);
    1237         [ +  - ]:        162 :         if (!s2n_kem_group_is_available(kem_group)) {
    1238                 :        162 :             continue;
    1239                 :        162 :         }
    1240                 :            : 
    1241 [ #  # ][ #  # ]:          0 :         POSIX_ENSURE(groups_count < groups_count_max, S2N_ERR_INSUFFICIENT_MEM_SIZE);
    1242                 :          0 :         groups[groups_count] = kem_group->iana_id;
    1243                 :          0 :         groups_count += 1;
    1244                 :          0 :     }
    1245                 :            : 
    1246         [ +  + ]:        474 :     for (uint8_t i = 0; i < ecc_preferences->count; i++) {
    1247                 :        347 :         const struct s2n_ecc_named_curve *ecc_curve = ecc_preferences->ecc_curves[i];
    1248 [ -  + ][ #  # ]:        347 :         POSIX_ENSURE_REF(ecc_curve);
    1249                 :            : 
    1250 [ +  + ][ +  - ]:        347 :         POSIX_ENSURE(groups_count < groups_count_max, S2N_ERR_INSUFFICIENT_MEM_SIZE);
    1251                 :        342 :         groups[groups_count] = ecc_curve->iana_id;
    1252                 :        342 :         groups_count += 1;
    1253                 :        342 :     }
    1254                 :            : 
    1255                 :        127 :     *groups_count_out = groups_count;
    1256                 :            : 
    1257                 :        127 :     return S2N_SUCCESS;
    1258                 :        132 : }
    1259                 :            : 
    1260                 :            : int s2n_config_set_serialization_version(struct s2n_config *config, s2n_serialization_version version)
    1261                 :          8 : {
    1262 [ #  # ][ -  + ]:          8 :     POSIX_ENSURE_REF(config);
    1263                 :            : 
    1264                 :            :     /* This feature cannot be used with renegotiation currently */
    1265 [ +  + ][ +  - ]:          8 :     POSIX_ENSURE(config->renegotiate_request_cb == NULL, S2N_ERR_INVALID_STATE);
    1266                 :            : 
    1267                 :            :     /* Currently there is only one format version supported */
    1268 [ -  + ][ #  # ]:          7 :     POSIX_ENSURE_EQ(version, S2N_SERIALIZED_CONN_V1);
    1269                 :          7 :     config->serialized_connection_version = version;
    1270                 :            : 
    1271                 :          7 :     return S2N_SUCCESS;
    1272                 :          7 : }
    1273                 :            : 
    1274                 :            : int s2n_config_set_max_blinding_delay(struct s2n_config *config, uint32_t seconds)
    1275                 :         23 : {
    1276 [ -  + ][ #  # ]:         23 :     POSIX_ENSURE_REF(config);
    1277                 :            : 
    1278                 :         23 :     config->custom_blinding_set = 1;
    1279                 :         23 :     config->max_blinding = seconds;
    1280                 :            : 
    1281                 :         23 :     return S2N_SUCCESS;
    1282                 :         23 : }

Generated by: LCOV version 1.14