From cfd7311b8beb4daafe9f64ffa2336b335ef666dd Mon Sep 17 00:00:00 2001 From: EKR Date: Mon, 4 Sep 2017 06:11:51 -0700 Subject: Bug 1370893 - Disable compression. r=ttaubert Bug #: 1370893 Differential Revision: https://phabricator.services.mozilla.com/D27 --- lib/ssl/ssl3con.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index c616e2a96..8daad7c50 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -1,3 +1,4 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * SSL3 Protocol @@ -233,11 +234,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. */ @@ -256,6 +261,7 @@ ssl_CompressionEnabled(sslSocket *ss, SSLCompressionMethod compression) } return ss->opt.enableDeflate; } +#endif #endif return PR_FALSE; } -- cgit v1.2.1 From 3e74ea8fcf7752a9f6ffe973927f40e56063cb22 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 4 Sep 2017 15:05:11 +1000 Subject: Bug 1375837 - Allow TLS 1.3 when renegotiation isn't enabled, r=ekr --- lib/ssl/ssl3con.c | 44 ++++++++++++++++++++++++-------------------- lib/ssl/ssl3exthandle.c | 8 ++++---- 2 files changed, 28 insertions(+), 24 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index 8daad7c50..a36c88ed4 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -8539,29 +8539,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 diff --git a/lib/ssl/ssl3exthandle.c b/lib/ssl/ssl3exthandle.c index 370bd8b3e..bda3d375f 100644 --- a/lib/ssl/ssl3exthandle.c +++ b/lib/ssl/ssl3exthandle.c @@ -1497,12 +1497,12 @@ ssl3_SendRenegotiationInfoXtn( PRInt32 len = 0; PRInt32 needed; - /* 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) + if (ss->ssl3.hs.sendingSCSV) { return 0; + } if (ss->firstHsDone) { len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2 : ss->ssl3.hs.finishedBytes; -- cgit v1.2.1 From 0b7c6d5be40edeb36dbf7b18db725d47966abc90 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 3 Oct 2017 10:24:36 -0700 Subject: Bug 1287711 - Implement SSLKEYLOGFILE for TLS 1.3 (v2) Summary: Extend the previous keylogging functionality with TLS 1.3 support. Verified that a session between nss (selfserv) and boringssl 15868b3bbaa resulted in the same keys and that it can be used with Wireshark. Reviewers: mt, ekr Reviewed By: mt Bug #: 1287711 Differential Revision: https://phabricator.services.mozilla.com/D82 --- lib/ssl/ssl3con.c | 62 ++++++++++++++++++++++++++++-------------------------- lib/ssl/sslimpl.h | 3 +++ lib/ssl/tls13con.c | 34 ++++++++++++++++++++++++------ 3 files changed, 63 insertions(+), 36 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index a36c88ed4..1167a0081 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -11160,40 +11160,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 */ @@ -11201,23 +11205,21 @@ 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'; + 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(j == sizeof(buf)); - - ssl_ReleaseSpecReadLock(ss); + PORT_Assert(offset == len); - if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1) + if (fwrite(buf, len, 1, ssl_keylog_iob) != 1) return; fflush(ssl_keylog_iob); - return; #endif } @@ -11284,7 +11286,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; diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h index 0ffaa3a6a..7ae84cd2e 100644 --- a/lib/ssl/sslimpl.h +++ b/lib/ssl/sslimpl.h @@ -1879,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/tls13con.c b/lib/ssl/tls13con.c index fff6f71f4..42918a5db 100644 --- a/lib/ssl/tls13con.c +++ b/lib/ssl/tls13con.c @@ -75,6 +75,7 @@ static SECStatus tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, const char *prefix, const char *suffix, + const char *keylogLabel, const SSL3Hashes *hashes, PK11SymKey **dest); static SECStatus tls13_SendEndOfEarlyData(sslSocket *ss); @@ -120,6 +121,13 @@ const char kHkdfLabelExporterMasterSecret[] = "exporter master secret"; const char kHkdfPurposeKey[] = "key"; const char kHkdfPurposeIv[] = "iv"; +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 \ @@ -757,14 +765,14 @@ tls13_ComputeEarlySecrets(sslSocket *ss) hashes.len = tls13_GetHashSize(ss); rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - NULL, kHkdfLabelPskBinderKey, &hashes, + NULL, kHkdfLabelPskBinderKey, NULL, &hashes, &ss->ssl3.hs.pskBinderKey); if (rv != SECSuccess) { return SECFailure; } rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, - NULL, kHkdfLabelEarlyExporterSecret, + NULL, kHkdfLabelEarlyExporterSecret, NULL, &hashes, &ss->ssl3.hs.earlyExporterSecret); if (rv != SECSuccess) { return SECFailure; @@ -802,7 +810,9 @@ tls13_ComputeHandshakeSecrets(sslSocket *ss) /* Now compute |*HsTrafficSecret| */ rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, - kHkdfLabelHandshakeTrafficSecret, NULL, + kHkdfLabelHandshakeTrafficSecret, + keylogLabelClientHsTrafficSecret, + NULL, &ss->ssl3.hs.clientHsTrafficSecret); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); @@ -810,7 +820,9 @@ tls13_ComputeHandshakeSecrets(sslSocket *ss) } rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, kHkdfLabelServer, - kHkdfLabelHandshakeTrafficSecret, NULL, + kHkdfLabelHandshakeTrafficSecret, + keylogLabelServerHsTrafficSecret, + NULL, &ss->ssl3.hs.serverHsTrafficSecret); if (rv != SECSuccess) { LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); @@ -845,6 +857,7 @@ tls13_ComputeApplicationSecrets(sslSocket *ss) rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, kHkdfLabelApplicationTrafficSecret, + keylogLabelClientTrafficSecret, NULL, &ss->ssl3.hs.clientTrafficSecret); if (rv != SECSuccess) { @@ -853,6 +866,7 @@ tls13_ComputeApplicationSecrets(sslSocket *ss) rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, kHkdfLabelServer, kHkdfLabelApplicationTrafficSecret, + keylogLabelServerTrafficSecret, NULL, &ss->ssl3.hs.serverTrafficSecret); if (rv != SECSuccess) { @@ -861,7 +875,9 @@ tls13_ComputeApplicationSecrets(sslSocket *ss) rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, NULL, kHkdfLabelExporterMasterSecret, - NULL, &ss->ssl3.hs.exporterSecret); + keylogLabelExporterSecret, + NULL, + &ss->ssl3.hs.exporterSecret); if (rv != SECSuccess) { return SECFailure; } @@ -880,7 +896,7 @@ tls13_ComputeFinalSecrets(sslSocket *ss) rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, NULL, kHkdfLabelResumptionMasterSecret, - NULL, &resumptionMasterSecret); + NULL, NULL, &resumptionMasterSecret); PK11_FreeSymKey(ss->ssl3.hs.currentSecret); ss->ssl3.hs.currentSecret = NULL; if (rv != SECSuccess) { @@ -1432,6 +1448,7 @@ tls13_HandleClientHelloPart2(sslSocket *ss, rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, kHkdfLabelEarlyTrafficSecret, + keylogLabelClientEarlyTrafficSecret, NULL, /* Current running hash. */ &ss->ssl3.hs.clientEarlyTrafficSecret); if (rv != SECSuccess) { @@ -2543,6 +2560,7 @@ static SECStatus tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, const char *prefix, const char *suffix, + const char *keylogLabel, const SSL3Hashes *hashes, PK11SymKey **dest) { @@ -2585,6 +2603,9 @@ tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } + if (keylogLabel) { + ssl3_RecordKeyLog(ss, keylogLabel, *dest); + } return SECSuccess; } @@ -4351,6 +4372,7 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss) rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, kHkdfLabelEarlyTrafficSecret, + keylogLabelClientEarlyTrafficSecret, NULL, &ss->ssl3.hs.clientEarlyTrafficSecret); if (rv != SECSuccess) -- cgit v1.2.1 From 89d4a25c4e85ddb1899484e8b9fba073f6a6f1f8 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 3 Oct 2017 14:49:25 -0700 Subject: Bug 1287711 - Remove RSA premaster secret from keylog file, r=mt Since the master secret is logged via "CLIENT_RANDOM", there is little reason to log the RSA premaster secret. Differential Revision: https://phabricator.services.mozilla.com/D85 --- lib/ssl/ssl3con.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index 1167a0081..ba0e90d1b 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -6054,35 +6054,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); } } } -- cgit v1.2.1 From 3115c20ff63a76c52371a1ea506deea36514f9ad Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 3 Oct 2017 14:55:02 -0700 Subject: Bug 1287711 - Make writes to SSLKEYLOGFILE thread-safe, r=mt Protect writes to the keylog file with a lock. Differential Revision: https://phabricator.services.mozilla.com/D86 --- lib/ssl/ssl3con.c | 7 ++++--- lib/ssl/sslimpl.h | 1 + lib/ssl/sslsock.c | 7 +++++++ 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index ba0e90d1b..9235528e1 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -11196,9 +11196,10 @@ ssl3_RecordKeyLog(sslSocket *ss, const char *label, PK11SymKey *secret) PORT_Assert(offset == len); - if (fwrite(buf, len, 1, ssl_keylog_iob) != 1) - return; - fflush(ssl_keylog_iob); + PZ_Lock(ssl_keylog_lock); + if (fwrite(buf, len, 1, ssl_keylog_iob) == 1) + fflush(ssl_keylog_iob); + PZ_Unlock(ssl_keylog_lock); #endif } diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h index 7ae84cd2e..50a73ff6c 100644 --- a/lib/ssl/sslimpl.h +++ b/lib/ssl/sslimpl.h @@ -1243,6 +1243,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; diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c index 9a7880c49..b3a6f1d76 100644 --- a/lib/ssl/sslsock.c +++ b/lib/ssl/sslsock.c @@ -124,6 +124,7 @@ FILE *ssl_trace_iob; #ifdef NSS_ALLOW_SSLKEYLOGFILE FILE *ssl_keylog_iob; +PZLock *ssl_keylog_lock; #endif char lockStatus[] = "Locks are ENABLED. "; @@ -3544,6 +3545,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 -- cgit v1.2.1 From c21e2ced85ff55b338ea1758179d358126d9204b Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Wed, 4 Oct 2017 10:05:29 +0200 Subject: Bug 1396525 - put keaGroup and sigScheme in the cache so we can put it in SSLChannelInfo, r=mt Summary: This adds originalKeaGroup and resumed fields to the SSLChannelInfo, which provide information about the key exchange group of the original TLS handshake when the session is resumed, and information whether a session is resumed or not. To do this this patch adds the keaGroup and sigScheme to the session cache and the session ticket. Reviewers: mt Reviewed By: mt Bug #: 1396525 Differential Revision: https://phabricator.services.mozilla.com/D29 --- lib/ssl/ssl3con.c | 12 ++++++++++++ lib/ssl/ssl3exthandle.c | 30 +++++++++++++++++++++++++++++- lib/ssl/sslimpl.h | 5 +++++ lib/ssl/sslinfo.c | 13 ++++++++++++- lib/ssl/sslsnce.c | 10 ++++++++-- lib/ssl/sslt.h | 8 ++++++++ lib/ssl/tls13con.c | 2 ++ 7 files changed, 76 insertions(+), 4 deletions(-) (limited to 'lib/ssl') diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index 9235528e1..cfead208e 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -6909,6 +6909,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; @@ -7919,6 +7921,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; @@ -8892,6 +8895,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); @@ -8963,6 +8968,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); @@ -11536,6 +11542,12 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid) 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_Time(); sid->expirationTime = sid->creationTime + ssl3_sid_timeout; sid->localCert = CERT_DupCertificate(ss->sec.localCert); diff --git a/lib/ssl/ssl3exthandle.c b/lib/ssl/ssl3exthandle.c index bda3d375f..3f05778b9 100644 --- a/lib/ssl/ssl3exthandle.c +++ b/lib/ssl/ssl3exthandle.c @@ -802,7 +802,7 @@ ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData } PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; /* 2 days in seconds */ -#define TLS_EX_SESS_TICKET_VERSION (0x0105) +#define TLS_EX_SESS_TICKET_VERSION (0x0106) /* * Called from ssl3_SendNewSessionTicket, tls13_SendNewSessionTicket @@ -882,6 +882,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, + sizeof(ssl3CipherSuite) /* ciphersuite */ + 1 /* compression */ + 10 /* cipher spec parameters */ + + 8 /* kea group and sig scheme */ + 1 /* certType arguments */ + 1 /* SessionTicket.ms_is_wrapped */ + 4 /* msWrapMech */ @@ -935,6 +936,19 @@ ssl3_EncodeSessionTicket(sslSocket *ss, if (rv != SECSuccess) goto loser; rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4); + if (rv != SECSuccess) + goto loser; + if (ss->sec.keaGroup) { + rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaGroup->name, 4); + if (rv != SECSuccess) + goto loser; + } else { + /* No kea group. Write 0 as invalid value. */ + rv = ssl3_AppendNumberToItem(&plaintext, 0, 4); + if (rv != SECSuccess) + goto loser; + } + rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.signatureScheme, 4); if (rv != SECSuccess) goto loser; @@ -1165,6 +1179,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); @@ -1319,7 +1345,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); diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h index 50a73ff6c..a64611d71 100644 --- a/lib/ssl/sslimpl.h +++ b/lib/ssl/sslimpl.h @@ -553,6 +553,8 @@ struct sslSessionIDStr { PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; + SSLNamedGroup keaGroup; + SSLSignatureScheme sigScheme; union { struct { @@ -1002,6 +1004,8 @@ typedef struct SessionTicketStr { PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; + SSLNamedGroup originalKeaGroup; + SSLSignatureScheme signatureScheme; const sslNamedGroupDef *namedCurve; /* For certificate lookup. */ /* @@ -1068,6 +1072,7 @@ struct sslSecurityInfoStr { SSLKEAType keaType; PRUint32 keaKeyBits; const sslNamedGroupDef *keaGroup; + const sslNamedGroupDef *originalKeaGroup; /* The selected certificate (for servers only). */ const sslServerCert *serverCert; diff --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c index 88162d814..e4416a57c 100644 --- a/lib/ssl/sslinfo.c +++ b/lib/ssl/sslinfo.c @@ -78,11 +78,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 3ef11f7a7..1c71f57dc 100644 --- a/lib/ssl/sslsnce.c +++ b/lib/ssl/sslsnce.c @@ -98,7 +98,9 @@ struct sidCacheEntryStr { /* 2 */ PRUint16 authKeyBits; /* 2 */ PRUint16 keaType; /* 2 */ PRUint16 keaKeyBits; - /* 72 - common header total */ + /* 4 */ PRUint32 signatureScheme; + /* 4 */ PRUint32 keaGroup; + /* 80 - common header total */ union { struct { @@ -116,7 +118,7 @@ struct sidCacheEntryStr { /* force sizeof(sidCacheEntry) to be a multiple of cache line size */ struct { - /*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */ + /*112 */ PRUint8 filler[112]; /* 80+112==192, a multiple of 16 */ } forceSize; } u; }; @@ -432,6 +434,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; @@ -541,6 +545,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/sslt.h b/lib/ssl/sslt.h index bd9a2ae88..bdf947669 100644 --- a/lib/ssl/sslt.h +++ b/lib/ssl/sslt.h @@ -275,6 +275,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 42918a5db..8c5479826 100644 --- a/lib/ssl/tls13con.c +++ b/lib/ssl/tls13con.c @@ -925,6 +925,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. */ -- cgit v1.2.1