diff options
author | Martin Thomson <martin.thomson@gmail.com> | 2018-05-18 12:51:29 +1000 |
---|---|---|
committer | Martin Thomson <martin.thomson@gmail.com> | 2018-05-18 12:51:29 +1000 |
commit | 08842869dc8c12d0622f63f111628ed36c3079f0 (patch) | |
tree | bff6d8c7ca17e3be8bdf3a3a365336dae8b69608 | |
parent | ecd9c58a97a3493825c8009bcef0a71b5f77d940 (diff) | |
download | nss-hg-08842869dc8c12d0622f63f111628ed36c3079f0.tar.gz |
Bug 1462303 - Allow TLS 1.3 compat mode when attempting to resume TLS 1.2, r=ekr,ttaubert
-rw-r--r-- | gtests/ssl_gtest/ssl_tls13compat_unittest.cc | 16 | ||||
-rw-r--r-- | lib/ssl/ssl3con.c | 40 |
2 files changed, 41 insertions, 15 deletions
diff --git a/gtests/ssl_gtest/ssl_tls13compat_unittest.cc b/gtests/ssl_gtest/ssl_tls13compat_unittest.cc index f4ea58e10..42f1065f6 100644 --- a/gtests/ssl_gtest/ssl_tls13compat_unittest.cc +++ b/gtests/ssl_gtest/ssl_tls13compat_unittest.cc @@ -436,4 +436,20 @@ TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) { EXPECT_EQ(0U, session_id_len); } +TEST_F(Tls13CompatTest, ConnectWith12ThenAttemptToResume13CompatMode) { + ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID); + ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_2); + Connect(); + + Reset(); + ExpectResumption(RESUME_NONE); + version_ = SSL_LIBRARY_VERSION_TLS_1_3; + client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_3); + EnableCompatMode(); + Connect(); +} + } // namespace nss_test diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index 5f7b7b84c..00e130786 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -6164,28 +6164,38 @@ ssl_ClientSetCipherSuite(sslSocket *ss, SSL3ProtocolVersion version, static PRBool ssl_CheckServerSessionIdCorrectness(sslSocket *ss, SECItem *sidBytes) { - PRBool sid_match = PR_FALSE; - PRBool sent_fake_sid = ss->opt.enableTls13CompatMode && !IS_DTLS(ss); - - /* If in compat mode and we received a session ID with the right length - * then compare it to the fake one we sent in the ClientHello. */ - if (sent_fake_sid && sidBytes->len == SSL3_SESSIONID_BYTES) { - PRUint8 buf[SSL3_SESSIONID_BYTES]; - ssl_MakeFakeSid(ss, buf); - sid_match = PORT_Memcmp(buf, sidBytes->data, sidBytes->len) == 0; + sslSessionID *sid = ss->sec.ci.sid; + PRBool sidMatch = PR_FALSE; + PRBool sentFakeSid = PR_FALSE; + PRBool sentRealSid = sid && sid->version < SSL_LIBRARY_VERSION_TLS_1_3; + + /* If attempting to resume a TLS 1.2 connection, the session ID won't be a + * fake. Check for the real value. */ + if (sentRealSid) { + sidMatch = (sidBytes->len == sid->u.ssl3.sessionIDLength) && + PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes->data, sidBytes->len) == 0; + } else { + /* Otherwise, the session ID was a fake if TLS 1.3 compat mode is + * enabled. If so, check for the fake value. */ + sentFakeSid = ss->opt.enableTls13CompatMode && !IS_DTLS(ss); + if (sentFakeSid && sidBytes->len == SSL3_SESSIONID_BYTES) { + PRUint8 buf[SSL3_SESSIONID_BYTES]; + ssl_MakeFakeSid(ss, buf); + sidMatch = PORT_Memcmp(buf, sidBytes->data, sidBytes->len) == 0; + } } - /* TLS 1.2: SessionID shouldn't match the fake one. */ + /* TLS 1.2: Session ID shouldn't match if we sent a fake. */ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - return !sid_match; + return !sentFakeSid || !sidMatch; } - /* TLS 1.3: [Compat Mode] Session ID should match the fake one. */ - if (sent_fake_sid) { - return sid_match; + /* TLS 1.3: We sent a session ID. The server's should match. */ + if (sentRealSid || sentFakeSid) { + return sidMatch; } - /* TLS 1.3: [Non-Compat Mode] Server shouldn't send a session ID. */ + /* TLS 1.3: The server shouldn't send a session ID. */ return sidBytes->len == 0; } |