Commit 37a27b57 authored by Matt Mueller's avatar Matt Mueller Committed by Commit Bot

Support SSLKEYLOGFILE in QUIC+TLS.

Introduces a singleton SSLKeyLoggerManager that owns the SSLKeyLogger so
that it can be used with multiple SSL_CTX instances.

Bug: 1101691
Change-Id: I3436c9158ddb28f59d1511924c7f6940f9877dc6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2558727
Commit-Queue: David Schinazi <dschinazi@chromium.org>
Reviewed-by: default avatarAdam Rice <ricea@chromium.org>
Reviewed-by: default avatarDavid Schinazi <dschinazi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#831085}
parent 6a56fb42
......@@ -362,6 +362,7 @@ component("net") {
"ssl/ssl_handshake_details.h",
"ssl/ssl_info.cc",
"ssl/ssl_info.h",
"ssl/ssl_key_logger.cc",
"ssl/ssl_key_logger.h",
"ssl/ssl_legacy_crypto_fallback.h",
"ssl/ssl_private_key.cc",
......
......@@ -55,6 +55,7 @@
#include "net/socket/socket_performance_watcher.h"
#include "net/socket/socket_performance_watcher_factory.h"
#include "net/socket/udp_client_socket.h"
#include "net/ssl/ssl_key_logger.h"
#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
......@@ -2152,6 +2153,10 @@ QuicStreamFactory::CreateCryptoConfigHandle(
crypto_config->AddCanonicalSuffix(".googlevideo.com");
crypto_config->AddCanonicalSuffix(".googleusercontent.com");
crypto_config->AddCanonicalSuffix(".gvt1.com");
if (SSLKeyLoggerManager::IsActive()) {
SSL_CTX_set_keylog_callback(crypto_config->ssl_ctx(),
SSLKeyLoggerManager::KeyLogCallback);
}
if (!prefer_aes_gcm_recorded_) {
bool prefer_aes_gcm =
......
......@@ -287,9 +287,9 @@ class SSLClientSocketImpl::SSLContext {
}
void SetSSLKeyLogger(std::unique_ptr<SSLKeyLogger> logger) {
DCHECK(!ssl_key_logger_);
ssl_key_logger_ = std::move(logger);
SSL_CTX_set_keylog_callback(ssl_ctx_.get(), KeyLogCallback);
net::SSLKeyLoggerManager::SetSSLKeyLogger(std::move(logger));
SSL_CTX_set_keylog_callback(ssl_ctx_.get(),
SSLKeyLoggerManager::KeyLogCallback);
}
static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
......@@ -367,10 +367,6 @@ class SSLClientSocketImpl::SSLContext {
return socket->PrivateKeyCompleteCallback(out, out_len, max_out);
}
static void KeyLogCallback(const SSL* ssl, const char* line) {
GetInstance()->ssl_key_logger_->WriteLine(line);
}
static void MessageCallback(int is_write,
int version,
int content_type,
......@@ -387,8 +383,6 @@ class SSLClientSocketImpl::SSLContext {
int ssl_socket_data_index_;
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
std::unique_ptr<SSLKeyLogger> ssl_key_logger_;
};
const SSL_PRIVATE_KEY_METHOD
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/ssl/ssl_key_logger.h"
#include "base/check.h"
namespace net {
// static
bool SSLKeyLoggerManager::IsActive() {
return Get()->ssl_key_logger_ != nullptr;
}
// static
void SSLKeyLoggerManager::SetSSLKeyLogger(
std::unique_ptr<SSLKeyLogger> logger) {
DCHECK(!IsActive());
Get()->ssl_key_logger_ = std::move(logger);
}
// static
void SSLKeyLoggerManager::KeyLogCallback(const SSL* /*ssl*/, const char* line) {
DCHECK(IsActive());
Get()->ssl_key_logger_->WriteLine(line);
}
SSLKeyLoggerManager::SSLKeyLoggerManager() = default;
// static
SSLKeyLoggerManager* SSLKeyLoggerManager::Get() {
static base::NoDestructor<SSLKeyLoggerManager> owner;
return owner.get();
}
} // namespace net
......@@ -5,9 +5,12 @@
#ifndef NET_SSL_SSL_KEY_LOGGER_H_
#define NET_SSL_SSL_KEY_LOGGER_H_
#include <memory>
#include <string>
#include "base/no_destructor.h"
#include "net/base/net_export.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
namespace net {
......@@ -25,6 +28,37 @@ class NET_EXPORT SSLKeyLogger {
virtual void WriteLine(const std::string& line) = 0;
};
// SSLKeyLoggerManager owns a single global instance of SSLKeyLogger, allowing
// it to safely be registered on multiple SSL_CTX instances.
class NET_EXPORT SSLKeyLoggerManager {
public:
~SSLKeyLoggerManager() = delete;
SSLKeyLoggerManager(const SSLKeyLoggerManager&) = delete;
SSLKeyLoggerManager& operator=(const SSLKeyLoggerManager&) = delete;
// Returns true if an SSLKeyLogger has been set.
static bool IsActive();
// Set the SSLKeyLogger to use.
static void SetSSLKeyLogger(std::unique_ptr<SSLKeyLogger> logger);
// Logs |line| to the |logger| that was registered with SetSSLKeyLogger.
// This function will crash if a logger has not been registered.
// The function signature allows it to be registered with
// SSL_CTX_set_keylog_callback, the |ssl| parameter is unused.
static void KeyLogCallback(const SSL* /*ssl*/, const char* line);
private:
friend base::NoDestructor<SSLKeyLoggerManager>;
SSLKeyLoggerManager();
// Get the global SSLKeyLoggerManager instance.
static SSLKeyLoggerManager* Get();
std::unique_ptr<SSLKeyLogger> ssl_key_logger_;
};
} // namespace net
#endif // NET_SSL_SSL_KEY_LOGGER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment