LCOV - code coverage report
Current view: top level - tls - s2n_config.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 770 851 90.5 %
Date: 2025-12-31 08:28:16 Functions: 84 88 95.5 %
Branches: 410 880 46.6 %

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

Generated by: LCOV version 1.14