Created
September 10, 2023 10:13
-
-
Save hlandau/f67b4065909913ed31da1500dc4a8719 to your computer and use it in GitHub Desktop.
LD_PRELOAD implementation of SSLKEYLOGFILE in OpenSSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ldkeylog.c - tool for dumping TLS keys from applications which | |
* dynamically link against OpenSSL on *nix systems | |
* | |
* Compile: | |
* cc -shared -fPIC -O3 -o ldkeylog.so ldkeylog.c | |
* | |
* Use: | |
* LD_PRELOAD=.../ldkeylog.so SSLKEYLOGFILE=.../keylog.txt \ | |
* openssl s_client -connect www.google.com:443 | |
* | |
* 2023 Hugo Landau <[email protected]> | |
* Released into the public domain. | |
*/ | |
#define _GNU_SOURCE | |
#include <dlfcn.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <sys/uio.h> | |
#include <pthread.h> | |
#include <stdlib.h> | |
#include <string.h> | |
typedef void (*keylog_callback_t)(const void *ssl, const char *line); | |
typedef void *(*SSL_CTX_new_t)(const void *method); | |
typedef void *(*SSL_CTX_new_ex_t)(void *libctx, const char *propq, const void *method); | |
typedef void (*SSL_CTX_set_keylog_callback_t)(void *ctx, keylog_callback_t fp); | |
static pthread_once_t g_initOnce = PTHREAD_ONCE_INIT; | |
static SSL_CTX_new_t fp_SSL_CTX_new; | |
static SSL_CTX_new_ex_t fp_SSL_CTX_new_ex; | |
static SSL_CTX_set_keylog_callback_t fp_SSL_CTX_set_keylog_callback; | |
static int g_logFile = -1; | |
static void _Teardown(void) | |
{ | |
close(g_logFile); | |
g_logFile = -1; | |
} | |
static void _InitActual(void) | |
{ | |
fp_SSL_CTX_new = dlsym(RTLD_NEXT, "SSL_CTX_new"); | |
fp_SSL_CTX_new_ex = dlsym(RTLD_NEXT, "SSL_CTX_new_ex"); | |
fp_SSL_CTX_set_keylog_callback = dlsym(RTLD_NEXT, "SSL_CTX_set_keylog_callback"); | |
if (!fp_SSL_CTX_set_keylog_callback) | |
return; | |
const char *klFilename = getenv("SSLKEYLOGFILE"); | |
if (!klFilename || !*klFilename) | |
return; | |
g_logFile = open(klFilename, O_WRONLY | O_CREAT | O_APPEND | O_CLOEXEC, 0644); | |
if (g_logFile >= 0) | |
atexit(_Teardown); | |
} | |
static void _Init(void) | |
{ | |
pthread_once(&g_initOnce, _InitActual); | |
} | |
static void _KeylogCallback(const void *ssl, const char *line) | |
{ | |
struct iovec iov[2]; | |
if (g_logFile < 0) | |
return; | |
iov[0].iov_base = (char *)line; | |
iov[0].iov_len = strlen(line); | |
iov[1].iov_base = "\n"; | |
iov[1].iov_len = 1; | |
writev(g_logFile, iov, 2); | |
} | |
static void _ConfigureKeylog(void *ctx) | |
{ | |
if (g_logFile < 0) | |
return; | |
fp_SSL_CTX_set_keylog_callback(ctx, _KeylogCallback); | |
} | |
void *SSL_CTX_new(const void *method) | |
{ | |
_Init(); | |
if (!fp_SSL_CTX_new) | |
abort(); | |
void *p = fp_SSL_CTX_new(method); | |
if (p) | |
_ConfigureKeylog(p); | |
return p; | |
} | |
void *SSL_CTX_new_ex(void *libctx, const char *propq, | |
const void *method) | |
{ | |
_Init(); | |
if (!fp_SSL_CTX_new_ex) | |
abort(); | |
void *p = fp_SSL_CTX_new_ex(libctx, propq, method); | |
if (p) | |
_ConfigureKeylog(p); | |
return p; | |
} | |
void SSL_CTX_set_keylog_callback(void *ctx, keylog_callback_t fp) | |
{ | |
/* ignore */ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ldkeylog.so: ldkeylog.c | |
gcc -Wall -shared -fPIC -O3 "$<" -o "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment