const char *chCAfile, STACK_OF(X509_CRL) *crls,
int crl_download);
void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
+int set_keylog_file(SSL_CTX *ctx, const char *keylog_file);
#endif
static unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
static int cookie_initialized = 0;
#endif
+static BIO *bio_keylog = NULL;
static const char *lookup(int val, const STRINT_PAIR* list, const char* def)
{
SSL_CTX_set_security_callback(ctx, security_callback_debug);
SSL_CTX_set0_security_ex_data(ctx, &sdb);
}
+
+static void keylog_callback(const SSL *ssl, const char *line)
+{
+ if (bio_keylog == NULL) {
+ BIO_printf(bio_err, "Keylog callback is invoked without valid file!\n");
+ return;
+ }
+
+ /*
+ * There might be concurrent writers to the keylog file, so we must ensure
+ * that the given line is written at once.
+ */
+ BIO_printf(bio_keylog, "%s\n", line);
+ (void)BIO_flush(bio_keylog);
+}
+
+int set_keylog_file(SSL_CTX *ctx, const char *keylog_file)
+{
+ /* Close any open files */
+ BIO_free_all(bio_keylog);
+ bio_keylog = NULL;
+
+ if (ctx == NULL || keylog_file == NULL) {
+ /* Keylogging is disabled, OK. */
+ return 0;
+ }
+
+ /*
+ * Append rather than write in order to allow concurrent modification.
+ * Furthermore, this preserves existing keylog files which is useful when
+ * the tool is run multiple times.
+ */
+ bio_keylog = BIO_new_file(keylog_file, "a");
+ if (bio_keylog == NULL) {
+ BIO_printf(bio_err, "Error writing keylog file %s\n", keylog_file);
+ return 1;
+ }
+
+ /* Write a header for seekable, empty files (this excludes pipes). */
+ if (BIO_tell(bio_keylog) == 0) {
+ BIO_puts(bio_keylog,
+ "# SSL/TLS secrets log file, generated by OpenSSL\n");
+ (void)BIO_flush(bio_keylog);
+ }
+ SSL_CTX_set_keylog_callback(ctx, keylog_callback);
+ return 0;
+}
OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME,
OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST,
OPT_ASYNC, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
+ OPT_KEYLOG_FILE,
OPT_V_ENUM,
OPT_X_ENUM,
OPT_S_ENUM,
{"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"},
{"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"},
#endif
+ {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
{NULL, OPT_EOF, 0x00, NULL}
};
int c_status_req = 0;
#endif
BIO *bio_c_msg = NULL;
+ const char *keylog_file = NULL;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
case OPT_READ_BUF:
read_buf_len = atoi(opt_arg());
break;
+ case OPT_KEYLOG_FILE:
+ keylog_file = opt_arg();
+ break;
}
}
if (count4or6 >= 2) {
SSL_CTX_sess_set_new_cb(ctx, new_session_cb);
}
+ if (set_keylog_file(ctx, keylog_file))
+ goto end;
+
con = SSL_new(ctx);
if (sess_in) {
SSL_SESSION *sess;
OPENSSL_free(next_proto.data);
#endif
SSL_CTX_free(ctx);
+ set_keylog_file(NULL, NULL);
X509_free(cert);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
EVP_PKEY_free(key);
OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
+ OPT_KEYLOG_FILE,
OPT_S_ENUM,
OPT_V_ENUM,
OPT_X_ENUM
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
+ {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
{NULL, OPT_EOF, 0, NULL}
};
int no_resume_ephemeral = 0;
unsigned int split_send_fragment = 0, max_pipelines = 0;
const char *s_serverinfo_file = NULL;
+ const char *keylog_file = NULL;
/* Init of few remaining global variables */
local_argc = argc;
case OPT_READ_BUF:
read_buf_len = atoi(opt_arg());
break;
+ case OPT_KEYLOG_FILE:
+ keylog_file = opt_arg();
+ break;
}
}
}
}
#endif
+ if (set_keylog_file(ctx, keylog_file))
+ goto end;
BIO_printf(bio_s_out, "ACCEPT\n");
(void)BIO_flush(bio_s_out);
ret = 0;
end:
SSL_CTX_free(ctx);
+ set_keylog_file(NULL, NULL);
X509_free(s_cert);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
X509_free(s_dcert);
A file containing a list of known Certificate Transparency logs. See
L<SSL_CTX_set_ctlog_list_file(3)> for the expected file format.
+=item B<-keylogfile path>
+
+Appends TLS secrets to the specified keylog file such that external programs
+(like Wireshark) can decrypt TLS connections.
+
=back
=head1 CONNECTED COMMANDS
print out some session cache status information.
+=item B<-keylogfile path>
+
+Appends TLS secrets to the specified keylog file such that external programs
+(like Wireshark) can decrypt TLS connections.
+
=back
=head1 NOTES