Replace NSS with Pale Moon's

This commit is contained in:
wuggy 2026-06-29 21:29:25 +01:00
commit 8c2e376f94
2870 changed files with 1762232 additions and 1374220 deletions

View file

@ -1,4 +1,5 @@
/* -*- 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/. */
@ -48,6 +49,7 @@ const std::string TlsAgent::kServerEcdhEcdsa = "ecdh_ecdsa";
const std::string TlsAgent::kServerDsa = "dsa";
const std::string TlsAgent::kDelegatorEcdsa256 = "delegator_ecdsa256";
const std::string TlsAgent::kDelegatorRsae2048 = "delegator_rsae2048";
const std::string TlsAgent::kDelegatorRsaPss2048 = "delegator_rsa_pss2048";
static const uint8_t kCannedTls13ServerHello[] = {
0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
@ -71,8 +73,9 @@ TlsAgent::TlsAgent(const std::string& nm, Role rl, SSLProtocolVariant var)
falsestart_enabled_(false),
expected_version_(0),
expected_cipher_suite_(0),
expect_resumption_(false),
expect_client_auth_(false),
expect_ech_(false),
expect_psk_(ssl_psk_none),
can_falsestart_hook_called_(false),
sni_hook_called_(false),
auth_certificate_hook_called_(false),
@ -90,7 +93,8 @@ TlsAgent::TlsAgent(const std::string& nm, Role rl, SSLProtocolVariant var)
auth_certificate_callback_(),
sni_callback_(),
skip_version_checks_(false),
resumption_token_() {
resumption_token_(),
policy_() {
memset(&info_, 0, sizeof(info_));
memset(&csinfo_, 0, sizeof(csinfo_));
SECStatus rv = SSL_VersionRangeGetDefault(variant_, &vrange_);
@ -224,6 +228,7 @@ bool TlsAgent::ConfigServerCert(const std::string& id, bool updateKeyBits,
bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
// Don't set up twice
if (ssl_fd_) return true;
NssManagePolicy policyManage(policy_, option_);
ScopedPRFileDesc dummy_fd(adapter_->CreateFD());
EXPECT_NE(nullptr, dummy_fd);
@ -299,7 +304,7 @@ bool TlsAgent::MaybeSetResumptionToken() {
// rv is SECFailure with error set to SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR
// if the resumption token was bad (expired/malformed/etc.).
if (expect_resumption_) {
if (expect_psk_ == ssl_psk_resume) {
// Only in case we expect resumption this has to be successful. We might
// not expect resumption due to some reason but the token is totally fine.
EXPECT_EQ(SECSuccess, rv);
@ -307,8 +312,8 @@ bool TlsAgent::MaybeSetResumptionToken() {
if (rv != SECSuccess) {
EXPECT_EQ(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR, PORT_GetError());
resumption_token_.clear();
EXPECT_FALSE(expect_resumption_);
if (expect_resumption_) return false;
EXPECT_FALSE(expect_psk_ == ssl_psk_resume);
if (expect_psk_ == ssl_psk_resume) return false;
}
}
@ -316,13 +321,22 @@ bool TlsAgent::MaybeSetResumptionToken() {
}
void TlsAgent::SetAntiReplayContext(ScopedSSLAntiReplayContext& ctx) {
EXPECT_EQ(SECSuccess, SSL_SetAntiReplayContext(ssl_fd_.get(), ctx.get()));
EXPECT_EQ(SECSuccess, SSL_SetAntiReplayContext(ssl_fd(), ctx.get()));
}
void TlsAgent::SetupClientAuth() {
// Defaults to a Sync callback returning success
void TlsAgent::SetupClientAuth(ClientAuthCallbackType callbackType,
bool callbackSuccess) {
EXPECT_TRUE(EnsureTlsSetup());
ASSERT_EQ(CLIENT, role_);
client_auth_callback_type_ = callbackType;
client_auth_callback_success_ = callbackSuccess;
if (callbackType == ClientAuthCallbackType::kNone && !callbackSuccess) {
// Don't set a callback for this case.
return;
}
EXPECT_EQ(SECSuccess,
SSL_GetClientAuthDataHook(ssl_fd(), GetClientAuthDataHook,
reinterpret_cast<void*>(this)));
@ -339,26 +353,95 @@ void CheckCertReqAgainstDefaultCAs(const CERTDistNames* caNames) {
}
}
// Complete processing of Client Certificate Selection
// A No-op if the agent is using synchronous client cert selection.
// Otherwise, calls SSL_ClientCertCallbackComplete.
// kAsyncDelay triggers a call to SSL_ForceHandshake prior to completion to
// ensure that the socket is correctly blocked.
void TlsAgent::ClientAuthCallbackComplete() {
ASSERT_EQ(CLIENT, role_);
if (client_auth_callback_type_ != ClientAuthCallbackType::kAsyncDelay &&
client_auth_callback_type_ != ClientAuthCallbackType::kAsyncImmediate) {
return;
}
client_auth_callback_fired_++;
EXPECT_TRUE(client_auth_callback_awaiting_);
std::cerr << "client: calling SSL_ClientCertCallbackComplete with status "
<< (client_auth_callback_success_ ? "success" : "failed")
<< std::endl;
client_auth_callback_awaiting_ = false;
if (client_auth_callback_type_ == ClientAuthCallbackType::kAsyncDelay) {
std::cerr
<< "Running Handshake prior to running SSL_ClientCertCallbackComplete"
<< std::endl;
SECStatus rv = SSL_ForceHandshake(ssl_fd());
EXPECT_EQ(rv, SECFailure);
EXPECT_EQ(PORT_GetError(), PR_WOULD_BLOCK_ERROR);
}
ScopedCERTCertificate cert;
ScopedSECKEYPrivateKey priv;
if (client_auth_callback_success_) {
ASSERT_TRUE(TlsAgent::LoadCertificate(name(), &cert, &priv));
EXPECT_EQ(SECSuccess,
SSL_ClientCertCallbackComplete(ssl_fd(), SECSuccess,
priv.release(), cert.release()));
} else {
EXPECT_EQ(SECSuccess, SSL_ClientCertCallbackComplete(ssl_fd(), SECFailure,
nullptr, nullptr));
}
}
SECStatus TlsAgent::GetClientAuthDataHook(void* self, PRFileDesc* fd,
CERTDistNames* caNames,
CERTCertificate** clientCert,
SECKEYPrivateKey** clientKey) {
TlsAgent* agent = reinterpret_cast<TlsAgent*>(self);
ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
EXPECT_EQ(CLIENT, agent->role_);
agent->client_auth_callback_fired_++;
// See bug 1573945
// CheckCertReqAgainstDefaultCAs(caNames);
switch (agent->client_auth_callback_type_) {
case ClientAuthCallbackType::kAsyncDelay:
case ClientAuthCallbackType::kAsyncImmediate:
std::cerr << "Waiting for complete call" << std::endl;
agent->client_auth_callback_awaiting_ = true;
return SECWouldBlock;
case ClientAuthCallbackType::kSync:
case ClientAuthCallbackType::kNone:
// Handle the sync case. None && Success is treated as Sync and Success.
if (!agent->client_auth_callback_success_) {
return SECFailure;
}
ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
ScopedCERTCertificate cert;
ScopedSECKEYPrivateKey priv;
if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
return SECFailure;
// See bug 1573945
// CheckCertReqAgainstDefaultCAs(caNames);
ScopedCERTCertificate cert;
ScopedSECKEYPrivateKey priv;
if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
return SECFailure;
}
*clientCert = cert.release();
*clientKey = priv.release();
return SECSuccess;
}
/* This is unreachable, but some old compilers can't tell that. */
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
*clientCert = cert.release();
*clientKey = priv.release();
return SECSuccess;
// Increments by 1 for each callback
bool TlsAgent::CheckClientAuthCallbacksCompleted(uint8_t expected) {
EXPECT_EQ(CLIENT, role_);
return expected == client_auth_callback_fired_;
}
bool TlsAgent::GetPeerChainLength(size_t* count) {
@ -632,7 +715,9 @@ void TlsAgent::CheckAuthType(SSLAuthType auth,
SSLSignatureScheme sig_scheme) const {
EXPECT_EQ(STATE_CONNECTED, state_);
EXPECT_EQ(auth, info_.authType);
EXPECT_EQ(server_key_bits_, info_.authKeyBits);
if (auth != ssl_auth_psk) {
EXPECT_EQ(server_key_bits_, info_.authKeyBits);
}
if (expected_version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
switch (auth) {
case ssl_auth_rsa_sign:
@ -683,13 +768,33 @@ void TlsAgent::EnableFalseStart() {
SetOption(SSL_ENABLE_FALSE_START, PR_TRUE);
}
void TlsAgent::ExpectResumption() { expect_resumption_ = true; }
void TlsAgent::ExpectEch(bool expected) { expect_ech_ = expected; }
void TlsAgent::ExpectPsk(SSLPskType psk) { expect_psk_ = psk; }
void TlsAgent::ExpectResumption() { expect_psk_ = ssl_psk_resume; }
void TlsAgent::EnableAlpn(const uint8_t* val, size_t len) {
EXPECT_TRUE(EnsureTlsSetup());
EXPECT_EQ(SECSuccess, SSL_SetNextProtoNego(ssl_fd(), val, len));
}
void TlsAgent::AddPsk(const ScopedPK11SymKey& psk, std::string label,
SSLHashType hash, uint16_t zeroRttSuite) {
EXPECT_TRUE(EnsureTlsSetup());
EXPECT_EQ(SECSuccess, SSL_AddExternalPsk0Rtt(
ssl_fd(), psk.get(),
reinterpret_cast<const uint8_t*>(label.data()),
label.length(), hash, zeroRttSuite, 1000));
}
void TlsAgent::RemovePsk(std::string label) {
EXPECT_EQ(SECSuccess,
SSL_RemoveExternalPsk(
ssl_fd(), reinterpret_cast<const uint8_t*>(label.data()),
label.length()));
}
void TlsAgent::CheckAlpn(SSLNextProtoState expected_state,
const std::string& expected) const {
SSLNextProtoState alpn_state;
@ -798,7 +903,6 @@ void TlsAgent::CheckPreliminaryInfo() {
SSL_GetPreliminaryChannelInfo(ssl_fd(), &preinfo, sizeof(preinfo)));
EXPECT_EQ(sizeof(preinfo), preinfo.length);
EXPECT_TRUE(preinfo.valuesSet & ssl_preinfo_version);
EXPECT_TRUE(preinfo.valuesSet & ssl_preinfo_cipher_suite);
// A version of 0 is invalid and indicates no expectation. This value is
// initialized to 0 so that tests that don't explicitly set an expected
@ -819,22 +923,22 @@ void TlsAgent::CheckPreliminaryInfo() {
void TlsAgent::CheckCallbacks() const {
// If false start happens, the handshake is reported as being complete at the
// point that false start happens.
if (expect_resumption_ || !falsestart_enabled_) {
if (expect_psk_ == ssl_psk_resume || !falsestart_enabled_) {
EXPECT_TRUE(handshake_callback_called_);
}
// These callbacks shouldn't fire if we are resuming, except on TLS 1.3.
if (role_ == SERVER) {
PRBool have_sni = SSLInt_ExtensionNegotiated(ssl_fd(), ssl_server_name_xtn);
EXPECT_EQ(((!expect_resumption_ && have_sni) ||
EXPECT_EQ(((expect_psk_ != ssl_psk_resume && have_sni) ||
expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3),
sni_hook_called_);
} else {
EXPECT_EQ(!expect_resumption_, auth_certificate_hook_called_);
EXPECT_EQ(expect_psk_ == ssl_psk_none, auth_certificate_hook_called_);
// Note that this isn't unconditionally called, even with false start on.
// But the callback is only skipped if a cipher that is ridiculously weak
// (80 bits) is chosen. Don't test that: plan to remove bad ciphers.
EXPECT_EQ(falsestart_enabled_ && !expect_resumption_,
EXPECT_EQ(falsestart_enabled_ && expect_psk_ != ssl_psk_resume,
can_falsestart_hook_called_);
}
}
@ -845,8 +949,8 @@ void TlsAgent::ResetPreliminaryInfo() {
}
void TlsAgent::UpdatePreliminaryChannelInfo() {
SECStatus rv = SSL_GetPreliminaryChannelInfo(ssl_fd_.get(), &pre_info_,
sizeof(pre_info_));
SECStatus rv =
SSL_GetPreliminaryChannelInfo(ssl_fd(), &pre_info_, sizeof(pre_info_));
EXPECT_EQ(SECSuccess, rv);
EXPECT_EQ(sizeof(pre_info_), pre_info_.length);
}
@ -870,7 +974,7 @@ void TlsAgent::ValidateCipherSpecs() {
} else {
// For DTLS 1.1 and 1.2, the last endpoint to send maintains a cipher spec
// until the holddown timer runs down.
if (expect_resumption_) {
if (expect_psk_ == ssl_psk_resume) {
if (role_ == CLIENT) {
expected = 3;
}
@ -908,7 +1012,9 @@ void TlsAgent::Connected() {
EXPECT_EQ(SECSuccess, rv);
EXPECT_EQ(sizeof(info_), info_.length);
EXPECT_EQ(expect_resumption_, info_.resumed == PR_TRUE);
EXPECT_EQ(expect_psk_ == ssl_psk_resume, info_.resumed == PR_TRUE);
EXPECT_EQ(expect_psk_, info_.pskType);
EXPECT_EQ(expect_ech_, info_.echAccepted);
// Preliminary values are exposed through callbacks during the handshake.
// If either expected values were set or the callbacks were called, check
@ -926,6 +1032,24 @@ void TlsAgent::Connected() {
SetState(STATE_CONNECTED);
}
void TlsAgent::CheckClientAuthCompleted(uint8_t handshakes) {
EXPECT_FALSE(client_auth_callback_awaiting_);
switch (client_auth_callback_type_) {
case ClientAuthCallbackType::kNone:
if (!client_auth_callback_success_) {
EXPECT_TRUE(CheckClientAuthCallbacksCompleted(0));
break;
}
case ClientAuthCallbackType::kSync:
EXPECT_TRUE(CheckClientAuthCallbacksCompleted(handshakes));
break;
case ClientAuthCallbackType::kAsyncDelay:
case ClientAuthCallbackType::kAsyncImmediate:
EXPECT_TRUE(CheckClientAuthCallbacksCompleted(2 * handshakes));
break;
}
}
void TlsAgent::EnableExtendedMasterSecret() {
SetOption(SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
}
@ -960,6 +1084,10 @@ void TlsAgent::SetDowngradeCheckVersion(uint16_t ver) {
void TlsAgent::Handshake() {
LOGV("Handshake");
SECStatus rv = SSL_ForceHandshake(ssl_fd());
if (client_auth_callback_awaiting_) {
ClientAuthCallbackComplete();
rv = SSL_ForceHandshake(ssl_fd());
}
if (rv == SECSuccess) {
Connected();
Poller::Instance()->Wait(READABLE_EVENT, adapter_, this,
@ -1063,21 +1191,28 @@ void TlsAgent::SendBuffer(const DataBuffer& buf) {
bool TlsAgent::SendEncryptedRecord(const std::shared_ptr<TlsCipherSpec>& spec,
uint64_t seq, uint8_t ct,
const DataBuffer& buf) {
LOGV("Encrypting " << buf.len() << " bytes");
// Ensure that we are doing TLS 1.3.
EXPECT_GE(expected_version_, SSL_LIBRARY_VERSION_TLS_1_3);
TlsRecordHeader header(variant_, expected_version_, ssl_ct_application_data,
seq);
if (variant_ != ssl_variant_datagram) {
ADD_FAILURE();
return false;
}
LOGV("Encrypting " << buf.len() << " bytes");
uint8_t dtls13_ct = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno |
kCtDtlsCiphertextLengthPresent;
TlsRecordHeader header(variant_, expected_version_, dtls13_ct, seq);
TlsRecordHeader out_header(header);
DataBuffer padded = buf;
padded.Write(padded.len(), ct, 1);
DataBuffer ciphertext;
if (!spec->Protect(header, padded, &ciphertext)) {
if (!spec->Protect(header, padded, &ciphertext, &out_header)) {
return false;
}
DataBuffer record;
auto rv = header.Write(&record, 0, ciphertext);
EXPECT_EQ(header.header_length() + ciphertext.len(), rv);
auto rv = out_header.Write(&record, 0, ciphertext);
EXPECT_EQ(out_header.header_length() + ciphertext.len(), rv);
SendDirect(record);
return true;
}
@ -1124,7 +1259,7 @@ void TlsAgent::ReadBytes(size_t amount) {
}
}
void TlsAgent::ResetSentBytes() { send_ctr_ = 0; }
void TlsAgent::ResetSentBytes(size_t bytes) { send_ctr_ = bytes; }
void TlsAgent::SetOption(int32_t option, int value) {
ASSERT_TRUE(EnsureTlsSetup());
@ -1137,9 +1272,9 @@ void TlsAgent::ConfigureSessionCache(SessionResumptionMode mode) {
mode & RESUME_TICKET ? PR_TRUE : PR_FALSE);
}
void TlsAgent::DisableECDHEServerKeyReuse() {
void TlsAgent::EnableECDHEServerKeyReuse() {
ASSERT_EQ(TlsAgent::SERVER, role_);
SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_TRUE);
}
static const std::string kTlsRolesAllArr[] = {"CLIENT", "SERVER"};
@ -1201,16 +1336,26 @@ void TlsAgentTestBase::MakeRecord(SSLProtocolVariant variant, uint8_t type,
uint16_t version, const uint8_t* buf,
size_t len, DataBuffer* out,
uint64_t sequence_number) {
// Fixup the content type for DTLSCiphertext
if (variant == ssl_variant_datagram &&
version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
type == ssl_ct_application_data) {
type = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno |
kCtDtlsCiphertextLengthPresent;
}
size_t index = 0;
index = out->Write(index, type, 1);
if (variant == ssl_variant_stream) {
index = out->Write(index, type, 1);
index = out->Write(index, version, 2);
} else if (version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
type == ssl_ct_application_data) {
(type & kCtDtlsCiphertextMask) == kCtDtlsCiphertext) {
uint32_t epoch = (sequence_number >> 48) & 0x3;
uint32_t seqno = sequence_number & ((1ULL << 30) - 1);
index = out->Write(index, (epoch << 30) | seqno, 4);
index = out->Write(index, type | epoch, 1);
uint32_t seqno = sequence_number & ((1ULL << 16) - 1);
index = out->Write(index, seqno, 2);
} else {
index = out->Write(index, type, 1);
index = out->Write(index, TlsVersionToDtlsVersion(version), 2);
index = out->Write(index, sequence_number >> 32, 4);
index = out->Write(index, sequence_number & PR_UINT32_MAX, 4);