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: 2 additions & 0 deletions iocore/net/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ libinknet_a_SOURCES = \
P_SSLUtils.h \
P_SSLClientCoordinator.h \
P_SSLClientUtils.h \
P_TLSKeyLogger.h \
P_OCSPStapling.h \
P_UDPConnection.h \
P_UDPIOEvent.h \
Expand Down Expand Up @@ -191,6 +192,7 @@ libinknet_a_SOURCES = \
SSLUtils.cc \
OCSPStapling.cc \
TLSBasicSupport.cc \
TLSKeyLogger.cc \
TLSSessionResumptionSupport.cc \
TLSSNISupport.cc \
UDPIOEvent.cc \
Expand Down
101 changes: 0 additions & 101 deletions iocore/net/P_SSLUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@
#include "P_SSLCertLookup.h"

#include <map>
#include <mutex>
#include <set>
#include <shared_mutex>

struct SSLConfigParams;
class SSLNetVConnection;
Expand All @@ -64,105 +62,6 @@ struct SSLLoadingContext {
explicit SSLLoadingContext(SSL_CTX *c, SSLCertContextType ctx_type) : ctx(c), ctx_type(ctx_type) {}
};

/** A class for handling TLS secrets logging. */
class TLSKeyLogger
{
public:
TLSKeyLogger(const TLSKeyLogger &) = delete;
TLSKeyLogger &operator=(const TLSKeyLogger &) = delete;

~TLSKeyLogger()
{
std::unique_lock lock{_mutex};
close_keylog_file();
}

/** A callback for TLS secret key logging.
*
* This is the callback registered with OpenSSL's SSL_CTX_set_keylog_callback
* to log TLS secrets if the user enabled that feature. For more information
* about this callback, see OpenSSL's documentation of
* SSL_CTX_set_keylog_callback.
*
* @param[in] ssl The SSL object associated with the connection.
* @param[in] line The line to place in the keylog file.
*/
static void
ssl_keylog_cb(const SSL *ssl, const char *line)
{
instance().log(line);
}

/** Return whether TLS key logging is enabled.
*
* @return True if TLS session key logging is enabled, false otherwise.
*/
static bool
is_enabled()
{
return instance()._fd >= 0;
}

/** Enable keylogging.
*
* @param[in] keylog_file The path to the file to log TLS secrets to.
*/
static void
enable_keylogging(const char *keylog_file)
{
instance().enable_keylogging_internal(keylog_file);
}

/** Disable TLS secrets logging. */
static void
disable_keylogging()
{
instance().disable_keylogging_internal();
}

private:
TLSKeyLogger() = default;

/** Return the TLSKeyLogger singleton.
*
* We use a getter rather than a class static singleton member so that the
* construction of the singleton delayed until after TLS configuration is
* processed.
*/
static TLSKeyLogger &
instance()
{
static TLSKeyLogger instance;
return instance;
}

/** Close the file descriptor for the key log file.
*
* @note This assumes that a unique lock has been acquired for _mutex.
*/
void close_keylog_file();

/** A TLS secret line to log to the keylog file.
*
* @param[in] line A line to log to the keylog file.
*/
void log(const char *line);

/** Enable TLS keylogging in the instance singleton. */
void enable_keylogging_internal(const char *keylog_file);

/** Disable TLS keylogging in the instance singleton. */
void disable_keylogging_internal();

private:
/** A file descriptor for the log file receiving the TLS secrets. */
int _fd = -1;

/** A mutex to coordinate dynamically changing TLS logging config changes and
* logging to the TLS log file. */
std::shared_mutex _mutex;
};

