From 34051fc42e2e0607cb9a85b35b5cd42330101a57 Mon Sep 17 00:00:00 2001 From: sebastian-carpenter Date: Wed, 27 May 2026 09:39:09 -0600 Subject: [PATCH] test public sni is always in outer ch --- src/tls.c | 4 +-- tests/api.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/tls.c b/src/tls.c index 62118d0678..1bc0b6aee1 100644 --- a/src/tls.c +++ b/src/tls.c @@ -16460,9 +16460,7 @@ static int TLSX_EchChangeSNI(WOLFSSL* ssl, TLSX** pEchX, /* if type is outer change sni to public name */ if (echX != NULL && - ((WOLFSSL_ECH*)echX->data)->type == ECH_TYPE_OUTER && - (ssl->options.echAccepted || - ((WOLFSSL_ECH*)echX->data)->innerCount == 0)) { + ((WOLFSSL_ECH*)echX->data)->type == ECH_TYPE_OUTER) { if (ssl->extensions) { serverNameX = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); diff --git a/tests/api.c b/tests/api.c index db7f271815..f8d9f81911 100644 --- a/tests/api.c +++ b/tests/api.c @@ -15914,6 +15914,94 @@ static int test_wolfSSL_Tls13_ECH_GREASE(void) return EXPECT_RESULT(); } +/* The public name must be visible and the private name must not be visible */ +static int test_wolfSSL_Tls13_ECH_wire_sni_ex(int accept) +{ + EXPECT_DECLS; + test_ssl_memio_ctx test_ctx; + WOLFSSL_CTX* tempCtx = NULL; + byte badConfig[128]; + word32 badConfigLen = sizeof(badConfig); + + XMEMSET(&test_ctx, 0, sizeof(test_ctx)); + + test_ctx.s_cb.method = wolfTLSv1_3_server_method; + test_ctx.c_cb.method = wolfTLSv1_3_client_method; + + test_ctx.s_cb.ctx_ready = test_ech_server_ctx_ready; + test_ctx.s_cb.ssl_ready = test_ech_server_ssl_ready; + /* Accept path uses the correct configs */ + if (accept) + test_ctx.c_cb.ssl_ready = test_ech_client_ssl_ready; + + ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS); + + /* Reject path installs bad configs (with the correct public name) */ + if (!accept) { + ExpectNotNull(tempCtx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())); + ExpectIntEQ(wolfSSL_CTX_GenerateEchConfig(tempCtx, echCbTestPublicName, + 0, 0, 0), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_GetEchConfigs(tempCtx, badConfig, + &badConfigLen), WOLFSSL_SUCCESS); + wolfSSL_CTX_free(tempCtx); + ExpectIntEQ(wolfSSL_SetEchConfigs(test_ctx.c_ssl, badConfig, + badConfigLen), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_UseSNI(test_ctx.c_ssl, WOLFSSL_SNI_HOST_NAME, + echCbTestPrivateName, (word16)XSTRLEN(echCbTestPrivateName)), + WOLFSSL_SUCCESS); + } + + /* force HelloRetryRequest */ + ExpectIntEQ(wolfSSL_NoKeyShares(test_ctx.c_ssl), WOLFSSL_SUCCESS); + + /* On reject, client aborts with ech_required and won't send a cert. */ + if (!accept) { + wolfSSL_set_verify(test_ctx.s_ssl, WOLFSSL_VERIFY_NONE, NULL); + wolfSSL_set_verify(test_ctx.c_ssl, WOLFSSL_VERIFY_PEER, NULL); + } + + /* client writes CH1 into s_buff */ + ExpectIntEQ(wolfSSL_connect(test_ctx.c_ssl), WOLFSSL_FATAL_ERROR); + ExpectIntEQ(wolfSSL_get_error(test_ctx.c_ssl, WOLFSSL_FATAL_ERROR), + WOLFSSL_ERROR_WANT_READ); + + /* CH1 wire bytes */ + ExpectNotNull(mymemmem(test_ctx.s_buff, test_ctx.s_len, + echCbTestPublicName, XSTRLEN(echCbTestPublicName))); + ExpectNull(mymemmem(test_ctx.s_buff, test_ctx.s_len, + echCbTestPrivateName, XSTRLEN(echCbTestPrivateName))); + + /* server consumes CH1 and writes HRR into c_buff */ + ExpectIntEQ(wolfSSL_accept(test_ctx.s_ssl), WOLFSSL_FATAL_ERROR); + ExpectIntEQ(wolfSSL_get_error(test_ctx.s_ssl, WOLFSSL_FATAL_ERROR), + WOLFSSL_ERROR_WANT_READ); + ExpectIntEQ(test_ctx.s_ssl->options.serverState, + SERVER_HELLO_RETRY_REQUEST_COMPLETE); + + /* client reads HRR from c_buff and writes CH2 into s_buff */ + ExpectIntEQ(wolfSSL_connect(test_ctx.c_ssl), WOLFSSL_FATAL_ERROR); + ExpectIntEQ(wolfSSL_get_error(test_ctx.c_ssl, WOLFSSL_FATAL_ERROR), + WOLFSSL_ERROR_WANT_READ); + + /* CH2 wire bytes: same property must hold */ + ExpectNotNull(mymemmem(test_ctx.s_buff, test_ctx.s_len, + echCbTestPublicName, XSTRLEN(echCbTestPublicName))); + ExpectNull(mymemmem(test_ctx.s_buff, test_ctx.s_len, + echCbTestPrivateName, XSTRLEN(echCbTestPrivateName))); + + test_ssl_memio_cleanup(&test_ctx); + + return EXPECT_RESULT(); +} + +static int test_wolfSSL_Tls13_ECH_wire_sni(void) +{ + EXPECT_DECLS; + ExpectIntEQ(test_wolfSSL_Tls13_ECH_wire_sni_ex(0), TEST_SUCCESS); + ExpectIntEQ(test_wolfSSL_Tls13_ECH_wire_sni_ex(1), TEST_SUCCESS); + return EXPECT_RESULT(); +} + static int test_wolfSSL_Tls13_ECH_disable_conn_ex(int enableServer, int enableClient) { @@ -40768,6 +40856,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_Tls13_ECH_new_config), TEST_DECL(test_wolfSSL_Tls13_ECH_trial_decrypt), TEST_DECL(test_wolfSSL_Tls13_ECH_GREASE), + TEST_DECL(test_wolfSSL_Tls13_ECH_wire_sni), TEST_DECL(test_wolfSSL_Tls13_ECH_disable_conn), TEST_DECL(test_wolfSSL_Tls13_ECH_long_SNI), TEST_DECL(test_wolfSSL_Tls13_ECH_HRR_rejection),