diff options
Diffstat (limited to 'security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc')
-rw-r--r-- | security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc | 271 |
1 files changed, 18 insertions, 253 deletions
diff --git a/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc index a60295490..85b7011a1 100644 --- a/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc @@ -7,7 +7,6 @@ #include "secerr.h" #include "ssl.h" #include "sslerr.h" -#include "sslexp.h" #include "sslproto.h" extern "C" { @@ -45,93 +44,6 @@ 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) { @@ -140,7 +52,8 @@ TEST_P(TlsConnectTls13, ZeroRttOptionsSetLate) { SendReceive(); // Need to read so that we absorb the session ticket. CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); Reset(); - StartConnect(); + server_->StartConnect(); + client_->StartConnect(); // Now turn on 0-RTT but too late for the ticket. client_->Set0RttEnabled(true); server_->Set0RttEnabled(true); @@ -167,7 +80,8 @@ TEST_P(TlsConnectTls13, ZeroRttServerForgetTicket) { TEST_P(TlsConnectTls13, ZeroRttServerOnly) { ExpectResumption(RESUME_NONE); server_->Set0RttEnabled(true); - StartConnect(); + client_->StartConnect(); + server_->StartConnect(); // Client sends ordinary ClientHello. client_->Handshake(); @@ -185,61 +99,6 @@ 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(); @@ -258,14 +117,6 @@ 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) { @@ -304,17 +155,12 @@ 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"); - client_->ExpectSendAlert(kTlsAlertIllegalParameter); + ExpectAlert(client_, kTlsAlertIllegalParameter); return true; }); - if (variant_ == ssl_variant_stream) { - server_->ExpectSendAlert(kTlsAlertBadRecordMac); - Handshake(); - server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); - } else { - client_->Handshake(); - } + 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. @@ -329,17 +175,12 @@ 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"); - client_->ExpectSendAlert(kTlsAlertIllegalParameter); + ExpectAlert(client_, kTlsAlertIllegalParameter); return true; }); - if (variant_ == ssl_variant_stream) { - server_->ExpectSendAlert(kTlsAlertBadRecordMac); - Handshake(); - server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ); - } else { - client_->Handshake(); - } + 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. @@ -377,7 +218,9 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngrade) { SSL_LIBRARY_VERSION_TLS_1_3); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_2); - StartConnect(); + client_->StartConnect(); + server_->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. @@ -418,7 +261,9 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttDowngradeEarlyData) { SSL_LIBRARY_VERSION_TLS_1_3); server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, SSL_LIBRARY_VERSION_TLS_1_2); - StartConnect(); + client_->StartConnect(); + server_->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); @@ -465,6 +310,7 @@ TEST_P(TlsConnectTls13, SendTooMuchEarlyData) { server_->Set0RttEnabled(true); ExpectResumption(RESUME_TICKET); + ExpectAlert(client_, kTlsAlertEndOfEarlyData); client_->Handshake(); CheckEarlyDataLimit(client_, short_size); @@ -518,6 +364,7 @@ TEST_P(TlsConnectTls13, ReceiveTooMuchEarlyData) { server_->Set0RttEnabled(true); ExpectResumption(RESUME_TICKET); + client_->ExpectSendAlert(kTlsAlertEndOfEarlyData); client_->Handshake(); // Send ClientHello CheckEarlyDataLimit(client_, limit); @@ -552,86 +399,4 @@ 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 |