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