diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /security/nss/gtests/ssl_gtest/tls_psk_unittest.cc | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/gtests/ssl_gtest/tls_psk_unittest.cc')
-rw-r--r-- | security/nss/gtests/ssl_gtest/tls_psk_unittest.cc | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/security/nss/gtests/ssl_gtest/tls_psk_unittest.cc b/security/nss/gtests/ssl_gtest/tls_psk_unittest.cc new file mode 100644 index 0000000000..678a9ff585 --- /dev/null +++ b/security/nss/gtests/ssl_gtest/tls_psk_unittest.cc @@ -0,0 +1,515 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <functional> +#include <memory> +#include "secerr.h" +#include "ssl.h" +#include "sslerr.h" +#include "sslproto.h" + +#include "gtest_utils.h" +#include "tls_connect.h" + +namespace nss_test { + +class Tls13PskTest : public TlsConnectTestBase, + public ::testing::WithParamInterface< + std::tuple<SSLProtocolVariant, uint16_t>> { + public: + Tls13PskTest() + : TlsConnectTestBase(std::get<0>(GetParam()), + SSL_LIBRARY_VERSION_TLS_1_3), + suite_(std::get<1>(GetParam())) {} + + void SetUp() override { + TlsConnectTestBase::SetUp(); + scoped_psk_.reset(GetPsk()); + ASSERT_TRUE(!!scoped_psk_); + } + + private: + PK11SymKey* GetPsk() { + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + ADD_FAILURE(); + return nullptr; + } + + SECItem psk_item; + psk_item.type = siBuffer; + psk_item.len = sizeof(kPskDummyVal_); + psk_item.data = const_cast<uint8_t*>(kPskDummyVal_); + + PK11SymKey* key = + PK11_ImportSymKey(slot.get(), CKM_HKDF_KEY_GEN, PK11_OriginUnwrap, + CKA_DERIVE, &psk_item, NULL); + if (!key) { + ADD_FAILURE(); + } + return key; + } + + protected: + ScopedPK11SymKey scoped_psk_; + const uint16_t suite_; + const uint8_t kPskDummyVal_[16] = {0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + const std::string kPskDummyLabel_ = "NSS PSK GTEST label"; + const SSLHashType kPskHash_ = ssl_hash_sha384; +}; + +// TLS 1.3 PSK connection test. +TEST_P(Tls13PskTest, NormalExternal) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); + client_->RemovePsk(kPskDummyLabel_); + server_->RemovePsk(kPskDummyLabel_); + + // Removing it again should fail. + EXPECT_EQ(SECFailure, SSL_RemoveExternalPsk(client_->ssl_fd(), + reinterpret_cast<const uint8_t*>( + kPskDummyLabel_.data()), + kPskDummyLabel_.length())); + EXPECT_EQ(SECFailure, SSL_RemoveExternalPsk(server_->ssl_fd(), + reinterpret_cast<const uint8_t*>( + kPskDummyLabel_.data()), + kPskDummyLabel_.length())); +} + +TEST_P(Tls13PskTest, KeyTooLarge) { + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + ASSERT_TRUE(!!slot); + ScopedPK11SymKey scoped_psk(PK11_KeyGen( + slot.get(), CKM_GENERIC_SECRET_KEY_GEN, nullptr, 128, nullptr)); + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); +} + +// Attempt to use a PSK with the wrong PRF hash. +// "Clients MUST verify that...the server selected a cipher suite +// indicating a Hash associated with the PSK" +TEST_P(Tls13PskTest, ClientVerifyHashType) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + MakeTlsFilter<SelectedCipherSuiteReplacer>(server_, + TLS_CHACHA20_POLY1305_SHA256); + client_->ExpectSendAlert(kTlsAlertIllegalParameter); + if (variant_ == ssl_variant_stream) { + server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); + ConnectExpectFail(); + EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code()); + } else { + ConnectExpectFailOneSide(TlsAgent::CLIENT); + } + EXPECT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code()); +} + +// Different EPSKs (by label) on each endpoint. Expect cert auth. +TEST_P(Tls13PskTest, LabelMismatch) { + client_->AddPsk(scoped_psk_, std::string("foo"), kPskHash_); + server_->AddPsk(scoped_psk_, std::string("bar"), kPskHash_); + Connect(); + CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); +} + +SSLHelloRetryRequestAction RetryFirstHello( + PRBool firstHello, const PRUint8* clientToken, unsigned int clientTokenLen, + PRUint8* appToken, unsigned int* appTokenLen, unsigned int appTokenMax, + void* arg) { + auto* called = reinterpret_cast<size_t*>(arg); + ++*called; + EXPECT_EQ(0U, clientTokenLen); + EXPECT_EQ(*called, firstHello ? 1U : 2U); + return firstHello ? ssl_hello_retry_request : ssl_hello_retry_accept; +} + +// Test resumption PSK with HRR. +TEST_P(Tls13PskTest, ResPskRetryStateless) { + ConfigureSelfEncrypt(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + Connect(); + SendReceive(); // Need to read so that we absorb the session ticket. + CheckKeys(); + + Reset(); + StartConnect(); + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( + server_->ssl_fd(), RetryFirstHello, &cb_called)); + ExpectResumption(RESUME_TICKET); + Handshake(); + CheckConnected(); + EXPECT_EQ(2U, cb_called); + CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); + SendReceive(); +} + +// Test external PSK with HRR. +TEST_P(Tls13PskTest, ExtPskRetryStateless) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + size_t cb_called = 0; + EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( + server_->ssl_fd(), RetryFirstHello, &cb_called)); + StartConnect(); + client_->Handshake(); + server_->Handshake(); + EXPECT_EQ(1U, cb_called); + auto replacement = std::make_shared<TlsAgent>( + server_->name(), TlsAgent::SERVER, server_->variant()); + server_ = replacement; + server_->SetVersionRange(version_, version_); + client_->SetPeer(server_); + server_->SetPeer(client_); + server_->AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + server_->ExpectPsk(); + server_->StartConnect(); + Handshake(); + CheckConnected(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); +} + +// Server not configured with PSK and sends a certificate instead of +// a selected_identity. Client should attempt certificate authentication. +TEST_P(Tls13PskTest, ClientOnly) { + client_->AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + Connect(); + CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); +} + +// Set a PSK, remove psk_key_exchange_modes. +TEST_P(Tls13PskTest, DropKexModes) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + StartConnect(); + MakeTlsFilter<TlsExtensionDropper>(client_, + ssl_tls13_psk_key_exchange_modes_xtn); + ConnectExpectAlert(server_, kTlsAlertMissingExtension); + client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT); + server_->CheckErrorCode(SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES); +} + +// "Clients MUST verify that...a server "key_share" extension is present +// if required by the ClientHello "psk_key_exchange_modes" extension." +// As we don't support PSK without DH, it is always required. +TEST_P(Tls13PskTest, DropRequiredKeyShare) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + StartConnect(); + MakeTlsFilter<TlsExtensionDropper>(server_, ssl_tls13_key_share_xtn); + client_->ExpectSendAlert(kTlsAlertMissingExtension); + if (variant_ == ssl_variant_stream) { + server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); + ConnectExpectFail(); + } else { + ConnectExpectFailOneSide(TlsAgent::CLIENT); + } + client_->CheckErrorCode(SSL_ERROR_MISSING_KEY_SHARE); +} + +// "Clients MUST verify that...the server's selected_identity is +// within the range supplied by the client". We send one OfferedPsk. +TEST_P(Tls13PskTest, InvalidSelectedIdentity) { + static const uint8_t selected_identity[] = {0x00, 0x01}; + DataBuffer buf(selected_identity, sizeof(selected_identity)); + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + StartConnect(); + MakeTlsFilter<TlsExtensionReplacer>(server_, ssl_tls13_pre_shared_key_xtn, + buf); + client_->ExpectSendAlert(kTlsAlertIllegalParameter); + if (variant_ == ssl_variant_stream) { + server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); + ConnectExpectFail(); + } else { + ConnectExpectFailOneSide(TlsAgent::CLIENT); + } + client_->CheckErrorCode(SSL_ERROR_MALFORMED_PRE_SHARED_KEY); +} + +// Resume-eligible reconnect with an EPSK configured. +// Expect the EPSK to be used. +TEST_P(Tls13PskTest, PreferEpsk) { + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + Connect(); + SendReceive(); // Need to read so that we absorb the session ticket. + CheckKeys(); + + Reset(); + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + ExpectResumption(RESUME_NONE); + StartConnect(); + Handshake(); + CheckConnected(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); +} + +// Enable resumption, but connect (initially) with an EPSK. +// Expect no session ticket. +TEST_P(Tls13PskTest, SuppressNewSessionTicket) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + auto nst_capture = + MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_new_session_ticket); + nst_capture->EnableDecryption(); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); + EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), nullptr, 0)); + EXPECT_EQ(0U, nst_capture->buffer().len()); + if (variant_ == ssl_variant_stream) { + EXPECT_EQ(SSL_ERROR_FEATURE_DISABLED, PORT_GetError()); + } else { + EXPECT_EQ(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, PORT_GetError()); + } + + Reset(); + ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + ExpectResumption(RESUME_NONE); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); +} + +TEST_P(Tls13PskTest, BadConfigValues) { + EXPECT_TRUE(client_->EnsureTlsSetup()); + std::vector<uint8_t> label{'L', 'A', 'B', 'E', 'L'}; + EXPECT_EQ(SECFailure, + SSL_AddExternalPsk(client_->ssl_fd(), nullptr, label.data(), + label.size(), kPskHash_)); + EXPECT_EQ(SECFailure, SSL_AddExternalPsk(client_->ssl_fd(), scoped_psk_.get(), + nullptr, label.size(), kPskHash_)); + + EXPECT_EQ(SECFailure, SSL_AddExternalPsk(client_->ssl_fd(), scoped_psk_.get(), + label.data(), 0, kPskHash_)); + EXPECT_EQ(SECSuccess, + SSL_AddExternalPsk(client_->ssl_fd(), scoped_psk_.get(), + label.data(), label.size(), ssl_hash_sha256)); + + EXPECT_EQ(SECFailure, + SSL_RemoveExternalPsk(client_->ssl_fd(), nullptr, label.size())); + + EXPECT_EQ(SECFailure, + SSL_RemoveExternalPsk(client_->ssl_fd(), label.data(), 0)); + + EXPECT_EQ(SECSuccess, SSL_RemoveExternalPsk(client_->ssl_fd(), label.data(), + label.size())); +} + +// If the server has an EPSK configured with a ciphersuite not supported +// by the client, it should use certificate authentication. +TEST_P(Tls13PskTest, FallbackUnsupportedCiphersuite) { + client_->AddPsk(scoped_psk_, kPskDummyLabel_, ssl_hash_sha256, + TLS_AES_128_GCM_SHA256); + server_->AddPsk(scoped_psk_, kPskDummyLabel_, ssl_hash_sha256, + TLS_CHACHA20_POLY1305_SHA256); + + client_->EnableSingleCipher(TLS_AES_128_GCM_SHA256); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); +} + +// That fallback should not occur if there is no cipher overlap. +TEST_P(Tls13PskTest, ExplicitSuiteNoOverlap) { + client_->AddPsk(scoped_psk_, kPskDummyLabel_, ssl_hash_sha256, + TLS_AES_128_GCM_SHA256); + server_->AddPsk(scoped_psk_, kPskDummyLabel_, ssl_hash_sha256, + TLS_CHACHA20_POLY1305_SHA256); + + client_->EnableSingleCipher(TLS_AES_128_GCM_SHA256); + server_->EnableSingleCipher(TLS_CHACHA20_POLY1305_SHA256); + ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); + server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); + client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); +} + +TEST_P(Tls13PskTest, SuppressHandshakeCertReq) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + server_->SetOption(SSL_REQUEST_CERTIFICATE, PR_TRUE); + server_->SetOption(SSL_REQUIRE_CERTIFICATE, PR_TRUE); + const std::set<uint8_t> hs_types = {ssl_hs_certificate, + ssl_hs_certificate_request}; + auto cr_cert_capture = MakeTlsFilter<TlsHandshakeRecorder>(server_, hs_types); + cr_cert_capture->EnableDecryption(); + + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); + EXPECT_EQ(0U, cr_cert_capture->buffer().len()); +} + +TEST_P(Tls13PskTest, DisallowClientConfigWithoutServerCert) { + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + server_->SetOption(SSL_REQUEST_CERTIFICATE, PR_TRUE); + server_->SetOption(SSL_REQUIRE_CERTIFICATE, PR_TRUE); + const std::set<uint8_t> hs_types = {ssl_hs_certificate, + ssl_hs_certificate_request}; + auto cr_cert_capture = MakeTlsFilter<TlsHandshakeRecorder>(server_, hs_types); + cr_cert_capture->EnableDecryption(); + + EXPECT_EQ(SECSuccess, SSLInt_RemoveServerCertificates(server_->ssl_fd())); + + ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); + server_->CheckErrorCode(SSL_ERROR_NO_CERTIFICATE); + client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); + EXPECT_EQ(0U, cr_cert_capture->buffer().len()); +} + +TEST_F(TlsConnectStreamTls13, ClientRejectHandshakeCertReq) { + // Stream only, as the filter doesn't support DTLS 1.3 yet. + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + ASSERT_TRUE(!!slot); + ScopedPK11SymKey scoped_psk(PK11_KeyGen( + slot.get(), CKM_GENERIC_SECRET_KEY_GEN, nullptr, 32, nullptr)); + AddPsk(scoped_psk, std::string("foo"), ssl_hash_sha256); + // Inject a CR after EE. This would be legal if not for ssl_auth_psk. + auto filter = MakeTlsFilter<TlsEncryptedHandshakeMessageReplacer>( + server_, kTlsHandshakeFinished, kTlsHandshakeCertificateRequest); + filter->EnableDecryption(); + + ExpectAlert(client_, kTlsAlertUnexpectedMessage); + ConnectExpectFail(); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST); + server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); +} + +TEST_F(TlsConnectStreamTls13, RejectPha) { + // Stream only, as the filter doesn't support DTLS 1.3 yet. + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + ASSERT_TRUE(!!slot); + ScopedPK11SymKey scoped_psk(PK11_KeyGen( + slot.get(), CKM_GENERIC_SECRET_KEY_GEN, nullptr, 32, nullptr)); + AddPsk(scoped_psk, std::string("foo"), ssl_hash_sha256); + server_->SetOption(SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE); + auto kuToCr = MakeTlsFilter<TlsEncryptedHandshakeMessageReplacer>( + server_, kTlsHandshakeKeyUpdate, kTlsHandshakeCertificateRequest); + kuToCr->EnableDecryption(); + Connect(); + + // Make sure the direct path is blocked. + EXPECT_EQ(SECFailure, SSL_SendCertificateRequest(server_->ssl_fd())); + EXPECT_EQ(SSL_ERROR_FEATURE_DISABLED, PORT_GetError()); + + // Inject a PHA CR. Since this is not allowed, send KeyUpdate + // and change the message type. + EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE)); + ExpectAlert(client_, kTlsAlertUnexpectedMessage); + client_->Handshake(); // Eat the CR. + server_->Handshake(); + client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST); + server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); +} + +class Tls13PskTestWithCiphers : public Tls13PskTest {}; + +TEST_P(Tls13PskTestWithCiphers, 0RttCiphers) { + RolloverAntiReplay(); + AddPsk(scoped_psk_, kPskDummyLabel_, tls13_GetHashForCipherSuite(suite_), + suite_); + StartConnect(); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + ZeroRttSendReceive(true, true); + Handshake(); + ExpectEarlyDataAccepted(true); + CheckConnected(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); +} + +TEST_P(Tls13PskTestWithCiphers, 0RttMaxEarlyData) { + EnsureTlsSetup(); + RolloverAntiReplay(); + const char* big_message = "0123456789abcdef"; + const size_t short_size = strlen(big_message) - 1; + const PRInt32 short_length = static_cast<PRInt32>(short_size); + + // Set up the PSK + EXPECT_EQ(SECSuccess, + SSL_AddExternalPsk0Rtt( + client_->ssl_fd(), scoped_psk_.get(), + reinterpret_cast<const uint8_t*>(kPskDummyLabel_.data()), + kPskDummyLabel_.length(), tls13_GetHashForCipherSuite(suite_), + suite_, short_length)); + EXPECT_EQ(SECSuccess, + SSL_AddExternalPsk0Rtt( + server_->ssl_fd(), scoped_psk_.get(), + reinterpret_cast<const uint8_t*>(kPskDummyLabel_.data()), + kPskDummyLabel_.length(), tls13_GetHashForCipherSuite(suite_), + suite_, short_length)); + client_->ExpectPsk(); + server_->ExpectPsk(); + client_->expected_cipher_suite(suite_); + server_->expected_cipher_suite(suite_); + StartConnect(); + client_->Set0RttEnabled(true); + server_->Set0RttEnabled(true); + client_->Handshake(); + CheckEarlyDataLimit(client_, short_size); + + PRInt32 sent; + // Writing more than the limit will succeed in TLS, but fail in DTLS. + if (variant_ == ssl_variant_stream) { + sent = PR_Write(client_->ssl_fd(), big_message, + static_cast<PRInt32>(strlen(big_message))); + } else { + sent = PR_Write(client_->ssl_fd(), big_message, + static_cast<PRInt32>(strlen(big_message))); + EXPECT_GE(0, sent); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); + + // Try an exact-sized write now. + sent = PR_Write(client_->ssl_fd(), big_message, short_length); + } + EXPECT_EQ(short_length, sent); + + // Even a single octet write should now fail. + sent = PR_Write(client_->ssl_fd(), big_message, 1); + EXPECT_GE(0, sent); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); + + // Process the ClientHello and read 0-RTT. + server_->Handshake(); + CheckEarlyDataLimit(server_, short_size); + + std::vector<uint8_t> buf(short_size + 1); + PRInt32 read = PR_Read(server_->ssl_fd(), buf.data(), buf.capacity()); + EXPECT_EQ(short_length, read); + EXPECT_EQ(0, memcmp(big_message, buf.data(), short_size)); + + // Second read fails. + read = PR_Read(server_->ssl_fd(), buf.data(), buf.capacity()); + EXPECT_EQ(SECFailure, read); + EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError()); + + Handshake(); + ExpectEarlyDataAccepted(true); + CheckConnected(); + SendReceive(); +} + +static const uint16_t k0RttCipherDefs[] = {TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_128_GCM_SHA256, + TLS_AES_256_GCM_SHA384}; + +static const uint16_t kDefaultSuite[] = {TLS_CHACHA20_POLY1305_SHA256}; + +INSTANTIATE_TEST_SUITE_P( + Tls13PskTest, Tls13PskTest, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, + ::testing::ValuesIn(kDefaultSuite))); + +INSTANTIATE_TEST_SUITE_P( + Tls13PskTestWithCiphers, Tls13PskTestWithCiphers, + ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, + ::testing::ValuesIn(k0RttCipherDefs))); + +} // namespace nss_test |