@@ -13696,9 +13696,14 @@ static int test_ech_server_sni_callback(WOLFSSL* ssl, int* ad, void* arg)
1369613696
1369713697 /* reached by *_disable_conn test: expect name to be the public SNI when
1369813698 * client has ECH enabled, otherwise it should be the private SNI */
13699- if (arg != NULL && *(int*)arg == 1 &&
13700- XSTRCMP(name, echCbTestPublicName) == 0) {
13701- return 0;
13699+ if (arg != NULL && *(int*)arg == 1) {
13700+ if (XSTRCMP(name, echCbTestPublicName) == 0) {
13701+ return 0;
13702+ }
13703+ else {
13704+ *ad = WOLFSSL_AD_UNRECOGNIZED_NAME;
13705+ return fatal_return;
13706+ }
1370213707 }
1370313708 else if (XSTRCMP(name, echCbTestPrivateName) == 0) {
1370413709 return 0;
@@ -13884,7 +13889,9 @@ static int test_wolfSSL_Tls13_ECH_all_algos(void)
1388413889 return EXPECT_RESULT();
1388513890}
1388613891
13887- /* Test ECH when no private SNI is set */
13892+ /* Test ECH when no private SNI is set
13893+ * SNI is by default permissive so these should pass
13894+ * (inner SNI is not required by ECH, only the outer SNI is required) */
1388813895static int test_wolfSSL_Tls13_ECH_no_private_name(void)
1388913896{
1389013897 EXPECT_DECLS;
@@ -13927,9 +13934,9 @@ static int test_wolfSSL_Tls13_ECH_no_private_name(void)
1392713934
1392813935 ExpectIntNE(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), TEST_SUCCESS);
1392913936 ExpectIntEQ(wolfSSL_GetEchStatus(test_ctx.c_ssl),
13930- WOLFSSL_ECH_STATUS_NOT_OFFERED );
13937+ WOLFSSL_ECH_STATUS_REJECTED );
1393113938 ExpectIntEQ(wolfSSL_GetEchStatus(test_ctx.s_ssl),
13932- WOLFSSL_ECH_STATUS_NOT_OFFERED );
13939+ WOLFSSL_ECH_STATUS_REJECTED );
1393313940
1393413941 test_ssl_memio_cleanup(&test_ctx);
1393513942
@@ -13949,9 +13956,9 @@ static int test_wolfSSL_Tls13_ECH_no_private_name(void)
1394913956
1395013957 ExpectIntNE(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), TEST_SUCCESS);
1395113958 ExpectIntEQ(wolfSSL_GetEchStatus(test_ctx.c_ssl),
13952- WOLFSSL_ECH_STATUS_NOT_OFFERED );
13959+ WOLFSSL_ECH_STATUS_REJECTED );
1395313960 ExpectIntEQ(wolfSSL_GetEchStatus(test_ctx.s_ssl),
13954- WOLFSSL_ECH_STATUS_NOT_OFFERED );
13961+ WOLFSSL_ECH_STATUS_REJECTED );
1395513962
1395613963 test_ssl_memio_cleanup(&test_ctx);
1395713964
@@ -14058,6 +14065,39 @@ static int test_wolfSSL_Tls13_ECH_bad_configs_ex(int hrr, int sniCb)
1405814065
1405914066 test_ssl_memio_cleanup(&test_ctx);
1406014067
14068+
14069+ /* verify with double public SNI */
14070+
14071+ XMEMSET(&test_ctx, 0, sizeof(test_ctx));
14072+
14073+ test_ctx.s_cb.method = wolfTLSv1_3_server_method;
14074+ test_ctx.c_cb.method = wolfTLSv1_3_client_method;
14075+
14076+ test_ctx.s_cb.ctx_ready = test_ech_server_ctx_ready;
14077+ test_ctx.s_cb.ssl_ready = test_ech_server_ssl_ready;
14078+
14079+ ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS);
14080+
14081+ /* set public SNI for private SNI on client */
14082+ ExpectIntEQ(wolfSSL_SetEchConfigs(test_ctx.c_ssl, echCbTestConfigs,
14083+ echCbTestConfigsLen), WOLFSSL_SUCCESS);
14084+ ExpectIntEQ(wolfSSL_UseSNI(test_ctx.c_ssl, WOLFSSL_SNI_HOST_NAME,
14085+ echCbTestPublicName, (word16)XSTRLEN(echCbTestPublicName)),
14086+ WOLFSSL_SUCCESS);
14087+
14088+ if (hrr) {
14089+ ExpectIntEQ(wolfSSL_NoKeyShares(test_ctx.c_ssl), WOLFSSL_SUCCESS);
14090+ }
14091+ if (sniCb) {
14092+ wolfSSL_CTX_set_servername_callback(test_ctx.s_ctx,
14093+ test_ech_server_sni_callback);
14094+ }
14095+
14096+ ExpectIntNE(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), TEST_SUCCESS);
14097+ ExpectIntEQ(test_ctx.c_ssl->options.echAccepted, 0);
14098+
14099+ test_ssl_memio_cleanup(&test_ctx);
14100+
1406114101 return EXPECT_RESULT();
1406214102}
1406314103
@@ -14608,6 +14648,132 @@ static int test_wolfSSL_Tls13_ECH_disable_conn_ex(int enableServer,
1460814648 return EXPECT_RESULT();
1460914649}
1461014650
14651+ static const byte* test_find_bytes(const char* needle,
14652+ const byte* haystack, int hayLen)
14653+ {
14654+ int needleLen = (int)XSTRLEN(needle);
14655+ int i;
14656+ if (hayLen < needleLen)
14657+ return NULL;
14658+ for (i = 0; i <= hayLen - needleLen; i++) {
14659+ if (XMEMCMP(haystack + i, needle, needleLen) == 0)
14660+ return haystack + i;
14661+ }
14662+ return NULL;
14663+ }
14664+
14665+ /* The public name must be visible and the private name must not be visible */
14666+ static int test_wolfSSL_Tls13_ECH_wire_sni_ex(int hrr, int accept)
14667+ {
14668+ EXPECT_DECLS;
14669+ test_ssl_memio_ctx test_ctx;
14670+ WOLFSSL_CTX* tempCtx = NULL;
14671+ byte badConfig[128];
14672+ word32 badConfigLen = sizeof(badConfig);
14673+ const char* expectedSni =
14674+ accept ? echCbTestPrivateName : echCbTestPublicName;
14675+ void* sniName = NULL;
14676+
14677+ XMEMSET(&test_ctx, 0, sizeof(test_ctx));
14678+
14679+ test_ctx.s_cb.method = wolfTLSv1_3_server_method;
14680+ test_ctx.c_cb.method = wolfTLSv1_3_client_method;
14681+
14682+ test_ctx.s_cb.ctx_ready = test_ech_server_ctx_ready;
14683+ test_ctx.s_cb.ssl_ready = test_ech_server_ssl_ready;
14684+ /* Accept path uses the correct configs */
14685+ if (accept)
14686+ test_ctx.c_cb.ssl_ready = test_ech_client_ssl_ready;
14687+
14688+ ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS);
14689+
14690+ /* Reject path installs bad configs (with the correct public name) */
14691+ if (!accept) {
14692+ ExpectNotNull(tempCtx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
14693+ ExpectIntEQ(wolfSSL_CTX_GenerateEchConfig(tempCtx, echCbTestPublicName,
14694+ 0, 0, 0), WOLFSSL_SUCCESS);
14695+ ExpectIntEQ(wolfSSL_CTX_GetEchConfigs(tempCtx, badConfig,
14696+ &badConfigLen), WOLFSSL_SUCCESS);
14697+ wolfSSL_CTX_free(tempCtx);
14698+ ExpectIntEQ(wolfSSL_SetEchConfigs(test_ctx.c_ssl, badConfig,
14699+ badConfigLen), WOLFSSL_SUCCESS);
14700+ ExpectIntEQ(wolfSSL_UseSNI(test_ctx.c_ssl, WOLFSSL_SNI_HOST_NAME,
14701+ echCbTestPrivateName, (word16)XSTRLEN(echCbTestPrivateName)),
14702+ WOLFSSL_SUCCESS);
14703+ }
14704+
14705+ if (hrr)
14706+ ExpectIntEQ(wolfSSL_NoKeyShares(test_ctx.c_ssl), WOLFSSL_SUCCESS);
14707+
14708+ /* On reject, client aborts with ech_required and won't send a cert. */
14709+ if (!accept) {
14710+ wolfSSL_set_verify(test_ctx.s_ssl, WOLFSSL_VERIFY_NONE, NULL);
14711+ wolfSSL_set_verify(test_ctx.c_ssl, WOLFSSL_VERIFY_PEER, NULL);
14712+ }
14713+
14714+ /* client writes CH1 into s_buff */
14715+ ExpectIntEQ(wolfSSL_connect(test_ctx.c_ssl), WOLFSSL_FATAL_ERROR);
14716+ ExpectIntEQ(wolfSSL_get_error(test_ctx.c_ssl, WOLFSSL_FATAL_ERROR),
14717+ WOLFSSL_ERROR_WANT_READ);
14718+
14719+ /* CH1 wire bytes */
14720+ ExpectNotNull(test_find_bytes(echCbTestPublicName, test_ctx.s_buff,
14721+ test_ctx.s_len));
14722+ ExpectNull(test_find_bytes(echCbTestPrivateName, test_ctx.s_buff,
14723+ test_ctx.s_len));
14724+
14725+ if (hrr) {
14726+ /* server consumes CH1 and writes HRR into c_buff */
14727+ ExpectIntEQ(wolfSSL_accept(test_ctx.s_ssl), WOLFSSL_FATAL_ERROR);
14728+ ExpectIntEQ(wolfSSL_get_error(test_ctx.s_ssl, WOLFSSL_FATAL_ERROR),
14729+ WOLFSSL_ERROR_WANT_READ);
14730+ ExpectIntEQ(test_ctx.s_ssl->options.serverState,
14731+ SERVER_HELLO_RETRY_REQUEST_COMPLETE);
14732+
14733+ /* client reads HRR from c_buff and writes CH2 into s_buff */
14734+ ExpectIntEQ(wolfSSL_connect(test_ctx.c_ssl), WOLFSSL_FATAL_ERROR);
14735+ ExpectIntEQ(wolfSSL_get_error(test_ctx.c_ssl, WOLFSSL_FATAL_ERROR),
14736+ WOLFSSL_ERROR_WANT_READ);
14737+
14738+ /* CH2 wire bytes: same property must hold */
14739+ ExpectNotNull(test_find_bytes(echCbTestPublicName, test_ctx.s_buff,
14740+ test_ctx.s_len));
14741+ ExpectNull(test_find_bytes(echCbTestPrivateName, test_ctx.s_buff,
14742+ test_ctx.s_len));
14743+ }
14744+
14745+ /* drive remaining rounds and verify the correct SNI is authoritative */
14746+ if (accept) {
14747+ ExpectIntEQ(test_ssl_memio_do_handshake(&test_ctx, 10, NULL),
14748+ TEST_SUCCESS);
14749+ }
14750+ else {
14751+ ExpectIntNE(test_ssl_memio_do_handshake(&test_ctx, 10, NULL),
14752+ TEST_SUCCESS);
14753+ }
14754+
14755+ ExpectIntEQ(test_ctx.c_ssl->options.echAccepted, accept ? 1 : 0);
14756+ wolfSSL_SNI_GetRequest(test_ctx.c_ssl, WOLFSSL_SNI_HOST_NAME, &sniName);
14757+ ExpectStrEQ((const char*)sniName, expectedSni);
14758+ sniName = NULL;
14759+ wolfSSL_SNI_GetRequest(test_ctx.s_ssl, WOLFSSL_SNI_HOST_NAME, &sniName);
14760+ ExpectStrEQ((const char*)sniName, expectedSni);
14761+
14762+ test_ssl_memio_cleanup(&test_ctx);
14763+
14764+ return EXPECT_RESULT();
14765+ }
14766+
14767+ static int test_wolfSSL_Tls13_ECH_wire_sni(void)
14768+ {
14769+ EXPECT_DECLS;
14770+ ExpectIntEQ(test_wolfSSL_Tls13_ECH_wire_sni_ex(0, 0), TEST_SUCCESS);
14771+ ExpectIntEQ(test_wolfSSL_Tls13_ECH_wire_sni_ex(0, 1), TEST_SUCCESS);
14772+ ExpectIntEQ(test_wolfSSL_Tls13_ECH_wire_sni_ex(1, 0), TEST_SUCCESS);
14773+ ExpectIntEQ(test_wolfSSL_Tls13_ECH_wire_sni_ex(1, 1), TEST_SUCCESS);
14774+ return EXPECT_RESULT();
14775+ }
14776+
1461114777/* setup a server and client with ECH then disable on one, the other, or both.
1461214778 * Verifies that disabling ECH prevents ECH from being used and that the
1461314779 * public/private SNI's are verified correctly */
@@ -34456,6 +34622,7 @@ TEST_CASE testCases[] = {
3445634622 TEST_DECL(test_wolfSSL_Tls13_ECH_new_config),
3445734623 TEST_DECL(test_wolfSSL_Tls13_ECH_trial_decrypt),
3445834624 TEST_DECL(test_wolfSSL_Tls13_ECH_GREASE),
34625+ TEST_DECL(test_wolfSSL_Tls13_ECH_wire_sni),
3445934626 TEST_DECL(test_wolfSSL_Tls13_ECH_disable_conn),
3446034627 TEST_DECL(test_wolfSSL_Tls13_ECH_long_SNI),
3446134628 TEST_DECL(test_wolfSSL_Tls13_ECH_HRR_rejection),
0 commit comments