summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DEPS2
-rw-r--r--chrome/browser/io_thread.cc32
-rw-r--r--net/BUILD.gn2
-rw-r--r--net/net.gypi2
-rw-r--r--net/net_common.gypi2
-rw-r--r--net/socket/ssl_client_socket.cc8
-rw-r--r--net/socket/ssl_client_socket.h18
-rw-r--r--net/socket/ssl_client_socket_openssl.cc43
-rw-r--r--net/socket/ssl_client_socket_openssl.h17
-rw-r--r--net/ssl/ssl_key_logger.cc68
-rw-r--r--net/ssl/ssl_key_logger.h50
-rw-r--r--third_party/boringssl/boringssl.gypi1
12 files changed, 209 insertions, 36 deletions
diff --git a/DEPS b/DEPS
index cd285c5..55f00dc 100644
--- a/DEPS
+++ b/DEPS
@@ -67,7 +67,7 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling BoringSSL
# and whatever else without interference from each other.
- 'boringssl_revision': '3ac32b1eda0da7a99d9c2b6c605fe50af80ccd90',
+ 'boringssl_revision': 'fde89b43c347155798dee8b1210c2c5faabe25f8',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling nss
# and whatever else without interference from each other.
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 485999c..37b1c40 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -13,6 +13,7 @@
#include "base/compiler_specific.h"
#include "base/debug/leak_tracker.h"
#include "base/environment.h"
+#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/prefs/pref_registry_simple.h"
@@ -23,6 +24,7 @@
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread.h"
#include "base/threading/worker_pool.h"
@@ -174,20 +176,24 @@ void ObserveKeychainEvents() {
// Gets file path into ssl_keylog_file from command line argument or
// environment variable. Command line argument has priority when
// both specified.
-std::string GetSSLKeyLogFile(const base::CommandLine& command_line) {
+base::FilePath GetSSLKeyLogFile(const base::CommandLine& command_line) {
if (command_line.HasSwitch(switches::kSSLKeyLogFile)) {
- std::string file =
- command_line.GetSwitchValueASCII(switches::kSSLKeyLogFile);
- if (!file.empty()) {
- return file;
- }
-
+ base::FilePath path =
+ command_line.GetSwitchValuePath(switches::kSSLKeyLogFile);
+ if (!path.empty())
+ return path;
LOG(WARNING) << "ssl-key-log-file argument missing";
}
+
scoped_ptr<base::Environment> env(base::Environment::Create());
- std::string file;
- env->GetVar("SSLKEYLOGFILE", &file);
- return file;
+ std::string path_str;
+ env->GetVar("SSLKEYLOGFILE", &path_str);
+#if defined(OS_WIN)
+ // base::Environment returns environment variables in UTF-8 on Windows.
+ return base::FilePath(base::UTF8ToUTF16(path_str));
+#else
+ return base::FilePath(path_str);
+#endif
}
// Used for the "system" URLRequestContext.
@@ -587,9 +593,11 @@ void IOThread::Init() {
*base::CommandLine::ForCurrentProcess();
// Export ssl keys if log file specified.
- std::string ssl_keylog_file = GetSSLKeyLogFile(command_line);
+ base::FilePath ssl_keylog_file = GetSSLKeyLogFile(command_line);
if (!ssl_keylog_file.empty()) {
- net::SSLClientSocket::SetSSLKeyLogFile(ssl_keylog_file);
+ net::SSLClientSocket::SetSSLKeyLogFile(
+ ssl_keylog_file,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
}
DCHECK(!globals_);
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 3f743ca..74d0c67 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -208,6 +208,8 @@ if (!is_nacl) {
"ssl/openssl_ssl_util.h",
"ssl/ssl_client_session_cache_openssl.cc",
"ssl/ssl_client_session_cache_openssl.h",
+ "ssl/ssl_key_logger.cc",
+ "ssl/ssl_key_logger.h",
"ssl/ssl_platform_key.h",
"ssl/ssl_platform_key_task_runner.cc",
"ssl/ssl_platform_key_task_runner.h",
diff --git a/net/net.gypi b/net/net.gypi
index 58261b7..bfab4cb 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -1148,6 +1148,8 @@
'ssl/client_cert_store_win.h',
'ssl/ssl_config_service_defaults.cc',
'ssl/ssl_config_service_defaults.h',
+ 'ssl/ssl_key_logger.cc',
+ 'ssl/ssl_key_logger.h',
'ssl/ssl_platform_key.h',
'ssl/ssl_platform_key_task_runner.cc',
'ssl/ssl_platform_key_task_runner.h',
diff --git a/net/net_common.gypi b/net/net_common.gypi
index 9489d0a..d373325 100644
--- a/net/net_common.gypi
+++ b/net/net_common.gypi
@@ -163,6 +163,8 @@
'ssl/openssl_ssl_util.h',
'ssl/ssl_client_session_cache_openssl.cc',
'ssl/ssl_client_session_cache_openssl.h',
+ 'ssl/ssl_key_logger.cc',
+ 'ssl/ssl_key_logger.h',
'ssl/ssl_platform_key.h',
'ssl/ssl_platform_key_nss.cc',
'ssl/ssl_platform_key_task_runner.cc',
diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc
index 68d44f8..ccd1f86 100644
--- a/net/socket/ssl_client_socket.cc
+++ b/net/socket/ssl_client_socket.cc
@@ -83,9 +83,11 @@ const char* SSLClientSocket::NextProtoStatusToString(
}
// static
-void SSLClientSocket::SetSSLKeyLogFile(const std::string& ssl_keylog_file) {
-#if defined(USE_OPENSSL)
- SSLClientSocketOpenSSL::SetSSLKeyLogFile(ssl_keylog_file);
+void SSLClientSocket::SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
+#if defined(USE_OPENSSL) && !defined(OS_NACL)
+ SSLClientSocketOpenSSL::SetSSLKeyLogFile(path, task_runner);
#else
NOTIMPLEMENTED();
#endif
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h
index ad458b2..c8bfa8e 100644
--- a/net/socket/ssl_client_socket.h
+++ b/net/socket/ssl_client_socket.h
@@ -15,6 +15,11 @@
#include "net/socket/stream_socket.h"
#include "net/ssl/ssl_failure_state.h"
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
namespace net {
class CertPolicyEnforcer;
@@ -114,9 +119,16 @@ class NET_EXPORT SSLClientSocket : public SSLSocket {
static const char* NextProtoStatusToString(const NextProtoStatus status);
- // Export SSL key material to be logged to the specified file if platform
- // uses OpenSSL. Must be called before SSLClientSockets are created.
- static void SetSSLKeyLogFile(const std::string& ssl_keylog_file);
+ // Log SSL key material to |path| on |task_runner|. Must be called before any
+ // SSLClientSockets are created.
+ //
+ // TODO(davidben): Switch this to a parameter on the SSLClientSocketContext
+ // once https://crbug.com/458365 is resolved. This will require splitting
+ // SSLKeyLogger into an interface, built with OS_NACL and a non-NaCl
+ // SSLKeyLoggerImpl.
+ static void SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner);
// Returns true if |error| is OK or |load_flags| ignores certificate errors
// and |error| is a certificate error.
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 34c8601..090f2bd 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -51,6 +51,10 @@
#include "base/win/windows_version.h"
#endif
+#if !defined(OS_NACL)
+#include "net/ssl/ssl_key_logger.h"
+#endif
+
#if defined(USE_NSS_CERTS) || defined(OS_IOS)
#include "net/cert_net/nss_ocsp.h"
#endif
@@ -146,11 +150,6 @@ ScopedX509Stack OSCertHandlesToOpenSSL(
return stack.Pass();
}
-int LogErrorCallback(const char* str, size_t len, void* context) {
- LOG(ERROR) << base::StringPiece(str, len);
- return 1;
-}
-
bool EVP_MDToPrivateKeyHash(const EVP_MD* md, SSLPrivateKey::Hash* hash) {
switch (EVP_MD_type(md)) {
case NID_md5_sha1:
@@ -206,6 +205,16 @@ class SSLClientSocketOpenSSL::SSLContext {
return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0;
}
+#if !defined(OS_NACL)
+ void SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
+ DCHECK(!ssl_key_logger_);
+ ssl_key_logger_.reset(new SSLKeyLogger(path, task_runner));
+ SSL_CTX_set_keylog_callback(ssl_ctx_.get(), KeyLogCallback);
+ }
+#endif
+
static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
private:
@@ -335,12 +344,22 @@ class SSLClientSocketOpenSSL::SSLContext {
return socket->PrivateKeySignCompleteCallback(out, out_len, max_out);
}
+#if !defined(OS_NACL)
+ static void KeyLogCallback(const SSL* ssl, const char* line) {
+ GetInstance()->ssl_key_logger_->WriteLine(line);
+ }
+#endif
+
// This is the index used with SSL_get_ex_data to retrieve the owner
// SSLClientSocketOpenSSL object from an SSL instance.
int ssl_socket_data_index_;
ScopedSSL_CTX ssl_ctx_;
+#if !defined(OS_NACL)
+ scoped_ptr<SSLKeyLogger> ssl_key_logger_;
+#endif
+
// TODO(davidben): Use a separate cache per URLRequestContext.
// https://crbug.com/458365
//
@@ -489,17 +508,13 @@ SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
Disconnect();
}
+#if !defined(OS_NACL)
void SSLClientSocketOpenSSL::SetSSLKeyLogFile(
- const std::string& ssl_keylog_file) {
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- BIO* bio = BIO_new_file(ssl_keylog_file.c_str(), "a");
- if (!bio) {
- LOG(ERROR) << "Failed to open " << ssl_keylog_file;
- ERR_print_errors_cb(&LogErrorCallback, NULL);
- } else {
- SSL_CTX_set_keylog_bio(SSLContext::GetInstance()->ssl_ctx(), bio);
- }
+ const base::FilePath& ssl_keylog_file,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
+ SSLContext::GetInstance()->SetSSLKeyLogFile(ssl_keylog_file, task_runner);
}
+#endif
void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
diff --git a/net/socket/ssl_client_socket_openssl.h b/net/socket/ssl_client_socket_openssl.h
index a5d545b..c200c31 100644
--- a/net/socket/ssl_client_socket_openssl.h
+++ b/net/socket/ssl_client_socket_openssl.h
@@ -12,9 +12,10 @@
#include <string>
#include <vector>
-#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/cert/cert_verifier.h"
@@ -28,6 +29,11 @@
#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_failure_state.h"
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
namespace net {
class CertVerifier;
@@ -53,8 +59,13 @@ class SSLClientSocketOpenSSL : public SSLClientSocket {
return ssl_session_cache_shard_;
}
- // Export ssl key log files if env variable is not set.
- static void SetSSLKeyLogFile(const std::string& ssl_keylog_file);
+#if !defined(OS_NACL)
+ // Log SSL key material to |path| on |task_runner|. Must be called before any
+ // SSLClientSockets are created.
+ static void SetSSLKeyLogFile(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner);
+#endif
// SSLClientSocket implementation.
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
diff --git a/net/ssl/ssl_key_logger.cc b/net/ssl/ssl_key_logger.cc
new file mode 100644
index 0000000..6e4c2d4
--- /dev/null
+++ b/net/ssl/ssl_key_logger.cc
@@ -0,0 +1,68 @@
+// Copyright 2015 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 <stdio.h>
+
+#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/sequence_checker.h"
+#include "base/sequenced_task_runner.h"
+
+namespace net {
+
+// An object which lives on the background SequencedTaskRunner and performs the
+// blocking file operations.
+class SSLKeyLogger::Core {
+ public:
+ Core() { sequence_checker_.DetachFromSequence(); }
+ ~Core() { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); }
+
+ void OpenFile(const base::FilePath& path) {
+ DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+ DCHECK(!file_);
+ file_.reset(base::OpenFile(path, "a"));
+ if (!file_)
+ LOG(WARNING) << "Could not open " << path.value();
+ }
+
+ void WriteLine(const std::string& line) {
+ DCHECK(sequence_checker_.CalledOnValidSequencedThread());
+ if (!file_)
+ return;
+ fprintf(file_.get(), "%s\n", line.c_str());
+ fflush(file_.get());
+ }
+
+ private:
+ base::ScopedFILE file_;
+ base::SequenceChecker sequence_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+};
+
+SSLKeyLogger::SSLKeyLogger(
+ const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner)
+ : task_runner_(task_runner), core_(new Core) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Core::OpenFile, base::Unretained(core_.get()), path));
+}
+
+SSLKeyLogger::~SSLKeyLogger() {
+ task_runner_->DeleteSoon(FROM_HERE, core_.release());
+}
+
+void SSLKeyLogger::WriteLine(const std::string& line) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&Core::WriteLine, base::Unretained(core_.get()), line));
+}
+
+} // namespace net
diff --git a/net/ssl/ssl_key_logger.h b/net/ssl/ssl_key_logger.h
new file mode 100644
index 0000000..dcaf6c6
--- /dev/null
+++ b/net/ssl/ssl_key_logger.h
@@ -0,0 +1,50 @@
+// Copyright 2015 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.
+
+#ifndef NET_SSL_SSL_KEY_LOGGER_H_
+#define NET_SSL_SSL_KEY_LOGGER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
+namespace net {
+
+// SSLKeyLogger logs SSL key material for debugging purposes. This should only
+// be used when requested by the user, typically via the SSLKEYLOGFILE
+// environment variable. See also
+// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
+class SSLKeyLogger {
+ public:
+ // Creates a new SSLKeyLogger which writes to |path|, scheduling write
+ // operations on |task_runner|.
+ SSLKeyLogger(const base::FilePath& path,
+ const scoped_refptr<base::SequencedTaskRunner>& task_runner);
+ ~SSLKeyLogger();
+
+ // Writes |line| followed by a newline. This may be called by multiple threads
+ // simultaneously. If two calls race, the order of the lines is undefined, but
+ // each line will be written atomically.
+ void WriteLine(const std::string& line);
+
+ private:
+ class Core;
+
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ // Destroyed on |task_runner_|.
+ scoped_ptr<Core> core_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSLKeyLogger);
+};
+
+} // namespace net
+
+#endif // NET_SSL_SSL_KEY_LOGGER_H_
diff --git a/third_party/boringssl/boringssl.gypi b/third_party/boringssl/boringssl.gypi
index c3ffa5b..096c903 100644
--- a/third_party/boringssl/boringssl.gypi
+++ b/third_party/boringssl/boringssl.gypi
@@ -324,6 +324,7 @@
'linux-arm/crypto/sha/sha512-armv4.S',
'src/crypto/chacha/chacha_vec_arm.S',
'src/crypto/cpu-arm-asm.S',
+ 'src/crypto/curve25519/asm/x25519-arm.S',
'src/crypto/poly1305/poly1305_arm_asm.S',
],
'boringssl_linux_x86_sources': [