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 4, 2024
1 parent 53c97bc commit 81bf39b
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ if(ENABLE_SSH_TLS)
else()
# dependencies - openssl
find_package(OpenSSL 3.0.0 REQUIRED)
list(APPEND libsrc src/session_openssl.c)
list(APPEND libsrc src/session_openssl.c src/keylog.c)
include_directories(${OPENSSL_INCLUDE_DIR})
target_link_libraries(netconf2 ${OPENSSL_LIBRARIES})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
Expand Down
72 changes: 72 additions & 0 deletions src/keylog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* @file keylog.h
* @author Gael COLIN <gael.colin@nokia.com>
* @brief libnetconf2 - log functions
*
* @copyright
* Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
* Copyright (c) 1996 - 2024, Daniel Stenberg, daniel@haxx.se, and many contributors, see the THANKS file.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* SPDX-License-Identifier: curl
*/
#include <stdlib.h>
#include "keylog.h"

#define KEYLOG_LABEL_MAXLEN (sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET") - 1)

#define CLIENT_RANDOM_SIZE 32

/*
* The master secret in TLS 1.2 and before is always 48 bytes. In TLS 1.3, the
* secret size depends on the cipher suite's hash function which is 32 bytes
* for SHA-256 and 48 bytes for SHA-384.
*/
#define SECRET_MAXLEN 48

/* The fp for the open SSLKEYLOGFILE, or NULL if not open */
FILE *keylog_file_fp = NULL;

void
tls_keylog_open(void)
{
char *keylog_file_name;

if (!keylog_file_fp) {
keylog_file_name = getenv("SSLKEYLOGFILE");
if (keylog_file_name) {
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;
}
}
}
}
}

void
tls_keylog_close(void)
{
if (keylog_file_fp) {
fclose(keylog_file_fp);
keylog_file_fp = NULL;
}
}

bool
tls_keylog_enabled(void)
{
return keylog_file_fp != NULL;
}
43 changes: 43 additions & 0 deletions src/keylog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @file keylog.h
* @author Gael COLIN <gael.colin@nokia.com>
* @brief libnetconf2 - log functions
*
* @copyright
* Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
* Copyright (c) 1996 - 2024, Daniel Stenberg, daniel@haxx.se, and many contributors, see the THANKS file.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* SPDX-License-Identifier: curl
*/
#include <stdio.h>
#include "stdbool.h"
#include "stddef.h"

extern FILE *keylog_file_fp;

/*
* Opens the TLS key log file if requested by the user. The SSLKEYLOGFILE
* environment variable specifies the output file.
*/
void tls_keylog_open(void);

/*
* Closes the TLS key log file if not already.
*/
void tls_keylog_close(void);

/*
* Returns true if the user successfully enabled the TLS key log file.
*/
bool tls_keylog_enabled(void);
7 changes: 7 additions & 0 deletions src/session_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

#include "compat.h"
#include "config.h"
#include "keylog.h"
#include "log_p.h"
#include "messages_p.h"
#include "session_client.h"
Expand Down Expand Up @@ -1991,6 +1992,9 @@ nc_client_init(void)
ERR(NULL, "%s: failed to init libssh.", __func__);
return -1;
}
#ifndef HAVE_MBEDTLS
tls_keylog_open();
#endif /* HAVE_MBEDTLS */
#endif

return 0;
Expand All @@ -2002,6 +2006,9 @@ nc_client_destroy(void)
pthread_mutex_destroy(&client_opts.ch_bind_lock);
nc_client_set_schema_searchpath(NULL);
#ifdef NC_ENABLED_SSH_TLS
#ifndef HAVE_MBEDTLS
tls_keylog_close();
#endif /* HAVE_MBEDTLS */
nc_client_ch_del_bind(NULL, 0, 0);
nc_client_ssh_destroy_opts();
nc_client_tls_destroy_opts();
Expand Down
35 changes: 35 additions & 0 deletions src/session_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "compat.h"
#include "config.h"
#include "keylog.h"
#include "log_p.h"
#include "session.h"
#include "session_p.h"
Expand All @@ -43,6 +44,36 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>

void
tls_keylog_write_line(const SSL *ssl, const char *line)
{
(void)ssl;
/* 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,6 +85,10 @@ nc_tls_session_new_wrap(void *tls_cfg)
return NULL;
}

if (tls_keylog_enabled()) {
SSL_CTX_set_keylog_callback(tls_cfg, tls_keylog_write_line);
}

return session;
}

Expand Down
5 changes: 5 additions & 0 deletions src/session_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "compat.h"
#include "config.h"
#include "keylog.h"
#include "log_p.h"
#include "messages_p.h"
#include "messages_server.h"
Expand Down Expand Up @@ -836,6 +837,9 @@ nc_server_init(void)
ERR(NULL, "%s: failed to init CURL.", __func__);
goto error;
}
#ifndef HAVE_MBEDTLS
tls_keylog_open();
#endif /* HAVE_MBEDTLS */

/* optional for dynamic library, mandatory for static */
if (ssh_init()) {
Expand Down Expand Up @@ -903,6 +907,7 @@ nc_server_destroy(void)
pthread_mutex_destroy(&server_opts.bind_lock);

#ifdef NC_ENABLED_SSH_TLS
tls_keylog_close();
free(server_opts.authkey_path_fmt);
server_opts.authkey_path_fmt = NULL;
free(server_opts.pam_config_name);
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 81bf39b

Please sign in to comment.