Skip to content

Commit 6be03a5

Browse files
authored
Merge pull request #10182 from embhorn/zd21576
Fix TLSX_EchChangeSNI to check hostname termination
2 parents 0c93bf9 + ff7a32d commit 6be03a5

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

src/tls.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16106,6 +16106,9 @@ static int TLSX_EchChangeSNI(WOLFSSL* ssl, TLSX** pEchX,
1610616106
hostNameSz = MAX_PUBLIC_NAME_SZ;
1610716107

1610816108
XMEMCPY(serverName, hostName, hostNameSz);
16109+
/* Guarantee NUL termination after truncation so that
16110+
* TLSX_EchRestoreSNI's XSTRLEN cannot read past the buffer. */
16111+
serverName[hostNameSz - 1] = '\0';
1610916112
}
1611016113

1611116114
/* only swap the SNI if one was found; extensions is non-NULL if an

tests/api.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15173,6 +15173,49 @@ static int test_wolfSSL_Tls13_ECH_disable_conn(void)
1517315173

1517415174
return EXPECT_RESULT();
1517515175
}
15176+
/* Regression test: an inner SNI hostname >= MAX_PUBLIC_NAME_SZ (256) bytes
15177+
* must not cause a stack-buffer-overflow in TLSX_EchRestoreSNI. Before the
15178+
* fix, the truncated copy omitted the NUL terminator and XSTRLEN read past
15179+
* the buffer. */
15180+
static int test_wolfSSL_Tls13_ECH_long_SNI(void)
15181+
{
15182+
EXPECT_DECLS;
15183+
#if !defined(NO_WOLFSSL_CLIENT)
15184+
test_ssl_memio_ctx test_ctx;
15185+
/* 300 chars > MAX_PUBLIC_NAME_SZ (256) to exercise truncation */
15186+
char longName[300];
15187+
15188+
XMEMSET(longName, 'a', sizeof(longName) - 1);
15189+
longName[sizeof(longName) - 1] = '\0';
15190+
15191+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
15192+
15193+
test_ctx.s_cb.method = wolfTLSv1_3_server_method;
15194+
test_ctx.c_cb.method = wolfTLSv1_3_client_method;
15195+
15196+
test_ctx.s_cb.ctx_ready = test_ech_server_ctx_ready;
15197+
test_ctx.s_cb.ssl_ready = test_ech_server_ssl_ready;
15198+
15199+
ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS);
15200+
15201+
/* Set ECH configs on the client */
15202+
ExpectIntEQ(wolfSSL_SetEchConfigs(test_ctx.c_ssl, echCbTestConfigs,
15203+
echCbTestConfigsLen), WOLFSSL_SUCCESS);
15204+
15205+
/* Set the over-long SNI as the inner hostname */
15206+
ExpectIntEQ(wolfSSL_UseSNI(test_ctx.c_ssl, WOLFSSL_SNI_HOST_NAME,
15207+
longName, (word16)XSTRLEN(longName)), WOLFSSL_SUCCESS);
15208+
15209+
/* The handshake triggers TLSX_EchChangeSNI / TLSX_EchRestoreSNI.
15210+
* Before the fix this would stack-buffer-overflow in XSTRLEN.
15211+
* The connection may fail (SNI mismatch) but must not crash. */
15212+
(void)test_ssl_memio_do_handshake(&test_ctx, 10, NULL);
15213+
15214+
test_ssl_memio_cleanup(&test_ctx);
15215+
#endif /* !NO_WOLFSSL_CLIENT */
15216+
15217+
return EXPECT_RESULT();
15218+
}
1517615219
#endif /* HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */
1517715220

1517815221
/* verify that ECH can be enabled/disabled without issue */
@@ -36256,6 +36299,7 @@ TEST_CASE testCases[] = {
3625636299
TEST_DECL(test_wolfSSL_Tls13_ECH_new_config),
3625736300
TEST_DECL(test_wolfSSL_Tls13_ECH_GREASE),
3625836301
TEST_DECL(test_wolfSSL_Tls13_ECH_disable_conn),
36302+
TEST_DECL(test_wolfSSL_Tls13_ECH_long_SNI),
3625936303
#endif
3626036304
TEST_DECL(test_wolfSSL_Tls13_ECH_enable_disable),
3626136305
#endif /* WOLFSSL_TLS13 && HAVE_ECH */

0 commit comments

Comments
 (0)