diff options
author | Leander Schwarz <lschwarz@mozilla.com> | 2022-08-26 14:35:36 +0000 |
---|---|---|
committer | Leander Schwarz <lschwarz@mozilla.com> | 2022-08-26 14:35:36 +0000 |
commit | 7ec3723610faa50a54d65156d67077f8fbdf5de9 (patch) | |
tree | 8b0caf8b4edb6b66b82ffc06f25d0b6b11c5245e | |
parent | 3a32db8013619cbe76836ebd54ba2c0447d8745e (diff) | |
download | nss-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.json | 7 | ||||
-rw-r--r-- | gtests/nss_bogo_shim/nss_bogo_shim.cc | 55 | ||||
-rw-r--r-- | lib/ssl/tls13ech.c | 11 | ||||
-rw-r--r-- | lib/ssl/tls13ech.h | 4 |
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, |