Update NSS to 3.35-RTM

This commit is contained in:
wolfbeast 2018-02-23 11:04:39 +01:00 • committed by Roy Tam
commit 66dd670b60
388 changed files with 39075 additions and 20752 deletions

View file

@ -7,6 +7,7 @@
#include "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslexp.h"
#include "sslproto.h"
extern "C" {
@ -44,6 +45,93 @@ TEST_P(TlsConnectTls13, ZeroRttServerRejectByOption) {
SendReceive();
}
TEST_P(TlsConnectTls13, ZeroRttApparentReplayAfterRestart) {
// The test fixtures call SSL_SetupAntiReplay() in SetUp(). This results in
// 0-RTT being rejected until at least one window passes. SetupFor0Rtt()
// forces a rollover of the anti-replay filters, which clears this state.
// Here, we do the setup manually here without that forced rollover.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
server_->Set0RttEnabled(true); // So we signal that we allow 0-RTT.
Connect();
SendReceive(); // Need to read so that we absorb the session ticket.
CheckKeys();
Reset();
StartConnect();
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
ZeroRttSendReceive(true, false);
Handshake();
CheckConnected();
SendReceive();
}
class TlsZeroRttReplayTest : public TlsConnectTls13 {
private:
class SaveFirstPacket : public PacketFilter {
public:
PacketFilter::Action Filter(const DataBuffer& input,
DataBuffer* output) override {
if (!packet_.len() && input.len()) {
packet_ = input;
}
return KEEP;
}
const DataBuffer& packet() const { return packet_; }
private:
DataBuffer packet_;
};
protected:
void RunTest(bool rollover) {
// Run the initial handshake
SetupForZeroRtt();
// Now run a true 0-RTT handshake, but capture the first packet.
auto first_packet = std::make_shared<SaveFirstPacket>();
client_->SetPacketFilter(first_packet);
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
ZeroRttSendReceive(true, true);
Handshake();
EXPECT_LT(0U, first_packet->packet().len());
ExpectEarlyDataAccepted(true);
CheckConnected();
SendReceive();
if (rollover) {
SSLInt_RolloverAntiReplay();
}
// Now replay that packet against the server.
Reset();
server_->StartConnect();
server_->Set0RttEnabled(true);
// Capture the early_data extension, which should not appear.
auto early_data_ext =
std::make_shared<TlsExtensionCapture>(ssl_tls13_early_data_xtn);
server_->SetPacketFilter(early_data_ext);
// Finally, replay the ClientHello and force the server to consume it. Stop
// after the server sends its first flight; the client will not be able to
// complete this handshake.
server_->adapter()->PacketReceived(first_packet->packet());
server_->Handshake();
EXPECT_FALSE(early_data_ext->captured());
}
};
TEST_P(TlsZeroRttReplayTest, ZeroRttReplay) { RunTest(false); }
TEST_P(TlsZeroRttReplayTest, ZeroRttReplayAfterRollover) { RunTest(true); }
// Test that we don't try to send 0-RTT data when the server sent
// us a ticket without the 0-RTT flags.
TEST_P(TlsConnectTls13, ZeroRttOptionsSetLate) {
@ -52,8 +140,7 @@ TEST_P(TlsConnectTls13, ZeroRttOptionsSetLate) {
SendReceive(); // Need to read so that we absorb the session ticket.
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
Reset();
server_->StartConnect();
client_->StartConnect();
StartConnect();
// Now turn on 0-RTT but too late for the ticket.
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
@ -80,8 +167,7 @@ TEST_P(TlsConnectTls13, ZeroRttServerForgetTicket) {
TEST_P(TlsConnectTls13, ZeroRttServerOnly) {
ExpectResumption(RESUME_NONE);
server_->Set0RttEnabled(true);
client_->StartConnect();
server_->StartConnect();
StartConnect();
// Client sends ordinary ClientHello.
client_->Handshake();
@ -99,6 +185,61 @@ TEST_P(TlsConnectTls13, ZeroRttServerOnly) {
CheckKeys();
}
// A small sleep after sending the ClientHello means that the ticket age that
// arrives at the server is too low. With a small tolerance for variation in
// ticket age (which is determined by the |window| parameter that is passed to
// SSL_SetupAntiReplay()), the server then rejects early data.
TEST_P(TlsConnectTls13, ZeroRttRejectOldTicket) {
SetupForZeroRtt();
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
EXPECT_EQ(SECSuccess, SSL_SetupAntiReplay(1, 1, 3));
SSLInt_RolloverAntiReplay(); // Make sure to flush replay state.
SSLInt_RolloverAntiReplay();
ExpectResumption(RESUME_TICKET);
ZeroRttSendReceive(true, false, []() {
PR_Sleep(PR_MillisecondsToInterval(10));
return true;
});
Handshake();
ExpectEarlyDataAccepted(false);
CheckConnected();
SendReceive();
}
// In this test, we falsely inflate the estimate of the RTT by delaying the
// ServerHello on the first handshake. This results in the server estimating a
// higher value of the ticket age than the client ultimately provides. Add a
// small tolerance for variation in ticket age and the ticket will appear to
// arrive prematurely, causing the server to reject early data.
TEST_P(TlsConnectTls13, ZeroRttRejectPrematureTicket) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
server_->Set0RttEnabled(true);
StartConnect();
client_->Handshake(); // ClientHello
server_->Handshake(); // ServerHello
PR_Sleep(PR_MillisecondsToInterval(10));
Handshake(); // Remainder of handshake
CheckConnected();
SendReceive();
CheckKeys();
Reset();
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
EXPECT_EQ(SECSuccess, SSL_SetupAntiReplay(1, 1, 3));
SSLInt_RolloverAntiReplay(); // Make sure to flush replay state.
SSLInt_RolloverAntiReplay();
ExpectResumption(RESUME_TICKET);
ExpectEarlyDataAccepted(false);
StartConnect();
ZeroRttSendReceive(true, false);
Handshake();
CheckConnected();
SendReceive();
}
TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpn) {
EnableAlpn();
SetupForZeroRtt();
@ -117,6 +258,14 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpn) {
CheckAlpn("a");
}
// NOTE: In this test and those below, the client always sends
// post-ServerHello alerts with the handshake keys, even if the server
// has accepted 0-RTT. In some cases, as with errors in
// EncryptedExtensions, the client can't know the server's behavior,
// and in others it's just simpler. What the server is expecting
// depends on whether it accepted 0-RTT or not. Eventually, we may
// make the server trial decrypt.
//
// Have the server negotiate a different ALPN value, and therefore
// reject 0-RTT.
TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpnChangeServer) {
@ -155,12 +304,17 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttNoAlpnServer) {
client_->CheckAlpn(SSL_NEXT_PROTO_EARLY_VALUE, "a");
EXPECT_EQ(SECSuccess, SSLInt_Set0RttAlpn(client_->ssl_fd(), b, sizeof(b)));
client_->CheckAlpn(SSL_NEXT_PROTO_EARLY_VALUE, "b");
ExpectAlert(client_, kTlsAlertIllegalParameter);
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
return true;
});
Handshake();
if (variant_ == ssl_variant_stream) {
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
Handshake();
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
} else {
client_->Handshake();
}
client_->CheckErrorCode(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}
// Set up with no ALPN and then set the client so it thinks it has ALPN.
@ -175,12 +329,17 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttNoAlpnClient) {
PRUint8 b[] = {'b'};
EXPECT_EQ(SECSuccess, SSLInt_Set0RttAlpn(client_->ssl_fd(), b, 1));
client_->CheckAlpn(SSL_NEXT_PROTO_EARLY_VALUE, "b");
ExpectAlert(client_, kTlsAlertIllegalParameter);
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
return true;
});
Handshake();
if (variant_ == ssl_variant_stream) {
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
Handshake();
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
} else {
client_->Handshake();
}
client_->CheckErrorCode(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}
// Remove the old ALPN value and so the client will not offer early data.
@ -218,9 +377,7 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngrade) {
SSL_LIBRARY_VERSION_TLS_1_3);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
SSL_LIBRARY_VERSION_TLS_1_2);
client_->StartConnect();
server_->StartConnect();
StartConnect();
// We will send the early data xtn without sending actual early data. Thus
// a 1.2 server shouldn't fail until the client sends an alert because the
// client sends end_of_early_data only after reading the server's flight.
@ -261,9 +418,7 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngradeEarlyData) {
SSL_LIBRARY_VERSION_TLS_1_3);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
SSL_LIBRARY_VERSION_TLS_1_2);
client_->StartConnect();
server_->StartConnect();
StartConnect();
// Send the early data xtn in the CH, followed by early app data. The server
// will fail right after sending its flight, when receiving the early data.
client_->Set0RttEnabled(true);
@ -310,7 +465,6 @@ TEST_P(TlsConnectTls13, SendTooMuchEarlyData) {
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
ExpectAlert(client_, kTlsAlertEndOfEarlyData);
client_->Handshake();
CheckEarlyDataLimit(client_, short_size);
@ -364,7 +518,6 @@ TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) {
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
client_->ExpectSendAlert(kTlsAlertEndOfEarlyData);
client_->Handshake(); // Send ClientHello
CheckEarlyDataLimit(client_, limit);
@ -399,4 +552,86 @@ TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) {
}
}
class PacketCoalesceFilter : public PacketFilter {
public:
PacketCoalesceFilter() : packet_data_() {}
void SendCoalesced(std::shared_ptr<TlsAgent> agent) {
agent->SendDirect(packet_data_);
}
protected:
PacketFilter::Action Filter(const DataBuffer& input,
DataBuffer* output) override {
packet_data_.Write(packet_data_.len(), input);
return DROP;
}
private:
DataBuffer packet_data_;
};
TEST_P(TlsConnectTls13, ZeroRttOrdering) {
SetupForZeroRtt();
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
// Send out the ClientHello.
client_->Handshake();
// Now, coalesce the next three things from the client: early data, second
// flight and 1-RTT data.
auto coalesce = std::make_shared<PacketCoalesceFilter>();
client_->SetPacketFilter(coalesce);
// Send (and hold) early data.
static const std::vector<uint8_t> early_data = {3, 2, 1};
EXPECT_EQ(static_cast<PRInt32>(early_data.size()),
PR_Write(client_->ssl_fd(), early_data.data(), early_data.size()));
// Send (and hold) the second client handshake flight.
// The client sends EndOfEarlyData after seeing the server Finished.
server_->Handshake();
client_->Handshake();
// Send (and hold) 1-RTT data.
static const std::vector<uint8_t> late_data = {7, 8, 9, 10};
EXPECT_EQ(static_cast<PRInt32>(late_data.size()),
PR_Write(client_->ssl_fd(), late_data.data(), late_data.size()));
// Now release them all at once.
coalesce->SendCoalesced(client_);
// Now ensure that the three steps are exposed in the right order on the
// server: delivery of early data, handshake callback, delivery of 1-RTT.
size_t step = 0;
server_->SetHandshakeCallback([&step](TlsAgent*) {
EXPECT_EQ(1U, step);
++step;
});
std::vector<uint8_t> buf(10);
PRInt32 read = PR_Read(server_->ssl_fd(), buf.data(), buf.size());
ASSERT_EQ(static_cast<PRInt32>(early_data.size()), read);
buf.resize(read);
EXPECT_EQ(early_data, buf);
EXPECT_EQ(0U, step);
++step;
// The third read should be after the handshake callback and should return the
// data that was sent after the handshake completed.
buf.resize(10);
read = PR_Read(server_->ssl_fd(), buf.data(), buf.size());
ASSERT_EQ(static_cast<PRInt32>(late_data.size()), read);
buf.resize(read);
EXPECT_EQ(late_data, buf);
EXPECT_EQ(2U, step);
}
#ifndef NSS_DISABLE_TLS_1_3
INSTANTIATE_TEST_CASE_P(Tls13ZeroRttReplayTest, TlsZeroRttReplayTest,
TlsConnectTestBase::kTlsVariantsAll);
#endif
} // namespace nss_test