/**
@brief Load SSL certificates from ssl_multicert.config and setup SSLCertLookup for SSLCertificateConfig
*/
Expand Down
129 changes: 129 additions & 0 deletions iocore/net/P_TLSKeyLogger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/**

@section license License

Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#pragma once

#ifndef OPENSSL_IS_BORINGSSL
#include <openssl/opensslconf.h>
#endif
#include <openssl/ssl.h>

#include <memory>
#include <shared_mutex>

/** A class for handling TLS secrets logging. */
class TLSKeyLogger
{
public:
TLSKeyLogger(const TLSKeyLogger &) = delete;
TLSKeyLogger &operator=(const TLSKeyLogger &) = delete;

~TLSKeyLogger()
{
std::unique_lock lock{_mutex};
close_keylog_file();
}

/** A callback for TLS secret key logging.
*
* This is the callback registered with OpenSSL's SSL_CTX_set_keylog_callback
* to log TLS secrets if the user enabled that feature. For more information
* about this callback, see OpenSSL's documentation of
* SSL_CTX_set_keylog_callback.
*
* @param[in] ssl The SSL object associated with the connection.
* @param[in] line The line to place in the keylog file.
*/
static void
ssl_keylog_cb(const SSL *ssl, const char *line)
{
instance().log(line);
}

/** Return whether TLS key logging is enabled.
*
* @return True if TLS session key logging is enabled, false otherwise.
*/
static bool
is_enabled()
{
return instance()._fd >= 0;
}

/** Enable keylogging.
*
* @param[in] keylog_file The path to the file to log TLS secrets to.
*/
static void
enable_keylogging(const char *keylog_file)
{
instance().enable_keylogging_internal(keylog_file);
}

/** Disable TLS secrets logging. */
static void
disable_keylogging()
{
instance().disable_keylogging_internal();
}

private:
TLSKeyLogger() = default;

/** Return the TLSKeyLogger singleton.
*
* We use a getter rather than a class static singleton member so that the
* construction of the singleton delayed until after TLS configuration is
* processed.
*/
static TLSKeyLogger &
instance()
{
static TLSKeyLogger instance;
return instance;
}

/** Close the file descriptor for the key log file.
*
* @note This assumes that a unique lock has been acquired for _mutex.
*/
void close_keylog_file();

/** A TLS secret line to log to the keylog file.
*
* @param[in] line A line to log to the keylog file.
*/
void log(const char *line);

/** Enable TLS keylogging in the instance singleton. */
void enable_keylogging_internal(const char *keylog_file);

/** Disable TLS keylogging in the instance singleton. */
void disable_keylogging_internal();

private:
/** A file descriptor for the log file receiving the TLS secrets. */
int _fd = -1;

/** A mutex to coordinate dynamically changing TLS logging config changes and
* logging to the TLS log file. */
std::shared_mutex _mutex;
};
1 change: 1 addition & 0 deletions iocore/net/SSLClientUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "P_SSLClientUtils.h"
#include "P_SSLConfig.h"
#include "P_SSLNetVConnection.h"
#include "P_TLSKeyLogger.h"
#include "YamlSNIConfig.h"
#include "SSLDiags.h"
#include "SSLSessionCache.h"
Expand Down
2 changes: 1 addition & 1 deletion iocore/net/SSLConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
#include "P_SSLSNI.h"
#include "P_SSLCertLookup.h"
#include "P_SSLSNI.h"
#include "P_SSLUtils.h"
#include "P_TLSKeyLogger.h"
#include "SSLDiags.h"
#include "SSLSessionCache.h"
#include "SSLSessionTicket.h"
Expand Down
73 changes: 1 addition & 72 deletions iocore/net/SSLUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "P_OCSPStapling.h"
#include "P_SSLSNI.h"
#include "P_SSLConfig.h"
#include "P_TLSKeyLogger.h"
#include "BoringSSLUtils.h"
#include "ProxyProtocol.h"
#include "SSLSessionCache.h"
Expand All @@ -46,11 +47,7 @@
#include "SSLDiags.h"
#include "SSLStats.h"

#include <fcntl.h>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <termios.h>
#include <vector>
Expand Down Expand Up @@ -104,74 +101,6 @@ static int ssl_vc_index = -1;
static ink_mutex *mutex_buf = nullptr;
static bool open_ssl_initialized = false;

// The caller of this function is responsible to acquire a unique_lock for
// _mutex.
void
TLSKeyLogger::close_keylog_file()
{
if (_fd == -1) {
return;
}
if (close(_fd) == -1) {
Error("Could not close keylog file: %s", strerror(errno));
}
_fd = -1;
}

void
TLSKeyLogger::enable_keylogging_internal(const char *keylog_file)
{
#if TS_HAS_TLS_KEYLOGGING
Debug("ssl_keylog", "Enabling TLS key logging to: %s.", keylog_file);
std::unique_lock lock{_mutex};
if (keylog_file == nullptr) {
close_keylog_file();
Debug("ssl_keylog", "Received a nullptr for keylog_file: disabling keylogging.");
return;
}

_fd = open(keylog_file, O_WRONLY | O_APPEND | O_CREAT, S_IWUSR | S_IRUSR);
if (_fd == -1) {
Error("Could not open keylog file %s: %s", keylog_file, strerror(errno));
return;
}
Note("Opened %s for TLS key logging.", keylog_file);
#else
Error("TLS keylogging is configured, but Traffic Server is not compiled with a version of OpenSSL that supports it.");
return;
#endif /* TS_HAS_TLS_KEYLOGGING */
}

void
TLSKeyLogger::disable_keylogging_internal()
{
std::unique_lock lock{_mutex};
if (is_enabled()) {
Note("Disabling TLS key logging.");
}
close_keylog_file();
Debug("ssl_keylog", "TLS keylogging is disabled.");
}

void
TLSKeyLogger::log(const char *line)
{
std::shared_lock lock{_mutex};
if (!is_enabled()) {
return;
}

// writev() is guaranteed to be thread safe.
struct iovec vector[2];
vector[0].iov_base = const_cast<void *>(reinterpret_cast<const void *>(line));
vector[0].iov_len = strlen(line);
vector[1].iov_base = const_cast<void *>(reinterpret_cast<const void *>("\n"));
vector[1].iov_len = 1;
if (writev(_fd, vector, 2) <= 0) {
Error("Could not write TLS session key to key log file: %s", strerror(errno));
}
}

/* Using pthread thread ID and mutex functions directly, instead of
* ATS this_ethread / ProxyMutex, so that other linked libraries
* may use pthreads and openssl without confusing us here. (TS-2271).
Expand Down
Loading