From f20cfa4a4481b9cf5bd644f482f9711dbe32a51d Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 16 Jan 2019 15:12:33 +0000 Subject: [PATCH] GnuTLS: Debug output keying info. OpenSSL: TLS1.2 keying. (cherry picked from commit 385b593e795430036b1685eed9d78d6c83cfcd67) --- src/src/tls-gnu.c | 56 +++++++++++++++++++++++++++++++++++++++++-- src/src/tls-openssl.c | 35 +++++++++++++++++++++++---- 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index f8d3580cb..c6a695cd5 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -67,6 +67,12 @@ require current GnuTLS, then we'll drop support for the ancient libraries). #if GNUTLS_VERSION_NUMBER >= 0x030109 # define SUPPORT_CORK #endif +#if GNUTLS_VERSION_NUMBER >= 0x03010a +# define SUPPORT_GNUTLS_SESS_DESC +#endif +#if GNUTLS_VERSION_NUMBER >= 0x030500 +# define SUPPORT_GNUTLS_KEYLOG +#endif #if GNUTLS_VERSION_NUMBER >= 0x030506 && !defined(DISABLE_OCSP) # define SUPPORT_SRV_OCSP_STACK #endif @@ -1991,6 +1997,18 @@ return 0; #endif +static gstring * +ddump(gnutls_datum_t * d) +{ +gstring * g = string_get((d->size+1) * 2); +uschar * s = d->data; +for (unsigned i = d->size; i > 0; i--, s++) + { + g = string_catn(g, US "0123456789abcdef" + (*s >> 4), 1); + g = string_catn(g, US "0123456789abcdef" + (*s & 0xf), 1); + } +return g; +} /* ------------------------------------------------------------------------ */ /* Exported functions */ @@ -2138,7 +2156,24 @@ if (rc != GNUTLS_E_SUCCESS) return FAIL; } -DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n"); +DEBUG(D_tls) + { + debug_printf("gnutls_handshake was successful\n"); +#ifdef SUPPORT_GNUTLS_SESS_DESC + debug_printf("%s\n", gnutls_session_get_desc(state->session)); +#endif +#ifdef SUPPORT_GNUTLS_KEYLOG + { + gnutls_datum_t c, s; + gstring * gc, * gs; + gnutls_session_get_random(state->session, &c, &s); + gnutls_session_get_master_secret(state->session, &s); + gc = ddump(&c); + gs = ddump(&s); + debug_printf("CLIENT_RANDOM %.*s %.*s\n", (int)gc->ptr, gc->s, (int)gs->ptr, gs->s); + } +#endif + } /* Verify after the fact */ @@ -2447,7 +2482,24 @@ if (rc != GNUTLS_E_SUCCESS) return NULL; } -DEBUG(D_tls) debug_printf("gnutls_handshake was successful\n"); +DEBUG(D_tls) + { + debug_printf("gnutls_handshake was successful\n"); +#ifdef SUPPORT_GNUTLS_SESS_DESC + debug_printf("%s\n", gnutls_session_get_desc(state->session)); +#endif +#ifdef SUPPORT_GNUTLS_KEYLOG + { + gnutls_datum_t c, s; + gstring * gc, * gs; + gnutls_session_get_random(state->session, &c, &s); + gnutls_session_get_master_secret(state->session, &s); + gc = ddump(&c); + gs = ddump(&s); + debug_printf("CLIENT_RANDOM %.*s %.*s\n", (int)gc->ptr, gc->s, (int)gs->ptr, gs->s); + } +#endif + } /* Verify late */ diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index b1f6bd4eb..e49966d98 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -70,6 +70,7 @@ change this guard and punt the issue for a while longer. */ # define EXIM_HAVE_OPENSSL_CHECKHOST # define EXIM_HAVE_OPENSSL_DH_BITS # define EXIM_HAVE_OPENSSL_TLS_METHOD +# define EXIM_HAVE_OPENSSL_KEYLOG # else # define EXIM_NEED_OPENSSL_INIT # endif @@ -2304,16 +2305,28 @@ and initialize things. */ peer_cert(server_ssl, &tls_in, peerdn, sizeof(peerdn)); -construct_cipher_name(server_ssl, cipherbuf, sizeof(cipherbuf), &tls_in.bits); -tls_in.cipher = cipherbuf; - DEBUG(D_tls) { uschar buf[2048]; if (SSL_get_shared_ciphers(server_ssl, CS buf, sizeof(buf)) != NULL) debug_printf("Shared ciphers: %s\n", buf); + +#ifdef EXIM_HAVE_OPENSSL_KEYLOG + { + BIO * bp = BIO_new(BIO_s_mem()); + uschar * s; + int len; + SSL_SESSION_print_keylog(bp, SSL_get_session(server_ssl)); + len = (int) BIO_get_mem_data(bp, CSS &s); + debug_printf("%.*s", len, s); + BIO_free(bp); + } +#endif } +construct_cipher_name(server_ssl, cipherbuf, sizeof(cipherbuf), &tls_in.bits); +tls_in.cipher = cipherbuf; + /* Record the certificate we presented */ { X509 * crt = SSL_get_certificate(server_ssl); @@ -2680,7 +2693,21 @@ if (rc <= 0) return NULL; } -DEBUG(D_tls) debug_printf("SSL_connect succeeded\n"); +DEBUG(D_tls) + { + debug_printf("SSL_connect succeeded\n"); +#ifdef EXIM_HAVE_OPENSSL_KEYLOG + { + BIO * bp = BIO_new(BIO_s_mem()); + uschar * s; + int len; + SSL_SESSION_print_keylog(bp, SSL_get_session(server_ssl)); + len = (int) BIO_get_mem_data(bp, CSS &s); + debug_printf("%.*s", len, s); + BIO_free(bp); + } +#endif + } peer_cert(exim_client_ctx->ssl, tlsp, peerdn, sizeof(peerdn)); -- 2.25.1