Update NSS to 3.48 while keeping vc2013 hackfix and no-sslkeylogfile intact.

This commit is contained in:
Roy Tam 2020-01-03 13:36:26 +08:00
commit 171849c8e5
351 changed files with 115185 additions and 57946 deletions

View file

@ -325,14 +325,17 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicketForget) {
SendReceive();
}
// Tickets last two days maximum; this is a time longer than that.
static const PRTime kLongerThanTicketLifetime =
3LL * 24 * 60 * 60 * PR_USEC_PER_SEC;
TEST_P(TlsConnectGenericResumption, ConnectWithExpiredTicketAtClient) {
SSLInt_SetTicketLifetime(1); // one second
// This causes a ticket resumption.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect();
SendReceive();
WAIT_(false, 1000);
AdvanceTime(kLongerThanTicketLifetime);
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
@ -354,7 +357,6 @@ TEST_P(TlsConnectGenericResumption, ConnectWithExpiredTicketAtClient) {
}
TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) {
SSLInt_SetTicketLifetime(1); // one second
// This causes a ticket resumption.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect();
@ -373,7 +375,7 @@ TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) {
EXPECT_TRUE(capture->captured());
EXPECT_LT(0U, capture->extension().len());
WAIT_(false, 1000); // Let the ticket expire on the server.
AdvanceTime(kLongerThanTicketLifetime);
Handshake();
CheckConnected();
@ -421,6 +423,7 @@ static int32_t SwitchCertificates(TlsAgent* agent, const SECItem* srvNameArr,
TEST_P(TlsConnectGeneric, ServerSNICertSwitch) {
Connect();
ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
ASSERT_NE(nullptr, cert1.get());
Reset();
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
@ -429,6 +432,7 @@ TEST_P(TlsConnectGeneric, ServerSNICertSwitch) {
Connect();
ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
ASSERT_NE(nullptr, cert2.get());
CheckKeys();
EXPECT_FALSE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
}
@ -437,6 +441,7 @@ TEST_P(TlsConnectGeneric, ServerSNICertTypeSwitch) {
Reset(TlsAgent::kServerEcdsa256);
Connect();
ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
ASSERT_NE(nullptr, cert1.get());
Reset();
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
@ -447,6 +452,7 @@ TEST_P(TlsConnectGeneric, ServerSNICertTypeSwitch) {
Connect();
ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
ASSERT_NE(nullptr, cert2.get());
CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
}
@ -531,6 +537,7 @@ TEST_P(TlsConnectTls13, TestTls13ResumeNoCertificateRequest) {
Connect();
SendReceive(); // Need to read so that we absorb the session ticket.
ScopedCERTCertificate cert1(SSL_LocalCertificate(client_->ssl_fd()));
ASSERT_NE(nullptr, cert1.get());
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
@ -546,6 +553,7 @@ TEST_P(TlsConnectTls13, TestTls13ResumeNoCertificateRequest) {
// Sanity check whether the client certificate matches the one
// decrypted from ticket.
ScopedCERTCertificate cert2(SSL_PeerCertificate(server_->ssl_fd()));
ASSERT_NE(nullptr, cert2.get());
EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
}
@ -561,6 +569,7 @@ TEST_P(TlsConnectTls13, WriteBeforeHandshakeCompleteOnResumption) {
Connect();
SendReceive(); // Absorb the session ticket.
ScopedCERTCertificate cert1(SSL_LocalCertificate(client_->ssl_fd()));
ASSERT_NE(nullptr, cert1.get());
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
@ -577,6 +586,7 @@ TEST_P(TlsConnectTls13, WriteBeforeHandshakeCompleteOnResumption) {
// Check whether the client certificate matches the one from the ticket.
ScopedCERTCertificate cert2(SSL_PeerCertificate(server_->ssl_fd()));
ASSERT_NE(nullptr, cert2.get());
EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
}
@ -589,15 +599,17 @@ static uint16_t ChooseOneCipher(uint16_t version) {
return TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
}
static uint16_t ChooseAnotherCipher(uint16_t version) {
static uint16_t ChooseIncompatibleCipher(uint16_t version) {
if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
return TLS_AES_256_GCM_SHA384;
}
return TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
}
// Test that we don't resume when we can't negotiate the same cipher.
TEST_P(TlsConnectGenericResumption, TestResumeClientDifferentCipher) {
// Test that we don't resume when we can't negotiate the same cipher. Note that
// for TLS 1.3, resumption is allowed between compatible ciphers, that is those
// with the same KDF hash, but we choose an incompatible one here.
TEST_P(TlsConnectGenericResumption, ResumeClientIncompatibleCipher) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
client_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
@ -607,7 +619,7 @@ TEST_P(TlsConnectGenericResumption, TestResumeClientDifferentCipher) {
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ExpectResumption(RESUME_NONE);
client_->EnableSingleCipher(ChooseAnotherCipher(version_));
client_->EnableSingleCipher(ChooseIncompatibleCipher(version_));
uint16_t ticket_extension;
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
ticket_extension = ssl_tls13_pre_shared_key_xtn;
@ -622,24 +634,24 @@ TEST_P(TlsConnectGenericResumption, TestResumeClientDifferentCipher) {
}
// Test that we don't resume when we can't negotiate the same cipher.
TEST_P(TlsConnectGenericResumption, TestResumeServerDifferentCipher) {
TEST_P(TlsConnectGenericResumption, ResumeServerIncompatibleCipher) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
server_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
SendReceive(); // Need to read so that we absorb the session ticket.
SendReceive(); // Absorb the session ticket.
CheckKeys();
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ExpectResumption(RESUME_NONE);
server_->EnableSingleCipher(ChooseAnotherCipher(version_));
server_->EnableSingleCipher(ChooseIncompatibleCipher(version_));
Connect();
CheckKeys();
}
// Test that the client doesn't tolerate the server picking a different cipher
// suite for resumption.
TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
TEST_P(TlsConnectStream, ResumptionOverrideCipher) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
server_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
@ -648,8 +660,8 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
MakeTlsFilter<SelectedCipherSuiteReplacer>(server_,
ChooseAnotherCipher(version_));
MakeTlsFilter<SelectedCipherSuiteReplacer>(
server_, ChooseIncompatibleCipher(version_));
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
@ -668,6 +680,38 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
}
}
// In TLS 1.3, it is possible to resume with a different cipher if it has the
// same hash.
TEST_P(TlsConnectTls13, ResumeClientCompatibleCipher) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
client_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
Connect();
SendReceive(); // Absorb the session ticket.
CheckKeys();
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ExpectResumption(RESUME_TICKET);
client_->EnableSingleCipher(TLS_CHACHA20_POLY1305_SHA256);
Connect();
CheckKeys();
}
TEST_P(TlsConnectTls13, ResumeServerCompatibleCipher) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
Connect();
SendReceive(); // Absorb the session ticket.
CheckKeys();
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ExpectResumption(RESUME_TICKET);
server_->EnableSingleCipher(TLS_CHACHA20_POLY1305_SHA256);
Connect();
CheckKeys();
}
class SelectedVersionReplacer : public TlsHandshakeFilter {
public:
SelectedVersionReplacer(const std::shared_ptr<TlsAgent>& a, uint16_t version)
@ -757,7 +801,7 @@ TEST_F(TlsConnectTest, TestTls13ResumptionTwice) {
ASSERT_LT(0U, initialTicket.len());
ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
ASSERT_TRUE(!!cert1.get());
ASSERT_NE(nullptr, cert1.get());
Reset();
ClearStats();
@ -773,7 +817,7 @@ TEST_F(TlsConnectTest, TestTls13ResumptionTwice) {
ASSERT_LT(0U, c2->extension().len());
ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
ASSERT_TRUE(!!cert2.get());
ASSERT_NE(nullptr, cert2.get());
// Check that the cipher suite is reported the same on both sides, though in
// TLS 1.3 resumption actually negotiates a different cipher suite.
@ -1109,7 +1153,7 @@ TEST_P(TlsConnectGenericResumption, ReConnectAgainTicket) {
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
}
void CheckGetInfoResult(uint32_t alpnSize, uint32_t earlyDataSize,
void CheckGetInfoResult(PRTime now, uint32_t alpnSize, uint32_t earlyDataSize,
ScopedCERTCertificate& cert,
ScopedSSLResumptionTokenInfo& token) {
ASSERT_TRUE(cert);
@ -1125,7 +1169,7 @@ void CheckGetInfoResult(uint32_t alpnSize, uint32_t earlyDataSize,
ASSERT_EQ(earlyDataSize, token->maxEarlyDataSize);
ASSERT_LT(ssl_TimeUsec(), token->expirationTime);
ASSERT_LT(now, token->expirationTime);
}
// The client should generate a new, randomized session_id
@ -1174,8 +1218,9 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfo) {
client_->GetTokenInfo(token);
ScopedCERTCertificate cert(
PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
ASSERT_NE(nullptr, cert.get());
CheckGetInfoResult(0, 0, cert, token);
CheckGetInfoResult(now(), 0, 0, cert, token);
Handshake();
CheckConnected();
@ -1183,6 +1228,56 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfo) {
SendReceive();
}
TEST_P(TlsConnectGenericResumptionToken, RefuseExpiredTicketClient) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
Connect();
SendReceive();
// Move the clock to the expiration time of the ticket.
SSLResumptionTokenInfo tokenInfo = {0};
ScopedSSLResumptionTokenInfo token(&tokenInfo);
client_->GetTokenInfo(token);
AdvanceTime(token->expirationTime - now());
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_TICKET);
StartConnect();
ASSERT_EQ(SECFailure,
SSL_SetResumptionToken(client_->ssl_fd(),
client_->GetResumptionToken().data(),
client_->GetResumptionToken().size()));
EXPECT_EQ(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR, PORT_GetError());
}
TEST_P(TlsConnectGenericResumptionToken, RefuseExpiredTicketServer) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
Connect();
SendReceive();
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_NONE);
// Start the handshake and send the ClientHello.
StartConnect();
ASSERT_EQ(SECSuccess,
SSL_SetResumptionToken(client_->ssl_fd(),
client_->GetResumptionToken().data(),
client_->GetResumptionToken().size()));
client_->Handshake();
// Move the clock to the expiration time of the ticket.
SSLResumptionTokenInfo tokenInfo = {0};
ScopedSSLResumptionTokenInfo token(&tokenInfo);
client_->GetTokenInfo(token);
AdvanceTime(token->expirationTime - now());
Handshake();
CheckConnected();
}
TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) {
EnableAlpn();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
@ -1204,8 +1299,9 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) {
client_->GetTokenInfo(token);
ScopedCERTCertificate cert(
PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
ASSERT_NE(nullptr, cert.get());
CheckGetInfoResult(1, 0, cert, token);
CheckGetInfoResult(now(), 1, 0, cert, token);
Handshake();
CheckConnected();
@ -1216,7 +1312,7 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) {
TEST_P(TlsConnectTls13ResumptionToken, ConnectResumeGetInfoZeroRtt) {
EnableAlpn();
SSLInt_RolloverAntiReplay();
RolloverAntiReplay();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
server_->Set0RttEnabled(true);
Connect();
@ -1239,8 +1335,8 @@ TEST_P(TlsConnectTls13ResumptionToken, ConnectResumeGetInfoZeroRtt) {
client_->GetTokenInfo(token);
ScopedCERTCertificate cert(
PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
CheckGetInfoResult(1, 1024, cert, token);
ASSERT_NE(nullptr, cert.get());
CheckGetInfoResult(now(), 1, 1024, cert, token);
ZeroRttSendReceive(true, true);
Handshake();
@ -1272,6 +1368,54 @@ TEST_P(TlsConnectGenericResumption, ConnectResumeClientAuth) {
SendReceive();
}
// Check that resumption is blocked if the server requires client auth.
TEST_P(TlsConnectGenericResumption, ClientAuthRequiredOnResumption) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
server_->RequestClientAuth(false);
Connect();
SendReceive();
Reset();
client_->SetupClientAuth();
server_->RequestClientAuth(true);
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
// Check that resumption is blocked if the server requires client auth and
// the client fails to provide a certificate.
TEST_P(TlsConnectGenericResumption, ClientAuthRequiredOnResumptionNoCert) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
server_->RequestClientAuth(false);
Connect();
SendReceive();
Reset();
server_->RequestClientAuth(true);
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
// Drive handshake manually because TLS 1.3 needs it.
StartConnect();
client_->Handshake(); // CH
server_->Handshake(); // SH.. (no resumption)
client_->Handshake(); // ...
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
// In TLS 1.3, the client thinks that everything is OK here.
ASSERT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
ExpectAlert(server_, kTlsAlertCertificateRequired);
server_->Handshake(); // Alert
client_->Handshake(); // Receive Alert
client_->CheckErrorCode(SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT);
} else {
ExpectAlert(server_, kTlsAlertBadCertificate);
server_->Handshake(); // Alert
client_->Handshake(); // Receive Alert
client_->CheckErrorCode(SSL_ERROR_BAD_CERT_ALERT);
}
server_->CheckErrorCode(SSL_ERROR_NO_CERTIFICATE);
}
TEST_F(TlsConnectStreamTls13, ExternalTokenAfterHrr) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
Connect();