Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/messages_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
#include "messages_server.h"
#include "netconf.h"

extern struct nc_server_opts server_opts;

API struct nc_server_reply *
nc_server_reply_ok(void)
{
Expand Down
2 changes: 0 additions & 2 deletions src/server_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
#include "server_config_p.h"
#include "session_p.h"

extern struct nc_server_opts server_opts;

/* returns a parent node of 'node' that matches the name 'name' */
static const struct lyd_node *
nc_server_config_get_parent(const struct lyd_node *node, const char *name)
Expand Down
2 changes: 0 additions & 2 deletions src/server_config_ks.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
#include "server_config_p.h"
#include "session_p.h"

extern struct nc_server_opts server_opts;

/**
* @brief Get the pointer to an asymmetric key structure based on node's location in the YANG data.
*
Expand Down
2 changes: 0 additions & 2 deletions src/server_config_ts.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
#include "server_config_p.h"
#include "session_p.h"

extern struct nc_server_opts server_opts;

/**
* @brief Get the pointer to a certificate bag structure based on node's location in the YANG data.
*
Expand Down
2 changes: 0 additions & 2 deletions src/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@
/* in milliseconds */
#define NC_CLOSE_REPLY_TIMEOUT 200

extern struct nc_server_opts server_opts;

void
nc_timeouttime_get(struct timespec *ts, uint32_t add_ms)
{
Expand Down
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);
}
9 changes: 9 additions & 0 deletions src/session_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "session_server_ch.h"
#include "session_wrapper.h"

extern struct nc_server_opts server_opts;

/**
* Enumeration of diff operation types.
*/
Expand Down Expand Up @@ -625,6 +627,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 +689,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 @@
}
}

#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 @@
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_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
2 changes: 0 additions & 2 deletions src/session_server_ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@
#include "session_p.h"
#include "session_wrapper.h"

extern struct nc_server_opts server_opts;

/**
* @brief Stores the private key data as a temporary file.
*
Expand Down
9 changes: 6 additions & 3 deletions 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,9 +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
nc_server_tls_ks_ref_get_cert_key(const char *referenced_key_name, const char *referenced_cert_name,
char **privkey_data, enum nc_privkey_format *privkey_type, char **cert_data)
Expand Down Expand Up @@ -899,6 +897,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
7 changes: 7 additions & 0 deletions src/session_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,4 +732,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
Loading