On 2017/6/12 15:14, Lukas Tribus wrote: > Hello, > > > Am 12.06.2017 um 19:35 schrieb Patrick Hemmer: >> Would we be able to get a new sample which provides the SSL session >> master-key? >> This is so that when performing packet captures with ephemeral ciphers >> (DHE), we can decrypt the traffic in the capture. > There is no master key. What you need is the key for the symmetric > crypto, and you cannot extract it from haproxy currently. > > More importantly, OpenSSL implements this functionality only the master > branch (see [1] and [2]), none of the release branches actually have > this functionality. > So we need OpenSSL to release a new branch with this functionality > (1.1.1), we have to implement it in haproxy and then still it will only > work for <=TLSv1.2. > > TLSv1.3 will need additional secrets and a different key logging API [3]. > > > I suggest you use SSLKEYLOGFILE features in the browsers at this point, > as the functionality is far from being ready for any OpenSSL based > application. > > > Regards, > Lukas > > [1] > https://github.com/openssl/openssl/commit/2faa1b48fd6864f6bb8f992fd638378202fdd416 > [2] > https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_keylog_callback.html > [3] https://github.com/openssl/openssl/pull/2287 >
Maybe there's some misunderstanding, because we seem to be talking about different things, as there definitely is a master key. I patched my haproxy to add a ssl_fc_session_key fetch, and with the value I was able to decrypt my test sessions encrypted with TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Since the implementation was fairly easy, I've included a patch for it. But I've never submitted anything before, so there's a good chance of something being wrong. The only thing is that the function to do the extraction was added in 1.1.0 (https://github.com/openssl/openssl/commit/858618e7e037559b75b0bfca4d30440f9515b888) The underlying vars are still there, and when I looked have been there since as early as I could find (going back to 1998). But I'm not sure how you feel about extracting the values without the helper function. -Patrick
From a6fa01c65f615887b08f86bb67ac7ef6231dbc34 Mon Sep 17 00:00:00 2001 From: Patrick Hemmer <hapr...@stormcloud9.net> Date: Mon, 12 Jun 2017 18:03:48 -0400 Subject: [PATCH] MINOR: ssl: add fetch 'ssl_fc_session_key' and 'ssl_bc_session_key' These fetches return the SSL master key of the front/back connection. This is useful to decrypt traffic encrypted with ephemeral ciphers. --- doc/configuration.txt | 10 ++++++++++ src/ssl_sock.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index 49bfd85..e7cfd85 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -13930,6 +13930,11 @@ ssl_bc_session_id : binary made over an SSL/TLS transport layer. It is useful to log if we want to know if session was reused or not. +ssl_bc_session_key : binary + Returns the SSL master key of the back connection when the outgoing + connection was made over an SSL/TLS transport layer. It is useful to decrypt + traffic sent using ephemeral ciphers. + ssl_bc_use_keysize : integer Returns the symmetric cipher key size used in bits when the outgoing connection was made over an SSL/TLS transport layer. @@ -14185,6 +14190,11 @@ ssl_fc_session_id : binary a server. It is important to note that some browsers refresh their session ID every few minutes. +ssl_fc_session_key : binary + Returns the SSL master key of the front connection when the incoming + connection was made over an SSL/TLS transport layer. It is useful to decrypt + traffic sent using ephemeral ciphers. + ssl_fc_sni : string This extracts the Server Name Indication TLS extension (SNI) field from an incoming connection made via an SSL/TLS transport layer and locally diff --git a/src/ssl_sock.c b/src/ssl_sock.c index af09cfb..2fe7e2f 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -6170,6 +6170,49 @@ smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const ch } static int +smp_fetch_ssl_fc_session_key(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin : + smp->strm ? smp->strm->si[1].end : NULL); + + SSL_SESSION *ssl_sess; + int data_len; + struct chunk *data; + + smp->flags = SMP_F_CONST; + smp->data.type = SMP_T_BIN; + + if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock) + return 0; + + ssl_sess = SSL_get_session(conn->xprt_ctx); + if (!ssl_sess) + return 0; + + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + data = get_trash_chunk(); + data_len = SSL_SESSION_get_master_key(ssl_sess, (unsigned char *)data->str, data->size); + if (!data_len) + return 0; +#else + if (ssl_sess->master_key_length <= 0) + return 0; + + data = get_trash_chunk(); + memcpy(data->str, &ssl_sess->master_key, + ssl_sess->master_key_length); + data_len = ssl_sess->master_key_length; +#endif + + data->len = data_len; + smp->data.u.str = *data; + smp->data.type = SMP_T_BIN; + + return 1; +} + +static int smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private) { #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME @@ -7841,6 +7884,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { { "ssl_bc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV }, { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV }, { "ssl_bc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV }, + { "ssl_bc_session_key", smp_fetch_ssl_fc_session_key, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV }, { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI }, { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI }, { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI }, @@ -7882,6 +7926,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI }, { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI }, { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI }, + { "ssl_fc_session_key", smp_fetch_ssl_fc_session_key, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI }, { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI }, { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI }, -- 2.7.4 (Apple Git-66)