LCOV - code coverage report
Current view: top level - tls - s2n_policy_writer.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 110 128 85.9 %
Date: 2026-08-22 07:27:53 Functions: 5 5 100.0 %
Branches: 100 182 54.9 %

           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                 :            : #include "tls/s2n_policy_writer.h"
      17                 :            : 
      18                 :            : #include <stdarg.h>
      19                 :            : #include <stdio.h>
      20                 :            : #include <unistd.h>
      21                 :            : 
      22                 :            : #include "stuffer/s2n_stuffer.h"
      23                 :            : #include "tls/s2n_security_policies.h"
      24                 :            : #include "tls/s2n_security_rules.h"
      25                 :            : #include "utils/s2n_safety.h"
      26                 :            : 
      27                 :            : #define BOOL_STR(b) ((b) ? "yes" : "no")
      28                 :            : 
      29                 :            : extern const struct s2n_security_rule security_rule_definitions[S2N_SECURITY_RULES_COUNT];
      30                 :            : 
      31                 :            : static const char *version_strs[] = {
      32                 :            :     [S2N_SSLv2] = "SSLv2",
      33                 :            :     [S2N_SSLv3] = "SSLv3",
      34                 :            :     [S2N_TLS10] = "TLS1.0",
      35                 :            :     [S2N_TLS11] = "TLS1.1",
      36                 :            :     [S2N_TLS12] = "TLS1.2",
      37                 :            :     [S2N_TLS13] = "TLS1.3",
      38                 :            : };
      39                 :            : 
      40                 :            : static S2N_RESULT s2n_security_policy_write_format_v1_to_stuffer(const struct s2n_security_policy *policy, struct s2n_stuffer *stuffer)
      41                 :         32 : {
      42 [ -  + ][ #  # ]:         32 :     RESULT_ENSURE_REF(policy);
      43 [ -  + ][ #  # ]:         32 :     RESULT_ENSURE_REF(stuffer);
      44                 :            : 
      45                 :         32 :     const char *version_str = NULL;
      46         [ +  - ]:         32 :     if (policy->minimum_protocol_version <= S2N_TLS13) {
      47                 :         32 :         version_str = version_strs[policy->minimum_protocol_version];
      48                 :         32 :     }
      49 [ -  + ][ +  - ]:         32 :     RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "min version: %s\n", version_str ? version_str : "None"));
      50                 :            : 
      51         [ -  + ]:         32 :     RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "rules:\n"));
      52         [ +  + ]:         96 :     for (size_t i = 0; i < S2N_SECURITY_RULES_COUNT; i++) {
      53 [ -  + ][ +  + ]:         64 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s: %s\n",
      54                 :         64 :                 security_rule_definitions[i].name, BOOL_STR(policy->rules[i])));
      55                 :         64 :     }
      56                 :            : 
      57         [ -  + ]:         32 :     RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "cipher suites:\n"));
      58         [ -  + ]:         32 :     if (policy->cipher_preferences->allow_chacha20_boosting) {
      59         [ #  # ]:          0 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- chacha20 boosting enabled\n"));
      60                 :          0 :     }
      61         [ +  + ]:        395 :     for (size_t i = 0; i < policy->cipher_preferences->count; i++) {
      62         [ -  + ]:        363 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s\n", policy->cipher_preferences->suites[i]->iana_name));
      63                 :        363 :     }
      64                 :            : 
      65         [ -  + ]:         32 :     RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "signature schemes:\n"));
      66         [ +  + ]:        496 :     for (size_t i = 0; i < policy->signature_preferences->count; i++) {
      67         [ -  + ]:        464 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s\n", policy->signature_preferences->signature_schemes[i]->name));
      68                 :        464 :     }
      69                 :            : 
      70         [ -  + ]:         32 :     RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "curves:\n"));
      71         [ +  + ]:        155 :     for (size_t i = 0; i < policy->ecc_preferences->count; i++) {
      72         [ -  + ]:        123 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s\n", policy->ecc_preferences->ecc_curves[i]->name));
      73                 :        123 :     }
      74                 :            : 
      75 [ +  + ][ +  + ]:         36 :     for (size_t i = 0; policy->strongly_preferred_groups != NULL && i < policy->strongly_preferred_groups->count; i++) {
      76         [ -  + ]:          4 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "strongly preferred groups:\n"));
      77                 :          4 :         const struct s2n_ecc_named_curve *strongly_preferred_curve = NULL;
      78                 :          4 :         const struct s2n_kem_group *strongly_preferred_kem_group = NULL;
      79                 :          4 :         bool found = false;
      80         [ -  + ]:          4 :         RESULT_GUARD_POSIX(s2n_find_ecc_curve_from_iana_id(policy->strongly_preferred_groups->iana_ids[i], &strongly_preferred_curve, &found));
      81         [ -  + ]:          4 :         RESULT_GUARD_POSIX(s2n_find_kem_group_from_iana_id(policy->strongly_preferred_groups->iana_ids[i], &strongly_preferred_kem_group, &found));
      82 [ #  # ][ -  + ]:          4 :         RESULT_ENSURE((strongly_preferred_curve == NULL) != (strongly_preferred_kem_group == NULL), S2N_ERR_INVALID_SUPPORTED_GROUP_STATE);
      83                 :            : 
      84         [ +  - ]:          4 :         if (strongly_preferred_curve != NULL) {
      85         [ -  + ]:          4 :             RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s\n", strongly_preferred_curve->name));
      86                 :          4 :         }
      87                 :            : 
      88         [ -  + ]:          4 :         if (strongly_preferred_kem_group != NULL) {
      89         [ #  # ]:          0 :             RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s\n", strongly_preferred_kem_group->name));
      90                 :          0 :         }
      91                 :          4 :     }
      92                 :            : 
      93         [ +  + ]:         32 :     if (policy->certificate_signature_preferences) {
      94         [ -  + ]:         10 :         if (policy->certificate_preferences_apply_locally) {
      95         [ #  # ]:          0 :             RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "certificate preferences apply locally\n"));
      96                 :          0 :         }
      97         [ -  + ]:         10 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "certificate signature schemes:\n"));
      98         [ +  + ]:        142 :         for (size_t i = 0; i < policy->certificate_signature_preferences->count; i++) {
      99         [ -  + ]:        132 :             RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s\n",
     100                 :        132 :                     policy->certificate_signature_preferences->signature_schemes[i]->name));
     101                 :        132 :         }
     102                 :         10 :     }
     103                 :            : 
     104         [ -  + ]:         32 :     if (policy->certificate_key_preferences) {
     105         [ #  # ]:          0 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "certificate keys:\n"));
     106         [ #  # ]:          0 :         for (size_t i = 0; i < policy->certificate_key_preferences->count; i++) {
     107         [ #  # ]:          0 :             RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- %s\n",
     108                 :          0 :                     policy->certificate_key_preferences->certificate_keys[i]->name));
     109                 :          0 :         }
     110                 :          0 :     }
     111                 :            : 
     112 [ +  - ][ +  + ]:         32 :     if (policy->kem_preferences && policy->kem_preferences != &kem_preferences_null) {
     113         [ -  + ]:         20 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "pq:\n"));
     114         [ -  + ]:         20 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- revision: %i\n",
     115                 :         20 :                 policy->kem_preferences->tls13_pq_hybrid_draft_revision));
     116                 :            : 
     117         [ -  + ]:         20 :         if (policy->kem_preferences->kem_count > 0) {
     118         [ #  # ]:          0 :             RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- kems:\n"));
     119         [ #  # ]:          0 :             for (size_t i = 0; i < policy->kem_preferences->kem_count; i++) {
     120         [ #  # ]:          0 :                 RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "-- %s\n",
     121                 :          0 :                         policy->kem_preferences->kems[i]->name));
     122                 :          0 :             }
     123                 :          0 :         }
     124                 :            : 
     125         [ -  + ]:         20 :         RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "- kem groups:\n"));
     126         [ +  + ]:         65 :         for (size_t i = 0; i < policy->kem_preferences->tls13_kem_group_count; i++) {
     127         [ -  + ]:         45 :             RESULT_GUARD_POSIX(s2n_stuffer_printf(stuffer, "-- %s\n",
     128                 :         45 :                     policy->kem_preferences->tls13_kem_groups[i]->name));
     129                 :         45 :         }
     130                 :         20 :     }
     131                 :            : 
     132                 :         32 :     return S2N_RESULT_OK;
     133                 :         32 : }
     134                 :            : 
     135                 :            : static S2N_RESULT s2n_security_policy_write_to_stuffer(const struct s2n_security_policy *policy,
     136                 :            :         s2n_policy_format format, struct s2n_stuffer *stuffer)
     137                 :         35 : {
     138 [ -  + ][ #  # ]:         35 :     RESULT_ENSURE_REF(policy);
     139 [ #  # ][ -  + ]:         35 :     RESULT_ENSURE_REF(stuffer);
     140                 :            : 
     141                 :         35 :     switch (format) {
     142         [ +  + ]:         32 :         case S2N_POLICY_FORMAT_DEBUG_V1:
     143         [ -  + ]:         32 :             RESULT_GUARD(s2n_security_policy_write_format_v1_to_stuffer(policy, stuffer));
     144                 :         32 :             break;
     145         [ +  + ]:         32 :         default:
     146         [ +  - ]:          3 :             RESULT_BAIL(S2N_ERR_INVALID_ARGUMENT);
     147                 :         35 :     }
     148                 :            : 
     149                 :         32 :     return S2N_RESULT_OK;
     150                 :         35 : }
     151                 :            : 
     152                 :            : int s2n_security_policy_write_length(const struct s2n_security_policy *policy,
     153                 :            :         s2n_policy_format format, uint32_t *length)
     154                 :          6 : {
     155 [ +  + ][ +  - ]:          6 :     POSIX_ENSURE_REF(policy);
     156 [ +  - ][ +  + ]:          5 :     POSIX_ENSURE_REF(length);
     157                 :            : 
     158                 :          4 :     DEFER_CLEANUP(struct s2n_stuffer stuffer = { 0 }, s2n_stuffer_free);
     159         [ -  + ]:          4 :     POSIX_GUARD(s2n_stuffer_growable_alloc(&stuffer, 1024));
     160                 :            : 
     161         [ +  + ]:          4 :     POSIX_GUARD_RESULT(s2n_security_policy_write_to_stuffer(policy, format, &stuffer));
     162                 :            : 
     163                 :          3 :     *length = s2n_stuffer_data_available(&stuffer);
     164                 :            : 
     165                 :          3 :     return S2N_SUCCESS;
     166                 :          4 : }
     167                 :            : 
     168                 :            : int s2n_security_policy_write_bytes(const struct s2n_security_policy *policy,
     169                 :            :         s2n_policy_format format, uint8_t *buffer, uint32_t buffer_length, uint32_t *output_size)
     170                 :          8 : {
     171 [ +  - ][ +  + ]:          8 :     POSIX_ENSURE_REF(policy);
     172 [ +  + ][ +  - ]:          7 :     POSIX_ENSURE_REF(buffer);
     173 [ +  - ][ +  + ]:          6 :     POSIX_ENSURE_REF(output_size);
     174                 :          5 :     *output_size = 0;
     175                 :            : 
     176                 :            :     /* Intermediate stuffer is needed because s2n_stuffer_printf requires temporary space for null 
     177                 :            :      * terminators. We cannot write directly to application memory which may not have the extra byte
     178                 :            :      * available 
     179                 :            :      */
     180                 :          5 :     DEFER_CLEANUP(struct s2n_stuffer stuffer = { 0 }, s2n_stuffer_free);
     181         [ -  + ]:          5 :     POSIX_GUARD(s2n_stuffer_growable_alloc(&stuffer, 1024));
     182         [ +  + ]:          5 :     POSIX_GUARD_RESULT(s2n_security_policy_write_to_stuffer(policy, format, &stuffer));
     183                 :          4 :     uint32_t required_size = s2n_stuffer_data_available(&stuffer);
     184 [ +  + ][ +  - ]:          4 :     POSIX_ENSURE(buffer_length >= required_size, S2N_ERR_INSUFFICIENT_MEM_SIZE);
     185                 :            : 
     186 [ #  # ][ -  + ]:          2 :     POSIX_CHECKED_MEMCPY(buffer, stuffer.blob.data, required_size);
                 [ +  - ]
     187                 :          2 :     *output_size = s2n_stuffer_data_available(&stuffer);
     188                 :          2 :     return S2N_SUCCESS;
     189                 :          2 : }
     190                 :            : 
     191                 :            : int s2n_security_policy_write_fd(const struct s2n_security_policy *policy,
     192                 :            :         s2n_policy_format format, int fd, uint32_t *output_size)
     193                 :         29 : {
     194 [ +  + ][ +  - ]:         29 :     POSIX_ENSURE_REF(policy);
     195 [ +  - ][ +  + ]:         28 :     POSIX_ENSURE_REF(output_size);
     196 [ +  + ][ +  - ]:         27 :     POSIX_ENSURE(fd >= 0, S2N_ERR_INVALID_ARGUMENT);
     197                 :         26 :     *output_size = 0;
     198                 :            : 
     199                 :         26 :     DEFER_CLEANUP(struct s2n_stuffer stuffer = { 0 }, s2n_stuffer_free);
     200         [ -  + ]:         26 :     POSIX_GUARD(s2n_stuffer_growable_alloc(&stuffer, 1024));
     201                 :            : 
     202         [ +  + ]:         26 :     POSIX_GUARD_RESULT(s2n_security_policy_write_to_stuffer(policy, format, &stuffer));
     203                 :            : 
     204                 :         25 :     uint32_t data_size = s2n_stuffer_data_available(&stuffer);
     205                 :         25 :     ssize_t written = write(fd, stuffer.blob.data, data_size);
     206 [ #  # ][ -  + ]:         25 :     POSIX_ENSURE(written == (ssize_t) data_size, S2N_ERR_IO);
     207                 :            : 
     208                 :         25 :     *output_size = (uint32_t) written;
     209                 :         25 :     return S2N_SUCCESS;
     210                 :         25 : }

Generated by: LCOV version 1.14