summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Jackson <djackson@mozilla.com>2022-03-22 14:28:47 +0000
committerDennis Jackson <djackson@mozilla.com>2022-03-22 14:28:47 +0000
commitec529cbb28c4dcec9231d2d49f44a8e25730d011 (patch)
treef91bbad2ba60de310564194991ad3fe08e89520c
parent6101439d8c7597f4c9490c013265928d280b1276 (diff)
downloadnss-hg-ec529cbb28c4dcec9231d2d49f44a8e25730d011.tar.gz
Bug 1759525 - Add SetTls13GreaseEchSize to experimental API. r=mt
Differential Revision: https://phabricator.services.mozilla.com/D140984
-rw-r--r--gtests/ssl_gtest/tls_ech_unittest.cc14
-rw-r--r--lib/ssl/ssl3con.c1
-rw-r--r--lib/ssl/sslexp.h13
-rw-r--r--lib/ssl/sslimpl.h2
-rw-r--r--lib/ssl/sslsock.c20
-rw-r--r--lib/ssl/tls13ech.c2
-rw-r--r--lib/ssl/tls13ech.h1
7 files changed, 43 insertions, 10 deletions
diff --git a/gtests/ssl_gtest/tls_ech_unittest.cc b/gtests/ssl_gtest/tls_ech_unittest.cc
index d933c48b6..5946007f9 100644
--- a/gtests/ssl_gtest/tls_ech_unittest.cc
+++ b/gtests/ssl_gtest/tls_ech_unittest.cc
@@ -909,6 +909,8 @@ TEST_P(EchCHPaddingTest, EchChPaddingEqual) {
SSL_SetURL(client_->ssl_fd(), name1);
if (grease_mode1) {
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), PR_TRUE));
+ EXPECT_EQ(SECSuccess,
+ SSL_SetTls13GreaseEchSize(client_->ssl_fd(), max_name_len));
client_->ExpectEch(false);
server_->ExpectEch(false);
} else {
@@ -927,6 +929,8 @@ TEST_P(EchCHPaddingTest, EchChPaddingEqual) {
SSL_SetURL(client_->ssl_fd(), name2);
if (grease_mode2) {
EXPECT_EQ(SECSuccess, SSL_EnableTls13GreaseEch(client_->ssl_fd(), PR_TRUE));
+ EXPECT_EQ(SECSuccess,
+ SSL_SetTls13GreaseEchSize(client_->ssl_fd(), max_name_len));
client_->ExpectEch(false);
server_->ExpectEch(false);
} else {
@@ -944,14 +948,8 @@ TEST_P(EchCHPaddingTest, EchChPaddingEqual) {
// Note: It will not be 0 % 32 because we pad the Payload, but have a number
// of extra bytes from the rest of the ECH extension (e.g. ciphersuite)
ASSERT_EQ(echXtnLen1 % 32, echXtnLen2 % 32);
- // Where both connections used the same effective maximum length and both
- // SNIs are below that maximum, we expect the same size length.
- PRUint8 effective_len1 =
- grease_mode1 ? TLS13_ECH_GREASE_SNI_LEN : max_name_len;
- PRUint8 effective_len2 =
- grease_mode2 ? TLS13_ECH_GREASE_SNI_LEN : max_name_len;
- if (effective_len1 == effective_len2 && name_str1.size() <= effective_len1 &&
- name_str2.size() <= effective_len2) {
+ // Both connections should have the same size after padding.
+ if (name_str1.size() <= max_name_len && name_str2.size() <= max_name_len) {
ASSERT_EQ(echXtnLen1, echXtnLen2);
}
}
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
index d7d79e1c8..9261684b4 100644
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -13531,6 +13531,7 @@ ssl3_InitState(sslSocket *ss)
ss->ssl3.hs.clientTrafficSecret = NULL;
ss->ssl3.hs.serverTrafficSecret = NULL;
ss->ssl3.hs.echHpkeCtx = NULL;
+ ss->ssl3.hs.greaseEchSize = 100;
ss->ssl3.hs.echAccepted = PR_FALSE;
ss->ssl3.hs.echDecided = PR_FALSE;
diff --git a/lib/ssl/sslexp.h b/lib/ssl/sslexp.h
index 1f98fe480..6eeafa502 100644
--- a/lib/ssl/sslexp.h
+++ b/lib/ssl/sslexp.h
@@ -517,6 +517,19 @@ typedef SECStatus(PR_CALLBACK *SSLResumptionTokenCallback)(
SSL_EXPERIMENTAL_API("SSL_EnableTls13GreaseEch", \
(PRFileDesc * _fd, PRBool _enabled), (fd, enabled))
+/*
+ * Client:
+ * When sending a GREASE ECH extension in a ClientHello, pad it as though the
+ * hypothetical ECHConfig had |maximum_name_length| equal to |size|. |size| may
+ * vary between 1 and 255 and defaults to 100.
+ *
+ * Server:
+ * Has no effect.
+ */
+#define SSL_SetTls13GreaseEchSize(fd, size) \
+ SSL_EXPERIMENTAL_API("SSL_SetTls13GreaseEchSize", \
+ (PRFileDesc * _fd, PRUint8 _size), (fd, size))
+
/* If |enabled|, a server receiving a Client Hello containing an encrypted_client_hello
* of type inner will respond with the ECH
* acceptance signal. This signals the client to continue with the inner
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
index aeb3b8370..7b4e73c88 100644
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -747,6 +747,7 @@ typedef struct SSL3HandshakeStateStr {
* used to generate ACKs. */
/* TLS 1.3 ECH state. */
+ PRUint8 greaseEchSize;
PRBool echAccepted; /* Client/Server: True if we've commited to using CHInner. */
PRBool echDecided;
HpkeContext *echHpkeCtx; /* Client/Server: HPKE context for ECH. */
@@ -1971,6 +1972,7 @@ SECStatus SSLExp_CreateMask(SSLMaskingContext *ctx, const PRUint8 *sample,
SECStatus SSLExp_DestroyMaskingContext(SSLMaskingContext *ctx);
SECStatus SSLExp_EnableTls13GreaseEch(PRFileDesc *fd, PRBool enabled);
+SECStatus SSLExp_SetTls13GreaseEchSize(PRFileDesc *fd, PRUint8 size);
SECStatus SSLExp_EnableTls13BackendEch(PRFileDesc *fd, PRBool enabled);
SECStatus SSLExp_CallExtensionWriterOnEchInner(PRFileDesc *fd, PRBool enabled);
diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c
index 422d7ae37..cfd9e5a9a 100644
--- a/lib/ssl/sslsock.c
+++ b/lib/ssl/sslsock.c
@@ -4330,6 +4330,7 @@ struct {
EXP(DestroyResumptionTokenInfo),
EXP(EnableTls13BackendEch),
EXP(EnableTls13GreaseEch),
+ EXP(SetTls13GreaseEchSize),
EXP(EncodeEchConfigId),
EXP(GetCurrentEpoch),
EXP(GetEchRetryConfigs),
@@ -4408,6 +4409,25 @@ SSLExp_EnableTls13GreaseEch(PRFileDesc *fd, PRBool enabled)
}
SECStatus
+SSLExp_SetTls13GreaseEchSize(PRFileDesc *fd, PRUint8 size)
+{
+ sslSocket *ss = ssl_FindSocket(fd);
+ if (!ss || size == 0) {
+ exit(-1);
+ return SECFailure;
+ }
+ ssl_Get1stHandshakeLock(ss);
+ ssl_GetSSL3HandshakeLock(ss);
+
+ ss->ssl3.hs.greaseEchSize = size;
+
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_Release1stHandshakeLock(ss);
+
+ return SECSuccess;
+}
+
+SECStatus
SSLExp_EnableTls13BackendEch(PRFileDesc *fd, PRBool enabled)
{
sslSocket *ss = ssl_FindSocket(fd);
diff --git a/lib/ssl/tls13ech.c b/lib/ssl/tls13ech.c
index 76c041a93..7adeabf76 100644
--- a/lib/ssl/tls13ech.c
+++ b/lib/ssl/tls13ech.c
@@ -2143,7 +2143,7 @@ tls13_MaybeGreaseEch(sslSocket *ss, const sslBuffer *preamble, sslBuffer *buf)
if (rv != SECSuccess) {
goto loser; /* Code set */
}
- rv = tls13_PadChInner(&encodedCh, TLS13_ECH_GREASE_SNI_LEN, strlen(ss->url));
+ rv = tls13_PadChInner(&encodedCh, ss->ssl3.hs.greaseEchSize, strlen(ss->url));
payloadLen = encodedCh.len;
payloadLen += TLS13_ECH_AEAD_TAG_LEN; /* Aead tag */
diff --git a/lib/ssl/tls13ech.h b/lib/ssl/tls13ech.h
index bfff32761..c60375660 100644
--- a/lib/ssl/tls13ech.h
+++ b/lib/ssl/tls13ech.h
@@ -24,7 +24,6 @@
#define TLS13_ECH_VERSION 0xfe0d
#define TLS13_ECH_SIGNAL_LEN 8
#define TLS13_ECH_AEAD_TAG_LEN 16
-#define TLS13_ECH_GREASE_SNI_LEN 100
static const char kHpkeInfoEch[] = "tls ech";
static const char hHkdfInfoEchConfigID[] = "tls ech config id";