re-introduce old nss im too tired for this

This commit is contained in:
wuggy 2026-06-30 06:37:32 +01:00
commit 3a838106b9
2871 changed files with 1374431 additions and 1762417 deletions

View file

@ -1,5 +1,4 @@
/* -*- 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/. */
@ -58,11 +57,10 @@ Config::Status Config::ParseArgs(int argc, char **argv) {
}
while (!args.empty()) {
auto e = entries_.find(XformFlag(args.front()));
args.pop();
if (e == entries_.end()) {
std::cerr << "Unimplemented shim flag: " << args.front() << std::endl;
return kUnknownFlag;
}
args.pop();
if (!e->second->Parse(args)) return kMalformedArgument;
}

View file

@ -1,5 +1,4 @@
/* -*- 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/. */

View file

@ -1,89 +1,77 @@
{
"DisabledTests": {
"####################":"####################",
"### Failures due to Bogo/NSS specifics":"",
"####################":"####################",
"SendEmptyRecords":"Bogo allows only 32 empty records to be sent before other TLS messages.",
"SendUserCanceledAlerts-TooMany-TLS13":"Bogo allows only 5 user canceled alerts to be sent.",
"SendWarningAlerts-TooMany":"Bogo allows only 5 warning alerts to be sent.",
"TooManyKeyUpdates":"Bogo allows only 32 KeyUpdate messages to be sent.",
"UnsolicitedServerNameAck-TLS*":"Boring wants us to fail with an unexpected_extension alert, we simply ignore ssl_server_name_xtn.",
"### These tests break whenever we rev versions, so just leave them here for easy uncommenting":"",
"*TLS13Draft*":"NSS supports RFC 8446 only.",
"IgnoreClientVersionOrder":"Uses draft23",
"DuplicateCertCompressionExt*":"BoGo expects that an alert is sent if more than one compression algorithm is sent.",
"*Auth-SHA1-Fallback*":"Boring wants us to fall back to SHA-1 if supported_signature_algorithms in CR is empty.",
"NoSupportedCurves":"This tests a non-spec behavior for TLS 1.2",
"SkipEarlyData-*TooMuchData*":"Test of internal BoGo features (see Bug 1339373).",
"Client-RejectJDK11DowngradeRandom":"This random is not specified in RFC8446.",
"Renegotiate-Server-Forbidden":"TLS 1.2 test, renegotiation is allowed in NSS.",
"EmptySessionID-TLS13":"This test also asserts BoringSSL always sending CCS messages for compatibility mode.",
"Http*":"Test sends http string to socket before handshake. his data is interpreted as a record header and leads to different IO errors in NSS.",
"V2ClientHello*":"Prefix data before V2 ClientHello leads to IO errors in NSS.",
"Server-JDK11-NoWorkaround-3":"Unexpected Bogo crash.",
"Resume-Server-UnofferedCipher-TLS13":"Bogo rejects resumption if client offers previously not used ciphersuites with equal hash algorithm (no 0Rtt).",
"EarlyData-FirstTicket-Server-TLS13":"Bogo provides specific early data logging which is the only check in this test but not supported by NSS.",
"*Ed25519*":"Add Ed25519 support (Bug 1325335)",
"*NoSSL3*":"Test passes but only because of handshake failure, NSS only rejects SSL3 immediately in TLS1.3 clients/servers.",
"ServerBogusVersion":"Check that SH.legacy_version=TLS12 when the server picks TLS 1.3 (Bug 1443761)",
"DummyPQPadding-Server*":"Boring is testing a dummy PQ padding extension",
"VerifyPreferences-Enforced":"NSS sends alerts in response to errors in protected handshake messages in the clear",
"Draft-Downgrade-Server":"Boring implements a draft downgrade sentinel used for measurements.",
"FilterExtraAlgorithms":"NSS doesn't allow sending unsupported signature algorithms",
"SendBogusAlertType":"Unexpected TLS alerts should abort connections (Bug 1438263)",
"VerifyPreferences-Ed25519":"Add Ed25519 support (Bug 1325335)",
"Ed25519DefaultDisable*":"Add Ed25519 support (Bug 1325335)",
"ServerCipherFilter*":"Add Ed25519 support (Bug 1325335)",
"GarbageCertificate*":"Send bad_certificate alert when certificate parsing fails (Bug 1441565)",
"SupportedVersionSelection-TLS12":"Should maybe reject TLS 1.2 in SH.supported_versions (Bug 1438266)",
"Resume-Server-BinderWrongLength":"Alert disagreement (Bug 1317633)",
"Resume-Server-NoPSKBinder":"Alert disagreement (Bug 1317633)",
"CheckRecordVersion-TLS*":"Bug 1317634",
"GarbageInitialRecordVersion-TLS*":"NSS doesn't strictly check the ClientHello record version",
"GREASE-Server-TLS13":"BoringSSL GREASEs without a flag, but we ignore it",
"TLS13-ExpectNoSessionTicketOnBadKEMode-Server":"Bug in NSS. Don't send ticket when not permitted by KE modes (Bug 1317635)",
"*KeyUpdate*":"KeyUpdate Unimplemented",
"ClientAuth-NoFallback-TLS13":"Disagreement about alerts. Bug 1294975",
"SendWarningAlerts-TLS13":"NSS needs to trigger on warning alerts",
"NoSupportedCurves":"This tests a non-spec behavior for TLS 1.2 and expects the wrong alert for TLS 1.3",
"SendEmptyRecords":"Tests a non-spec behavior in BoGo where it chokes on too many empty records",
"LargePlaintext":"NSS needs to check for over-long records. Bug 1294978",
"TLS13-RC4-MD5-server":"This fails properly but returns an unexpected error. Not a bug but needs cleanup",
"*SSL3*":"NSS disables SSLv3",
"*SSLv3*":"NSS disables SSLv3",
"*AES256*":"Inconsistent support for AES256",
"*AES128-SHA256*":"No support for Suite B ciphers",
"DuplicateExtension*":"NSS sends unexpected_extension alert",
"WeakDH":"NSS supports 768-bit DH",
"SillyDH":"NSS supports 4097-bit DH",
"SendWarningAlerts":"This appears to be Boring-specific",
"TLS12-AES128-GCM-client":"Bug 1292895",
"*TLS12-AES128-GCM-LargeRecord*":"Bug 1292895",
"Renegotiate-Client-Forbidden-1":"Bug 1292898",
"Renegotiate-Server-Forbidden":"NSS doesn't disable renegotiation by default",
"Renegotiate-Client-NoIgnore":"NSS doesn't disable renegotiation by default",
"StrayHelloRequest*":"NSS doesn't disable renegotiation by default",
"NoSupportedCurves-TLS13":"wanted SSL_ERROR_NO_CYPHER_OVERLAP, got missing extension error",
"FragmentedClientVersion":"received a malformed Client Hello handshake message",
"WrongMessageType-TLS13-EncryptedExtensions":"Boring expects CCS (Bugs 1481209, 1304603)",
"TrailingMessageData-TLS13-EncryptedExtensions":"Boring expects CCS (Bugs 1481209, 1304603)",
"UnofferedExtension-Client-TLS13":"Boring expects CCS (Bugs 1481209, 1304603)",
"UnknownExtension-Client-TLS13":"Boring expects CCS (Bugs 1481209, 1304603)",
"WrongMessageType-TLS13-CertificateRequest":"Boring expects CCS (Bugs 1481209, 1304603)",
"WrongMessageType-TLS13-ServerCertificateVerify":"Boring expects CCS (Bugs 1481209, 1304603)",
"WrongMessageType-TLS13-ServerCertificate":"Boring expects CCS (Bugs 1481209, 1304603)",
"WrongMessageType-TLS13-ServerFinished":"Boring expects CCS (Bugs 1481209, 1304603)",
"TrailingMessageData-*": "Bug 1304575",
"DuplicateKeyShares":"Bug 1304578",
"Resume-Server-TLS13-TLS13":"Bug 1314351",
"SkipEarlyData-Interleaved":"Bug 1336916",
"ECDSAKeyUsage-TLS1*":"Bug 1338194",
"PointFormat-Client-MissingUncompressed":"We ignore ec_point_formats extensions sent by servers.",
"SkipEarlyData-SecondClientHelloEarlyData":"Boring doesn't reject early_data in the 2nd CH but fails later with bad_record_mac.",
"SkipEarlyData-*TooMuchData":"Bug 1339373",
"UnsolicitedServerNameAck-TLS1*":"Boring wants us to fail with an unexpected_extension alert, we simply ignore ssl_server_name_xtn.",
"RequireAnyClientCertificate-TLS1*":"Bug 1339387",
"SendExtensionOnClientCertificate-TLS13":"Bug 1339392",
"CheckRecordVersion-TLS1":"NSS doesn't check record version field. Bug 1317634",
"CheckRecordVersion-TLS11":"NSS doesn't check record version field. Bug 1317634",
"CheckRecordVersion-TLS12":"NSS doesn't check record version field. Bug 1317634",
"GarbageInitialRecordVersion-TLS*":"NSS doesn't strictly check the ClientHello record version.",
"DuplicateKeyShares*":"NSS doesn't check for duplicates. Bug 1304578",
"PointFormat-Client-MissingUncompressed":"NSS ignores ec_point_formats extensions sent by servers.",
"SkipEarlyData-Interleaved-TLS13":"NSS ignores invalid early data records by default since ssl_0rtt_ignore_trial is default. Bug 1336916",
"ECDSAKeyUsage*":"NSS only checks KeyUsage on server setup and with delegated credential verification. Bug 1338194",
"RSAKeyUsage-*-WantSignature-GotEncipherment-*":"NSS only checks KeyUsage on server setup and with delegated credential verification. See Bug 1338194",
"TLS13-ExpectNoSessionTicketOnBadKEMode-Server":"NSS Server side bug. Don't send ticket when not permitted by KE modes (Bug 1317635)",
"Resume-Server-OmitPSKsOnSecondClientHello":"NSS Server side bug. It does not detect ClientHello dropping of PSK extension (after HRR).",
"Renegotiate-Client-Forbidden-1":"By default NSS allows renegotiation with extension contrary to bogo.",
"TrailingData*":"NSS does only check for trailing data on possible key change handshake messages in TLS 1.3",
"Partial*":"See TrailingData* description.",
"QUIC-ECH*":"NSS does not support QUIC.",
"*ECH*SkipInvalidPublicName*":"NSS allows hostnames to include underscores in contrary to the spec. Bug 1136616",
"*ECH*CompressSupportedVersions":"NSS never compresses supported versions, Bogo does if CHOuter is TLS 1.3 only (equal to CHInner).",
"*ECH*NoSupportedConfigs*":"NSS throws error if unsupported but well formed retry configs could not be set on client, Bogo just does not offer ECH.",
"*ECH*RandomHRR*":"NSS sends real ECH in CH2 after receiving HRR rejcting ECH formally, Bogo expects instant ech_required alert. Bug 1779357",
"*ECH*UnsolicitedInnerServerNameAck":"NSS always sends SNI in CHInner, Bogo tests if the client detects an unsolicited SNI in SH if CHInner did not include it. Bug 1781224",
"CorruptTicket-TLS-TLS12":"NSS sends an alert on reception of a corrupted session ticket instead of falling back to full handshake. Bug 1783812",
"FalseStart-ALPN*":"TODO - Implementing TLS 1.2 only FalseStart has low priority.",
"####################":"####################",
"### TLS1/11 failures due to unsupported signature algorithms":"",
"####################":"####################",
"FallbackSCSV":"",
"TicketSessionIDLength*":"",
"NoExtendedMasterSecret-TLS1-Server":"",
"NoExtendedMasterSecret-TLS11-Server":"",
"TLS1-Server-ClientAuth*":"",
"TLS11-Server-ClientAuth*":"",
"Resume-Server-TLS1-TLS1-TLS":"",
"Resume-Server-TLS11-TLS11-TLS":"",
"Resume-Server-NoTickets-TLS1-TLS1-TLS":"",
"Resume-Server-NoTickets-TLS11-TLS11-TLS":"",
"VersionNegotiation-Server*-TLS1-TLS":"",
"VersionNegotiation-Server*-TLS11-TLS":"",
"MinimumVersion-Server*-TLS1-TLS1-TLS":"",
"MinimumVersion-Server*-TLS1-TLS11-TLS":"",
"MinimumVersion-Server*-TLS11-TLS11-TLS":"",
"GarbageCertificate-Server-TLS1":"",
"GarbageCertificate-Server-TLS11":"",
"LooseInitialRecordVersion-TLS1":"",
"LooseInitialRecordVersion-TLS11":"",
"*Certificate-TLS1":"",
"*Certificate-TLS11":"",
"CorruptTicket*TLS1":"",
"CorruptTicket*TLS11":"",
"Resume-Server*TLS1-*":"",
"Resume-Server*TLS11-*":"",
"BadRSAClientKeyExchange-*":"This is a TLS11 only test.",
"RSAKeyUsage-Server-WantSignature-GotSignature-TLS1":"Only Server side of TLS 1 fails",
"RSAKeyUsage-Server-WantSignature-GotSignature-TLS11":"Only Server side of TLS 11 fails",
"":""
"ALPNClient-Mismatch-TLS13":"NSS sends alerts in response to errors in protected handshake messages in the clear",
"P224-Server":"NSS doesn't support P-224",
"ClientAuth-SHA1-Fallback*":"Boring wants us to fall back to SHA-1 if supported_signature_algorithms in CR is empty."
},
"ErrorMap" : {
":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:":"SSL_ERROR_NO_CYPHER_OVERLAP",
":UNKNOWN_CIPHER_RETURNED:":"SSL_ERROR_NO_CYPHER_OVERLAP",
":OLD_SESSION_CIPHER_NOT_RETURNED:":"SSL_ERROR_RX_MALFORMED_SERVER_HELLO",
":NO_SHARED_CIPHER:":"SSL_ERROR_NO_CYPHER_OVERLAP",
":DIGEST_CHECK_FAILED:":"SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE"
}
}

