summaryrefslogtreecommitdiffstats
path: root/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc')
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc274
1 files changed, 50 insertions, 224 deletions
diff --git a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
index a413caf2c..ce0e3ca8d 100644
--- a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
@@ -9,7 +9,6 @@
#include "secerr.h"
#include "ssl.h"
#include "sslerr.h"
-#include "sslexp.h"
#include "sslproto.h"
extern "C" {
@@ -247,7 +246,8 @@ TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) {
: ssl_session_ticket_xtn;
auto capture = std::make_shared<TlsExtensionCapture>(xtn);
client_->SetPacketFilter(capture);
- StartConnect();
+ client_->StartConnect();
+ server_->StartConnect();
client_->Handshake();
EXPECT_TRUE(capture->captured());
EXPECT_LT(0U, capture->extension().len());
@@ -355,7 +355,10 @@ TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) {
// This test parses the ServerKeyExchange, which isn't in 1.3
TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceNewKey) {
- server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
+ server_->EnsureTlsSetup();
+ SECStatus rv =
+ SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
+ EXPECT_EQ(SECSuccess, rv);
auto i1 = std::make_shared<TlsInspectorRecordHandshakeMessage>(
kTlsHandshakeServerKeyExchange);
server_->SetPacketFilter(i1);
@@ -366,7 +369,9 @@ TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceNewKey) {
// Restart
Reset();
- server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
+ server_->EnsureTlsSetup();
+ rv = SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
+ EXPECT_EQ(SECSuccess, rv);
auto i2 = std::make_shared<TlsInspectorRecordHandshakeMessage>(
kTlsHandshakeServerKeyExchange);
server_->SetPacketFilter(i2);
@@ -396,8 +401,7 @@ TEST_P(TlsConnectTls13, TestTls13ResumeDifferentGroup) {
client_->ConfigNamedGroups(kFFDHEGroups);
server_->ConfigNamedGroups(kFFDHEGroups);
Connect();
- CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_sha256);
+ CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign, ssl_sig_none);
}
// We need to enable different cipher suites at different times in the following
@@ -457,6 +461,36 @@ TEST_P(TlsConnectGeneric, TestResumeServerDifferentCipher) {
CheckKeys();
}
+class SelectedCipherSuiteReplacer : public TlsHandshakeFilter {
+ public:
+ SelectedCipherSuiteReplacer(uint16_t suite) : cipher_suite_(suite) {}
+
+ protected:
+ PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
+ const DataBuffer& input,
+ DataBuffer* output) override {
+ if (header.handshake_type() != kTlsHandshakeServerHello) {
+ return KEEP;
+ }
+
+ *output = input;
+ uint32_t temp = 0;
+ EXPECT_TRUE(input.Read(0, 2, &temp));
+ // Cipher suite is after version(2) and random(32).
+ size_t pos = 34;
+ if (temp < SSL_LIBRARY_VERSION_TLS_1_3) {
+ // In old versions, we have to skip a session_id too.
+ EXPECT_TRUE(input.Read(pos, 1, &temp));
+ pos += 1 + temp;
+ }
+ output->Write(pos, static_cast<uint32_t>(cipher_suite_), 2);
+ return CHANGE;
+ }
+
+ private:
+ uint16_t cipher_suite_;
+};
+
// Test that the client doesn't tolerate the server picking a different cipher
// suite for resumption.
TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
@@ -490,13 +524,16 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
class SelectedVersionReplacer : public TlsHandshakeFilter {
public:
- SelectedVersionReplacer(uint16_t version)
- : TlsHandshakeFilter({kTlsHandshakeServerHello}), version_(version) {}
+ SelectedVersionReplacer(uint16_t version) : version_(version) {}
protected:
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
DataBuffer* output) override {
+ if (header.handshake_type() != kTlsHandshakeServerHello) {
+ return KEEP;
+ }
+
*output = input;
output->Write(0, static_cast<uint32_t>(version_), 2);
return CHANGE;
@@ -572,7 +609,7 @@ TEST_F(TlsConnectTest, TestTls13ResumptionTwice) {
Connect();
SendReceive();
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_sha256);
+ ssl_sig_none);
// The filter will go away when we reset, so save the captured extension.
DataBuffer initialTicket(c1->extension());
ASSERT_LT(0U, initialTicket.len());
@@ -590,7 +627,7 @@ TEST_F(TlsConnectTest, TestTls13ResumptionTwice) {
Connect();
SendReceive();
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_sha256);
+ ssl_sig_none);
ASSERT_LT(0U, c2->extension().len());
ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
@@ -615,158 +652,18 @@ TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNST) {
// Clear the session ticket keys to invalidate the old ticket.
SSLInt_ClearSelfEncryptKey();
- SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0);
-
- SendReceive(); // Need to read so that we absorb the session tickets.
- CheckKeys();
-
- // Resume the connection.
- Reset();
- ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
- ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
- ExpectResumption(RESUME_TICKET);
- Connect();
- SendReceive();
-}
-
-// Check that the value captured in a NewSessionTicket message matches the value
-// captured from a pre_shared_key extension.
-void NstTicketMatchesPskIdentity(const DataBuffer& nst, const DataBuffer& psk) {
- uint32_t len;
-
- size_t offset = 4 + 4; // Skip ticket_lifetime and ticket_age_add.
- ASSERT_TRUE(nst.Read(offset, 1, &len));
- offset += 1 + len; // Skip ticket_nonce.
-
- ASSERT_TRUE(nst.Read(offset, 2, &len));
- offset += 2; // Skip the ticket length.
- ASSERT_LE(offset + len, nst.len());
- DataBuffer nst_ticket(nst.data() + offset, static_cast<size_t>(len));
-
- offset = 2; // Skip the identities length.
- ASSERT_TRUE(psk.Read(offset, 2, &len));
- offset += 2; // Skip the identity length.
- ASSERT_LE(offset + len, psk.len());
- DataBuffer psk_ticket(psk.data() + offset, static_cast<size_t>(len));
-
- EXPECT_EQ(nst_ticket, psk_ticket);
-}
-
-TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNSTWithToken) {
- ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
- ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
-
- auto nst_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
- ssl_hs_new_session_ticket);
- server_->SetTlsRecordFilter(nst_capture);
- Connect();
-
- // Clear the session ticket keys to invalidate the old ticket.
- SSLInt_ClearSelfEncryptKey();
- nst_capture->Reset();
- uint8_t token[] = {0x20, 0x20, 0xff, 0x00};
- EXPECT_EQ(SECSuccess,
- SSL_SendSessionTicket(server_->ssl_fd(), token, sizeof(token)));
+ SSLInt_SendNewSessionTicket(server_->ssl_fd());
SendReceive(); // Need to read so that we absorb the session tickets.
CheckKeys();
- EXPECT_LT(0U, nst_capture->buffer().len());
// Resume the connection.
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
ExpectResumption(RESUME_TICKET);
-
- auto psk_capture =
- std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
- client_->SetPacketFilter(psk_capture);
Connect();
SendReceive();
-
- NstTicketMatchesPskIdentity(nst_capture->buffer(), psk_capture->extension());
-}
-
-// Disable SSL_ENABLE_SESSION_TICKETS but ensure that tickets can still be sent
-// by invoking SSL_SendSessionTicket directly (and that the ticket is usable).
-TEST_F(TlsConnectTest, SendSessionTicketWithTicketsDisabled) {
- ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
- ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
-
- EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
- SSL_ENABLE_SESSION_TICKETS, PR_FALSE));
-
- auto nst_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
- ssl_hs_new_session_ticket);
- server_->SetTlsRecordFilter(nst_capture);
- Connect();
-
- EXPECT_EQ(0U, nst_capture->buffer().len()) << "expect nothing captured yet";
-
- EXPECT_EQ(SECSuccess, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0));
- EXPECT_LT(0U, nst_capture->buffer().len()) << "should capture now";
-
- SendReceive(); // Ensure that the client reads the ticket.
-
- // Resume the connection.
- Reset();
- ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
- ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
- ExpectResumption(RESUME_TICKET);
-
- auto psk_capture =
- std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
- client_->SetPacketFilter(psk_capture);
- Connect();
- SendReceive();
-
- NstTicketMatchesPskIdentity(nst_capture->buffer(), psk_capture->extension());
-}
-
-// Test calling SSL_SendSessionTicket in inappropriate conditions.
-TEST_F(TlsConnectTest, SendSessionTicketInappropriate) {
- ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
- ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_2);
-
- EXPECT_EQ(SECFailure, SSL_SendSessionTicket(client_->ssl_fd(), NULL, 0))
- << "clients can't send tickets";
- EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
-
- StartConnect();
-
- EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0))
- << "no ticket before the handshake has started";
- EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
- Handshake();
- EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0))
- << "no special tickets in TLS 1.2";
- EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
-}
-
-TEST_F(TlsConnectTest, SendSessionTicketMassiveToken) {
- ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
- ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
- Connect();
- // It should be safe to set length with a NULL token because the length should
- // be checked before reading token.
- EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0x1ffff))
- << "this is clearly too big";
- EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
-
- static const uint8_t big_token[0xffff] = {1};
- EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), big_token,
- sizeof(big_token)))
- << "this is too big, but that's not immediately obvious";
- EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
-}
-
-TEST_F(TlsConnectDatagram13, SendSessionTicketDtls) {
- ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
- ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
- Connect();
- EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0))
- << "no extra tickets in DTLS until we have Ack support";
- EXPECT_EQ(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, PORT_GetError());
}
TEST_F(TlsConnectTest, TestTls13ResumptionDowngrade) {
@@ -822,84 +719,13 @@ TEST_F(TlsConnectTest, TestTls13ResumptionForcedDowngrade) {
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256));
filters.push_back(
std::make_shared<SelectedVersionReplacer>(SSL_LIBRARY_VERSION_TLS_1_2));
-
- // Drop a bunch of extensions so that we get past the SH processing. The
- // version extension says TLS 1.3, which is counter to our goal, the others
- // are not permitted in TLS 1.2 handshakes.
- filters.push_back(
- std::make_shared<TlsExtensionDropper>(ssl_tls13_supported_versions_xtn));
- filters.push_back(
- std::make_shared<TlsExtensionDropper>(ssl_tls13_key_share_xtn));
- filters.push_back(
- std::make_shared<TlsExtensionDropper>(ssl_tls13_pre_shared_key_xtn));
server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(filters));
- // The client here generates an unexpected_message alert when it receives an
- // encrypted handshake message from the server (EncryptedExtension). The
- // client expects to receive an unencrypted TLS 1.2 Certificate message.
- // The server can't decrypt the alert.
- client_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
+ client_->ExpectSendAlert(kTlsAlertDecodeError);
server_->ExpectSendAlert(kTlsAlertBadRecordMac); // Server can't read
ConnectExpectFail();
- client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA);
+ client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
}
-TEST_P(TlsConnectGeneric, ReConnectTicket) {
- ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
- server_->EnableSingleCipher(ChooseOneCipher(version_));
- Connect();
- SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_sha256);
- // Resume
- Reset();
- ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
- ExpectResumption(RESUME_TICKET);
- Connect();
- // Only the client knows this.
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
- ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
-}
-
-TEST_P(TlsConnectGenericPre13, ReConnectCache) {
- ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
- server_->EnableSingleCipher(ChooseOneCipher(version_));
- Connect();
- SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_sha256);
- // Resume
- Reset();
- ExpectResumption(RESUME_SESSIONID);
- Connect();
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
- ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
-}
-
-TEST_P(TlsConnectGeneric, ReConnectAgainTicket) {
- ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
- server_->EnableSingleCipher(ChooseOneCipher(version_));
- Connect();
- SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_sha256);
- // Resume
- Reset();
- ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
- ExpectResumption(RESUME_TICKET);
- Connect();
- // Only the client knows this.
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
- ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
- // Resume connection again
- Reset();
- ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
- ExpectResumption(RESUME_TICKET, 2);
- Connect();
- // Only the client knows this.
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
- ssl_auth_rsa_sign, ssl_sig_rsa_pss_sha256);
-}
-
} // namespace nss_test