[Curl] Add TLS debugging feature to log encryption keys
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Feb 2020 21:35:09 +0000 (21:35 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Feb 2020 21:35:09 +0000 (21:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=208192

Patch by Takashi Komori <Takashi.Komori@sony.com> on 2020-02-28
Reviewed by Fujii Hironori.

This patch enables recording encryption keys on curl port.
When you set key log file path to environment variable SSLKEYLOGFILE on curl port, network process writes encryption keys into the path.
The key log file follows the NSS key log format and this feature is as same as Chrome and Firefox have.

See also: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format

Test: No tests for this debugging feature. We have to check manually if the log file is generate.

.:

* Source/cmake/OptionsPlayStation.cmake:
* Source/cmake/OptionsWin.cmake:

Source/WebCore:

* platform/network/curl/CurlContext.cpp:
(WebCore::CurlContext::CurlContext):
* platform/network/curl/CurlContext.h:
(WebCore::CurlContext::shouldLogTLSKey const):
(WebCore::CurlContext::tlsKeyLogFilePath const):
* platform/network/curl/CurlSSLVerifier.cpp:
(WebCore::CurlSSLVerifier::CurlSSLVerifier):
(WebCore::CurlSSLVerifier::infoCallback):
(WebCore::CurlSSLVerifier::logTLSKey):
* platform/network/curl/CurlSSLVerifier.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@257656 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
Source/WebCore/ChangeLog
Source/WebCore/platform/network/curl/CurlContext.cpp
Source/WebCore/platform/network/curl/CurlContext.h
Source/WebCore/platform/network/curl/CurlSSLVerifier.cpp
Source/WebCore/platform/network/curl/CurlSSLVerifier.h
Source/cmake/OptionsPlayStation.cmake
Source/cmake/OptionsWin.cmake

index 7d36c47..f0b4152 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2020-02-28  Takashi Komori  <Takashi.Komori@sony.com>
+
+        [Curl] Add TLS debugging feature to log encryption keys
+        https://bugs.webkit.org/show_bug.cgi?id=208192
+
+        Reviewed by Fujii Hironori.
+
+        This patch enables recording encryption keys on curl port.
+        When you set key log file path to environment variable SSLKEYLOGFILE on curl port, network process writes encryption keys into the path.
+        The key log file follows the NSS key log format and this feature is as same as Chrome and Firefox have.
+
+        See also: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
+
+        Test: No tests for this debugging feature. We have to check manually if the log file is generate.
+
+        * Source/cmake/OptionsPlayStation.cmake:
+        * Source/cmake/OptionsWin.cmake:
+
 2020-02-28  Keith Miller  <keith_miller@apple.com>
 
         Fix issue in cmake build for checking ccache
index 9ee7643..2db10b2 100644 (file)
@@ -1,3 +1,29 @@
+2020-02-28  Takashi Komori  <Takashi.Komori@sony.com>
+
+        [Curl] Add TLS debugging feature to log encryption keys
+        https://bugs.webkit.org/show_bug.cgi?id=208192
+
+        Reviewed by Fujii Hironori.
+
+        This patch enables recording encryption keys on curl port.
+        When you set key log file path to environment variable SSLKEYLOGFILE on curl port, network process writes encryption keys into the path.
+        The key log file follows the NSS key log format and this feature is as same as Chrome and Firefox have.
+
+        See also: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
+
+        Test: No tests for this debugging feature. We have to check manually if the log file is generate.
+
+        * platform/network/curl/CurlContext.cpp:
+        (WebCore::CurlContext::CurlContext):
+        * platform/network/curl/CurlContext.h:
+        (WebCore::CurlContext::shouldLogTLSKey const):
+        (WebCore::CurlContext::tlsKeyLogFilePath const):
+        * platform/network/curl/CurlSSLVerifier.cpp:
+        (WebCore::CurlSSLVerifier::CurlSSLVerifier):
+        (WebCore::CurlSSLVerifier::infoCallback):
+        (WebCore::CurlSSLVerifier::logTLSKey):
+        * platform/network/curl/CurlSSLVerifier.h:
+
 2020-02-28  Chris Dumez  <cdumez@apple.com>
 
         MediaResourceLoader leaks resource responses
index 1464eb0..57c3b6f 100644 (file)
@@ -125,6 +125,11 @@ CurlContext::CurlContext()
     if (logFile)
         m_logFile = fopen(logFile, "a");
 #endif
+
+#if ENABLE(TLS_DEBUG)
+    if (auto filePath = envVar.read("SSLKEYLOGFILE"))
+        m_tlsKeyLogFilePath = filePath;
+#endif
 }
 
 CurlContext::~CurlContext()
index 3c90e4b..f1d15d5 100644 (file)
@@ -127,6 +127,11 @@ public:
     bool isVerbose() const { return m_verbose; }
 #endif
 
+#if ENABLE(TLS_DEBUG)
+    bool shouldLogTLSKey() const { return !m_tlsKeyLogFilePath.isEmpty(); }
+    const String& tlsKeyLogFilePath() const { return m_tlsKeyLogFilePath; }
+#endif
+
 private:
     CurlContext();
     void initShareHandle();
@@ -144,6 +149,10 @@ private:
     FILE* m_logFile { nullptr };
     bool m_verbose { false };
 #endif
+
+#if ENABLE(TLS_DEBUG)
+    String m_tlsKeyLogFilePath;
+#endif
 };
 
 // CurlMultiHandle --------------------------------------------
