summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeander Schwarz <lschwarz@mozilla.com>2022-08-26 14:35:36 +0000
committerLeander Schwarz <lschwarz@mozilla.com>2022-08-26 14:35:36 +0000
commit7ec3723610faa50a54d65156d67077f8fbdf5de9 (patch)
tree8b0caf8b4edb6b66b82ffc06f25d0b6b11c5245e
parent3a32db8013619cbe76836ebd54ba2c0447d8745e (diff)
downloadnss-hg-7ec3723610faa50a54d65156d67077f8fbdf5de9.tar.gz
Bug 1771100 - Added ECH client support to BoGo shim. Changed CHInner creation to skip TLS 1.2 only extensions to comply with BoGo. r=djackson
Differential Revision: https://phabricator.services.mozilla.com/D151489
-rw-r--r--gtests/nss_bogo_shim/config.json7
-rw-r--r--gtests/nss_bogo_shim/nss_bogo_shim.cc55
-rw-r--r--lib/ssl/tls13ech.c11
-rw-r--r--lib/ssl/tls13ech.h4
4 files changed, 64 insertions, 13 deletions
diff --git a/gtests/nss_bogo_shim/config.json b/gtests/nss_bogo_shim/config.json
index f3e893fa3..7779ce30b 100644
--- a/gtests/nss_bogo_shim/config.json
+++ b/gtests/nss_bogo_shim/config.json
@@ -40,8 +40,11 @@
"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.",
-
- "TLS-ECH-*Client*":"TODO",
+ "*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*Config*":"TODO",
+ "*ECH*ServerName*":"TODO",
+ "*ECH*RandomHRRExtension*":"TODO",
"####################":"####################",
"### 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 8d9add4c2..8871c2c8f 100644
--- a/gtests/nss_bogo_shim/nss_bogo_shim.cc
+++ b/gtests/nss_bogo_shim/nss_bogo_shim.cc
@@ -20,6 +20,8 @@
#include "sslproto.h"
#include "nss_scoped_ptrs.h"
#include "sslimpl.h"
+#include "tls13ech.h"
+#include "base64.h"
#include "nsskeys.h"
@@ -338,9 +340,24 @@ class TestAgent {
}
if (!cfg_.get<bool>("server")) {
- // Needed to make resumption work.
- rv = SSL_SetURL(ssl_fd_.get(), "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);
+ }
}
rv = SSL_OptionSet(ssl_fd_.get(), SSL_ENABLE_EXTENDED_MASTER_SECRET,
@@ -353,6 +370,11 @@ class TestAgent {
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 (!ConfigureCiphers()) return false;
return true;
@@ -543,17 +565,17 @@ 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 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;
@@ -561,6 +583,13 @@ class TestAgent {
}
}
+ if (cfg_.get<bool>("expect-ech-accept")) {
+ if (!info.echAccepted) {
+ std::cerr << "Expected ECH" << std::endl;
+ return SECFailure;
+ }
+ }
+
return SECSuccess;
}
@@ -599,6 +628,10 @@ std::unique_ptr<const Config> ReadConfig(int argc, char** argv) {
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<bool>("expect-ech-accept", false);
+ cfg->AddEntry<bool>("enable-ech-grease", false);
auto rv = cfg->ParseArgs(argc, argv);
switch (rv) {
diff --git a/lib/ssl/tls13ech.c b/lib/ssl/tls13ech.c
index d752d6ebf..a245a885b 100644
--- a/lib/ssl/tls13ech.c
+++ b/lib/ssl/tls13ech.c
@@ -1382,6 +1382,17 @@ tls13_ConstructInnerExtensionsFromOuter(sslSocket *ss, sslBuffer *chOuterXtnsBuf
goto loser;
}
+ /* Skip extensions that are TLS < 1.3 only, since CHInner MUST
+ * negotiate TLS 1.3 or above.
+ * If the extension is supported by default (sslSupported) but unknown
+ * to TLS 1.3 it must be a TLS < 1.3 only extension. */
+ SSLExtensionSupport sslSupported;
+ (void)SSLExp_GetExtensionSupport(extensionType, &sslSupported);
+ if (sslSupported != ssl_ext_none &&
+ tls13_ExtensionStatus(extensionType, ssl_hs_client_hello) == tls13_extension_unknown) {
+ continue;
+ }
+
switch (extensionType) {
case ssl_server_name_xtn:
/* Write the real (private) SNI value. */
diff --git a/lib/ssl/tls13ech.h b/lib/ssl/tls13ech.h
index 0ad98592d..90b674e40 100644
--- a/lib/ssl/tls13ech.h
+++ b/lib/ssl/tls13ech.h
@@ -82,6 +82,8 @@ struct sslEchXtnStateStr {
PRUint8 *payloadStart; /* Server: Start of ECH Payload*/
};
+SEC_BEGIN_PROTOS
+
SECStatus SSLExp_EncodeEchConfigId(PRUint8 configId, const char *publicName, unsigned int maxNameLen,
HpkeKemId kemId, const SECKEYPublicKey *pubKey,
const HpkeSymmetricSuite *hpkeSuites, unsigned int hpkeSuiteCount,
@@ -94,6 +96,8 @@ SECStatus SSLExp_SetServerEchConfigs(PRFileDesc *fd,
const PRUint8 *echConfigs, unsigned int numEchConfigs);
SECStatus SSLExp_RemoveEchConfigs(PRFileDesc *fd);
+SEC_END_PROTOS
+
SECStatus tls13_ClientSetupEch(sslSocket *ss, sslClientHelloType type);
SECStatus tls13_ConstructClientHelloWithEch(sslSocket *ss, const sslSessionID *sid,
PRBool freshSid, sslBuffer *chOuterBuf,