LCOV - code coverage report
Current view: top level - tls/policy - s2n_policy_writer.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 90 113 79.6 %
Date: 2025-11-15 08:28:27 Functions: 5 5 100.0 %
Branches: 82 160 51.2 %

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

Generated by: LCOV version 1.14