View file

@ -1,5 +1,4 @@
/* -*- 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/. */
@ -19,18 +18,12 @@
#include "sslerr.h"
#include "sslproto.h"
#include "nss_scoped_ptrs.h"
#include "sslimpl.h"
#include "tls13ech.h"
#include "base64.h"
#include "nsskeys.h"
static const char* kVersionDisableFlags[] = {"no-ssl3", "no-tls1", "no-tls11",
"no-tls12", "no-tls13"};
/* Default EarlyData dummy data determined by Bogo implementation. */
const unsigned char kBogoDummyData[] = {'h', 'e', 'l', 'l', 'o'};
bool exitCodeUnimplemented = false;
std::string FormatError(PRErrorCode code) {
@ -38,11 +31,6 @@ std::string FormatError(PRErrorCode code) {
PORT_ErrorToString(code);
}
static void StringRemoveNewlines(std::string& str) {
str.erase(std::remove(str.begin(), str.end(), '\n'), str.cend());
str.erase(std::remove(str.begin(), str.end(), '\r'), str.cend());
}
class TestAgent {
public:
TestAgent(const Config& cfg) : cfg_(cfg) {}
@ -348,39 +336,8 @@ class TestAgent {
}
if (!cfg_.get<bool>("server")) {
auto hostname = cfg_.get<std::string>("host-name");
if (!hostname.empty()) {
rv = SSL_SetURL(ssl_fd_.get(), hostname.c_str());
} else {
// Needed to make resumption work.
rv = SSL_SetURL(ssl_fd_.get(), "server");
}
if (rv != SECSuccess) return false;
// Setup ECH configs on client if provided
auto echConfigList = cfg_.get<std::string>("ech-config-list");
if (!echConfigList.empty()) {
unsigned int binLen;
auto bin = ATOB_AsciiToData(echConfigList.c_str(), &binLen);
rv = SSLExp_SetClientEchConfigs(ssl_fd_.get(), bin, binLen);
if (rv != SECSuccess) return false;
free(bin);
}
if (cfg_.get<bool>("enable-grease")) {
rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_GREASE, PR_TRUE);
if (rv != SECSuccess) return false;
}
if (cfg_.get<bool>("permute-extensions")) {
rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_CH_EXTENSION_PERMUTATION,
PR_TRUE);
if (rv != SECSuccess) return false;
}
} else {
// GREASE - BoGo expects servers to enable GREASE by default
rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_GREASE, PR_TRUE);
// Needed to make resumption work.
rv = SSL_SetURL(ssl_fd_.get(), "server");
if (rv != SECSuccess) return false;
}
@ -388,22 +345,6 @@ class TestAgent {
PR_TRUE);
if (rv != SECSuccess) return false;
if (cfg_.get<bool>("server")) {
// BoGo expects servers to enable ECH (backend) by default
rv = SSLExp_EnableTls13BackendEch(ssl_fd_.get(), true);
if (rv != SECSuccess) return false;
}
if (cfg_.get<bool>("enable-ech-grease")) {
rv = SSLExp_EnableTls13GreaseEch(ssl_fd_.get(), true);
if (rv != SECSuccess) return false;
}
if (cfg_.get<bool>("enable-early-data")) {
rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_0RTT_DATA, PR_TRUE);
if (rv != SECSuccess) return false;
}
if (!ConfigureCiphers()) return false;
return true;
@ -502,6 +443,7 @@ class TestAgent {
return SECFailure;
}
}
return SECSuccess;
}
// Write bytes to the other side then read them back and check
@ -544,180 +486,8 @@ class TestAgent {
return SECSuccess;
}
SECStatus CheckALPN(std::string expectedALPN) {
SECStatus rv;
SSLNextProtoState state;
char chosen[256];
unsigned int chosen_len;
rv = SSL_GetNextProto(ssl_fd_.get(), &state,
reinterpret_cast<unsigned char*>(chosen), &chosen_len,
sizeof(chosen));
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "SSL_GetNextProto failed with error=" << FormatError(err)
<< std::endl;
return SECFailure;
}
assert(chosen_len <= sizeof(chosen));
if (std::string(chosen, chosen_len) != expectedALPN) {
std::cerr << "Expexted ALPN (" << expectedALPN << ") != Choosen ALPN ("
<< std::string(chosen, chosen_len) << ")" << std::endl;
return SECFailure;
}
return SECSuccess;
}
SECStatus AdvertiseALPN(std::string alpn) {
return SSL_SetNextProtoNego(
ssl_fd_.get(), reinterpret_cast<const unsigned char*>(alpn.c_str()),
alpn.size());
}
SECStatus DoExchange(bool resuming) {
SECStatus rv;
int earlyDataSent = 0;
std::string str;
sslSocket* ss = ssl_FindSocket(ssl_fd_.get());
if (!ss) {
return SECFailure;
}
/* Apply resumption SSL options (if any). */
if (resuming) {
/* Client options */
if (!cfg_.get<bool>("server")) {
auto resumeEchConfigList =
cfg_.get<std::string>("on-resume-ech-config-list");
if (!resumeEchConfigList.empty()) {
unsigned int binLen;
auto bin = ATOB_AsciiToData(resumeEchConfigList.c_str(), &binLen);
rv = SSLExp_SetClientEchConfigs(ssl_fd_.get(), bin, binLen);
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "Setting up resumption ECH configs failed with error="
<< err << FormatError(err) << std::endl;
}
free(bin);
}
str = cfg_.get<std::string>("on-resume-advertise-alpn");
if (!str.empty()) {
if (AdvertiseALPN(str) != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "Setting up resumption ALPN failed with error=" << err
<< FormatError(err) << std::endl;
}
}
}
} else { /* Explicitly not on resume (on initial) */
/* Client options */
if (!cfg_.get<bool>("server")) {
str = cfg_.get<std::string>("on-initial-advertise-alpn");
if (!str.empty()) {
if (AdvertiseALPN(str) != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "Setting up initial ALPN failed with error=" << err
<< FormatError(err) << std::endl;
}
}
}
}
/* If client send ClientHello. */
if (!cfg_.get<bool>("server")) {
ssl_Get1stHandshakeLock(ss);
rv = ssl_BeginClientHandshake(ss);
ssl_Release1stHandshakeLock(ss);
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "Handshake failed with error=" << err << FormatError(err)
<< std::endl;
return SECFailure;
}
/* If the client is resuming. */
if (ss->statelessResume) {
SSLPreliminaryChannelInfo pinfo;
rv = SSL_GetPreliminaryChannelInfo(ssl_fd_.get(), &pinfo,
sizeof(SSLPreliminaryChannelInfo));
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "SSL_GetPreliminaryChannelInfo failed with " << err
<< std::endl;
return SECFailure;
}
/* Check that the used ticket supports early data. */
if (cfg_.get<bool>("expect-ticket-supports-early-data")) {
if (!pinfo.ticketSupportsEarlyData) {
std::cerr << "Expected ticket to support EarlyData" << std::endl;
return SECFailure;
}
}
/* If the client should send EarlyData. */
if (cfg_.get<bool>("on-resume-shim-writes-first")) {
earlyDataSent =
ssl_SecureWrite(ss, kBogoDummyData, sizeof(kBogoDummyData));
if (earlyDataSent < 0) {
std::cerr << "Sending of EarlyData failed" << std::endl;
return SECFailure;
}
}
if (cfg_.get<bool>("expect-no-offer-early-data")) {
if (earlyDataSent) {
std::cerr << "Unexpectedly offered EarlyData" << std::endl;
return SECFailure;
}
}
}
}
/* As server start, as client continue handshake. */
rv = Handshake();
/* Retry config evaluation must be done before error handling since
* handshake failure is intended on ech_required tests. */
if (cfg_.get<bool>("expect-no-ech-retry-configs")) {
if (ss->xtnData.ech && ss->xtnData.ech->retryConfigsValid) {
std::cerr << "Unexpectedly received ECH retry configs" << std::endl;
return SECFailure;
}
}
/* If given, verify received retry configs before error handling. */
std::string expectedRCs64 =
cfg_.get<std::string>("expect-ech-retry-configs");
if (!expectedRCs64.empty()) {
SECItem receivedRCs;
/* Get received RetryConfigs. */
if (SSLExp_GetEchRetryConfigs(ssl_fd_.get(), &receivedRCs) !=
SECSuccess) {
std::cerr << "Failed to get ECH retry configs." << std::endl;
return SECFailure;
}
/* (Re-)Encode received configs to compare with expected ASCII string. */
std::string receivedRCs64(
BTOA_DataToAscii(receivedRCs.data, receivedRCs.len));
/* Remove newlines (for unknown reasons) added during b64 encoding. */
StringRemoveNewlines(receivedRCs64);
if (receivedRCs64 != expectedRCs64) {
std::cerr << "Received ECH retry configs did not match expected retry "
"configs."
<< std::endl;
return SECFailure;
}
}
/* Check if handshake succeeded. */
SECStatus DoExchange() {
SECStatus rv = Handshake();
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "Handshake failed with error=" << err << FormatError(err)
@ -725,20 +495,6 @@ class TestAgent {
return SECFailure;
}
/* If parts of data was sent as EarlyData make sure to send possibly
* unsent rest. This is required to pass bogo resumption tests. */
if (earlyDataSent && earlyDataSent < int(sizeof(kBogoDummyData))) {
int toSend = sizeof(kBogoDummyData) - earlyDataSent;
earlyDataSent =
ssl_SecureWrite(ss, &kBogoDummyData[earlyDataSent], toSend);
if (earlyDataSent != toSend) {
std::cerr
<< "Could not send rest of EarlyData after handshake completion"
<< std::endl;
return SECFailure;
}
}
if (cfg_.get<bool>("write-then-read")) {
rv = WriteRead();
if (rv != SECSuccess) {
@ -757,17 +513,39 @@ class TestAgent {
}
}
SSLChannelInfo info;
rv = SSL_GetChannelInfo(ssl_fd_.get(), &info, sizeof(info));
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "SSL_GetChannelInfo failed with error=" << FormatError(err)
<< std::endl;
return SECFailure;
auto alpn = cfg_.get<std::string>("expect-alpn");
if (!alpn.empty()) {
SSLNextProtoState state;
char chosen[256];
unsigned int chosen_len;
rv = SSL_GetNextProto(ssl_fd_.get(), &state,
reinterpret_cast<unsigned char*>(chosen),
&chosen_len, sizeof(chosen));
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "SSL_GetNextProto failed with error=" << FormatError(err)
<< std::endl;
return SECFailure;
}
assert(chosen_len <= sizeof(chosen));
if (std::string(chosen, chosen_len) != alpn) {
std::cerr << "Unexpected ALPN selection" << std::endl;
return SECFailure;
}
}
auto sig_alg = cfg_.get<int>("expect-peer-signature-algorithm");
if (sig_alg) {
SSLChannelInfo info;
rv = SSL_GetChannelInfo(ssl_fd_.get(), &info, sizeof(info));
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
std::cerr << "SSL_GetChannelInfo failed with error=" << FormatError(err)
<< std::endl;
return SECFailure;
}
auto expected = static_cast<SSLSignatureScheme>(sig_alg);
if (info.signatureScheme != expected) {
std::cerr << "Unexpected signature scheme" << std::endl;
@ -775,92 +553,6 @@ class TestAgent {
}
}
if (cfg_.get<bool>("expect-ech-accept")) {
if (!info.echAccepted) {
std::cerr << "Expected ECH" << std::endl;
return SECFailure;
}
}
if (cfg_.get<bool>("expect-hrr")) {
if (!ss->ssl3.hs.helloRetry) {
std::cerr << "Expected HRR" << std::endl;
return SECFailure;
}
}
str = cfg_.get<std::string>("expect-alpn");
if (!str.empty()) {
if (CheckALPN(str) != SECSuccess) {
std::cerr << "Unexpected ALPN" << std::endl;
return SECFailure;
}
}
/* if resumed */
if (info.resumed) {
if (cfg_.get<bool>("expect-session-miss")) {
std::cerr << "Expected reject Resume" << std::endl;
return SECFailure;
}
if (cfg_.get<bool>("on-resume-expect-ech-accept")) {
if (!info.echAccepted) {
std::cerr << "Expected ECH on Resume" << std::endl;
return SECFailure;
}
}
if (cfg_.get<bool>("on-resume-expect-reject-early-data")) {
if (info.earlyDataAccepted) {
std::cerr << "Expected reject EarlyData" << std::endl;
return SECFailure;
}
}
if (cfg_.get<bool>("on-resume-expect-accept-early-data")) {
if (!info.earlyDataAccepted) {
std::cerr << "Expected accept EarlyData" << std::endl;
return SECFailure;
}
}
/* On successfully resumed connection. */
if (info.earlyDataAccepted) {
str = cfg_.get<std::string>("on-resume-expect-alpn");
if (!str.empty()) {
if (CheckALPN(str) != SECSuccess) {
std::cerr << "Unexpected ALPN on Resume" << std::endl;
return SECFailure;
}
} else { /* No real resume but new handshake on EarlyData rejection. */
/* On Retry... */
str = cfg_.get<std::string>("on-retry-expect-alpn");
if (!str.empty()) {
if (CheckALPN(str) != SECSuccess) {
std::cerr << "Unexpected ALPN on HRR" << std::endl;
return SECFailure;
}
}
}
}
} else { /* Explicitly not on resume */
if (cfg_.get<bool>("on-initial-expect-ech-accept")) {
if (!info.echAccepted) {
std::cerr << "Expected ECH accept on initial connection" << std::endl;
return SECFailure;
}
}
str = cfg_.get<std::string>("on-initial-expect-alpn");
if (!str.empty()) {
if (CheckALPN(str) != SECSuccess) {
std::cerr << "Unexpected ALPN on Initial" << std::endl;
return SECFailure;
}
}
}
return SECSuccess;
}
@ -894,41 +586,11 @@ std::unique_ptr<const Config> ReadConfig(int argc, char** argv) {
cfg->AddEntry<bool>("is-handshaker-supported", false);
cfg->AddEntry<std::string>("handshaker-path", ""); // Ignore this
cfg->AddEntry<std::string>("advertise-alpn", "");
cfg->AddEntry<std::string>("on-initial-advertise-alpn", "");
cfg->AddEntry<std::string>("on-resume-advertise-alpn", "");
cfg->AddEntry<std::string>("expect-alpn", "");
cfg->AddEntry<std::string>("on-initial-expect-alpn", "");
cfg->AddEntry<std::string>("on-resume-expect-alpn", "");
cfg->AddEntry<std::string>("on-retry-expect-alpn", "");
cfg->AddEntry<std::vector<int>>("signing-prefs", std::vector<int>());
cfg->AddEntry<std::vector<int>>("verify-prefs", std::vector<int>());
cfg->AddEntry<int>("expect-peer-signature-algorithm", 0);
cfg->AddEntry<std::string>("nss-cipher", "");
cfg->AddEntry<std::string>("host-name", "");
cfg->AddEntry<std::string>("ech-config-list", "");
cfg->AddEntry<std::string>("on-resume-ech-config-list", "");
cfg->AddEntry<bool>("expect-ech-accept", false);
cfg->AddEntry<bool>("expect-hrr", false);
cfg->AddEntry<bool>("enable-ech-grease", false);
cfg->AddEntry<bool>("enable-early-data", false);
cfg->AddEntry<bool>("enable-grease", false);
cfg->AddEntry<bool>("permute-extensions", false);
cfg->AddEntry<bool>("on-resume-expect-reject-early-data", false);
cfg->AddEntry<bool>("on-resume-expect-accept-early-data", false);
cfg->AddEntry<bool>("expect-ticket-supports-early-data", false);
cfg->AddEntry<bool>("on-resume-shim-writes-first",
false); // Always means 0Rtt write
cfg->AddEntry<bool>("shim-writes-first",
false); // Unimplemented since not required so far
cfg->AddEntry<bool>("expect-session-miss", false);
cfg->AddEntry<std::string>("expect-ech-retry-configs", "");
cfg->AddEntry<bool>("expect-no-ech-retry-configs", false);
cfg->AddEntry<bool>("on-initial-expect-ech-accept", false);
cfg->AddEntry<bool>("on-resume-expect-ech-accept", false);
cfg->AddEntry<bool>("expect-no-offer-early-data", false);
/* NSS does not support earlydata rejection reason logging => Ignore. */
cfg->AddEntry<std::string>("on-resume-expect-early-data-reason", "none");
cfg->AddEntry<std::string>("on-retry-expect-early-data-reason", "none");
auto rv = cfg->ParseArgs(argc, argv);
switch (rv) {
@ -944,9 +606,9 @@ std::unique_ptr<const Config> ReadConfig(int argc, char** argv) {
return std::move(cfg);
}
bool RunCycle(std::unique_ptr<const Config>& cfg, bool resuming = false) {
bool RunCycle(std::unique_ptr<const Config>& cfg) {
std::unique_ptr<TestAgent> agent(TestAgent::Create(*cfg));
return agent && agent->DoExchange(resuming) == SECSuccess;
return agent && agent->DoExchange() == SECSuccess;
}
int GetExitCode(bool success) {
@ -989,7 +651,7 @@ int main(int argc, char** argv) {
int resume_count = cfg->get<int>("resume-count");
while (success && resume_count-- > 0) {
std::cout << "Resuming" << std::endl;
success = RunCycle(cfg, true);
success = RunCycle(cfg);
}
SSL_ClearSessionCache();

View file

@ -1,5 +1,4 @@
/* -*- 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/. */

View file

@ -1,5 +1,4 @@
/* -*- 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/. */