diff options
author | Martin Thomson <martin.thomson@gmail.com> | 2017-10-09 11:30:43 +1100 |
---|---|---|
committer | Martin Thomson <martin.thomson@gmail.com> | 2017-10-09 11:30:43 +1100 |
commit | e78fea278cc67fa308ea7b62630c02f8217c3630 (patch) | |
tree | 0d43bcc8af95c8b3c6632571f5121faf4092588c /lib/ssl | |
parent | 474f1bcabd34eee91a34831260ea514660162d2f (diff) | |
parent | c21e2ced85ff55b338ea1758179d358126d9204b (diff) | |
download | nss-hg-e78fea278cc67fa308ea7b62630c02f8217c3630.tar.gz |
Merge NSS trunk to NSS_TLS13_DRAFT19_BRANCH
Diffstat (limited to 'lib/ssl')
-rw-r--r-- | lib/ssl/ssl3con.c | 165 | ||||
-rw-r--r-- | lib/ssl/ssl3exthandle.c | 37 | ||||
-rw-r--r-- | lib/ssl/sslimpl.h | 9 | ||||
-rw-r--r-- | lib/ssl/sslinfo.c | 13 | ||||
-rw-r--r-- | lib/ssl/sslsnce.c | 10 | ||||
-rw-r--r-- | lib/ssl/sslsock.c | 7 | ||||
-rw-r--r-- | lib/ssl/sslt.h | 8 | ||||
-rw-r--r-- | lib/ssl/tls13con.c | 31 |
8 files changed, 188 insertions, 92 deletions
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index d3f0d40b7..5bf4b1cdd 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -230,11 +230,15 @@ static const unsigned int ssl_compression_method_count = static PRBool ssl_CompressionEnabled(sslSocket *ss, SSLCompressionMethod compression) { - SSL3ProtocolVersion version; - if (compression == ssl_compression_null) { return PR_TRUE; /* Always enabled */ } +/* Compression was disabled in NSS 3.33. It is temporarily possible + * to re-enable it by unifdefing the following block. We will remove + * compression entirely in future versions of NSS. */ +#if 0 + SSL3ProtocolVersion version; + if (ss->sec.isServer) { /* We can't easily check that the client didn't attempt TLS 1.3, * so this will have to do. */ @@ -254,6 +258,7 @@ ssl_CompressionEnabled(sslSocket *ss, SSLCompressionMethod compression) return ss->opt.enableDeflate; } #endif +#endif return PR_FALSE; } @@ -5967,35 +5972,14 @@ ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey) goto loser; } -#ifdef NSS_ALLOW_SSLKEYLOGFILE - if (ssl_keylog_iob) { +#ifdef TRACE + if (ssl_trace >= 100) { 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 */ - - /* There could be multiple, concurrent writers to the - * keylog, so we have to do everything in a single call to - * fwrite. */ - char buf[4 + 8 * 2 + 1 + 48 * 2 + 1]; - - strcpy(buf, "RSA "); - hexEncode(buf + 4, enc_pms.data, 8); - buf[20] = ' '; - hexEncode(buf + 21, keyData->data, 48); - buf[sizeof(buf) - 1] = '\n'; - - fwrite(buf, sizeof(buf), 1, ssl_keylog_iob); - fflush(ssl_keylog_iob); - } + ssl_PrintBuf(ss, "Pre-Master Secret", + keyData->data, keyData->len); } } } @@ -6869,6 +6853,8 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, ss->sec.authKeyBits = sid->authKeyBits; ss->sec.keaType = sid->keaType; ss->sec.keaKeyBits = sid->keaKeyBits; + ss->sec.originalKeaGroup = ssl_LookupNamedGroup(sid->keaGroup); + ss->sec.signatureScheme = sid->sigScheme; if (sid->u.ssl3.keys.msIsWrapped) { PK11SlotInfo *slot; @@ -7879,6 +7865,7 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server) sid->references = 1; sid->cached = never_cached; sid->version = ss->version; + sid->sigScheme = ssl_sig_none; sid->u.ssl3.keys.resumable = PR_TRUE; sid->u.ssl3.policy = SSL_ALLOWED; @@ -8492,29 +8479,33 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length) } } } + /* This is a second check for TLS 1.3 and re-handshake to stop us * from re-handshake up to TLS 1.3, so it happens after version * negotiation. */ - if (ss->firstHsDone && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - desc = unexpected_message; - errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; - goto alert_loser; - } - if (ss->firstHsDone && - (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN || - ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) && - !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { - desc = no_renegotiation; - level = alert_warning; - errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; - goto alert_loser; - } - if ((ss->opt.requireSafeNegotiation || - (ss->firstHsDone && ss->peerRequestedProtection)) && - !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { - desc = handshake_failure; - errCode = SSL_ERROR_UNSAFE_NEGOTIATION; - goto alert_loser; + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + if (ss->firstHsDone) { + desc = unexpected_message; + errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; + goto alert_loser; + } + } else { + if (ss->firstHsDone && + (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN || + ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) && + !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { + desc = no_renegotiation; + level = alert_warning; + errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; + goto alert_loser; + } + if ((ss->opt.requireSafeNegotiation || + (ss->firstHsDone && ss->peerRequestedProtection)) && + !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { + desc = handshake_failure; + errCode = SSL_ERROR_UNSAFE_NEGOTIATION; + goto alert_loser; + } } /* We do stateful resumes only if we are in TLS < 1.3 and @@ -8875,6 +8866,8 @@ compression_found: ss->sec.authKeyBits = sid->authKeyBits; ss->sec.keaType = sid->keaType; ss->sec.keaKeyBits = sid->keaKeyBits; + ss->sec.originalKeaGroup = ssl_LookupNamedGroup(sid->keaGroup); + ss->sec.signatureScheme = sid->sigScheme; ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert); @@ -8946,6 +8939,7 @@ compression_found: } if (sid) { /* we had a sid, but it's no longer valid, free it */ + ss->statelessResume = PR_FALSE; SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_not_ok); ss->sec.uncache(sid); ssl_FreeSID(sid); @@ -11133,40 +11127,44 @@ ssl3_SendNextProto(sslSocket *ss) return rv; } -/* called from ssl3_SendFinished +/* called from ssl3_SendFinished and tls13_DeriveSecret. * * This function is simply a debugging aid and therefore does not return a * SECStatus. */ -static void -ssl3_RecordKeyLog(sslSocket *ss) +void +ssl3_RecordKeyLog(sslSocket *ss, const char *label, PK11SymKey *secret) { #ifdef NSS_ALLOW_SSLKEYLOGFILE 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; + /* Longest label is "CLIENT_HANDSHAKE_TRAFFIC_SECRET", master secret is 48 + * bytes which happens to be the largest in TLS 1.3 as well (SHA384). + * Maximum line length: "CLIENT_HANDSHAKE_TRAFFIC_SECRET" (31) + " " (1) + + * client_random (32*2) + " " (1) + + * traffic_secret (48*2) + "\n" (1) = 194. */ + char buf[200]; + unsigned int offset, len; PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); if (!ssl_keylog_iob) return; - rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret); + rv = PK11_ExtractKeyValue(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); + keyData = PK11_GetKeyData(secret); + if (!keyData || !keyData->data) + return; + + len = strlen(label) + 1 + /* label + space */ + SSL3_RANDOM_LENGTH * 2 + 1 + /* client random (hex) + space */ + keyData->len * 2 + 1; /* secret (hex) + newline */ + PORT_Assert(len <= sizeof(buf)); + if (len > sizeof(buf)) return; - } /* https://developer.mozilla.org/en/NSS_Key_Log_Format */ @@ -11174,23 +11172,22 @@ ssl3_RecordKeyLog(sslSocket *ss) * 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; + strcpy(buf, label); + offset = strlen(label); + buf[offset++] += ' '; + hexEncode(buf + offset, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH); + offset += SSL3_RANDOM_LENGTH * 2; + buf[offset++] = ' '; + hexEncode(buf + offset, keyData->data, keyData->len); + offset += keyData->len * 2; + buf[offset++] = '\n'; + + PORT_Assert(offset == len); + + PZ_Lock(ssl_keylog_lock); + if (fwrite(buf, len, 1, ssl_keylog_iob) == 1) + fflush(ssl_keylog_iob); + PZ_Unlock(ssl_keylog_lock); #endif } @@ -11257,7 +11254,7 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags) goto fail; /* error code set by ssl3_FlushHandshake */ } - ssl3_RecordKeyLog(ss); + ssl3_RecordKeyLog(ss, "CLIENT_RANDOM", ss->ssl3.cwSpec->master_secret); return SECSuccess; @@ -11537,6 +11534,12 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid, PK11SymKey *secret) sid->authKeyBits = ss->sec.authKeyBits; sid->keaType = ss->sec.keaType; sid->keaKeyBits = ss->sec.keaKeyBits; + if (ss->sec.keaGroup) { + sid->keaGroup = ss->sec.keaGroup->name; + } else { + sid->keaGroup = ssl_grp_none; + } + sid->sigScheme = ss->sec.signatureScheme; sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); sid->expirationTime = sid->creationTime + ssl3_sid_timeout * PR_USEC_PER_SEC; sid->localCert = CERT_DupCertificate(ss->sec.localCert); diff --git a/lib/ssl/ssl3exthandle.c b/lib/ssl/ssl3exthandle.c index a9c678184..c3d32f696 100644 --- a/lib/ssl/ssl3exthandle.c +++ b/lib/ssl/ssl3exthandle.c @@ -750,6 +750,19 @@ ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket, rv = sslBuffer_AppendNumber(&plaintext, ss->sec.keaKeyBits, 4); if (rv != SECSuccess) goto loser; + if (ss->sec.keaGroup) { + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.keaGroup->name, 4); + if (rv != SECSuccess) + goto loser; + } else { + /* No kea group. Write 0 as invalid value. */ + rv = sslBuffer_AppendNumber(&plaintext, 0, 4); + if (rv != SECSuccess) + goto loser; + } + rv = sslBuffer_AppendNumber(&plaintext, ss->sec.signatureScheme, 4); + if (rv != SECSuccess) + goto loser; /* certificate type */ PORT_Assert(SSL_CERT_IS(ss->sec.serverCert, ss->sec.authType)); @@ -1007,6 +1020,18 @@ ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, return SECFailure; } parsedTicket->keaKeyBits = temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->originalKeaGroup = temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->signatureScheme = (SSLSignatureScheme)temp; /* Read the optional named curve. */ rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); @@ -1184,7 +1209,9 @@ ssl_CreateSIDFromTicket(sslSocket *ss, const SECItem *rawTicket, sid->authKeyBits = parsedTicket->authKeyBits; sid->keaType = parsedTicket->keaType; sid->keaKeyBits = parsedTicket->keaKeyBits; + sid->keaGroup = parsedTicket->originalKeaGroup; sid->namedCurve = parsedTicket->namedCurve; + sid->sigScheme = parsedTicket->signatureScheme; rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.locked.sessionTicket.ticket, rawTicket); @@ -1378,14 +1405,12 @@ ssl3_SendRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRInt32 len = 0; SECStatus rv; - /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send - * both the SCSV and the empty RI, so when we send SCSV in - * the initial handshake, we don't also send RI. + /* In RFC 5746, it is NOT RECOMMENDED to send both the SCSV and the empty + * RI, so when we send SCSV in the initial handshake, we don't also send RI. */ - if (!ss || ss->ssl3.hs.sendingSCSV) { - return SECSuccess; + if (ss->ssl3.hs.sendingSCSV) { + return 0; } - if (ss->firstHsDone) { len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2 : ss->ssl3.hs.finishedBytes; diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h index 28d326617..81b22760b 100644 --- a/lib/ssl/sslimpl.h +++ b/lib/ssl/sslimpl.h @@ -551,6 +551,8 @@ struct sslSessionIDStr { PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; + SSLNamedGroup keaGroup; + SSLSignatureScheme sigScheme; union { struct { @@ -1014,6 +1016,8 @@ typedef struct SessionTicketStr { PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; + SSLNamedGroup originalKeaGroup; + SSLSignatureScheme signatureScheme; const sslNamedGroupDef *namedCurve; /* For certificate lookup. */ /* @@ -1082,6 +1086,7 @@ struct sslSecurityInfoStr { SSLKEAType keaType; PRUint32 keaKeyBits; const sslNamedGroupDef *keaGroup; + const sslNamedGroupDef *originalKeaGroup; /* The selected certificate (for servers only). */ const sslServerCert *serverCert; @@ -1260,6 +1265,7 @@ extern char ssl_debug; extern char ssl_trace; extern FILE *ssl_trace_iob; extern FILE *ssl_keylog_iob; +extern PZLock *ssl_keylog_lock; extern PRUint32 ssl3_sid_timeout; extern PRUint32 ssl_ticket_lifetime; extern PRUint32 ssl_max_early_data_size; @@ -1873,6 +1879,9 @@ ssl3_TLSPRFWithMasterSecret(sslSocket *ss, ssl3CipherSpec *spec, const unsigned char *val, unsigned int valLen, unsigned char *out, unsigned int outLen); +extern void +ssl3_RecordKeyLog(sslSocket *ss, const char *label, PK11SymKey *secret); + PRBool ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag); #ifdef TRACE diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c index f2b680d00..a8b4f2f26 100644 --- a/lib/ssl/sslinfo.c +++ b/lib/ssl/sslinfo.c @@ -79,11 +79,22 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) /* Get these fromm |ss->sec| because that is accurate * even with TLS 1.3 disaggregated cipher suites. */ inf.keaType = ss->sec.keaType; - inf.keaGroup = ss->sec.keaGroup ? ss->sec.keaGroup->name : ssl_grp_none; + inf.originalKeaGroup = ss->sec.originalKeaGroup + ? ss->sec.originalKeaGroup->name + : ssl_grp_none; + inf.keaGroup = ss->sec.keaGroup + ? ss->sec.keaGroup->name + : ssl_grp_none; inf.keaKeyBits = ss->sec.keaKeyBits; inf.authType = ss->sec.authType; inf.authKeyBits = ss->sec.authKeyBits; inf.signatureScheme = ss->sec.signatureScheme; + /* If this is a resumed session, signatureScheme isn't set in ss->sec. + * Use the signature scheme from the previous handshake. */ + if (inf.signatureScheme == ssl_sig_none && sid->sigScheme) { + inf.signatureScheme = sid->sigScheme; + } + inf.resumed = ss->statelessResume || ss->ssl3.hs.isResuming; } if (sid) { unsigned int sidLen; diff --git a/lib/ssl/sslsnce.c b/lib/ssl/sslsnce.c index cf9b0b424..7b86e074a 100644 --- a/lib/ssl/sslsnce.c +++ b/lib/ssl/sslsnce.c @@ -99,7 +99,9 @@ struct sidCacheEntryStr { /* 2 */ PRUint16 authKeyBits; /* 2 */ PRUint16 keaType; /* 2 */ PRUint16 keaKeyBits; - /* 84 - common header total */ + /* 4 */ PRUint32 signatureScheme; + /* 4 */ PRUint32 keaGroup; + /* 92 - common header total */ union { struct { @@ -117,7 +119,7 @@ struct sidCacheEntryStr { /* force sizeof(sidCacheEntry) to be a multiple of cache line size */ struct { - /*124 */ PRUint8 filler[124]; /* 84+124==208, a multiple of 16 */ + /*112 */ PRUint8 filler[112]; /* 80+112==192, a multiple of 16 */ } forceSize; } u; }; @@ -433,6 +435,8 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from) to->authKeyBits = from->authKeyBits; to->keaType = from->keaType; to->keaKeyBits = from->keaKeyBits; + to->keaGroup = from->keaGroup; + to->signatureScheme = from->sigScheme; to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite; to->u.ssl3.compression = (PRUint16)from->u.ssl3.compression; @@ -543,6 +547,8 @@ ConvertToSID(sidCacheEntry *from, to->authKeyBits = from->authKeyBits; to->keaType = from->keaType; to->keaKeyBits = from->keaKeyBits; + to->keaGroup = from->keaGroup; + to->sigScheme = from->signatureScheme; return to; diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c index 7dcd6ceab..9d8002759 100644 --- a/lib/ssl/sslsock.c +++ b/lib/ssl/sslsock.c @@ -119,6 +119,7 @@ FILE *ssl_trace_iob; #ifdef NSS_ALLOW_SSLKEYLOGFILE FILE *ssl_keylog_iob; +PZLock *ssl_keylog_lock; #endif char lockStatus[] = "Locks are ENABLED. "; @@ -3577,6 +3578,12 @@ ssl_SetDefaultsFromEnvironment(void) ssl_keylog_iob); } SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev)); + ssl_keylog_lock = PR_NewLock(); + if (!ssl_keylog_lock) { + SSL_TRACE(("SSL: failed to create key log lock")); + fclose(ssl_keylog_iob); + ssl_keylog_iob = NULL; + } } } #endif diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h index b4127d77f..177d24f7a 100644 --- a/lib/ssl/sslt.h +++ b/lib/ssl/sslt.h @@ -297,6 +297,14 @@ typedef struct SSLChannelInfoStr { SSLAuthType authType; SSLSignatureScheme signatureScheme; + /* The following fields were added in NSS 3.34. */ + /* When the session was resumed this holds the key exchange group of the + * original handshake. */ + SSLNamedGroup originalKeaGroup; + /* This field is PR_TRUE when the session is resumed and PR_FALSE + * otherwise. */ + PRBool resumed; + /* When adding new fields to this structure, please document the * NSS version in which they were added. */ } SSLChannelInfo; diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c index 0d563f274..7099ea7e3 100644 --- a/lib/ssl/tls13con.c +++ b/lib/ssl/tls13con.c @@ -67,6 +67,7 @@ static SECStatus tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key, const char *prefix, const char *suffix, + const char *keylogLabel, PK11SymKey **dest); static SECStatus tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, @@ -120,6 +121,13 @@ const char kHkdfPurposeKey[] = "key"; const char kHkdfPurposeIv[] = "iv"; const char kKeyPhaseCleartext[] = "clear"; +const char keylogLabelClientEarlyTrafficSecret[] = "CLIENT_EARLY_TRAFFIC_SECRET"; +const char keylogLabelClientHsTrafficSecret[] = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; +const char keylogLabelServerHsTrafficSecret[] = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; +const char keylogLabelClientTrafficSecret[] = "CLIENT_TRAFFIC_SECRET_0"; +const char keylogLabelServerTrafficSecret[] = "SERVER_TRAFFIC_SECRET_0"; +const char keylogLabelExporterSecret[] = "EXPORTER_SECRET"; + #define TRAFFIC_SECRET(ss, dir, name) ((ss->sec.isServer ^ \ (dir == CipherSpecWrite)) \ ? ss->ssl3.hs.client##name \ @@ -822,6 +830,7 @@ tls13_ComputeHandshakeSecrets(sslSocket *ss) rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, kHkdfLabelHandshakeTrafficSecret, + keylogLabelClientHsTrafficSecret, &ss->ssl3.hs.clientHsTrafficSecret); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); @@ -830,6 +839,7 @@ tls13_ComputeHandshakeSecrets(sslSocket *ss) rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, kHkdfLabelServer, kHkdfLabelHandshakeTrafficSecret, + keylogLabelServerHsTrafficSecret, &ss->ssl3.hs.serverHsTrafficSecret); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); @@ -872,6 +882,7 @@ tls13_ComputeApplicationSecrets(sslSocket *ss) rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, kHkdfLabelApplicationTrafficSecret, + keylogLabelClientTrafficSecret, &ss->ssl3.hs.clientTrafficSecret); if (rv != SECSuccess) { return SECFailure; @@ -879,6 +890,7 @@ tls13_ComputeApplicationSecrets(sslSocket *ss) rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, kHkdfLabelServer, kHkdfLabelApplicationTrafficSecret, + keylogLabelServerTrafficSecret, &ss->ssl3.hs.serverTrafficSecret); if (rv != SECSuccess) { return SECFailure; @@ -886,6 +898,7 @@ tls13_ComputeApplicationSecrets(sslSocket *ss) rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, NULL, kHkdfLabelExporterMasterSecret, + keylogLabelExporterSecret, &ss->ssl3.hs.exporterSecret); if (rv != SECSuccess) { return SECFailure; @@ -904,6 +917,7 @@ tls13_ComputeFinalSecrets(sslSocket *ss) rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, NULL, kHkdfLabelResumptionMasterSecret, + NULL, &ss->ssl3.hs.resumptionMasterSecret); PK11_FreeSymKey(ss->ssl3.hs.currentSecret); ss->ssl3.hs.currentSecret = NULL; @@ -923,6 +937,8 @@ tls13_RestoreCipherInfo(sslSocket *ss, sslSessionID *sid) */ ss->sec.authType = sid->authType; ss->sec.authKeyBits = sid->authKeyBits; + ss->sec.originalKeaGroup = ssl_LookupNamedGroup(sid->keaGroup); + ss->sec.signatureScheme = sid->sigScheme; } /* Check whether resumption-PSK is allowed. */ @@ -1588,6 +1604,7 @@ tls13_HandleClientHelloPart2(sslSocket *ss, rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, kHkdfLabelEarlyTrafficSecret, + keylogLabelClientEarlyTrafficSecret, &ss->ssl3.hs.clientEarlyTrafficSecret); if (rv != SECSuccess) { FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error); @@ -2826,6 +2843,7 @@ static SECStatus tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key, const char *prefix, const char *suffix, + const char *keylogLabel, PK11SymKey **dest) { SECStatus rv; @@ -2855,8 +2873,16 @@ tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key, return SECFailure; } - return tls13_DeriveSecret(ss, key, label, strlen(label), - &hashes, dest); + rv = tls13_DeriveSecret(ss, key, label, strlen(label), + &hashes, dest); + if (rv != SECSuccess) { + return SECFailure; + } + + if (keylogLabel) { + ssl3_RecordKeyLog(ss, keylogLabel, *dest); + } + return SECSuccess; } /* Derive traffic keys for the next cipher spec in the queue. */ @@ -4813,6 +4839,7 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss) rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, kHkdfLabelEarlyTrafficSecret, + keylogLabelClientEarlyTrafficSecret, &ss->ssl3.hs.clientEarlyTrafficSecret); if (rv != SECSuccess) return SECFailure; |