S2N_RESULT s2n_key_log_tls13_secret()

in tls/s2n_key_log.c [53:127]


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));

    struct s2n_blob client_random = { 0 };
    RESULT_GUARD_POSIX(s2n_blob_init(&client_random, conn->handshake_params.client_random,
            sizeof(conn->handshake_params.client_random)));

    RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(&output, label, label_size));
    RESULT_GUARD(s2n_stuffer_write_hex(&output, &client_random));
    RESULT_GUARD_POSIX(s2n_stuffer_write_uint8(&output, ' '));
    RESULT_GUARD(s2n_stuffer_write_hex(&output, secret));

    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;
}