LCOV - code coverage report
Current view: top level - tls - s2n_next_protocol.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 53 53 100.0 %
Date: 2025-08-15 07:28:39 Functions: 5 5 100.0 %
Branches: 40 84 47.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                 :            : #include "error/s2n_errno.h"
      17                 :            : #include "stuffer/s2n_stuffer.h"
      18                 :            : #include "tls/s2n_tls.h"
      19                 :            : #include "utils/s2n_safety.h"
      20                 :            : 
      21                 :            : S2N_RESULT s2n_calculate_padding(uint8_t protocol_len, uint8_t *padding_len)
      22                 :         19 : {
      23 [ #  # ][ -  + ]:         19 :     RESULT_ENSURE_REF(padding_len);
      24                 :            : 
      25                 :            :     /*
      26                 :            :      *= https://datatracker.ietf.org/doc/id/draft-agl-tls-nextprotoneg-03#section-3
      27                 :            :      *# The length of "padding" SHOULD be 32 - ((len(selected_protocol) + 2) % 32).
      28                 :            :      */
      29                 :         19 :     *padding_len = 32 - (((uint16_t) protocol_len + 2) % 32);
      30                 :         19 :     return S2N_RESULT_OK;
      31                 :         19 : }
      32                 :            : 
      33                 :            : S2N_RESULT s2n_write_npn_protocol(struct s2n_connection *conn, struct s2n_stuffer *out)
      34                 :          6 : {
      35 [ -  + ][ #  # ]:          6 :     RESULT_ENSURE_REF(conn);
      36                 :            : 
      37                 :          6 :     uint8_t protocol_len = strlen(conn->application_protocol);
      38         [ -  + ]:          6 :     RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, protocol_len));
      39         [ -  + ]:          6 :     RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(out, (uint8_t *) conn->application_protocol, protocol_len));
      40                 :            : 
      41                 :          6 :     uint8_t padding_len = 0;
      42         [ -  + ]:          6 :     RESULT_GUARD(s2n_calculate_padding(protocol_len, &padding_len));
      43         [ -  + ]:          6 :     RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(out, padding_len));
      44                 :          6 :     uint8_t *data_ptr = s2n_stuffer_raw_write(out, padding_len);
      45 [ -  + ][ #  # ]:          6 :     RESULT_ENSURE_REF(data_ptr);
      46 [ #  # ][ -  + ]:          6 :     RESULT_CHECKED_MEMSET(data_ptr, 0, padding_len);
                 [ +  - ]
      47                 :            : 
      48                 :          6 :     return S2N_RESULT_OK;
      49                 :          6 : }
      50                 :            : 
      51                 :            : S2N_RESULT s2n_read_npn_protocol(struct s2n_connection *conn, struct s2n_stuffer *in)
      52                 :          7 : {
      53 [ #  # ][ -  + ]:          7 :     RESULT_ENSURE_REF(conn);
      54                 :            : 
      55                 :          7 :     uint8_t protocol_len = 0;
      56         [ -  + ]:          7 :     RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &protocol_len));
      57                 :            : 
      58                 :          7 :     uint8_t *protocol = s2n_stuffer_raw_read(in, protocol_len);
      59 [ +  + ][ +  - ]:          7 :     RESULT_ENSURE_REF(protocol);
      60 [ -  + ][ #  # ]:          6 :     RESULT_CHECKED_MEMCPY(conn->application_protocol, protocol, protocol_len);
                 [ +  + ]
      61                 :          6 :     conn->application_protocol[protocol_len] = '\0';
      62                 :            : 
      63                 :          6 :     uint8_t expected_padding_len = 0;
      64         [ -  + ]:          6 :     RESULT_GUARD(s2n_calculate_padding(protocol_len, &expected_padding_len));
      65                 :          6 :     uint8_t padding_len = 0;
      66         [ -  + ]:          6 :     RESULT_GUARD_POSIX(s2n_stuffer_read_uint8(in, &padding_len));
      67 [ +  + ][ +  - ]:          6 :     RESULT_ENSURE_EQ(padding_len, expected_padding_len);
      68                 :            : 
      69                 :          5 :     uint8_t *data_ptr = s2n_stuffer_raw_read(in, padding_len);
      70 [ -  + ][ #  # ]:          5 :     RESULT_ENSURE_REF(data_ptr);
      71                 :          5 :     uint8_t empty_array[UINT8_MAX] = { 0 };
      72 [ -  + ][ #  # ]:          5 :     RESULT_ENSURE_EQ(s2n_constant_time_equals(data_ptr, empty_array, padding_len), 1);
      73                 :            : 
      74 [ -  + ][ #  # ]:          5 :     RESULT_ENSURE_EQ(s2n_stuffer_data_available(in), 0);
      75                 :            : 
      76                 :          5 :     return S2N_RESULT_OK;
      77                 :          5 : }
      78                 :            : 
      79                 :            : int s2n_next_protocol_send(struct s2n_connection *conn)
      80                 :          6 : {
      81 [ +  + ][ +  - ]:          6 :     POSIX_ENSURE_REF(conn);
      82 [ +  + ][ +  - ]:          5 :     POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE);
      83                 :            : 
      84                 :          4 :     struct s2n_stuffer *out = &conn->handshake.io;
      85         [ -  + ]:          4 :     POSIX_GUARD_RESULT(s2n_write_npn_protocol(conn, out));
      86                 :            : 
      87         [ -  + ]:          4 :     POSIX_GUARD_RESULT(s2n_crypto_parameters_switch(conn));
      88                 :            : 
      89                 :          4 :     return S2N_SUCCESS;
      90                 :          4 : }
      91                 :            : 
      92                 :            : int s2n_next_protocol_recv(struct s2n_connection *conn)
      93                 :          5 : {
      94 [ +  + ][ +  - ]:          5 :     POSIX_ENSURE_REF(conn);
      95 [ +  + ][ +  - ]:          4 :     POSIX_ENSURE(conn->actual_protocol_version < S2N_TLS13, S2N_ERR_BAD_MESSAGE);
      96                 :            : 
      97                 :          3 :     struct s2n_stuffer *in = &conn->handshake.io;
      98         [ -  + ]:          3 :     POSIX_GUARD_RESULT(s2n_read_npn_protocol(conn, in));
      99                 :            : 
     100                 :          3 :     return S2N_SUCCESS;
     101                 :          3 : }

Generated by: LCOV version 1.14