3434#include " records/I_RecCore.h"
3535#include " P_SSLCertLookup.h"
3636
37- #include < set>
3837#include < map>
38+ #include < mutex>
39+ #include < set>
40+ #include < shared_mutex>
3941
4042struct SSLConfigParams ;
4143class SSLNetVConnection ;
@@ -60,6 +62,105 @@ struct SSLLoadingContext {
6062 explicit SSLLoadingContext (SSL_CTX *c, SSLCertContextType ctx_type) : ctx(c), ctx_type(ctx_type) {}
6163};
6264
65+ /* * A class for handling TLS secrets logging. */
66+ class TLSKeyLogger
67+ {
68+ public:
69+ TLSKeyLogger (const TLSKeyLogger &) = delete ;
70+ TLSKeyLogger &operator =(const TLSKeyLogger &) = delete ;
71+
72+ ~TLSKeyLogger ()
73+ {
74+ std::unique_lock lock{_mutex};
75+ close_keylog_file ();
76+ }
77+
78+ /* * A callback for TLS secret key logging.
79+ *
80+ * This is the callback registered with OpenSSL's SSL_CTX_set_keylog_callback
81+ * to log TLS secrets if the user enabled that feature. For more information
82+ * about this callback, see OpenSSL's documentation of
83+ * SSL_CTX_set_keylog_callback.
84+ *
85+ * @param[in] ssl The SSL object associated with the connection.
86+ * @param[in] line The line to place in the keylog file.
87+ */
88+ static void
89+ ssl_keylog_cb (const SSL *ssl, const char *line)
90+ {
91+ instance ().log (line);
92+ }
93+
94+ /* * Return whether TLS key logging is enabled.
95+ *
96+ * @return True if TLS session key logging is enabled, false otherwise.
97+ */
98+ static bool
99+ is_enabled ()
100+ {
101+ return instance ()._fd >= 0 ;
102+ }
103+
104+ /* * Enable keylogging.
105+ *
106+ * @param[in] keylog_file The path to the file to log TLS secrets to.
107+ */
108+ static void
109+ enable_keylogging (const char *keylog_file)
110+ {
111+ instance ().enable_keylogging_internal (keylog_file);
112+ }
113+
114+ /* * Disable TLS secrets logging. */
115+ static void
116+ disable_keylogging ()
117+ {
118+ instance ().disable_keylogging_internal ();
119+ }
120+
121+ private:
122+ TLSKeyLogger () = default ;
123+
124+ /* * Return the TLSKeyLogger singleton.
125+ *
126+ * We use a getter rather than a class static singleton member so that the
127+ * construction of the singleton delayed until after TLS configuration is
128+ * processed.
129+ */
130+ static TLSKeyLogger &
131+ instance ()
132+ {
133+ static TLSKeyLogger instance;
134+ return instance;
135+ }
136+
137+ /* * Close the file descriptor for the key log file.
138+ *
139+ * @note This assumes that a unique lock has been acquired for _mutex.
140+ */
141+ void close_keylog_file ();
142+
143+ /* * A TLS secret line to log to the keylog file.
144+ *
145+ * @param[in] line A line to log to the keylog file.
146+ */
147+ void log (const char *line);
148+
149+ /* * Enable TLS keylogging in the instance singleton. */
150+ void enable_keylogging_internal (const char *keylog_file);
151+
152+ /* * Disable TLS keylogging in the instance singleton. */
153+ void disable_keylogging_internal ();
154+
155+ private:
156+ /* * A file descriptor for the log file receiving the TLS secrets. */
157+ int _fd = -1 ;
158+
159+ /* * A mutex to coordinate dynamically changing TLS logging config changes and
160+ * logging to the TLS log file. */
161+ std::shared_mutex _mutex;
162+ };
163+
63164/* *
64165 @brief Load SSL certificates from ssl_multicert.config and setup SSLCertLookup for SSLCertificateConfig
65166 */
@@ -122,6 +223,7 @@ class SSLMultiCertConfigLoader
122223 virtual bool _set_info_callback (SSL_CTX *ctx);
123224 virtual bool _set_npn_callback (SSL_CTX *ctx);
124225 virtual bool _set_alpn_callback (SSL_CTX *ctx);
226+ virtual bool _set_keylog_callback (SSL_CTX *ctx);
125227};
126228
127229// Create a new SSL server context fully configured (cert and keys are optional).
0 commit comments