LCOV - code coverage report
Current view: top level - tls - s2n_key_log.c (source / functions) Hit Total Coverage
Test: unit_test_coverage.info Lines: 85 91 93.4 %
Date: 2025-08-15 07:28:39 Functions: 2 2 100.0 %
Branches: 36 72 50.0 %

           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                 :            : /**
      17                 :            :  * This module implements key logging as defined by the NSS Key Log Format
      18                 :            :  *
      19                 :            :  * See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
      20                 :            :  *
      21                 :            :  * This key log file is a series of lines. Comment lines begin with a sharp
      22                 :            :  * character ('#') and are ignored. Secrets follow the format
      23                 :            :  * <Label> <space> <ClientRandom> <space> <Secret> where:
      24                 :            :  *
      25                 :            :  *   <Label> describes the following secret.
      26                 :            :  *   <ClientRandom> is 32 bytes Random value from the Client Hello message, encoded as 64 hexadecimal characters.
      27                 :            :  *   <Secret> depends on the Label (see below).
      28                 :            :  *
      29                 :            :  * The following labels are defined, followed by a description of the secret:
      30                 :            :  *
      31                 :            :  *   RSA: 48 bytes for the premaster secret, encoded as 96 hexadecimal characters (removed in NSS 3.34)
      32                 :            :  *   CLIENT_RANDOM: 48 bytes for the master secret, encoded as 96 hexadecimal characters (for SSL 3.0, TLS 1.0, 1.1 and 1.2)
      33                 :            :  *   CLIENT_EARLY_TRAFFIC_SECRET: the hex-encoded early traffic secret for the client side (for TLS 1.3)
      34                 :            :  *   CLIENT_HANDSHAKE_TRAFFIC_SECRET: the hex-encoded handshake traffic secret for the client side (for TLS 1.3)
      35                 :            :  *   SERVER_HANDSHAKE_TRAFFIC_SECRET: the hex-encoded handshake traffic secret for the server side (for TLS 1.3)
      36                 :            :  *   CLIENT_TRAFFIC_SECRET_0: the first hex-encoded application traffic secret for the client side (for TLS 1.3)
      37                 :            :  *   SERVER_TRAFFIC_SECRET_0: the first hex-encoded application traffic secret for the server side (for TLS 1.3)
      38                 :            :  *   EARLY_EXPORTER_SECRET: the hex-encoded early exporter secret (for TLS 1.3).
      39                 :            :  *   EXPORTER_SECRET: the hex-encoded exporter secret (for TLS 1.3)
      40                 :            :  */
      41                 :            : 
      42                 :            : #include "api/s2n.h"
      43                 :            : #include "tls/s2n_config.h"
      44                 :            : #include "tls/s2n_connection.h"
      45                 :            : #include "tls/s2n_crypto_constants.h"
      46                 :            : #include "tls/s2n_quic_support.h" /* this currently holds the s2n_secret_type_t enum */
      47                 :            : #include "utils/s2n_blob.h"
      48                 :            : #include "utils/s2n_safety.h"
      49                 :            : 
      50                 :            : /* hex requires 2 chars per byte */
      51                 :         24 : #define HEX_ENCODING_SIZE 2
      52                 :            : 
      53                 :            : S2N_RESULT s2n_key_log_tls13_secret(struct s2n_connection *conn, const struct s2n_blob *secret, s2n_secret_type_t secret_type)
      54                 :      37918 : {
      55 [ -  + ][ #  # ]:      37918 :     RESULT_ENSURE_REF(conn);
      56 [ #  # ][ -  + ]:      37918 :     RESULT_ENSURE_REF(conn->config);
      57 [ -  + ][ #  # ]:      37918 :     RESULT_ENSURE_REF(secret);
      58                 :            : 
      59                 :            :     /* only emit keys if the callback has been set */
      60         [ +  + ]:      37918 :     if (!conn->config->key_log_cb) {
      61                 :      37908 :         return S2N_RESULT_OK;
      62                 :      37908 :     }
      63                 :            : 
      64                 :         10 :     const uint8_t client_early_traffic_label[] = "CLIENT_EARLY_TRAFFIC_SECRET ";
      65                 :         10 :     const uint8_t client_handshake_label[] = "CLIENT_HANDSHAKE_TRAFFIC_SECRET ";
      66                 :         10 :     const uint8_t server_handshake_label[] = "SERVER_HANDSHAKE_TRAFFIC_SECRET ";
      67                 :         10 :     const uint8_t client_traffic_label[] = "CLIENT_TRAFFIC_SECRET_0 ";
      68                 :         10 :     const uint8_t server_traffic_label[] = "SERVER_TRAFFIC_SECRET_0 ";
      69                 :         10 :     const uint8_t exporter_secret_label[] = "EXPORTER_SECRET ";
      70                 :            : 
      71                 :         10 :     const uint8_t *label = NULL;
      72                 :         10 :     uint8_t label_size = 0;
      73                 :            : 
      74                 :         10 :     switch (secret_type) {
      75         [ -  + ]:          0 :         case S2N_CLIENT_EARLY_TRAFFIC_SECRET:
      76                 :          0 :             label = client_early_traffic_label;
      77                 :          0 :             label_size = sizeof(client_early_traffic_label) - 1;
      78                 :          0 :             break;
      79         [ +  + ]:          2 :         case S2N_CLIENT_HANDSHAKE_TRAFFIC_SECRET:
      80                 :          2 :             label = client_handshake_label;
      81                 :          2 :             label_size = sizeof(client_handshake_label) - 1;
      82                 :          2 :             break;
      83         [ +  + ]:          2 :         case S2N_SERVER_HANDSHAKE_TRAFFIC_SECRET:
      84                 :          2 :             label = server_handshake_label;
      85                 :          2 :             label_size = sizeof(server_handshake_label) - 1;
      86                 :          2 :             break;
      87         [ +  + ]:          2 :         case S2N_CLIENT_APPLICATION_TRAFFIC_SECRET:
      88                 :          2 :             label = client_traffic_label;
      89                 :          2 :             label_size = sizeof(client_traffic_label) - 1;
      90                 :          2 :             break;
      91         [ +  + ]:          2 :         case S2N_SERVER_APPLICATION_TRAFFIC_SECRET:
      92                 :          2 :             label = server_traffic_label;
      93                 :          2 :             label_size = sizeof(server_traffic_label) - 1;
      94                 :          2 :             break;
      95         [ +  + ]:          2 :         case S2N_EXPORTER_SECRET:
      96                 :          2 :             label = exporter_secret_label;
      97                 :          2 :             label_size = sizeof(exporter_secret_label) - 1;
      98                 :          2 :             break;
      99         [ -  + ]:          0 :         default:
     100                 :            :             /* Ignore the secret types we don't understand */
     101                 :          0 :             return S2N_RESULT_OK;
     102                 :         10 :     }
     103                 :            : 
     104                 :         10 :     const uint8_t len = label_size
     105                 :         10 :             + S2N_TLS_RANDOM_DATA_LEN * HEX_ENCODING_SIZE
     106                 :         10 :             + 1 /* SPACE */
     107                 :         10 :             + secret->size * HEX_ENCODING_SIZE;
     108                 :            : 
     109                 :         10 :     DEFER_CLEANUP(struct s2n_stuffer output, s2n_stuffer_free);
     110         [ -  + ]:         10 :     RESULT_GUARD_POSIX(s2n_stuffer_alloc(&output, len));
     111                 :            : 
     112                 :         10 :     struct s2n_blob client_random = { 0 };
     113         [ -  + ]:         10 :     RESULT_GUARD_POSIX(s2n_blob_init(&client_random, conn->handshake_params.client_random,
     114                 :         10 :             sizeof(conn->handshake_params.client_random)));
     115                 :            : 
     116         [ -  + ]:         10 :     RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(&output, label, label_size));
     117         [ -  + ]:         10 :     RESULT_GUARD(s2n_stuffer_write_hex(&output, &client_random));
     118         [ -  + ]:         10 :     RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(&output, ' '));
     119         [ -  + ]:         10 :     RESULT_GUARD(s2n_stuffer_write_hex(&output, secret));
     120                 :            : 
     121                 :         10 :     uint8_t *data = s2n_stuffer_raw_read(&output, len);
     122 [ -  + ][ #  # ]:         10 :     RESULT_ENSURE_REF(data);
     123                 :            : 
     124                 :         10 :     conn->config->key_log_cb(conn->config->key_log_ctx, conn, data, len);
     125                 :            : 
     126                 :         10 :     return S2N_RESULT_OK;
     127                 :         10 : }
     128                 :            : 
     129                 :            : S2N_RESULT s2n_key_log_tls12_secret(struct s2n_connection *conn)
     130                 :       4440 : {
     131 [ -  + ][ #  # ]:       4440 :     RESULT_ENSURE_REF(conn);
     132 [ #  # ][ -  + ]:       4440 :     RESULT_ENSURE_REF(conn->config);
     133                 :            : 
     134                 :            :     /* only emit keys if the callback has been set */
     135         [ +  + ]:       4440 :     if (!conn->config->key_log_cb) {
     136                 :       4438 :         return S2N_RESULT_OK;
     137                 :       4438 :     }
     138                 :            : 
     139                 :            :     /* CLIENT_RANDOM: 48 bytes for the master secret, encoded as 96 hexadecimal characters (for SSL 3.0, TLS 1.0, 1.1 and 1.2) */
     140                 :          2 :     const uint8_t label[] = "CLIENT_RANDOM ";
     141                 :          2 :     const uint8_t label_size = sizeof(label) - 1;
     142                 :            : 
     143                 :          2 :     const uint8_t len = label_size
     144                 :          2 :             + S2N_TLS_RANDOM_DATA_LEN * HEX_ENCODING_SIZE
     145                 :          2 :             + 1 /* SPACE */
     146                 :          2 :             + S2N_TLS_SECRET_LEN * HEX_ENCODING_SIZE;
     147                 :            : 
     148                 :          2 :     DEFER_CLEANUP(struct s2n_stuffer output, s2n_stuffer_free);
     149         [ -  + ]:          2 :     RESULT_GUARD_POSIX(s2n_stuffer_alloc(&output, len));
     150                 :            : 
     151                 :          2 :     struct s2n_blob client_random = { 0 };
     152         [ -  + ]:          2 :     RESULT_GUARD_POSIX(s2n_blob_init(&client_random, conn->handshake_params.client_random,
     153                 :          2 :             sizeof(conn->handshake_params.client_random)));
     154                 :            : 
     155                 :          2 :     struct s2n_blob master_secret = { 0 };
     156         [ -  + ]:          2 :     RESULT_GUARD_POSIX(s2n_blob_init(&master_secret, conn->secrets.version.tls12.master_secret,
     157                 :          2 :             sizeof(conn->secrets.version.tls12.master_secret)));
     158                 :            : 
     159         [ -  + ]:          2 :     RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(&output, label, label_size));
     160         [ -  + ]:          2 :     RESULT_GUARD(s2n_stuffer_write_hex(&output, &client_random));
     161         [ -  + ]:          2 :     RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(&output, ' '));
     162         [ -  + ]:          2 :     RESULT_GUARD(s2n_stuffer_write_hex(&output, &master_secret));
     163                 :            : 
     164                 :          2 :     uint8_t *data = s2n_stuffer_raw_read(&output, len);
     165 [ -  + ][ #  # ]:          2 :     RESULT_ENSURE_REF(data);
     166                 :            : 
     167                 :          2 :     conn->config->key_log_cb(conn->config->key_log_ctx, conn, data, len);
     168                 :            : 
     169                 :          2 :     return S2N_RESULT_OK;
     170                 :          2 : }

Generated by: LCOV version 1.14