Bug 1256143 - Dump TLS 1.3 intermediate values for debugging. r=mt
authorEKR <ekr@rtfm.com>
Sun, 13 Mar 2016 14:39:48 +0100
changeset 11987 c03680bf22ec81f2b544064324c2272b5a14391e
parent 11986 7947fd4431c579dabf087fd3b4ff1696d773cc4b
child 11988 6a3f96b8c70d593c6bcf6a67c0114172663dbd6a
push id1060
push userekr@mozilla.com
push dateMon, 14 Mar 2016 12:13:50 +0000
reviewersmt
bugs1256143
Bug 1256143 - Dump TLS 1.3 intermediate values for debugging. r=mt
lib/ssl/sslimpl.h
lib/ssl/ssltrace.c
lib/ssl/tls13con.c
lib/ssl/tls13hkdf.c
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -81,19 +81,23 @@ extern int Debug;
 
 #ifdef TRACE
 #define SSL_TRC(a, b)     \
     if (ssl_trace >= (a)) \
     ssl_Trace b
 #define PRINT_BUF(a, b)   \
     if (ssl_trace >= (a)) \
     ssl_PrintBuf b
+#define PRINT_KEY(a, b) \
+    if (ssl_trace >= (a)) \
+    ssl_PrintKey b
 #else
 #define SSL_TRC(a, b)
 #define PRINT_BUF(a, b)
+#define PRINT_KEY(a, b)
 #endif
 
 #ifdef DEBUG
 #define SSL_DBG(b) \
     if (ssl_debug) \
     ssl_Trace b
 #else
 #define SSL_DBG(b)
@@ -1352,16 +1356,17 @@ extern void ssl3_DestroyGather(sslGather
 extern SECStatus ssl_GatherRecord1stHandshake(sslSocket *ss);
 
 extern SECStatus ssl_CreateSecurityInfo(sslSocket *ss);
 extern SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os);
 extern void ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset);
 extern void ssl_DestroySecurityInfo(sslSecurityInfo *sec);
 
 extern void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *cp, int len);
+extern void ssl_PrintKey(sslSocket *ss, const char *msg, PK11SymKey* key);
 
 extern int ssl_SendSavedWriteData(sslSocket *ss);
 extern SECStatus ssl_SaveWriteData(sslSocket *ss,
                                    const void *p, unsigned int l);
 extern SECStatus ssl_BeginClientHandshake(sslSocket *ss);
 extern SECStatus ssl_BeginServerHandshake(sslSocket *ss);
 extern int ssl_Do1stHandshake(sslSocket *ss);
 
--- a/lib/ssl/ssltrace.c
+++ b/lib/ssl/ssltrace.c
@@ -1,16 +1,17 @@
 /*
  * Functions to trace SSL protocol behavior in DEBUG builds.
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include <stdarg.h>
 #include "cert.h"
+#include "pk11func.h"
 #include "ssl.h"
 #include "sslimpl.h"
 #include "sslproto.h"
 #include "prprf.h"
 
 #if defined(DEBUG) || defined(TRACE)
 static const char *hex = "0123456789abcdef";
 
@@ -80,9 +81,28 @@ ssl_Trace(const char *format, ...)
         va_start(args, format);
         PR_vsnprintf(buf, sizeof(buf), format, args);
         va_end(args);
 
         fputs(buf, ssl_trace_iob);
         fputs("\n", ssl_trace_iob);
     }
 }
+
+void
+ssl_PrintKey(sslSocket *ss, const char *msg, PK11SymKey* key)
+{
+    SECStatus rv;
+    SECItem *rawkey;
+
+    rv = PK11_ExtractKeyValue(key);
+    if (rv != SECSuccess) {
+        ssl_Trace("Could not extract key for %s", msg);
+        return;
+    }
+    rawkey = PK11_GetKeyData(key);
+    if (!rawkey) {
+        ssl_Trace("Could not extract key for %s", msg);
+        return;
+    }
+    ssl_PrintBuf(ss, msg, rawkey->data, rawkey->len);
+}
 #endif
--- a/lib/ssl/tls13con.c
+++ b/lib/ssl/tls13con.c
@@ -899,16 +899,18 @@ tls13_AddContextToHashes(sslSocket *ss, 
     if (!ctx) {
         PORT_SetError(SEC_ERROR_NO_MEMORY);
         goto loser;
     }
 
     PORT_Assert(SECFailure);
     PORT_Assert(!SECSuccess);
 
+    PRINT_BUF(90, (ss, "TLS 1.3 hash without context", hashes->u.raw, hashes->len));
+    PRINT_BUF(90, (ss, "Context string", context_string, strlen(context_string)));
     rv |= PK11_DigestBegin(ctx);
     rv |= PK11_DigestOp(ctx, context_padding, sizeof(context_padding));
     rv |= PK11_DigestOp(ctx, (unsigned char *)context_string,
                         strlen(context_string) + 1); /* +1 includes the terminating 0 */
     rv |= PK11_DigestOp(ctx, hashes->u.raw, hashes->len);
     /* Update the hash in-place */
     rv |= PK11_DigestFinal(ctx, hashes->u.raw, &hashlength, sizeof(hashes->u.raw));
     PK11_DestroyContext(ctx, PR_TRUE);
