diff options
author | Leander Schwarz <lschwarz@mozilla.com> | 2023-01-16 17:56:43 +0000 |
---|---|---|
committer | Leander Schwarz <lschwarz@mozilla.com> | 2023-01-16 17:56:43 +0000 |
commit | 11bdd24bb405af450ad1007064eb70db02b3317d (patch) | |
tree | 3966d9cfd360110a370be7d7ce4a9f02fe64121c | |
parent | a9974d3eb4d2bd0241f8c24d2d8fcc2282d69af9 (diff) | |
download | nss-hg-11bdd24bb405af450ad1007064eb70db02b3317d.tar.gz |
Bug 1771100 - Added ECH 0Rtt support to BoGo shim. r=djackson
Differential Revision: https://phabricator.services.mozilla.com/D154209
-rw-r--r-- | gtests/nss_bogo_shim/config.cc | 3 | ||||
-rw-r--r-- | gtests/nss_bogo_shim/config.json | 7 | ||||
-rw-r--r-- | gtests/nss_bogo_shim/nss_bogo_shim.cc | 104 |
3 files changed, 109 insertions, 5 deletions
diff --git a/gtests/nss_bogo_shim/config.cc b/gtests/nss_bogo_shim/config.cc index 603bb6029..fd56db998 100644 --- a/gtests/nss_bogo_shim/config.cc +++ b/gtests/nss_bogo_shim/config.cc @@ -58,10 +58,11 @@ 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; } diff --git a/gtests/nss_bogo_shim/config.json b/gtests/nss_bogo_shim/config.json index a3ccecfec..52d477ad1 100644 --- a/gtests/nss_bogo_shim/config.json +++ b/gtests/nss_bogo_shim/config.json @@ -19,6 +19,7 @@ "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).", "*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.", @@ -45,6 +46,8 @@ "*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", + "HelloRetryRequest-NonResumableCipher-TLS13":"TODO", "####################":"####################", "### TLS1/11 failures due to unsupported signature algorithms":"", @@ -71,6 +74,10 @@ "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", diff --git a/gtests/nss_bogo_shim/nss_bogo_shim.cc b/gtests/nss_bogo_shim/nss_bogo_shim.cc index e23b3c4f1..e8de3e3f9 100644 --- a/gtests/nss_bogo_shim/nss_bogo_shim.cc +++ b/gtests/nss_bogo_shim/nss_bogo_shim.cc @@ -375,6 +375,11 @@ class TestAgent { 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; @@ -517,7 +522,61 @@ class TestAgent { } SECStatus DoExchange() { - SECStatus rv = Handshake(); + SECStatus rv; + sslSocket* ss = ssl_FindSocket(ssl_fd_.get()); + if (!ss) { + return SECFailure; + } + + /* Default EarlyData determined by Bogo implementation. */ + const unsigned char earlyDataDefault[] = {'h', 'e', 'l', 'l', 'o'}; + int earlyDataSent = 0; + + /* As 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) { + /* If the client should send EarlyData. */ + if (cfg_.get<bool>("on-resume-shim-writes-first")) { + earlyDataSent = + ssl_SecureWrite(ss, earlyDataDefault, sizeof(earlyDataDefault)); + if (earlyDataSent < 0) { + std::cerr << "Sending of EarlyData failed" << std::endl; + return SECFailure; + } + } + + SSLPreliminaryChannelInfo pinfo; + rv = SSL_GetPreliminaryChannelInfo(ssl_fd_.get(), &pinfo, + sizeof(SSLPreliminaryChannelInfo)); + if (rv != SECSuccess) { + PRErrorCode err = PR_GetError(); + std::cerr << "SSL_GetPreliminaryChannelInfo failed with error=" + << FormatError(err) << std::endl; + return SECFailure; + } + + /* Check that the used ticket supports early data. */ + if (cfg_.get<bool>("expect-ticket-supports-early-data")) { + if (!pinfo.canSendEarlyData) { + std::cerr << "Expected ticket to support EarlyData" << std::endl; + } + } + } + } + + /* As server start, as client continue handshake. */ + rv = Handshake(); if (rv != SECSuccess) { PRErrorCode err = PR_GetError(); std::cerr << "Handshake failed with error=" << err << FormatError(err) @@ -525,6 +584,20 @@ 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(earlyDataDefault))) { + int toSend = sizeof(earlyDataDefault) - earlyDataSent; + earlyDataSent = + ssl_SecureWrite(ss, &earlyDataDefault[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) { @@ -590,11 +663,27 @@ class TestAgent { } } - if (cfg_.get<bool>("expect-hrr")) { - sslSocket* ss = ssl_FindSocket(ssl_fd_.get()); - if (!ss) { + 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-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; + } + } + } + + if (cfg_.get<bool>("expect-hrr")) { if (!ss->ssl3.hs.helloRetry) { std::cerr << "Expected HRR" << std::endl; return SECFailure; @@ -644,6 +733,13 @@ std::unique_ptr<const Config> ReadConfig(int argc, char** argv) { 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>("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>("expect-session-miss", false); auto rv = cfg->ParseArgs(argc, argv); switch (rv) { |