Skip to content

Commit

Permalink
session server tls UPDATE add tls keylog support
Browse files Browse the repository at this point in the history
Resolves CESNET#517
  • Loading branch information
roman committed Nov 15, 2024
1 parent acfb5cb commit 5783373
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 1 deletion.
89 changes: 89 additions & 0 deletions src/session_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <ctype.h>
#include <errno.h>
#include <poll.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -1923,3 +1924,91 @@ nc_tls_get_cert_exp_time_wrap(void *cert)

return timegm(&t);
}

/**
* @brief Convert the MbedTLS key export type to a label for the keylog file.
*
* @param[in] type MbedTLS key export type.
* @return Label for the keylog file or NULL if the type is not supported.
*/
static const char *
nc_tls_keylog_type2label(mbedtls_ssl_key_export_type type)
{
switch (type) {
case MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET:
return "CLIENT_RANDOM";
#ifdef MBEDTLS_SSL_PROTO_TLS1_3
case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET:
return "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET:
return "SERVER_HANDSHAKE_TRAFFIC_SECRET";
case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET:
return "CLIENT_TRAFFIC_SECRET_0";
case MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET:
return "SERVER_TRAFFIC_SECRET_0";
#endif
default:
return NULL;
}
}

/**
* @brief Callback for writing a line in the keylog file.
*/
static void
nc_tls_keylog_write_line(void *UNUSED(p_expkey), mbedtls_ssl_key_export_type type, const unsigned char *secret,
size_t secret_len, const unsigned char client_random[32],
const unsigned char UNUSED(server_random[32]), mbedtls_tls_prf_types UNUSED(tls_prf_type))
{
size_t linelen, len = 0, i, client_random_len;
char buf[256];
const char *label;

if (!server_opts.tls_keylog_file) {
return;
}

label = nc_tls_keylog_type2label(type);
if (!label) {
/* type not supported */
return;
}

/* <Label> <space> 0x<ClientRandom> <space> 0x<Secret> */
linelen = strlen(label) + 1 + 2 * 32 + 1 + 2 * secret_len + 1;
if (linelen > sizeof(buf)) {
/* sanity check, should not happen since the max len should be 196 bytes */
return;
}

/* write the label */
len += sprintf(buf + len, "%s ", label);

/* write the client random */
client_random_len = 32;
for (i = 0; i < client_random_len; i++) {
len += sprintf(buf + len, "%02x", client_random[i]);
}
len += sprintf(buf + len, " ");

/* write the secret */
for (i = 0; i < secret_len; i++) {
len += sprintf(buf + len, "%02x", secret[i]);
}

len += sprintf(buf + len, "\n");
buf[len] = '\0';

if (len != linelen) {
return;
}

fputs(buf, server_opts.tls_keylog_file);
fflush(server_opts.tls_keylog_file);
}

void
nc_tls_keylog_session_wrap(void *session)
{
mbedtls_ssl_set_export_keys_cb(session, nc_tls_keylog_write_line, NULL);
}
43 changes: 43 additions & 0 deletions src/session_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <ctype.h>
#include <poll.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -1449,3 +1450,45 @@ nc_tls_get_cert_exp_time_wrap(void *cert)

return timegm(&t);
}

/**
* @brief Callback for writing a line in the keylog file.
*/
static void
nc_tls_keylog_write_line(const SSL *UNUSED(ssl), const char *line)
{
size_t linelen;
char buf[256];

if (!server_opts.tls_keylog_file || !line) {
return;
}

/* linelen should not exceed 196 bytes, so 256 should be enough */
linelen = strlen(line);
if (!linelen || (linelen > sizeof(buf) - 2)) {
return;
}

memcpy(buf, line, linelen);
if (line[linelen - 1] != '\n') {
buf[linelen++] = '\n';
}
buf[linelen] = '\0';

fputs(buf, server_opts.tls_keylog_file);
fflush(server_opts.tls_keylog_file);
}

