"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "nss/gtests/ssl_gtest/tls_ech_unittest.cc" between
nss-3.61.tar.gz and nss-3.62.tar.gz

About: NSS is a set of libraries, APIs, utilities, and documentation designed to support cross-platform development of security-enabled client and server applications. It provides a complete implementation of the crypto libraries used by Mozilla and other companies.

tls_ech_unittest.cc  (nss-3.61):tls_ech_unittest.cc  (nss-3.62)
skipping to change at line 22 skipping to change at line 22
#include "gtest_utils.h" #include "gtest_utils.h"
#include "pk11pub.h" #include "pk11pub.h"
#include "tls_agent.h" #include "tls_agent.h"
#include "tls_connect.h" #include "tls_connect.h"
#include "util.h" #include "util.h"
namespace nss_test { namespace nss_test {
class TlsAgentEchTest : public TlsAgentTestClient13 { class TlsAgentEchTest : public TlsAgentTestClient13 {
protected: protected:
void InstallEchConfig(const DataBuffer& record, PRErrorCode err = 0) { void InstallEchConfig(const DataBuffer& echconfig, PRErrorCode err = 0) {
SECStatus rv = SECStatus rv = SSL_SetClientEchConfigs(agent_->ssl_fd(), echconfig.data(),
SSL_SetClientEchConfigs(agent_->ssl_fd(), record.data(), record.len()); echconfig.len());
if (err == 0) { if (err == 0) {
ASSERT_EQ(SECSuccess, rv); ASSERT_EQ(SECSuccess, rv);
} else { } else {
ASSERT_EQ(SECFailure, rv); ASSERT_EQ(SECFailure, rv);
ASSERT_EQ(err, PORT_GetError()); ASSERT_EQ(err, PORT_GetError());
} }
} }
}; };
#ifdef NSS_ENABLE_DRAFT_HPKE #ifdef NSS_ENABLE_DRAFT_HPKE
skipping to change at line 146 skipping to change at line 146
server_priv.get(), server_rec.data(), server_priv.get(), server_rec.data(),
server_rec.len())); server_rec.len()));
ASSERT_EQ(SECSuccess, ASSERT_EQ(SECSuccess,
SSL_SetClientEchConfigs(client_->ssl_fd(), retry_configs.data, SSL_SetClientEchConfigs(client_->ssl_fd(), retry_configs.data,
retry_configs.len)); retry_configs.len));
client_->ExpectEch(); client_->ExpectEch();
server_->ExpectEch(); server_->ExpectEch();
Connect(); Connect();
} }
private:
// Testing certan invalid CHInner configurations is tricky, particularly
// since the CHOuter forms AAD and isn't available in filters. Instead of
// generating these inputs on the fly, use a fixed server keypair so that
// the input can be generated once (e.g. via a debugger) and replayed in
// each invocation of the test.
std::string kFixedServerPubkey =
"3067020100301406072a8648ce3d020106092b06010401da470f01044c304a"
"02010104205a8aa0d2476b28521588e0c704b14db82cdd4970d340d293a957"
"6deaee9ec1c7a1230321008756e2580c07c1d2ffcb662f5fadc6d6ff13da85"
"abd7adfecf984aaa102c1269";
void ImportFixedEchKeypair(ScopedSECKEYPublicKey& pub, void ImportFixedEchKeypair(ScopedSECKEYPublicKey& pub,
ScopedSECKEYPrivateKey& priv) { ScopedSECKEYPrivateKey& priv) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) { if (!slot) {
ADD_FAILURE() << "No slot"; ADD_FAILURE() << "No slot";
return; return;
} }
std::vector<uint8_t> pkcs8_r = hex_string_to_bytes(kFixedServerPubkey); std::vector<uint8_t> pkcs8_r = hex_string_to_bytes(kFixedServerPubkey);
SECItem pkcs8_r_item = {siBuffer, toUcharPtr(pkcs8_r.data()), SECItem pkcs8_r_item = {siBuffer, toUcharPtr(pkcs8_r.data()),
static_cast<unsigned int>(pkcs8_r.size())}; static_cast<unsigned int>(pkcs8_r.size())};
skipping to change at line 179 skipping to change at line 167
SECKEYPrivateKey* tmp_priv = nullptr; SECKEYPrivateKey* tmp_priv = nullptr;
ASSERT_EQ(SECSuccess, PK11_ImportDERPrivateKeyInfoAndReturnKey( ASSERT_EQ(SECSuccess, PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8_r_item, nullptr, nullptr, slot.get(), &pkcs8_r_item, nullptr, nullptr,
false, false, KU_ALL, &tmp_priv, nullptr)); false, false, KU_ALL, &tmp_priv, nullptr));
priv.reset(tmp_priv); priv.reset(tmp_priv);
SECKEYPublicKey* tmp_pub = SECKEY_ConvertToPublicKey(tmp_priv); SECKEYPublicKey* tmp_pub = SECKEY_ConvertToPublicKey(tmp_priv);
pub.reset(tmp_pub); pub.reset(tmp_pub);
ASSERT_NE(nullptr, tmp_pub); ASSERT_NE(nullptr, tmp_pub);
} }
private:
// Testing certan invalid CHInner configurations is tricky, particularly
// since the CHOuter forms AAD and isn't available in filters. Instead of
// generating these inputs on the fly, use a fixed server keypair so that
// the input can be generated once (e.g. via a debugger) and replayed in
// each invocation of the test.
std::string kFixedServerPubkey =
"3067020100301406072a8648ce3d020106092b06010401da470f01044c304a"
"02010104205a8aa0d2476b28521588e0c704b14db82cdd4970d340d293a957"
"6deaee9ec1c7a1230321008756e2580c07c1d2ffcb662f5fadc6d6ff13da85"
"abd7adfecf984aaa102c1269";
void SetMutualEchConfigs(ScopedSECKEYPublicKey& pub, void SetMutualEchConfigs(ScopedSECKEYPublicKey& pub,
ScopedSECKEYPrivateKey& priv) { ScopedSECKEYPrivateKey& priv) {
DataBuffer record; DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub,
priv);
ASSERT_EQ(SECSuccess, ASSERT_EQ(SECSuccess,
SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(), SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(),
record.data(), record.len())); echconfig.data(), echconfig.len()));
ASSERT_EQ(SECSuccess, SSL_SetClientEchConfigs(client_->ssl_fd(), ASSERT_EQ(SECSuccess,
record.data(), record.len())); SSL_SetClientEchConfigs(client_->ssl_fd(), echconfig.data(),
echconfig.len()));
} }
}; };
static void CheckCertVerifyPublicName(TlsAgent* agent) { static void CheckCertVerifyPublicName(TlsAgent* agent) {
agent->UpdatePreliminaryChannelInfo(); agent->UpdatePreliminaryChannelInfo();
EXPECT_NE(0U, (agent->pre_info().valuesSet & ssl_preinfo_ech)); EXPECT_NE(0U, (agent->pre_info().valuesSet & ssl_preinfo_ech));
EXPECT_EQ(agent->GetEchExpected(), agent->pre_info().echAccepted); EXPECT_EQ(agent->GetEchExpected(), agent->pre_info().echAccepted);
// Check that echPublicName is only exposed in the rejection // Check that echPublicName is only exposed in the rejection
// case, so that the application can use it for CertVerfiy. // case, so that the application can use it for CertVerfiy.
skipping to change at line 227 skipping to change at line 229
return SECFailure; return SECFailure;
} }
TEST_P(TlsAgentEchTest, EchConfigsSupportedYesNo) { TEST_P(TlsAgentEchTest, EchConfigsSupportedYesNo) {
if (variant_ == ssl_variant_datagram) { if (variant_ == ssl_variant_datagram) {
GTEST_SKIP(); GTEST_SKIP();
} }
// ECHConfig 2 cipher_suites are unsupported. // ECHConfig 2 cipher_suites are unsupported.
const std::string mixed = const std::string mixed =
"0086FE08003F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304" "0086FE09003F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304"
"444156E4E04D1BF0FFDA7783B6B457F75600200008000100030001000100640000FE0800" "444156E4E04D1BF0FFDA7783B6B457F75600200008000100030001000100640000FE0900"
"3F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304444156E4E0" "3F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304444156E4E0"
"4D1BF0FFDA7783B6B457F756002000080001FFFFFFFF000100640000"; "4D1BF0FFDA7783B6B457F756002000080001FFFFFFFF000100640000";
std::vector<uint8_t> config = hex_string_to_bytes(mixed); std::vector<uint8_t> config = hex_string_to_bytes(mixed);
DataBuffer record(config.data(), config.size()); DataBuffer echconfig(config.data(), config.size());
EnsureInit(); EnsureInit();
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
InstallEchConfig(record, 0); InstallEchConfig(echconfig, 0);
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_TRUE(filter->captured()); ASSERT_TRUE(filter->captured());
} }
TEST_P(TlsAgentEchTest, EchConfigsSupportedNoYes) { TEST_P(TlsAgentEchTest, EchConfigsSupportedNoYes) {
if (variant_ == ssl_variant_datagram) { if (variant_ == ssl_variant_datagram) {
GTEST_SKIP(); GTEST_SKIP();
} }
// ECHConfig 1 cipher_suites are unsupported. // ECHConfig 1 cipher_suites are unsupported.
const std::string mixed = const std::string mixed =
"0086FE08003F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304" "0086FE09003F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304"
"444156E4E04D1BF0FFDA7783B6B457F756002000080001FFFFFFFF000100640000FE0800" "444156E4E04D1BF0FFDA7783B6B457F756002000080001FFFFFFFF000100640000FE0900"
"3F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304444156E4E0" "3F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304444156E4E0"
"4D1BF0FFDA7783B6B457F75600200008000100030001000100640000"; "4D1BF0FFDA7783B6B457F75600200008000100030001000100640000";
std::vector<uint8_t> config = hex_string_to_bytes(mixed); std::vector<uint8_t> config = hex_string_to_bytes(mixed);
DataBuffer record(config.data(), config.size()); DataBuffer echconfig(config.data(), config.size());
EnsureInit(); EnsureInit();
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
InstallEchConfig(record, 0); InstallEchConfig(echconfig, 0);
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_TRUE(filter->captured()); ASSERT_TRUE(filter->captured());
} }
TEST_P(TlsAgentEchTest, EchConfigsSupportedNoNo) { TEST_P(TlsAgentEchTest, EchConfigsSupportedNoNo) {
if (variant_ == ssl_variant_datagram) { if (variant_ == ssl_variant_datagram) {
GTEST_SKIP(); GTEST_SKIP();
} }
// ECHConfig 1 and 2 cipher_suites are unsupported. // ECHConfig 1 and 2 cipher_suites are unsupported.
const std::string unsupported = const std::string unsupported =
"0086FE08003F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304" "0086FE09003F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304"
"444156E4E04D1BF0FFDA7783B6B457F756002000080001FFFF0001FFFF00640000FE0800" "444156E4E04D1BF0FFDA7783B6B457F756002000080001FFFF0001FFFF00640000FE0900"
"3F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304444156E4E0" "3F000B7075626C69632E6E616D6500203BB6D46C201B820F1AE4AFD4DEC304444156E4E0"
"4D1BF0FFDA7783B6B457F75600200008FFFF0003FFFF000100640000"; "4D1BF0FFDA7783B6B457F75600200008FFFF0003FFFF000100640000";
std::vector<uint8_t> config = hex_string_to_bytes(unsupported); std::vector<uint8_t> config = hex_string_to_bytes(unsupported);
DataBuffer record(config.data(), config.size()); DataBuffer echconfig(config.data(), config.size());
EnsureInit(); EnsureInit();
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
InstallEchConfig(record, SEC_ERROR_INVALID_ARGS); InstallEchConfig(echconfig, SEC_ERROR_INVALID_ARGS);
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_P(TlsAgentEchTest, ShortEchConfig) { TEST_P(TlsAgentEchTest, ShortEchConfig) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
record.Truncate(record.len() - 1); echconfig.Truncate(echconfig.len() - 1);
InstallEchConfig(record, SEC_ERROR_BAD_DATA); InstallEchConfig(echconfig, SEC_ERROR_BAD_DATA);
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_P(TlsAgentEchTest, LongEchConfig) { TEST_P(TlsAgentEchTest, LongEchConfig) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
record.Write(record.len(), 1, 1); // Append one byte echconfig.Write(echconfig.len(), 1, 1); // Append one byte
InstallEchConfig(record, SEC_ERROR_BAD_DATA); InstallEchConfig(echconfig, SEC_ERROR_BAD_DATA);
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_P(TlsAgentEchTest, UnsupportedEchConfigVersion) { TEST_P(TlsAgentEchTest, UnsupportedEchConfigVersion) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
static const uint8_t bad_version[] = {0xff, 0xff}; static const uint8_t bad_version[] = {0xff, 0xff};
DataBuffer bad_ver_buf(bad_version, sizeof(bad_version)); DataBuffer bad_ver_buf(bad_version, sizeof(bad_version));
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
record.Splice(bad_ver_buf, 2, 2); echconfig.Splice(bad_ver_buf, 2, 2);
InstallEchConfig(record, SEC_ERROR_INVALID_ARGS); InstallEchConfig(echconfig, SEC_ERROR_INVALID_ARGS);
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_P(TlsAgentEchTest, UnsupportedHpkeKem) { TEST_P(TlsAgentEchTest, UnsupportedHpkeKem) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
// SSL_EncodeEchConfig encodes without validation. // SSL_EncodeEchConfig encodes without validation.
TlsConnectTestBase::GenerateEchConfig(static_cast<HpkeKemId>(0xff), TlsConnectTestBase::GenerateEchConfig(static_cast<HpkeKemId>(0xff),
kDefaultSuites, kPublicName, 100, kDefaultSuites, kPublicName, 100,
record, pub, priv); echconfig, pub, priv);
InstallEchConfig(record, SEC_ERROR_INVALID_ARGS); InstallEchConfig(echconfig, SEC_ERROR_INVALID_ARGS);
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_P(TlsAgentEchTest, EchRejectIgnoreAllUnknownSuites) { TEST_P(TlsAgentEchTest, EchRejectIgnoreAllUnknownSuites) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kBogusSuite, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kBogusSuite,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
InstallEchConfig(record, SEC_ERROR_INVALID_ARGS); InstallEchConfig(echconfig, SEC_ERROR_INVALID_ARGS);
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake();
ASSERT_FALSE(filter->captured());
}
TEST_P(TlsAgentEchTest, EchConfigRejectEmptyPublicName) {
EnsureInit();
ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv;
DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kBogusSuite, "",
100, echconfig, pub, priv);
InstallEchConfig(echconfig, SSL_ERROR_RX_MALFORMED_ECH_CONFIG);
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_F(TlsConnectStreamTls13, EchAcceptIgnoreSingleUnknownSuite) { TEST_F(TlsConnectStreamTls13, EchAcceptIgnoreSingleUnknownSuite) {
EnsureTlsSetup(); EnsureTlsSetup();
DataBuffer record; DataBuffer echconfig;
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256,
kUnknownFirstSuite, kPublicName, 100, kUnknownFirstSuite, kPublicName, 100,
record, pub, priv); echconfig, pub, priv);
ASSERT_EQ(SECSuccess, SSL_SetClientEchConfigs(client_->ssl_fd(), ASSERT_EQ(SECSuccess,
record.data(), record.len())); SSL_SetClientEchConfigs(client_->ssl_fd(), echconfig.data(),
echconfig.len()));
ASSERT_EQ(SECSuccess, ASSERT_EQ(SECSuccess,
SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(), SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(),
record.data(), record.len())); echconfig.data(), echconfig.len()));
client_->ExpectEch(); client_->ExpectEch();
server_->ExpectEch(); server_->ExpectEch();
Connect(); Connect();
} }
TEST_P(TlsAgentEchTest, ApiInvalidArgs) { TEST_P(TlsAgentEchTest, ApiInvalidArgs) {
EnsureInit(); EnsureInit();
// SetClient // SetClient
EXPECT_EQ(SECFailure, SSL_SetClientEchConfigs(agent_->ssl_fd(), nullptr, 1)); EXPECT_EQ(SECFailure, SSL_SetClientEchConfigs(agent_->ssl_fd(), nullptr, 1));
skipping to change at line 491 skipping to change at line 510
TEST_P(TlsAgentEchTest, NoEarlyRetryConfigs) { TEST_P(TlsAgentEchTest, NoEarlyRetryConfigs) {
EnsureInit(); EnsureInit();
StackSECItem retry_configs; StackSECItem retry_configs;
EXPECT_EQ(SECFailure, EXPECT_EQ(SECFailure,
SSL_GetEchRetryConfigs(agent_->ssl_fd(), &retry_configs)); SSL_GetEchRetryConfigs(agent_->ssl_fd(), &retry_configs));
EXPECT_EQ(SSL_ERROR_HANDSHAKE_NOT_COMPLETED, PORT_GetError()); EXPECT_EQ(SSL_ERROR_HANDSHAKE_NOT_COMPLETED, PORT_GetError());
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
InstallEchConfig(record, 0); InstallEchConfig(echconfig, 0);
EXPECT_EQ(SECFailure, EXPECT_EQ(SECFailure,
SSL_GetEchRetryConfigs(agent_->ssl_fd(), &retry_configs)); SSL_GetEchRetryConfigs(agent_->ssl_fd(), &retry_configs));
EXPECT_EQ(SSL_ERROR_HANDSHAKE_NOT_COMPLETED, PORT_GetError()); EXPECT_EQ(SSL_ERROR_HANDSHAKE_NOT_COMPLETED, PORT_GetError());
} }
TEST_P(TlsAgentEchTest, NoSniSoNoEch) { TEST_P(TlsAgentEchTest, NoSniSoNoEch) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
SSL_SetURL(agent_->ssl_fd(), ""); SSL_SetURL(agent_->ssl_fd(), "");
InstallEchConfig(record, 0); InstallEchConfig(echconfig, 0);
SSL_SetURL(agent_->ssl_fd(), ""); SSL_SetURL(agent_->ssl_fd(), "");
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_P(TlsAgentEchTest, NoEchConfigSoNoEch) { TEST_P(TlsAgentEchTest, NoEchConfigSoNoEch) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
TEST_P(TlsAgentEchTest, EchConfigDuplicateExtensions) { TEST_P(TlsAgentEchTest, EchConfigDuplicateExtensions) {
EnsureInit(); EnsureInit();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
static const uint8_t duped_xtn[] = {0x00, 0x08, 0x00, 0x01, 0x00, static const uint8_t duped_xtn[] = {0x00, 0x08, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00}; 0x00, 0x00, 0x01, 0x00, 0x00};
DataBuffer buf(duped_xtn, sizeof(duped_xtn)); DataBuffer buf(duped_xtn, sizeof(duped_xtn));
record.Truncate(record.len() - 2); echconfig.Truncate(echconfig.len() - 2);
record.Append(buf); echconfig.Append(buf);
uint32_t len; uint32_t len;
ASSERT_TRUE(record.Read(0, 2, &len)); ASSERT_TRUE(echconfig.Read(0, 2, &len));
len += buf.len() - 2; len += buf.len() - 2;
DataBuffer new_len; DataBuffer new_len;
ASSERT_TRUE(new_len.Write(0, len, 2)); ASSERT_TRUE(new_len.Write(0, len, 2));
record.Splice(new_len, 0, 2); echconfig.Splice(new_len, 0, 2);
new_len.Truncate(0); new_len.Truncate(0);
ASSERT_TRUE(record.Read(4, 2, &len)); ASSERT_TRUE(echconfig.Read(4, 2, &len));
len += buf.len() - 2; len += buf.len() - 2;
ASSERT_TRUE(new_len.Write(0, len, 2)); ASSERT_TRUE(new_len.Write(0, len, 2));
record.Splice(new_len, 4, 2); echconfig.Splice(new_len, 4, 2);
InstallEchConfig(record, SEC_ERROR_EXTENSION_VALUE_INVALID); InstallEchConfig(echconfig, SEC_ERROR_EXTENSION_VALUE_INVALID);
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(agent_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
agent_, ssl_tls13_encrypted_client_hello_xtn); agent_, ssl_tls13_encrypted_client_hello_xtn);
agent_->Handshake(); agent_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
} }
// Test an encoded ClientHelloInner containing an extra extensionType // Test an encoded ClientHelloInner containing an extra extensionType
// in outer_extensions, for which there is no corresponding (uncompressed) // in outer_extensions, for which there is no corresponding (uncompressed)
// extension in ClientHelloOuter. // extension in ClientHelloOuter.
TEST_F(TlsConnectStreamTls13Ech, EchOuterExtensionsReferencesMissing) { TEST_F(TlsConnectStreamTls13Ech, EchOuterExtensionsReferencesMissing) {
std::string ch = std::string ch =
"01000170030374d616d97efe591bf9bee4496bcc1118145b4dd02f7d1ff979fd0cf61749" "010001580303dfff91b5e1ba00f29d2338419b3abf125ee1051a942ae25163bbf609a1ea"
"a91e0000061301130313020100014100000010000e00000b7075626c69632e6e616d65ff" "11920000061301130313020100012900000010000e00000b7075626c69632e6e616d65ff"
"01000100000a00140012001d00170018001901000101010201030104003300260024001d" "01000100000a00140012001d00170018001901000101010201030104003300260024001d"
"00204f346f86351b077492c83564c909d1aaab4f6f3ee2566af0e90a4684c793805d002b" "0020d94c1590c261e9ea8ae55bc9581f397cc598115f8b70aec1b0236f4c8c555537002b"
"0003020304000d0018001604030503060302030804080508060401050106010201002d00" "0003020304000d0018001604030503060302030804080508060401050106010201002d00"
"020101001c00024001fe0800b30001000320a10698ccbd4bd86df91f617e58dd2ca96b8b" "020101001c00024001fe09009b0001000308fde4163c5c6e8bb6002067a895efa2721c88"
"a5f058dd5c5ab1ca9750ef9d28c70020924764b36fe5d4a985f9857ceb75edb10b5f4b5b" "63ecfa1bea1e520ae6f6cf938e3e37802688f7a83a871a04006aa693f053f87db87cf82a"
"f9d59290db70743e3c582163006acea5d7785cc506ecf5c859a9cad18f2b1df1a32231fe" "7caa20670d79b92ccda97893fdf99352fc766fb3dd5570948311dddb6d41214234fae585"
"0330471ee0e88ece9047e6491a381bfabed58f7fc542f0ba78eb55030bcfe1d400f67275" "e354a048c072b3fb00a0a64e8e089e4a90152ee91a2c5b947c99d3dcebfb6334453b023d"
"eac8619d1e4237e9d6176dd4eb54f3f25865686756f313a4ba47901c83e5ad5413609d39" "4d725010996a290a0552e4b238ec91c21440adc0d51a4435";
"816346b940115fd68e534609";
ReplayChWithMalformedInner(ch, kTlsAlertIllegalParameter, ReplayChWithMalformedInner(ch, kTlsAlertIllegalParameter,
SSL_ERROR_RX_MALFORMED_ECH_EXTENSION, SSL_ERROR_RX_MALFORMED_ECH_EXTENSION,
SSL_ERROR_ILLEGAL_PARAMETER_ALERT); SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
} }
// Drop supported_versions from CHInner, make sure we don't negotiate 1.2+ECH. // Drop supported_versions from CHInner, make sure we don't negotiate 1.2+ECH.
TEST_F(TlsConnectStreamTls13Ech, EchVersion12Inner) { TEST_F(TlsConnectStreamTls13Ech, EchVersion12Inner) {
std::string ch = std::string ch =
"0100017003034dd5bf4c12835e9be21f983953720e3595b3a8eeb4a44467678caceb7727" "0100015103038fbe6f75b0123116fa5c4eccf0cf26c17ab1ded5529307e419c036ac7e9c"
"3be90000061301130313020100014100000010000e00000b7075626c69632e6e616d65ff" "e8e30000061301130313020100012200000010000e00000b7075626c69632e6e616d65ff"
"01000100000a00140012001d00170018001901000101010201030104003300260024001d" "01000100000a00140012001d00170018001901000101010201030104003300260024001d"
"0020af7b976cdf69ffcd494ca5a93ae3ecde692b09be518ee033aad908c45b82c368002b" "002078d644583b4f056bec4d8ae9bddd383aed6eb7cdb3294f88b0e37a4f26a02549002b"
"0003020304000d0018001604030503060302030804080508060401050106010201002d00" "0003020304000d0018001604030503060302030804080508060401050106010201002d00"
"020101001c0002400100150003000000fe0800ac0001000320a10698ccbd4bd86df91f61" "020101001c00024001fe0900940001000308fde4163c5c6e8bb600208958e66d1d4bbd46"
"7e58dd2ca96b8ba5f058dd5c5ab1ca9750ef9d28c70020f5ece4c187b76f7e3d467c7506" "4792f392e119dbce91ee3e65067899b45c83855dae61e67a00637df038e7b35483786707"
"215e73c27c918cd863c0e80d76a7987ec274320063e037492868eff5296a22dc50885e9d" "dd1b25be5cd3dd07f1ca4b33a3595ddb959e5c0da3d2f0b3314417614968691700c05232"
"f6964a5e26546f1bada043f8834988dfea5394b4c45a4d0b3afc52142d33f94161135a63" "07c729b34f3b5de62728b3cb6b45b00e6f94b204a9504d0e7e24c66f42aacc73591c86ef"
"ed3c1b63f60d8133fb1cff17e1f9ced6c871984e412ed8ddb0f487c4d09d7aea80488004" "571e61cebd6ba671081150a2dae89e7493";
"c45a17cd3b5cdca316155fdb";
ReplayChWithMalformedInner(ch, kTlsAlertProtocolVersion, ReplayChWithMalformedInner(ch, kTlsAlertProtocolVersion,
SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_UNSUPPORTED_VERSION,
SSL_ERROR_PROTOCOL_VERSION_ALERT); SSL_ERROR_PROTOCOL_VERSION_ALERT);
} }
// Use CHInner supported_versions to negotiate 1.2. // Use CHInner supported_versions to negotiate 1.2.
TEST_F(TlsConnectStreamTls13Ech, EchVersion12InnerSupportedVersions) { TEST_F(TlsConnectStreamTls13Ech, EchVersion12InnerSupportedVersions) {
std::string ch = std::string ch =
"010001700303845c298db4017d2ed2584284b90e4ecba57a63663560c57aa0b1ac51203d" "01000158030378a601a3f12229e53e0b8d92c3599bf1782e8261d2ecaec9bbe595d4c901"
"c8560000061301130313020100014100000010000e00000b7075626c69632e6e616d65ff" "98770000061301130313020100012900000010000e00000b7075626c69632e6e616d65ff"
"01000100000a00140012001d00170018001901000101010201030104003300260024001d" "01000100000a00140012001d00170018001901000101010201030104003300260024001d"
"00203356719e88b539645438f645916aeeffe93c38803a59d6997938aa98eefbcf64002b" "00201c8017d6970f3a92ac1c9919c3a26788052f84599fb0c3cb7bd381304148724e002b"
"0003020304000d0018001604030503060302030804080508060401050106010201002d00" "0003020304000d0018001604030503060302030804080508060401050106010201002d00"
"020101001c00024001fe0800b30001000320a10698ccbd4bd86df91f617e58dd2ca96b8b" "020101001c00024001fe09009b0001000308fde4163c5c6e8bb60020f7347d34f125e866"
"a5f058dd5c5ab1ca9750ef9d28c700208412c945c53624bcace5eda0dc1ad300a1620e86" "76b1cdc43455c6c00918a3c8a961335e1b9aa864da2b5313006a21e6ad81533e90cea24e"
"5a0f4a27755a3477b115b65b006abf1dfd77ddc1b80c5976732174a5fe7ebcf9ff1a548b" "c2c3656f6b53114b4c63bf89462696f1c8ad4e1193d87062a5537edbe83c9b35c41e9763"
"097daa12a37f3e32a613a0798544ba1d96239431bc807ddd9055ac3fb3e32b2eb42cec30" "1d2333270854758ee02548afb7f2264f904474465415a5085024487f22b017208e250ca4"
"e915357418a953027d73020fd739287414205349eeff376dd464750ca70a965141a88800" "7902d61d98fbd1cb8afc0a14dcd70a68343cf67c258758d9";
"6a043fe1d6d882d9a2c2f6f3";
ReplayChWithMalformedInner(ch, kTlsAlertProtocolVersion, ReplayChWithMalformedInner(ch, kTlsAlertProtocolVersion,
SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_UNSUPPORTED_VERSION,
SSL_ERROR_PROTOCOL_VERSION_ALERT); SSL_ERROR_PROTOCOL_VERSION_ALERT);
} }
// Replay a CH for which the ECH Inner lacks the required // Replay a CH for which CHInner lacks the required ech_is_inner extension.
// empty ECH extension.
TEST_F(TlsConnectStreamTls13Ech, EchInnerMissingEmptyEch) { TEST_F(TlsConnectStreamTls13Ech, EchInnerMissingEmptyEch) {
std::string ch = std::string ch =
"0100017103032bf866cbd6d4abdec8ce23107eaef9af51b644043953e3b70f2f28f1898e" "010001540303033b3284790ada882445bfb38b8af3509659033c931e6ae97febbaa62b19"
"87880000061301130313020100014200000010000e00000b7075626c69632e6e616d65ff" "b4ac0000061301130313020100012500000010000e00000b7075626c69632e6e616d65ff"
"01000100000a00140012001d00170018001901000101010201030104003300260024001d" "01000100000a00140012001d00170018001901000101010201030104003300260024001d"
"00208f614d3017575332ca009a42d33bcaf876b4ba6d44b052e8019c31f6f1559e41002b" "00209d1ed410ccb05ce9e424f52b1be3599bcc1efb0913ae14a24d9a69cbfbc39744002b"
"0003020304000d0018001604030503060302030804080508060401050106010201002d00" "0003020304000d0018001604030503060302030804080508060401050106010201002d00"
"020101001c000240010015000100fe0800af0001000320a10698ccbd4bd86df91f617e58" "020101001c00024001fe0900970001000308fde4163c5c6e8bb600206321bdc543a23d47"
"dd2ca96b8ba5f058dd5c5ab1ca9750ef9d28c70020da1d5d9f183a5d5e49892e38eaae5e" "7a7104ba69177cb722927c6c485117df4a077b8e82167f0b0066103d9aac7e5fc4ef990b"
"9e3e6c5d404a5fdb672ca37f9cebabd57400660ea1d61917cc1049aab22506078ccecfc4" "2ce38593589f7f6ba043847d7db6c9136adb811f63b956d56e6ca8cbe6864e3fc43a3bc5"
"16a364a1beaa8915b250bb86ac2c725698c3c641830c4aa4e8b7f50152b5732b29b1ac43" "94a332d4d63833e411c89ef14af63b5cd18c7adee99ffd1ad3112449ea18d6650bbaca66"
"45c97fc018855fd68e5600d0ef188e905b69997c3711b0ec0114a857177df728c7b84f52" "528f7e4146fafbf338c27cf89b145a55022b26a3";
"2923f932838f7f15bb22644fd4"; ReplayChWithMalformedInner(ch, kTlsAlertIllegalParameter,
ReplayChWithMalformedInner(ch, kTlsAlertDecodeError,
SSL_ERROR_MISSING_ECH_EXTENSION, SSL_ERROR_MISSING_ECH_EXTENSION,
SSL_ERROR_DECODE_ERROR_ALERT); SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}
// Replay a CH for which CHInner contains both an ECH and ech_is_inner
// extension.
TEST_F(TlsConnectStreamTls13Ech, InnerWithEchAndEchIsInner) {
std::string ch =
"0100015c030383fb49c98b62bcdf04cbbae418dd684f8f9512f40fca6861ba40555269a9"
"789f0000061301130313020100012d00000010000e00000b7075626c69632e6e616d65ff"
"01000100000a00140012001d00170018001901000101010201030104003300260024001d"
"00201e3d35a6755b7dddf7e481359429e9677baaa8dd99569c2bf0b0f7ea56e68b12002b"
"0003020304000d0018001604030503060302030804080508060401050106010201002d00"
"020101001c00024001fe09009f0001000308fde4163c5c6e8bb6002090110b89c1ba6618"
"942ea7aae8c472c22e97f10bef7dd490bee50cc108082b48006eed016fa2b3e3419cf5ef"
"9b41ab9ecffa84a4b60e2f4cc710cf31c739d1f6f88b48207aaf7ccabdd744a25a8f2a38"
"029d1b133e9d990681cf08c07a255d9242b3a002bc0865935cbb609b2b1996fab0626cb0"
"2ece6544bbde0d3218333ffd95c383a41854b76b1a254bb346a2702b";
ReplayChWithMalformedInner(ch, kTlsAlertIllegalParameter,
SSL_ERROR_RX_MALFORMED_CLIENT_HELLO,
SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}
TEST_F(TlsConnectStreamTls13, OuterWithEchAndEchIsInner) {
static uint8_t empty_buf[1] = {0};
DataBuffer empty(empty_buf, 0);
EnsureTlsSetup();
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), PR_TRUE));
MakeTlsFilter<TlsExtensionAppender>(client_, kTlsHandshakeClientHello,
ssl_tls13_ech_is_inner_xtn, empty);
ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_EXTENSION);
}
// Apply two ECHConfigs on the server. They are identical with the exception
// of the public key: the first ECHConfig contains a public key for which we
// lack the private value. Use an SSLInt function to zero all the config_ids
// (client and server), then confirm that trial decryption works.
TEST_F(TlsConnectStreamTls13Ech, EchConfigsTrialDecrypt) {
ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv;
EnsureTlsSetup();
ImportFixedEchKeypair(pub, priv);
const std::string two_configs_str =
"007EFE09003B000B7075626C69632E6E616D650020111111111111111111111111111111"
"1111111111111111111111111111111111002000040001000100640000fe09003B000B70"
"75626C69632E6E616D6500208756E2580C07C1D2FFCB662F5FADC6D6FF13DA85ABD7ADFE"
"CF984AAA102C1269002000040001000100640000";
const std::string second_config_str =
"003FFE09003B000B7075626C69632E6E616D6500208756E2580C07C1D2FFCB662F5FADC6"
"D6FF13DA85ABD7ADFECF984AAA102C1269002000040001000100640000";
std::vector<uint8_t> two_configs = hex_string_to_bytes(two_configs_str);
std::vector<uint8_t> second_config = hex_string_to_bytes(second_config_str);
ASSERT_EQ(SECSuccess,
SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(),
two_configs.data(), two_configs.size()));
ASSERT_EQ(SECSuccess,
SSL_SetClientEchConfigs(client_->ssl_fd(), second_config.data(),
second_config.size()));
ASSERT_EQ(SECSuccess, SSLInt_ZeroEchConfigIds(client_->ssl_fd()));
ASSERT_EQ(SECSuccess, SSLInt_ZeroEchConfigIds(server_->ssl_fd()));
client_->ExpectEch();
server_->ExpectEch();
Connect();
} }
// An empty config_id should prompt an alert. We don't support // An empty config_id should prompt an alert. We don't support
// Optional Configuration Identifiers. // Optional Configuration Identifiers.
TEST_F(TlsConnectStreamTls13, EchRejectEmptyConfigId) { TEST_F(TlsConnectStreamTls13, EchRejectEmptyConfigId) {
static const uint8_t junk[16] = {0}; static const uint8_t junk[16] = {0};
DataBuffer junk_buf(junk, sizeof(junk)); DataBuffer junk_buf(junk, sizeof(junk));
DataBuffer ech_xtn; DataBuffer ech_xtn;
ech_xtn.Write(ech_xtn.len(), HpkeKdfHkdfSha256, 2); ech_xtn.Write(ech_xtn.len(), HpkeKdfHkdfSha256, 2);
ech_xtn.Write(ech_xtn.len(), HpkeAeadAes128Gcm, 2); ech_xtn.Write(ech_xtn.len(), HpkeAeadAes128Gcm, 2);
skipping to change at line 772 skipping to change at line 852
++*called; ++*called;
EXPECT_EQ(0U, clientTokenLen); EXPECT_EQ(0U, clientTokenLen);
return firstHello ? ssl_hello_retry_request : ssl_hello_retry_accept; return firstHello ? ssl_hello_retry_request : ssl_hello_retry_accept;
} }
// Generate HRR on CH1 Inner // Generate HRR on CH1 Inner
TEST_F(TlsConnectStreamTls13, EchAcceptWithHrr) { TEST_F(TlsConnectStreamTls13, EchAcceptWithHrr) {
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
ConfigureSelfEncrypt(); ConfigureSelfEncrypt();
EnsureTlsSetup(); EnsureTlsSetup();
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
ASSERT_EQ(SECSuccess, ASSERT_EQ(SECSuccess,
SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(), SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(),
record.data(), record.len())); echconfig.data(), echconfig.len()));
ASSERT_EQ(SECSuccess, SSL_SetClientEchConfigs(client_->ssl_fd(), ASSERT_EQ(SECSuccess,
record.data(), record.len())); SSL_SetClientEchConfigs(client_->ssl_fd(), echconfig.data(),
echconfig.len()));
client_->ExpectEch(); client_->ExpectEch();
server_->ExpectEch(); server_->ExpectEch();
client_->SetAuthCertificateCallback(AuthCompleteSuccess); client_->SetAuthCertificateCallback(AuthCompleteSuccess);
size_t cb_called = 0; size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called)); server_->ssl_fd(), RetryEchHello, &cb_called));
// Start the handshake. // Start the handshake.
client_->StartConnect(); client_->StartConnect();
server_->StartConnect(); server_->StartConnect();
client_->Handshake(); client_->Handshake();
server_->Handshake(); server_->Handshake();
MakeNewServer(); MakeNewServer();
ASSERT_EQ(SECSuccess, ASSERT_EQ(SECSuccess,
SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(), SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(),
record.data(), record.len())); echconfig.data(), echconfig.len()));
client_->ExpectEch(); client_->ExpectEch();
server_->ExpectEch(); server_->ExpectEch();
client_->SetAuthCertificateCallback(AuthCompleteSuccess); client_->SetAuthCertificateCallback(AuthCompleteSuccess);
Handshake(); Handshake();
EXPECT_EQ(1U, cb_called); EXPECT_EQ(1U, cb_called);
CheckConnected(); CheckConnected();
SendReceive(); SendReceive();
} }
// Send GREASE ECH in CH1. CH2 must send exactly the same GREASE ECH contents.
TEST_F(TlsConnectStreamTls13, GreaseEchHrrMatches) {
ConfigureSelfEncrypt();
EnsureTlsSetup();
size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called));
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(),
PR_TRUE)); // GREASE
auto capture = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_tls13_encrypted_client_hello_xtn);
// Start the handshake.
client_->StartConnect();
server_->StartConnect();
client_->Handshake(); // Send CH1
EXPECT_TRUE(capture->captured());
DataBuffer ch1_grease = capture->extension();
server_->Handshake();
MakeNewServer();
capture = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_tls13_encrypted_client_hello_xtn);
EXPECT_FALSE(capture->captured());
client_->Handshake(); // Send CH2
EXPECT_TRUE(capture->captured());
EXPECT_EQ(ch1_grease, capture->extension());
EXPECT_EQ(1U, cb_called);
server_->StartConnect();
Handshake();
CheckConnected();
}
// Fail to decrypt CH2. Unlike CH1, this generates an alert. // Fail to decrypt CH2. Unlike CH1, this generates an alert.
TEST_F(TlsConnectStreamTls13, EchFailDecryptCH2) { TEST_F(TlsConnectStreamTls13, EchFailDecryptCH2) {
EnsureTlsSetup(); EnsureTlsSetup();
SetupEch(client_, server_); SetupEch(client_, server_);
size_t cb_called = 0; size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called)); server_->ssl_fd(), RetryEchHello, &cb_called));
client_->StartConnect(); client_->StartConnect();
server_->StartConnect(); server_->StartConnect();
skipping to change at line 851 skipping to change at line 968
// Start the handshake, send GREASE ECH. // Start the handshake, send GREASE ECH.
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(),
PR_TRUE)); // GREASE PR_TRUE)); // GREASE
client_->StartConnect(); client_->StartConnect();
server_->StartConnect(); server_->StartConnect();
client_->Handshake(); client_->Handshake();
server_->Handshake(); server_->Handshake();
MakeNewServer(); MakeNewServer();
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
ExpectAlert(server_, kTlsAlertIllegalParameter); ExpectAlert(server_, kTlsAlertMissingExtension);
Handshake(); Handshake();
client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO); server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO);
EXPECT_EQ(1U, cb_called); EXPECT_EQ(1U, cb_called);
} }
TEST_F(TlsConnectStreamTls13, EchHrrChangeCh2OfferingNY) { TEST_F(TlsConnectStreamTls13, EchHrrChangeCh2OfferingNY) {
ConfigureSelfEncrypt(); ConfigureSelfEncrypt();
EnsureTlsSetup(); EnsureTlsSetup();
SetupEch(client_, server_);
size_t cb_called = 0; size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called)); server_->ssl_fd(), RetryEchHello, &cb_called));
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), MakeTlsFilter<TlsExtensionDropper>(client_,
PR_FALSE)); // Don't GREASE ssl_tls13_encrypted_client_hello_xtn);
// Start the handshake. // Start the handshake.
client_->StartConnect(); client_->StartConnect();
server_->StartConnect(); server_->StartConnect();
client_->Handshake(); client_->Handshake();
server_->Handshake(); server_->Handshake();
MakeNewServer(); MakeNewServer();
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), client_->ClearFilter(); // Let the second ECH offering through.
PR_TRUE)); // Send GREASE ExpectAlert(server_, kTlsAlertIllegalParameter);
Handshake();
client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO);
EXPECT_EQ(1U, cb_called);
}
// Change the ECHCipherSuite between CH1 and CH2. Expect alert.
TEST_F(TlsConnectStreamTls13, EchHrrChangeCipherSuite) {
ConfigureSelfEncrypt();
EnsureTlsSetup();
SetupEch(client_, server_);
size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called));
// Start the handshake and trigger HRR.
client_->StartConnect();
server_->StartConnect();
client_->Handshake();
server_->Handshake();
MakeNewServer();
// Damage the first byte of the ciphersuite (offset 0)
MakeTlsFilter<TlsExtensionDamager>(client_,
ssl_tls13_encrypted_client_hello_xtn, 0);
ExpectAlert(server_, kTlsAlertIllegalParameter); ExpectAlert(server_, kTlsAlertIllegalParameter);
Handshake(); Handshake();
client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT); client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO); server_->CheckErrorCode(SSL_ERROR_BAD_2ND_CLIENT_HELLO);
EXPECT_EQ(1U, cb_called); EXPECT_EQ(1U, cb_called);
} }
// Configure an external PSK. Generate an HRR off CH1Inner (which contains // Configure an external PSK. Generate an HRR off CH1Inner (which contains
// the PSK extension). Use the same PSK in CH2 and connect. // the PSK extension). Use the same PSK in CH2 and connect.
TEST_F(TlsConnectStreamTls13, EchAcceptWithHrrAndPsk) { TEST_F(TlsConnectStreamTls13, EchAcceptWithHrrAndPsk) {
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
ConfigureSelfEncrypt(); ConfigureSelfEncrypt();
EnsureTlsSetup(); EnsureTlsSetup();
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
ASSERT_EQ(SECSuccess, ASSERT_EQ(SECSuccess,
SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(), SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(),
record.data(), record.len())); echconfig.data(), echconfig.len()));
ASSERT_EQ(SECSuccess, SSL_SetClientEchConfigs(client_->ssl_fd(), ASSERT_EQ(SECSuccess,
record.data(), record.len())); SSL_SetClientEchConfigs(client_->ssl_fd(), echconfig.data(),
echconfig.len()));
client_->ExpectEch(); client_->ExpectEch();
server_->ExpectEch(); server_->ExpectEch();
size_t cb_called = 0; size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called)); server_->ssl_fd(), RetryEchHello, &cb_called));
static const uint8_t key_buf[16] = {0}; static const uint8_t key_buf[16] = {0};
SECItem key_item = {siBuffer, const_cast<uint8_t*>(&key_buf[0]), SECItem key_item = {siBuffer, const_cast<uint8_t*>(&key_buf[0]),
sizeof(key_buf)}; sizeof(key_buf)};
skipping to change at line 925 skipping to change at line 1070
AddPsk(key, std::string(label), ssl_hash_sha256); AddPsk(key, std::string(label), ssl_hash_sha256);
// Start the handshake. // Start the handshake.
client_->StartConnect(); client_->StartConnect();
server_->StartConnect(); server_->StartConnect();
client_->Handshake(); client_->Handshake();
server_->Handshake(); server_->Handshake();
MakeNewServer(); MakeNewServer();
ASSERT_EQ(SECSuccess, ASSERT_EQ(SECSuccess,
SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(), SSL_SetServerEchConfigs(server_->ssl_fd(), pub.get(), priv.get(),
record.data(), record.len())); echconfig.data(), echconfig.len()));
client_->ExpectEch(); client_->ExpectEch();
server_->ExpectEch(); server_->ExpectEch();
EXPECT_EQ(SECSuccess, EXPECT_EQ(SECSuccess,
SSL_AddExternalPsk0Rtt(server_->ssl_fd(), key.get(), SSL_AddExternalPsk0Rtt(server_->ssl_fd(), key.get(),
reinterpret_cast<const uint8_t*>(label), reinterpret_cast<const uint8_t*>(label),
strlen(label), ssl_hash_sha256, 0, 1000)); strlen(label), ssl_hash_sha256, 0, 1000));
server_->ExpectPsk(); server_->ExpectPsk();
Handshake(); Handshake();
EXPECT_EQ(1U, cb_called); EXPECT_EQ(1U, cb_called);
CheckConnected(); CheckConnected();
SendReceive(); SendReceive();
} }
// Generate an HRR on CHOuter. Reject ECH on the second CH. // Generate an HRR on CHOuter. Reject ECH on the second CH.
TEST_F(TlsConnectStreamTls13Ech, EchRejectWithHrr) { TEST_F(TlsConnectStreamTls13Ech, EchRejectWithHrr) {
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
ConfigureSelfEncrypt(); ConfigureSelfEncrypt();
EnsureTlsSetup(); EnsureTlsSetup();
SetupForEchRetry(); SetupForEchRetry();
size_t cb_called = 0; size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called)); server_->ssl_fd(), RetryEchHello, &cb_called));
client_->SetAuthCertificateCallback(AuthCompleteSuccess); client_->SetAuthCertificateCallback(AuthCompleteSuccess);
// Start the handshake. // Start the handshake.
skipping to change at line 969 skipping to change at line 1114
client_->ExpectEch(false); client_->ExpectEch(false);
server_->ExpectEch(false); server_->ExpectEch(false);
ExpectAlert(client_, kTlsAlertEchRequired); ExpectAlert(client_, kTlsAlertEchRequired);
Handshake(); Handshake();
client_->CheckErrorCode(SSL_ERROR_ECH_RETRY_WITHOUT_ECH); client_->CheckErrorCode(SSL_ERROR_ECH_RETRY_WITHOUT_ECH);
server_->ExpectReceiveAlert(kTlsAlertEchRequired, kTlsAlertFatal); server_->ExpectReceiveAlert(kTlsAlertEchRequired, kTlsAlertFatal);
server_->Handshake(); server_->Handshake();
EXPECT_EQ(1U, cb_called); EXPECT_EQ(1U, cb_called);
} }
// Reject ECH on CH1 and (HRR) CH2. PSKs are no longer allowed // Reject ECH on CH1 and CH2. PSKs are no longer allowed
// in CHOuter, but can still make sure the handshake succeeds. // in CHOuter, but we can still make sure the handshake succeeds.
// (prompting ech_required at the completion). // This prompts an ech_required alert when the handshake completes.
TEST_F(TlsConnectStreamTls13, EchRejectWithHrrAndPsk) { TEST_F(TlsConnectStreamTls13, EchRejectWithHrrAndPsk) {
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
ConfigureSelfEncrypt(); ConfigureSelfEncrypt();
EnsureTlsSetup(); EnsureTlsSetup();
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kDefaultSuites,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
ASSERT_EQ(SECSuccess, SSL_SetClientEchConfigs(client_->ssl_fd(), ASSERT_EQ(SECSuccess,
record.data(), record.len())); SSL_SetClientEchConfigs(client_->ssl_fd(), echconfig.data(),
echconfig.len()));
size_t cb_called = 0; size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback( EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
server_->ssl_fd(), RetryEchHello, &cb_called)); server_->ssl_fd(), RetryEchHello, &cb_called));
// Add a PSK to both endpoints. // Add a PSK to both endpoints.
static const uint8_t key_buf[16] = {0}; static const uint8_t key_buf[16] = {0};
SECItem key_item = {siBuffer, const_cast<uint8_t*>(&key_buf[0]), SECItem key_item = {siBuffer, const_cast<uint8_t*>(&key_buf[0]),
sizeof(key_buf)}; sizeof(key_buf)};
const char* label = "foo"; const char* label = "foo";
skipping to change at line 1116 skipping to change at line 1262
server_->Handshake(); server_->Handshake();
// Reset expectations for the TlsAgent dtor. // Reset expectations for the TlsAgent dtor.
server_->ExpectReceiveAlert(kTlsAlertCloseNotify, kTlsAlertWarning); server_->ExpectReceiveAlert(kTlsAlertCloseNotify, kTlsAlertWarning);
} }
// Test a critical extension in ECHConfig // Test a critical extension in ECHConfig
TEST_F(TlsConnectStreamTls13, EchRejectUnknownCriticalExtension) { TEST_F(TlsConnectStreamTls13, EchRejectUnknownCriticalExtension) {
EnsureTlsSetup(); EnsureTlsSetup();
ScopedSECKEYPublicKey pub; ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv; ScopedSECKEYPrivateKey priv;
DataBuffer record; DataBuffer echconfig;
DataBuffer crit_rec; DataBuffer crit_rec;
DataBuffer len_buf; DataBuffer len_buf;
uint64_t tmp; uint64_t tmp;
static const uint8_t crit_extensions[] = {0x00, 0x04, 0xff, 0xff, 0x00, 0x00}; static const uint8_t crit_extensions[] = {0x00, 0x04, 0xff, 0xff, 0x00, 0x00};
static const uint8_t extensions[] = {0x00, 0x04, 0x7f, 0xff, 0x00, 0x00}; static const uint8_t extensions[] = {0x00, 0x04, 0x7f, 0xff, 0x00, 0x00};
DataBuffer crit_exts(crit_extensions, sizeof(crit_extensions)); DataBuffer crit_exts(crit_extensions, sizeof(crit_extensions));
DataBuffer non_crit_exts(extensions, sizeof(extensions)); DataBuffer non_crit_exts(extensions, sizeof(extensions));
TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kSuiteChaCha, TlsConnectTestBase::GenerateEchConfig(HpkeDhKemX25519Sha256, kSuiteChaCha,
kPublicName, 100, record, pub, priv); kPublicName, 100, echconfig, pub, priv);
record.Truncate(record.len() - 2); // Eat the empty extensions. echconfig.Truncate(echconfig.len() - 2); // Eat the empty extensions.
crit_rec.Assign(record); crit_rec.Assign(echconfig);
ASSERT_TRUE(crit_rec.Read(0, 2, &tmp)); ASSERT_TRUE(crit_rec.Read(0, 2, &tmp));
len_buf.Write(0, tmp + crit_exts.len() - 2, 2); // two bytes of length len_buf.Write(0, tmp + crit_exts.len() - 2, 2); // two bytes of length
crit_rec.Splice(len_buf, 0, 2); crit_rec.Splice(len_buf, 0, 2);
len_buf.Truncate(0); len_buf.Truncate(0);
ASSERT_TRUE(crit_rec.Read(4, 2, &tmp)); ASSERT_TRUE(crit_rec.Read(4, 2, &tmp));
len_buf.Write(0, tmp + crit_exts.len() - 2, 2); // two bytes of length len_buf.Write(0, tmp + crit_exts.len() - 2, 2); // two bytes of length
crit_rec.Append(crit_exts); crit_rec.Append(crit_exts);
crit_rec.Splice(len_buf, 4, 2); crit_rec.Splice(len_buf, 4, 2);
len_buf.Truncate(0); len_buf.Truncate(0);
ASSERT_TRUE(record.Read(0, 2, &tmp)); ASSERT_TRUE(echconfig.Read(0, 2, &tmp));
len_buf.Write(0, tmp + non_crit_exts.len() - 2, 2); len_buf.Write(0, tmp + non_crit_exts.len() - 2, 2);
record.Append(non_crit_exts); echconfig.Append(non_crit_exts);
record.Splice(len_buf, 0, 2); echconfig.Splice(len_buf, 0, 2);
ASSERT_TRUE(record.Read(4, 2, &tmp)); ASSERT_TRUE(echconfig.Read(4, 2, &tmp));
len_buf.Write(0, tmp + non_crit_exts.len() - 2, 2); len_buf.Write(0, tmp + non_crit_exts.len() - 2, 2);
record.Splice(len_buf, 4, 2); echconfig.Splice(len_buf, 4, 2);
EXPECT_EQ(SECFailure, EXPECT_EQ(SECFailure,
SSL_SetClientEchConfigs(client_->ssl_fd(), crit_rec.data(), SSL_SetClientEchConfigs(client_->ssl_fd(), crit_rec.data(),
crit_rec.len())); crit_rec.len()));
EXPECT_EQ(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, PORT_GetError()); EXPECT_EQ(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, PORT_GetError());
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(),
PR_FALSE)); // Don't GREASE PR_FALSE)); // Don't GREASE
auto filter = MakeTlsFilter<TlsExtensionCapture>( auto filter = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_tls13_encrypted_client_hello_xtn); client_, ssl_tls13_encrypted_client_hello_xtn);
StartConnect(); StartConnect();
client_->Handshake(); client_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
ASSERT_FALSE(filter->captured()); ASSERT_FALSE(filter->captured());
// Now try a variant with non-critical extensions, it should work. // Now try a variant with non-critical extensions, it should work.
Reset(); Reset();
EnsureTlsSetup(); EnsureTlsSetup();
EXPECT_EQ(SECSuccess, SSL_SetClientEchConfigs(client_->ssl_fd(), EXPECT_EQ(SECSuccess,
record.data(), record.len())); SSL_SetClientEchConfigs(client_->ssl_fd(), echconfig.data(),
echconfig.len()));
filter = MakeTlsFilter<TlsExtensionCapture>( filter = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_tls13_encrypted_client_hello_xtn); client_, ssl_tls13_encrypted_client_hello_xtn);
StartConnect(); StartConnect();
client_->Handshake(); client_->Handshake();
ASSERT_EQ(TlsAgent::STATE_CONNECTING, client_->state()); ASSERT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
ASSERT_TRUE(filter->captured()); ASSERT_TRUE(filter->captured());
} }
// Secure disable without ECH // Secure disable without ECH
TEST_F(TlsConnectStreamTls13, EchRejectAuthCertSuccessNoRetries) { TEST_F(TlsConnectStreamTls13, EchRejectAuthCertSuccessNoRetries) {
skipping to change at line 1580 skipping to change at line 1727
DataBuffer outer_buf(outer, sizeof(outer)); DataBuffer outer_buf(outer, sizeof(outer));
MakeTlsFilter<TlsExtensionAppender>(client_, kTlsHandshakeClientHello, MakeTlsFilter<TlsExtensionAppender>(client_, kTlsHandshakeClientHello,
ssl_tls13_outer_extensions_xtn, ssl_tls13_outer_extensions_xtn,
outer_buf); outer_buf);
ConnectExpectAlert(server_, kTlsAlertUnsupportedExtension); ConnectExpectAlert(server_, kTlsAlertUnsupportedExtension);
client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT); client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT);
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
} }
// At draft-09: If a CH containing the ech_is_inner extension is received, the
// server acts as backend server in split-mode by responding with the ECH
// acceptance signal. The signal value itself depends on the handshake secret,
// which we've broken by appending ech_is_inner. For now, just check that the
// server negotiates ech_is_inner (which is what triggers sending the signal).
TEST_F(TlsConnectStreamTls13, EchBackendAcceptance) {
DataBuffer ch_buf;
static uint8_t empty_buf[1] = {0};
DataBuffer empty(empty_buf, 0);
EnsureTlsSetup();
StartConnect();
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), PR_FALSE));
MakeTlsFilter<TlsExtensionAppender>(client_, kTlsHandshakeClientHello,
ssl_tls13_ech_is_inner_xtn, empty);
EXPECT_EQ(SECSuccess, SSL_EnableTls13BackendEch(server_->ssl_fd(), PR_TRUE));
client_->Handshake();
server_->Handshake();
ExpectAlert(client_, kTlsAlertBadRecordMac);
client_->Handshake();
EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
EXPECT_EQ(PR_TRUE, SSLInt_ExtensionNegotiated(server_->ssl_fd(),
ssl_tls13_ech_is_inner_xtn));
server_->ExpectReceiveAlert(kTlsAlertCloseNotify, kTlsAlertWarning);
}
INSTANTIATE_TEST_SUITE_P(EchAgentTest, TlsAgentEchTest, INSTANTIATE_TEST_SUITE_P(EchAgentTest, TlsAgentEchTest,
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
TlsConnectTestBase::kTlsV13)); TlsConnectTestBase::kTlsV13));
#else #else
TEST_P(TlsAgentEchTest, NoEchWithoutHpke) { TEST_P(TlsAgentEchTest, NoEchWithoutHpke) {
EnsureInit(); EnsureInit();
uint8_t non_null[1]; uint8_t non_null[1];
SECKEYPublicKey pub; SECKEYPublicKey pub;
SECKEYPrivateKey priv; SECKEYPrivateKey priv;
 End of changes. 81 change blocks. 
148 lines changed or deleted 323 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)