Skip to content

Commit

Permalink
Add Keylog file with env variable SSLKEYLOGFILE (for openssl)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gael COLIN committed Nov 6, 2024
1 parent 53c97bc commit 7f436ae
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
73 changes: 73 additions & 0 deletions src/session_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,73 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#define SSLKEYLOGFILE_ENV "SSLKEYLOGFILE"
/* The fp for the open SSLKEYLOGFILE, or NULL if not open */
FILE *keylog_file_fp = NULL;
uint32_t active_sessions = 0;

FILE*
nc_tls_keylog_open(void)
{
char *keylog_file_name = getenv(SSLKEYLOGFILE_ENV);

if (keylog_file_name) {
active_sessions++;
if (!keylog_file_fp) {
keylog_file_fp = fopen(keylog_file_name, "a");
if (keylog_file_fp) {
if (setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) {
fclose(keylog_file_fp);
keylog_file_fp = NULL;
}
}
}
}
return keylog_file_fp;
}

void
nc_tls_keylog_close(void)
{
char *keylog_file_name = getenv(SSLKEYLOGFILE_ENV);
if (keylog_file_name) {
active_sessions--;
if (active_sessions == 0) {
fclose(keylog_file_fp);
keylog_file_fp = NULL;
}
}
}

void
nc_tls_keylog_write_line(const SSL *UNUSED(ssl), const char *line)
{
/* The current maximum valid keylog line length LF and NUL is 195. */
size_t linelen;
char buf[256];

if (!keylog_file_fp || !line) {
return;
}

linelen = strlen(line);
if ((linelen == 0) || (linelen > sizeof(buf) - 2)) {
/* Empty line or too big to fit in a LF and NUL. */
return;
}

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

/* Using fputs here instead of fprintf since libcurl's fprintf replacement
may not be thread-safe. */
fputs(buf, keylog_file_fp);
return;
}

void *
nc_tls_session_new_wrap(void *tls_cfg)
{
Expand All @@ -54,13 +121,19 @@ nc_tls_session_new_wrap(void *tls_cfg)
return NULL;
}

if (nc_tls_keylog_open()) {
SSL_CTX_set_keylog_callback(tls_cfg, nc_tls_keylog_write_line);
}

return session;
}

void
nc_tls_session_destroy_wrap(void *tls_session)
{
SSL_free(tls_session);

nc_tls_keylog_close();
}

void *
Expand Down
45 changes: 45 additions & 0 deletions tests/test_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

int TEST_PORT = 10050;
const char *TEST_PORT_STR = "10050";
const char *KEYLOG_FILE = "keylog.txt";

static void *
client_thread(void *arg)
Expand Down Expand Up @@ -54,6 +55,45 @@ client_thread(void *arg)
return NULL;
}

#ifndef HAVE_MBEDTLS

/** test keylog.txt file */
static void
assert_keylog_file()
{
fprintf(stderr, "Checking keylog file\n");
FILE *file;
char line[256];
const char *lines_types[] = {
"SERVER_HANDSHAKE_TRAFFIC_SECRET",
"CLIENT_HANDSHAKE_TRAFFIC_SECRET",
"EXPORTER_SECRET",
"SERVER_TRAFFIC_SECRET_0",
"CLIENT_TRAFFIC_SECRET_0"
};
int lines_types_count[] = {0, 0, 0, 0, 0};

file = fopen(KEYLOG_FILE, "r");
assert_non_null(file);

while (fgets(line, sizeof(line), file)) {
assert_true(strlen(line) > 32);
for (int i = 0; i < 5; i++) {
if (strncmp(line, lines_types[i], strlen(lines_types[i])) == 0) {
lines_types_count[i]++;
}
}
}
for (int i = 0; i < 5; i++) {
assert_int_equal(lines_types_count[i], 2);
}

fclose(file);
remove(KEYLOG_FILE);
}

#endif

static void
test_nc_tls(void **state)
{
Expand All @@ -70,6 +110,10 @@ test_nc_tls(void **state)
for (i = 0; i < 2; i++) {
pthread_join(tids[i], NULL);
}

#ifndef HAVE_MBEDTLS
assert_keylog_file();
#endif
}

static int
Expand Down Expand Up @@ -128,5 +172,6 @@ main(void)
}

setenv("CMOCKA_TEST_ABORT", "1", 1);
setenv("SSLKEYLOGFILE", KEYLOG_FILE, 1);
return cmocka_run_group_tests(tests, NULL, NULL);
}

0 comments on commit 7f436ae

Please sign in to comment.