From be4d8fa77ddb1aff903b770980b79e02671d79b9 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 3 Dec 2013 18:14:43 +0100 Subject: [PATCH] Implement SSLKEYLOGFILE support for ClientRandom Based on NSS code, the format of the SSLKEYLOGFILE file is documented at https://developer.mozilla.org/en-US/docs/NSS_Key_Log_Format This debugging facility allows the master-key established in a SSL handshake to be saved to a file specified by the SSLKEYLOGFILE. --- src/internal.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/ssl.c | 16 ++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/internal.c b/src/internal.c index 85e64f9..acb2a52 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5423,6 +5423,47 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, return sz; } +static void hexEncode(byte* dst_str, const byte* src_bytes, size_t src_len) +{ + const byte hex[] = "0123456789abcdef"; + size_t n; + + for (n = 0; n < src_len; ++n) { + byte val = *src_bytes++; + *dst_str++ = hex[val >> 4]; + *dst_str++ = hex[val & 0xf]; + } +} + +/* defined in src/ssl.c */ +extern FILE* ssl_keylog_iob; + +static void RecordKeyLog(CYASSL* ssl) +{ + byte buf[14 /* "CLIENT_RANDOM " */ + + RAN_LEN*2 /* client_random */ + + 1 /* " " */ + + SECRET_LEN*2 /* master secret */ + + 1 /* new line */]; + unsigned int j; + + if (!ssl_keylog_iob) + return; + + memcpy(buf, "CLIENT_RANDOM ", 14); + j = 14; + hexEncode(buf + j, ssl->arrays->clientRandom, RAN_LEN); + j += RAN_LEN*2; + buf[j++] = ' '; + hexEncode(buf + j, ssl->arrays->masterSecret, SECRET_LEN); + j += SECRET_LEN*2; + buf[j] = '\n'; + + if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1) + return; + fflush(ssl_keylog_iob); +} + int SendFinished(CYASSL* ssl) { @@ -5529,6 +5570,8 @@ int SendFinished(CYASSL* ssl) ssl->buffers.outputBuffer.length += sendSz; + RecordKeyLog(ssl); + return SendBuffered(ssl); } diff --git a/src/ssl.c b/src/ssl.c index 827369f..1332839 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1496,9 +1496,12 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) #endif /* NO_SESSION_CACHE */ +FILE* ssl_keylog_iob; + int CyaSSL_Init(void) { int ret = SSL_SUCCESS; + char* keylogfile; CYASSL_ENTER("CyaSSL_Init"); @@ -1519,6 +1522,19 @@ int CyaSSL_Init(void) UnLockMutex(&count_mutex); } + /* used in src/internal.c, format is described at + * https://developer.mozilla.org/en-US/docs/NSS_Key_Log_Format */ + keylogfile = getenv("SSLKEYLOGFILE"); + if (keylogfile && keylogfile[0]) { + ssl_keylog_iob = fopen(keylogfile, "a"); + if (ssl_keylog_iob) { + if (ftell(ssl_keylog_iob) == 0) { + fputs("# SSL/TLS secrets log file, generated by CyaSSL\n", + ssl_keylog_iob); + } + } + } + return ret; } -- 1.8.4.2