Skip to content
Merged
Changes from 1 commit
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
42 changes: 42 additions & 0 deletions src/brpc/details/ssl_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#ifndef USE_MESALINK

#include <sys/socket.h> // recv
#include <pthread.h> // pthread_once
#include <stdio.h> // fopen
#include <stdlib.h> // getenv
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509.h>
Expand Down Expand Up @@ -185,6 +188,43 @@ static void SSLMessageCallback(int write_p, int version, int content_type,
#endif // TLS1_RT_HEARTBEAT
}

#if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER >= 0x10101000L)
static pthread_once_t g_ssl_keylog_once = PTHREAD_ONCE_INIT;
static FILE* g_ssl_keylog_file = NULL;

static void InitSSLKeyLogFile() {
const char* path = getenv("SSLKEYLOGFILE");
if (path == NULL || path[0] == '\0') {
return;
}
g_ssl_keylog_file = fopen(path, "a");
if (g_ssl_keylog_file == NULL) {
PLOG(WARNING) << "Fail to open SSLKEYLOGFILE=" << path;
}
}

static void SSLKeyLogCallback(const SSL* ssl, const char* line) {
(void)ssl;
if (line == NULL) {
return;
}
// Write the full key log line with newline in one call to keep output atomic.
fprintf(g_ssl_keylog_file, "%s\n", line);
fflush(g_ssl_keylog_file);
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fprintf and fflush operations on g_ssl_keylog_file are not thread-safe. The SSLKeyLogCallback can be invoked concurrently from multiple SSL connections, and without synchronization, concurrent writes could interleave or corrupt the output. Consider adding a mutex to protect the file write operations or use flockfile/funlockfile for atomic writes.

Copilot uses AI. Check for mistakes.
}

static void MaybeSetKeyLogCallback(SSL_CTX* ctx) {
pthread_once(&g_ssl_keylog_once, InitSSLKeyLogFile);
if (ctx != NULL && g_ssl_keylog_file != NULL) {
SSL_CTX_set_keylog_callback(ctx, SSLKeyLogCallback);
}
}
Comment on lines 196 to 226
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The InitSSLKeyLogFile, SSLKeyLogCallback, and MaybeSetKeyLogCallback functions lack documentation explaining their purpose, the SSLKEYLOGFILE format expectations, and any security implications of enabling this feature. Adding comments would help other developers understand when and how this debugging feature should be used, especially since it exposes sensitive cryptographic material.

Copilot uses AI. Check for mistakes.
#else
static void MaybeSetKeyLogCallback(SSL_CTX* ctx) {
(void)ctx;
}
#endif

#ifndef OPENSSL_NO_DH
static DH* SSLGetDHCallback(SSL* ssl, int exp, int keylen) {
(void)exp;
Expand Down Expand Up @@ -494,6 +534,7 @@ SSL_CTX* CreateClientSSLContext(const ChannelSSLOptions& options) {
LOG(ERROR) << "Fail to new SSL_CTX: " << SSLError(ERR_get_error());
return NULL;
}
MaybeSetKeyLogCallback(ssl_ctx.get());

if (!options.client_cert.certificate.empty()
&& LoadCertificate(ssl_ctx.get(),
Expand Down Expand Up @@ -532,6 +573,7 @@ SSL_CTX* CreateServerSSLContext(const std::string& certificate,
LOG(ERROR) << "Fail to new SSL_CTX: " << SSLError(ERR_get_error());
return NULL;
}
MaybeSetKeyLogCallback(ssl_ctx.get());

if (LoadCertificate(ssl_ctx.get(), certificate,
private_key, hostnames) != 0) {
Expand Down
Loading