--- a/lib/ssl/tls13hkdf.c
+++ b/lib/ssl/tls13hkdf.c
@@ -4,18 +4,20 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "keyhi.h"
 #include "pk11func.h"
 #include "secitem.h"
+#include "ssl.h"
 #include "sslt.h"
 #include "sslerr.h"
+#include "sslimpl.h"
 
 // TODO(ekr@rtfm.com): Export this separately.
 unsigned char *tls13_EncodeUintX(PRUint32 value, unsigned int bytes, unsigned char *to);
 
 /* This table contains the mapping between TLS hash identifiers and the
  * PKCS#11 identifiers */
 static const struct {
     SSLHashType hash;
@@ -75,18 +77,19 @@ tls13_HkdfExtract(PK11SymKey *ikm1, PK11
     PORT_Assert(kTlsHkdfInfo[baseHash].pkcs11Mech);
     PORT_Assert(kTlsHkdfInfo[baseHash].hashSize);
     PORT_Assert(kTlsHkdfInfo[baseHash].hash == baseHash);
     prk = PK11_Derive(ikm2, kTlsHkdfInfo[baseHash].pkcs11Mech,
                       &paramsi, kTlsHkdfInfo[baseHash].pkcs11Mech,
                       CKA_DERIVE, kTlsHkdfInfo[baseHash].hashSize);
     if (!prk)
         return SECFailure;
+    PRINT_KEY(60, (NULL, "HKDF Extract", prk));
+    *prkp = prk;
 
-    *prkp = prk;
     return SECSuccess;
 }
 
 SECStatus
 tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash,
                       const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
                       const char *label, unsigned int labelLen,
                       CK_MECHANISM_TYPE algorithm, unsigned int keySize,
@@ -157,16 +160,31 @@ tls13_HkdfExpandLabel(PK11SymKey *prk, S
                                    &paramsi, algorithm,
                                    CKA_DERIVE, keySize,
                                    CKF_SIGN | CKF_VERIFY);
     if (!derived)
         return SECFailure;
 
     *keyp = derived;
 
+#ifdef TRACE
+    if (ssl_trace >= 10) {
+        /* Make sure the label is null terminated. */
+        char labelStr[100];
+        PORT_Memcpy(labelStr, label, labelLen);
+        labelStr[labelLen] = 0;
+        SSL_TRC(60, ("HKDF Expand: label=[TLS 1.3, ] + '%s',requested length=%d",
+                     labelStr, keySize));
+    }
+    PRINT_KEY(60, (NULL, "PRK", prk));
+    PRINT_BUF(60, (NULL, "Hash", handshakeHash, handshakeHashLen));
+    PRINT_BUF(60, (NULL, "Info", info, infoLen));
+    PRINT_KEY(60, (NULL, "Derived key", derived));
+#endif
+
     return SECSuccess;
 
 abort:
     PORT_SetError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
     return SECFailure;
 }
 
 SECStatus