Browse Source

LibTLS+RequestServer: Add an option to dump TLS keys to a log file

This file allows us to decrypt TLS messages in wireshark, which can help
immensely in debugging network stuff :^)
Ali Mohammad Pur 3 years ago
parent
commit
cb7becb067

+ 4 - 0
AK/Debug.h.in

@@ -434,6 +434,10 @@
 #cmakedefine01 TLS_DEBUG
 #endif
 
+#ifndef TLS_SSL_KEYLOG_DEBUG
+#cmakedefine01 TLS_SSL_KEYLOG_DEBUG
+#endif
+
 #ifndef TOKENIZER_TRACE_DEBUG
 #cmakedefine01 TOKENIZER_TRACE_DEBUG
 #endif

+ 1 - 0
Meta/CMake/all_the_debug_macros.cmake

@@ -182,6 +182,7 @@ set(TERMINAL_DEBUG ON)
 set(TEXTEDITOR_DEBUG ON)
 set(THREAD_DEBUG ON)
 set(TLS_DEBUG ON)
+set(TLS_SSL_KEYLOG_DEBUG ON)
 set(TOKENIZER_TRACE_DEBUG ON)
 set(TTY_DEBUG ON)
 set(UCI_DEBUG ON)

+ 11 - 0
Userland/Libraries/LibTLS/HandshakeClient.cpp

@@ -5,6 +5,7 @@
  */
 
 #include <AK/Debug.h>
+#include <AK/Hex.h>
 #include <AK/Random.h>
 #include <LibCrypto/ASN1/DER.h>
 #include <LibCrypto/BigInt/UnsignedBigInteger.h>
@@ -136,6 +137,16 @@ bool TLSv12::compute_master_secret_from_pre_master_secret(size_t length)
         dbgln("master key:");
         print_buffer(m_context.master_key);
     }
+
+    if constexpr (TLS_SSL_KEYLOG_DEBUG) {
+        auto file = MUST(Core::Stream::File::open("/home/anon/ssl_keylog", Core::Stream::OpenMode::Append | Core::Stream::OpenMode::Write));
+        VERIFY(file->write_or_error("CLIENT_RANDOM "sv.bytes()));
+        VERIFY(file->write_or_error(encode_hex({ m_context.local_random, 32 }).bytes()));
+        VERIFY(file->write_or_error(" "sv.bytes()));
+        VERIFY(file->write_or_error(encode_hex(m_context.master_key).bytes()));
+        VERIFY(file->write_or_error("\n"sv.bytes()));
+    }
+
     expand_key();
     return true;
 }

+ 12 - 2
Userland/Services/RequestServer/main.cpp

@@ -19,9 +19,17 @@
 
 ErrorOr<int> serenity_main(Main::Arguments)
 {
-    TRY(Core::System::pledge("stdio inet accept unix rpath sendfd recvfd sigaction"));
+    if constexpr (TLS_SSL_KEYLOG_DEBUG)
+        TRY(Core::System::pledge("stdio inet accept unix cpath wpath rpath sendfd recvfd sigaction"));
+    else
+        TRY(Core::System::pledge("stdio inet accept unix rpath sendfd recvfd sigaction"));
+
     signal(SIGINFO, [](int) { RequestServer::ConnectionCache::dump_jobs(); });
-    TRY(Core::System::pledge("stdio inet accept unix rpath sendfd recvfd"));
+
+    if constexpr (TLS_SSL_KEYLOG_DEBUG)
+        TRY(Core::System::pledge("stdio inet accept unix cpath wpath rpath sendfd recvfd"));
+    else
+        TRY(Core::System::pledge("stdio inet accept unix rpath sendfd recvfd"));
 
     // Ensure the certificates are read out here.
     [[maybe_unused]] auto& certs = DefaultRootCACertificates::the();
@@ -30,6 +38,8 @@ ErrorOr<int> serenity_main(Main::Arguments)
     // FIXME: Establish a connection to LookupServer and then drop "unix"?
     TRY(Core::System::unveil("/tmp/portal/lookup", "rw"));
     TRY(Core::System::unveil("/etc/timezone", "r"));
+    if constexpr (TLS_SSL_KEYLOG_DEBUG)
+        TRY(Core::System::unveil("/home/anon", "rwc"));
     TRY(Core::System::unveil(nullptr, nullptr));
 
     [[maybe_unused]] auto gemini = make<RequestServer::GeminiProtocol>();