diff options
Diffstat (limited to 'security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc')
-rw-r--r-- | security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc | 136 |
1 files changed, 129 insertions, 7 deletions
diff --git a/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc index 05ae87034..77b335e86 100644 --- a/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc +++ b/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc @@ -69,8 +69,8 @@ TEST_P(TlsConnectTls13, HelloRetryRequestAbortsZeroRtt) { // handshake packets, this will break. class CorrectMessageSeqAfterHrrFilter : public TlsRecordFilter { public: - CorrectMessageSeqAfterHrrFilter(const std::shared_ptr<TlsAgent>& agent) - : TlsRecordFilter(agent) {} + CorrectMessageSeqAfterHrrFilter(const std::shared_ptr<TlsAgent>& a) + : TlsRecordFilter(a) {} protected: PacketFilter::Action FilterRecord(const TlsRecordHeader& header, @@ -81,8 +81,9 @@ class CorrectMessageSeqAfterHrrFilter : public TlsRecordFilter { } DataBuffer buffer(record); - TlsRecordHeader new_header = {header.version(), header.content_type(), - header.sequence_number() + 1}; + TlsRecordHeader new_header(header.variant(), header.version(), + header.content_type(), + header.sequence_number() + 1); // Correct message_seq. buffer.Write(4, 1U, 2); @@ -151,8 +152,8 @@ TEST_P(TlsConnectTls13, SecondClientHelloRejectEarlyDataXtn) { class KeyShareReplayer : public TlsExtensionFilter { public: - KeyShareReplayer(const std::shared_ptr<TlsAgent>& agent) - : TlsExtensionFilter(agent) {} + KeyShareReplayer(const std::shared_ptr<TlsAgent>& a) + : TlsExtensionFilter(a) {} virtual PacketFilter::Action FilterExtension(uint16_t extension_type, const DataBuffer& input, @@ -567,6 +568,28 @@ void TriggerHelloRetryRequest(std::shared_ptr<TlsAgent>& client, client->Handshake(); server->Handshake(); EXPECT_EQ(1U, cb_called); + // Stop the callback from being called in future handshakes. + EXPECT_EQ(SECSuccess, + SSL_HelloRetryRequestCallback(server->ssl_fd(), nullptr, nullptr)); +} + +TEST_P(TlsConnectTls13, VersionNumbersAfterRetry) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + auto r = MakeTlsFilter<TlsRecordRecorder>(client_); + TriggerHelloRetryRequest(client_, server_); + Handshake(); + ASSERT_GT(r->count(), 1UL); + auto ch1 = r->record(0); + if (ch1.header.is_dtls()) { + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, ch1.header.version()); + } else { + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, ch1.header.version()); + } + auto ch2 = r->record(1); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, ch2.header.version()); + + CheckConnected(); } TEST_P(TlsConnectTls13, RetryStateless) { @@ -577,6 +600,7 @@ TEST_P(TlsConnectTls13, RetryStateless) { MakeNewServer(); Handshake(); + CheckConnected(); SendReceive(); } @@ -593,6 +617,68 @@ TEST_P(TlsConnectTls13, RetryStatefulDropCookie) { server_->CheckErrorCode(SSL_ERROR_MISSING_COOKIE_EXTENSION); } +class TruncateHrrCookie : public TlsExtensionFilter { + public: + TruncateHrrCookie(const std::shared_ptr<TlsAgent>& a) + : TlsExtensionFilter(a) {} + virtual PacketFilter::Action FilterExtension(uint16_t extension_type, + const DataBuffer& input, + DataBuffer* output) { + if (extension_type != ssl_tls13_cookie_xtn) { + return KEEP; + } + + // Claim a zero-length cookie. + output->Allocate(2); + output->Write(0, static_cast<uint32_t>(0), 2); + return CHANGE; + } +}; + +TEST_P(TlsConnectTls13, RetryCookieEmpty) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + MakeTlsFilter<TruncateHrrCookie>(client_); + + ExpectAlert(server_, kTlsAlertHandshakeFailure); + Handshake(); + client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); + server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); +} + +class AddJunkToCookie : public TlsExtensionFilter { + public: + AddJunkToCookie(const std::shared_ptr<TlsAgent>& a) : TlsExtensionFilter(a) {} + virtual PacketFilter::Action FilterExtension(uint16_t extension_type, + const DataBuffer& input, + DataBuffer* output) { + if (extension_type != ssl_tls13_cookie_xtn) { + return KEEP; + } + + *output = input; + // Add junk after the cookie. + static const uint8_t junk[2] = {1, 2}; + output->Append(DataBuffer(junk, sizeof(junk))); + return CHANGE; + } +}; + +TEST_P(TlsConnectTls13, RetryCookieWithExtras) { + ConfigureSelfEncrypt(); + EnsureTlsSetup(); + + TriggerHelloRetryRequest(client_, server_); + MakeTlsFilter<AddJunkToCookie>(client_); + + ExpectAlert(server_, kTlsAlertHandshakeFailure); + Handshake(); + client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); + server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); +} + // Stream only because DTLS drops bad packets. TEST_F(TlsConnectStreamTls13, RetryStatelessDamageFirstClientHello) { ConfigureSelfEncrypt(); @@ -907,7 +993,10 @@ class HelloRetryRequestAgentTest : public TlsAgentTestClient { hrr_data.Allocate(len + 6); size_t i = 0; - i = hrr_data.Write(i, 0x0303, 2); + i = hrr_data.Write(i, variant_ == ssl_variant_datagram + ? SSL_LIBRARY_VERSION_DTLS_1_2_WIRE + : SSL_LIBRARY_VERSION_TLS_1_2, + 2); i = hrr_data.Write(i, ssl_hello_retry_random, sizeof(ssl_hello_retry_random)); i = hrr_data.Write(i, static_cast<uint32_t>(0), 1); // session_id @@ -973,6 +1062,39 @@ TEST_P(HelloRetryRequestAgentTest, HandleNoopHelloRetryRequest) { SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST); } +class ReplaceRandom : public TlsHandshakeFilter { + public: + ReplaceRandom(const std::shared_ptr<TlsAgent>& a, const DataBuffer& r) + : TlsHandshakeFilter(a, {kTlsHandshakeServerHello}), random_(r) {} + + PacketFilter::Action FilterHandshake(const HandshakeHeader& header, + const DataBuffer& input, + DataBuffer* output) override { + output->Assign(input); + output->Write(2, random_); + return CHANGE; + } + + private: + DataBuffer random_; +}; + +// Make sure that the TLS 1.3 special value for the ServerHello.random +// is rejected by earlier versions. +TEST_P(TlsConnectStreamPre13, HrrRandomOnTls10) { + static const uint8_t hrr_random[] = { + 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, + 0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, + 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C}; + + EnsureTlsSetup(); + MakeTlsFilter<ReplaceRandom>(server_, + DataBuffer(hrr_random, sizeof(hrr_random))); + ConnectExpectAlert(client_, kTlsAlertIllegalParameter); + client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO); + server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); +} + INSTANTIATE_TEST_CASE_P(HelloRetryRequestAgentTests, HelloRetryRequestAgentTest, ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV13)); |