On 2017/6/16 09:34, Willy Tarreau wrote:
> Hi Patrick,
>
> On Mon, Jun 12, 2017 at 07:31:36PM -0400, Patrick Hemmer wrote:
>> 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.
> No problem, that's what public review is made for. BTW at first glance
> your patch looks clean ;-)
>
>> 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.
> I'd then suggest to proceed differently (if that's OK for you), which
> is to only expose this sample fetch function in 1.1.0 and above. If
> you're fine with running on 1.1 you won't feel any difference. Others
> who don't need this sample fetch right now will not feel any risk of
> build problem.
The main reason I had for supporting the older code is that it seems
many (most?) linux distros, such as the one we use (CentOS/7), still
ship with 1.0.1 or 1.0.2. However since this is a minor change and a
feature enhancement, I doubt this will get backported to 1.7, meaning
we'll have to manually patch it into the version we use. And since we're
doing that, we can just use the patch that supports older OpenSSL.

Anyway, here is the updated patch with the support for <1.1.0 dropped,
as well as the BoringSSL support Emmanuel requested.

One other minor thing I was unsure about was the fetch name. Currently I
have it as "ssl_fc_session_key", but "ssl_fc_session_master_key" might
be more accurate. However this is rather verbose and would make it far
longer than any other sample fetch name, and I was unsure if there were
rules around the naming.

-Patrick
From 217f02d6cd39cb0f40cae74098acf3b586442194 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        | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 49bfd85..3b9d96e 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 session 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 session 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 3680515..73fbc31 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6170,6 +6170,40 @@ 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)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L || defined(OPENSSL_IS_BORINGSSL)
+       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;
+
+       if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
+               return 0;
+
+       ssl_sess = SSL_get_session(conn->xprt_ctx);
+       if (!ssl_sess)
+               return 0;
+
+       data = get_trash_chunk();
+       data_len = SSL_SESSION_get_master_key(ssl_sess, (unsigned char 
*)data->str, data->size);
+       if (!data_len)
+               return 0;
+
+       smp->flags = SMP_F_CONST;
+       smp->data.type = SMP_T_BIN;
+       data->len = data_len;
+       smp->data.u.str = *data;
+
+       return 1;
+#else
+       return 0;
+#endif
+}
+
+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 +7875,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 +7917,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)

Reply via email to