void
nc_tls_keylog_session_wrap(void *session)
{
SSL_CTX *ctx;

ctx = SSL_get_SSL_CTX(session);
if (!ctx) {
return;
}

SSL_CTX_set_keylog_callback(ctx, nc_tls_keylog_write_line);
}
7 changes: 7 additions & 0 deletions src/session_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,8 @@ struct nc_server_opts {
} *intervals;
int interval_count; /**< Number of intervals. */
} cert_exp_notif;

FILE *tls_keylog_file; /**< File to log TLS secrets to. */
#endif
};

Expand Down Expand Up @@ -685,6 +687,11 @@ struct nc_server_opts {
*/
#define NC_CLIENT_MONITORING_LOCK_TIMEOUT 500

/**
* TLS key log file environment variable name.
*/
#define NC_TLS_KEYLOGFILE_ENV "SSLKEYLOGFILE"

/**
* @brief Type of the session
*/
Expand Down
31 changes: 31 additions & 0 deletions src/session_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,29 @@ nc_server_init_cb_ctx(const struct ly_ctx *ctx)
}
}

#ifdef NC_ENABLED_SSH_TLS

/**
* @brief Open the keylog file for writing TLS secrets.
*/
static void
nc_server_keylog_file_open(void)
{
char *keylog_file_name;

keylog_file_name = getenv(NC_TLS_KEYLOGFILE_ENV);
if (!keylog_file_name) {
return;
}

server_opts.tls_keylog_file = fopen(keylog_file_name, "a");
if (!server_opts.tls_keylog_file) {
WRN(NULL, "Failed to open keylog file \"%s\".", keylog_file_name);
}
}

#endif

API int
nc_server_init(void)
{
Expand Down Expand Up @@ -858,6 +881,9 @@ nc_server_init(void)
ERR(NULL, "%s: failed to init certificate expiration notification thread condition(%s).", __func__, strerror(r));
goto error;
}

/* try to open the keylog file for writing TLS secrets */
nc_server_keylog_file_open();
#endif

return 0;
Expand Down Expand Up @@ -917,6 +943,11 @@ nc_server_destroy(void)
nc_server_config_ts_truststore(NULL, NC_OP_DELETE);
curl_global_cleanup();
ssh_finalize();

/* close the TLS keylog file */
if (server_opts.tls_keylog_file) {
fclose(server_opts.tls_keylog_file);
}
#endif /* NC_ENABLED_SSH_TLS */
}

Expand Down
7 changes: 6 additions & 1 deletion src/session_server_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#define _GNU_SOURCE

#include <errno.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
Expand All @@ -32,7 +33,6 @@
#include "session_p.h"
#include "session_wrapper.h"

struct nc_server_tls_opts tls_ch_opts;
extern struct nc_server_opts server_opts;

static int
Expand Down Expand Up @@ -899,6 +899,11 @@ nc_accept_tls_session(struct nc_session *session, struct nc_server_tls_opts *opt
goto fail;
}

/* if keylog file is set, log the tls secrets there */
if (server_opts.tls_keylog_file) {
nc_tls_keylog_session_wrap(session->ti.tls.session);
}

/* set session fd */
nc_tls_set_fd_wrap(session->ti.tls.session, sock, &session->ti.tls.ctx);

Expand Down
9 changes: 9 additions & 0 deletions src/session_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ struct nc_tls_verify_cb_data {
void *chain; /**< Certificate chain used to verify the client cert. */
};

extern struct nc_server_opts server_opts;

/**
* @brief Creates a new TLS session from the given configuration.
*
Expand Down Expand Up @@ -732,4 +734,11 @@ void nc_server_tls_set_cipher_suites_wrap(void *tls_cfg, void *cipher_suites);
*/
time_t nc_tls_get_cert_exp_time_wrap(void *cert);

/**
* @brief Set the session to log TLS secrets for.
*
* @param[in] session Session to log secrets for.
*/
void nc_tls_keylog_session_wrap(void *session);

#endif

0 comments on commit 5783373

Please sign in to comment.