index bf14b28..93b9c22 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2013 University of Szeged
- * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,6 +57,10 @@ CurlSSLVerifier::CurlSSLVerifier(void* sslCtx)
     const auto& curvesList = sslHandle.getCurvesList();
     if (!curvesList.isEmpty())
         SSL_CTX_set1_curves_list(ctx, curvesList.utf8().data());
+
+#if ENABLE(TLS_DEBUG)
+    SSL_CTX_set_info_callback(ctx, infoCallback);
+#endif
 }
 
 void CurlSSLVerifier::collectInfo(X509_STORE_CTX* ctx)
@@ -79,6 +83,62 @@ int CurlSSLVerifier::verifyCallback(int preverified, X509_STORE_CTX* ctx)
     return preverified;
 }
 
+#if ENABLE(TLS_DEBUG)
+
+void CurlSSLVerifier::infoCallback(const SSL* ssl, int where, int)
+{
+    auto sslCtx = SSL_get_SSL_CTX(ssl);
+    auto verifier = static_cast<CurlSSLVerifier*>(SSL_CTX_get_app_data(sslCtx));
+
+    if (where & SSL_CB_HANDSHAKE_DONE)
+        verifier->logTLSKey(ssl);
+}
+
+void CurlSSLVerifier::logTLSKey(const SSL* ssl)
+{
+    // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
+
+    if (!CurlContext::singleton().shouldLogTLSKey())
+        return;
+
+    auto* session = SSL_get_session(ssl);
+    if (!session)
+        return;
+
+    auto& version = session->ssl_version;
+    if (version != TLS1_VERSION && version != TLS1_1_VERSION && version != TLS1_2_VERSION)
+        return;
+
+    auto requiredSize = SSL_get_client_random(ssl, nullptr, 0);
+    Vector<uint8_t> clientRandom(requiredSize);
+    if (SSL_get_client_random(ssl, clientRandom.data(), clientRandom.size()) != clientRandom.size())
+        return;
+
+    requiredSize = SSL_SESSION_get_master_key(session, nullptr, 0);
+    Vector<uint8_t> masterKey(requiredSize);
+    if (SSL_SESSION_get_master_key(session, masterKey.data(), masterKey.size()) != masterKey.size())
+        return;
+
+    auto fp = fopen(CurlContext::singleton().tlsKeyLogFilePath().utf8().data(), "a");
+    if (!fp)
+        return;
+
+    fprintf(fp, "CLIENT_RANDOM ");
+
+    for (size_t i = 0; i < clientRandom.size(); i++)
+        fprintf(fp, "%02X", clientRandom[i]);
+
+    fprintf(fp, " ");
+
+    for (size_t i = 0; i < masterKey.size(); i++)
+        fprintf(fp, "%02X", masterKey[i]);
+
+    fprintf(fp, "\n");
+    fclose(fp);
+}
+
+#endif
+
 static CurlSSLVerifier::SSLCertificateFlags convertToSSLCertificateFlags(unsigned sslError)
 {
     switch (sslError) {
index 3b59cb1..2bea4fa 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2013 University of Szeged
- * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ * Copyright (C) 2020 Sony Interactive Entertainment Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,6 +56,11 @@ private:
     static int verifyCallback(int, X509_STORE_CTX*);
     void collectInfo(X509_STORE_CTX*);
 
+#if ENABLE(TLS_DEBUG)
+    static void infoCallback(const SSL*, int, int);
+    void logTLSKey(const SSL*);
+#endif
+
     int m_sslErrors { 0 };
     CertificateInfo m_certificateInfo;
 };
index 4e1de1d..5a1e094 100644 (file)
@@ -46,6 +46,9 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CRYPTO PRIVATE ${ENABLE_EXPERIMENTAL
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_AUDIO PRIVATE OFF)
 
+# TLS debugging feature
+WEBKIT_OPTION_DEFINE(ENABLE_TLS_DEBUG "Enable TLS key log support" PRIVATE ON)
+
 # Reenable after updating fontconfig
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VARIATION_FONTS PRIVATE OFF)
 
index bca9670..67b3a0d 100644 (file)
@@ -73,6 +73,8 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_SYSTEM_MALLOC PRIVATE ON)
 
 if (${WTF_PLATFORM_WIN_CAIRO})
+    WEBKIT_OPTION_DEFINE(ENABLE_TLS_DEBUG "Enable TLS key log support" PRIVATE ON)
+
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTL PUBLIC ON)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_ENCRYPTED_MEDIA PUBLIC OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PUBLIC_SUFFIX_LIST PRIVATE ON)