Index: net/third_party/nss/patches/keylog.patch |
diff --git a/net/third_party/nss/patches/keylog.patch b/net/third_party/nss/patches/keylog.patch |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b40c6ecd86f53b027a3d5925df44f8ce92ac9b0b |
--- /dev/null |
+++ b/net/third_party/nss/patches/keylog.patch |
@@ -0,0 +1,186 @@ |
+diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c |
+index 6780a84..4cf011b 100644 |
+--- a/net/third_party/nss/ssl/ssl3con.c |
++++ b/net/third_party/nss/ssl/ssl3con.c |
+@@ -4793,6 +4793,17 @@ done: |
+ return unwrappedWrappingKey; |
+ } |
+ |
++/* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2| |
++ * bytes to |out|. */ |
++static void hexEncode(char *out, const unsigned char *in, size_t length) { |
++ static const char hextable[] = "0123456789abcdef"; |
++ size_t i; |
++ |
++ for (i = 0; i < length; i++) { |
++ *(out++) = hextable[in[i] >> 4]; |
++ *(out++) = hextable[in[i] & 15]; |
++ } |
++} |
+ |
+ /* Called from ssl3_SendClientKeyExchange(). */ |
+ /* Presently, this always uses PKCS11. There is no bypass for this. */ |
+@@ -4832,16 +4843,17 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
+ goto loser; |
+ } |
+ |
+-#if defined(TRACE) |
+- if (ssl_trace >= 100 || ssl_keylog_iob) { |
++ if (ssl_keylog_iob) { |
+ SECStatus extractRV = PK11_ExtractKeyValue(pms); |
+ if (extractRV == SECSuccess) { |
+ SECItem * keyData = PK11_GetKeyData(pms); |
+ if (keyData && keyData->data && keyData->len) { |
++#ifdef TRACE |
+ if (ssl_trace >= 100) { |
+ ssl_PrintBuf(ss, "Pre-Master Secret", |
+ keyData->data, keyData->len); |
+ } |
++#endif |
+ if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) { |
+ /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ |
+ |
+@@ -4849,21 +4861,11 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
+ * keylog, so we have to do everything in a single call to |
+ * fwrite. */ |
+ char buf[4 + 8*2 + 1 + 48*2 + 1]; |
+- static const char hextable[16] = "0123456789abcdef"; |
+- unsigned int i; |
+ |
+ strcpy(buf, "RSA "); |
+- |
+- for (i = 0; i < 8; i++) { |
+- buf[4 + i*2] = hextable[enc_pms.data[i] >> 4]; |
+- buf[4 + i*2 + 1] = hextable[enc_pms.data[i] & 15]; |
+- } |
++ hexEncode(buf + 4, enc_pms.data, 8); |
+ buf[20] = ' '; |
+- |
+- for (i = 0; i < 48; i++) { |
+- buf[21 + i*2] = hextable[keyData->data[i] >> 4]; |
+- buf[21 + i*2 + 1] = hextable[keyData->data[i] & 15]; |
+- } |
++ hexEncode(buf + 21, keyData->data, 48); |
+ buf[sizeof(buf) - 1] = '\n'; |
+ |
+ fwrite(buf, sizeof(buf), 1, ssl_keylog_iob); |
+@@ -4872,7 +4874,6 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
+ } |
+ } |
+ } |
+-#endif |
+ |
+ rv = ssl3_InitPendingCipherSpec(ss, pms); |
+ PK11_FreeSymKey(pms); pms = NULL; |
+@@ -9046,6 +9047,69 @@ ssl3_RestartHandshakeAfterChannelIDReq(sslSocket *ss, |
+ return SECSuccess; |
+ } |
+ |
++/* called from ssl3_SendFinished |
++ * |
++ * Caller must already hold the SpecReadLock. (wish we could assert that!). |
++ * This function is simply a debugging aid and therefore does not return a |
++ * SECStatus. */ |
++static void |
++ssl3_RecordKeyLog(sslSocket *ss) |
++{ |
++ sslSessionID *sid; |
++ SECStatus rv; |
++ SECItem *keyData; |
++ char buf[14 /* "CLIENT_RANDOM " */ + |
++ SSL3_RANDOM_LENGTH*2 /* client_random */ + |
++ 1 /* " " */ + |
++ 48*2 /* master secret */ + |
++ 1 /* new line */]; |
++ unsigned int j; |
++ |
++ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
++ |
++ sid = ss->sec.ci.sid; |
++ |
++ if (!ssl_keylog_iob) |
++ return; |
++ |
++ rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret); |
++ if (rv != SECSuccess) |
++ return; |
++ |
++ ssl_GetSpecReadLock(ss); |
++ |
++ /* keyData does not need to be freed. */ |
++ keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret); |
++ if (!keyData || !keyData->data || keyData->len != 48) { |
++ ssl_ReleaseSpecReadLock(ss); |
++ return; |
++ } |
++ |
++ /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ |
++ |
++ /* There could be multiple, concurrent writers to the |
++ * keylog, so we have to do everything in a single call to |
++ * fwrite. */ |
++ |
++ memcpy(buf, "CLIENT_RANDOM ", 14); |
++ j = 14; |
++ hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); |
++ j += SSL3_RANDOM_LENGTH*2; |
++ buf[j++] = ' '; |
++ hexEncode(buf + j, keyData->data, 48); |
++ j += 48*2; |
++ buf[j++] = '\n'; |
++ |
++ PORT_Assert(j == sizeof(buf)); |
++ |
++ ssl_ReleaseSpecReadLock(ss); |
++ |
++ if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1) |
++ return; |
++ fflush(ssl_keylog_iob); |
++ return; |
++} |
++ |
+ /* called from ssl3_HandleServerHelloDone |
+ * ssl3_HandleClientHello |
+ * ssl3_HandleFinished |
+@@ -9107,6 +9171,9 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags) |
+ if (rv != SECSuccess) { |
+ goto fail; /* error code set by ssl3_FlushHandshake */ |
+ } |
++ |
++ ssl3_RecordKeyLog(ss); |
++ |
+ return SECSuccess; |
+ |
+ fail: |
+diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c |
+index c61ab44..3bd11d2 100644 |
+--- a/net/third_party/nss/ssl/sslsock.c |
++++ b/net/third_party/nss/ssl/sslsock.c |
+@@ -2903,6 +2903,13 @@ ssl_SetDefaultsFromEnvironment(void) |
+ ssl_trace = atoi(ev); |
+ SSL_TRACE(("SSL: tracing set to %d", ssl_trace)); |
+ } |
++#endif /* TRACE */ |
++ ev = getenv("SSLDEBUG"); |
++ if (ev && ev[0]) { |
++ ssl_debug = atoi(ev); |
++ SSL_TRACE(("SSL: debugging set to %d", ssl_debug)); |
++ } |
++#endif /* DEBUG */ |
+ ev = getenv("SSLKEYLOGFILE"); |
+ if (ev && ev[0]) { |
+ ssl_keylog_iob = fopen(ev, "a"); |
+@@ -2912,13 +2919,6 @@ ssl_SetDefaultsFromEnvironment(void) |
+ } |
+ SSL_TRACE(("SSL: logging pre-master secrets to %s", ev)); |
+ } |
+-#endif /* TRACE */ |
+- ev = getenv("SSLDEBUG"); |
+- if (ev && ev[0]) { |
+- ssl_debug = atoi(ev); |
+- SSL_TRACE(("SSL: debugging set to %d", ssl_debug)); |
+- } |
+-#endif /* DEBUG */ |
+ ev = getenv("SSLBYPASS"); |
+ if (ev && ev[0]) { |
+ ssl_defaults.bypassPKCS11 = (ev[0] == '1'); |