summaryrefslogtreecommitdiff
path: root/gtests
diff options
context:
space:
mode:
authorLeander Schwarz <lschwarz@mozilla.com>2023-01-16 17:56:45 +0000
committerLeander Schwarz <lschwarz@mozilla.com>2023-01-16 17:56:45 +0000
commitf1d7967e22830a08584bc88133932bef98ff622f (patch)
treee0e07aaa8fe6014b3f56fe53f53beda773abcb8a /gtests
parentcf55859f44ab6f15a2e0d0c66c29c313e38b3070 (diff)
downloadnss-hg-f1d7967e22830a08584bc88133932bef98ff622f.tar.gz
Bug 1771100 - Added EarlyData ALPN test support to BoGo shim. r=djackson
Differential Revision: https://phabricator.services.mozilla.com/D157290
Diffstat (limited to 'gtests')
-rw-r--r--gtests/nss_bogo_shim/config.json4
-rw-r--r--gtests/nss_bogo_shim/nss_bogo_shim.cc169
2 files changed, 131 insertions, 42 deletions
diff --git a/gtests/nss_bogo_shim/config.json b/gtests/nss_bogo_shim/config.json
index bf32596cb..24aad553b 100644
--- a/gtests/nss_bogo_shim/config.json
+++ b/gtests/nss_bogo_shim/config.json
@@ -20,6 +20,7 @@
"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.",
@@ -47,7 +48,8 @@
"*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",
+
+ "FalseStart-ALPN*":"TODO - Implementing TLS 1.2 only FalseStart has low priority.",
"####################":"####################",
"### TLS1/11 failures due to unsupported signature algorithms":"",
diff --git a/gtests/nss_bogo_shim/nss_bogo_shim.cc b/gtests/nss_bogo_shim/nss_bogo_shim.cc
index f653e3784..fb178d0a9 100644
--- a/gtests/nss_bogo_shim/nss_bogo_shim.cc
+++ b/gtests/nss_bogo_shim/nss_bogo_shim.cc
@@ -529,9 +529,42 @@ 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;
@@ -549,11 +582,33 @@ class TestAgent {
rv = SSLExp_SetClientEchConfigs(ssl_fd_.get(), bin, binLen);
if (rv != SECSuccess) {
PRErrorCode err = PR_GetError();
- std::cerr << "Setting up resuption ECH configs failed with error="
+ 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;
+ }
+ }
}
}
@@ -571,30 +626,38 @@ class TestAgent {
/* 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, kBogoDummyData, sizeof(kBogoDummyData));
- 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;
+ 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.canSendEarlyData) {
+ 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;
}
}
}
@@ -679,28 +742,6 @@ class TestAgent {
}
}
- 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;
- }
- }
-
SSLChannelInfo info;
rv = SSL_GetChannelInfo(ssl_fd_.get(), &info, sizeof(info));
if (rv != SECSuccess) {
@@ -726,6 +767,21 @@ class TestAgent {
}
}
+ 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")) {
@@ -752,6 +808,27 @@ class TestAgent {
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) {
@@ -759,12 +836,13 @@ class TestAgent {
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>("on-initial-expect-alpn");
+ if (!str.empty()) {
+ if (CheckALPN(str) != SECSuccess) {
+ std::cerr << "Unexpected ALPN on Initial" << std::endl;
+ return SECFailure;
+ }
}
}
@@ -801,7 +879,12 @@ 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);
@@ -825,6 +908,10 @@ std::unique_ptr<const Config> ReadConfig(int argc, char** argv) {
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) {