@@ -840,17 +840,10 @@ static int save_client_hello(ptls_on_client_hello_t *self, ptls_t *tls, ptls_on_
840840 return 0 ;
841841}
842842
843- enum test_ech_mode {
844- TEST_ECH_NONE ,
845- TEST_ECH_REAL ,
846- TEST_ECH_GREASE
847- };
848-
849843/**
850- * Sentinel value for `ctx->ech.client.ciphers` indicating grease mode. `get_test_ech_mode` recognizes this pointer and returns
851- * `TEST_ECH_GREASE`. Contains a single cipher entry sufficient for `client_setup_ech_grease`.
844+ * What ECH configs the client should send. `base == NULL` means no ECH, `len == 0` means grease, `len > 0` means real ECH.
852845 */
853- static ptls_hpke_cipher_suite_t * grease_ciphers [ 2 ] ;
846+ static ptls_iovec_t test_client_ech_configs = { NULL } ;
854847
855848enum {
856849 TEST_HANDSHAKE_1RTT ,
@@ -867,19 +860,6 @@ static int on_extension_cb(ptls_on_extension_t *self, ptls_t *tls, uint8_t hstyp
867860 return 0 ;
868861}
869862
870- static enum test_ech_mode get_test_ech_mode (ptls_context_t * ctx , int is_server )
871- {
872- if (is_server ) {
873- return ctx -> ech .server .create_opener != NULL ? TEST_ECH_REAL : TEST_ECH_NONE ;
874- } else {
875- if (ctx -> ech .client .ciphers == NULL )
876- return TEST_ECH_NONE ;
877- if (ctx -> ech .client .ciphers == grease_ciphers )
878- return TEST_ECH_GREASE ;
879- return TEST_ECH_REAL ;
880- }
881- }
882-
883863static void check_clone (ptls_t * src , ptls_t * dest )
884864{
885865 ok (src -> cipher_suite -> hash -> digest_size == dest -> cipher_suite -> hash -> digest_size );
@@ -956,17 +936,9 @@ static void test_handshake(ptls_iovec_t ticket, int mode, int expect_ticket, int
956936 ptls_set_server_name (client , "test.example.com" , 0 );
957937 }
958938
959- switch (get_test_ech_mode (ctx , 0 )) {
960- case TEST_ECH_REAL :
961- ptls_set_server_name (client , "test.example.com" , 0 );
962- client_hs_prop .client .ech .configs = ptls_iovec_init (ECH_CONFIG_LIST , sizeof (ECH_CONFIG_LIST ) - 1 );
963- break ;
964- case TEST_ECH_GREASE :
939+ if (test_client_ech_configs .base != NULL ) {
965940 ptls_set_server_name (client , "test.example.com" , 0 );
966- client_hs_prop .client .ech .configs = ptls_iovec_init ("" , 0 );
967- break ;
968- default :
969- break ;
941+ client_hs_prop .client .ech .configs = test_client_ech_configs ;
970942 }
971943
972944 static ptls_on_extension_t cb = {on_extension_cb };
@@ -1040,7 +1012,7 @@ static void test_handshake(ptls_iovec_t ticket, int mode, int expect_ticket, int
10401012 ok (sbuf .off != 0 );
10411013 if (check_ch ) {
10421014 ok (ptls_get_server_name (server ) != NULL );
1043- if (get_test_ech_mode ( ctx , 0 ) != TEST_ECH_NONE && get_test_ech_mode ( ctx_peer , 1 ) == TEST_ECH_NONE ) {
1015+ if (test_client_ech_configs . base != NULL && ctx_peer -> ech . server . create_opener == NULL ) {
10441016 /* server should be using CHouter.sni that includes the public name of the ECH extension */
10451017 ok (strcmp (ptls_get_server_name (server ), "example.com" ) == 0 );
10461018 } else {
@@ -1198,7 +1170,7 @@ static void test_handshake(ptls_iovec_t ticket, int mode, int expect_ticket, int
11981170 }
11991171
12001172 /* original_server is used for the server-side checks because handshake data is never migrated */
1201- if (get_test_ech_mode ( ctx_peer , 1 ) != TEST_ECH_NONE && get_test_ech_mode ( ctx , 0 ) == TEST_ECH_REAL ) {
1173+ if (ctx_peer -> ech . server . create_opener != NULL && test_client_ech_configs . len > 0 ) {
12021174 ok (ptls_is_ech_handshake (client , NULL , NULL , NULL ));
12031175 ok (ptls_is_ech_handshake (original_server , NULL , NULL , NULL ));
12041176 } else {
@@ -1438,21 +1410,14 @@ static void test_resumption(int different_preferred_key_share, int require_clien
14381410static void test_grease_resumption (void )
14391411{
14401412 ptls_ech_create_opener_t * orig_create_opener = ctx_peer -> ech .server .create_opener ;
1441- ptls_hpke_cipher_suite_t * * orig_ciphers = ctx -> ech .client .ciphers ;
1442-
1443- if (get_test_ech_mode (ctx , 0 ) == TEST_ECH_NONE )
1444- return ;
1445-
1446- /* populate grease_ciphers (once) with a single entry from the real list */
1447- if (grease_ciphers [0 ] == NULL )
1448- grease_ciphers [0 ] = orig_ciphers [0 ];
1413+ ptls_iovec_t orig_configs = test_client_ech_configs ;
14491414
14501415 ctx_peer -> ech .server .create_opener = NULL ;
1451- ctx -> ech . client . ciphers = grease_ciphers ;
1416+ test_client_ech_configs = ptls_iovec_init ( "" , 0 ) ;
14521417
14531418 test_resumption (0 , 0 );
14541419
1455- ctx -> ech . client . ciphers = orig_ciphers ;
1420+ test_client_ech_configs = orig_configs ;
14561421 ctx_peer -> ech .server .create_opener = orig_create_opener ;
14571422}
14581423
@@ -2133,17 +2098,17 @@ static void test_all_handshakes_core(void)
21332098 subtest ("full-handshake+client-auth" , test_full_handshake_with_client_authentication );
21342099 subtest ("hrr-handshake" , test_hrr_handshake );
21352100 /* resumption does not work when the client offers ECH but the server does not recognize that */
2136- if (!(get_test_ech_mode ( ctx , 0 ) != TEST_ECH_NONE && get_test_ech_mode ( ctx_peer , 1 ) == TEST_ECH_NONE )) {
2101+ if (!(test_client_ech_configs . base != NULL && ctx_peer -> ech . server . create_opener == NULL )) {
21372102 subtest ("resumption" , test_resumption , 0 , 0 );
21382103 if (ctx != ctx_peer )
21392104 subtest ("resumption-different-preferred-key-share" , test_resumption , 1 , 0 );
21402105 subtest ("resumption-with-client-authentication" , test_resumption , 0 , 1 );
21412106 }
2142- if (get_test_ech_mode ( ctx , 0 ) != TEST_ECH_NONE )
2107+ if (test_client_ech_configs . base != NULL )
21432108 subtest ("resumption-with-grease" , test_grease_resumption );
21442109 subtest ("async-sign-certificate" , test_async_sign_certificate );
21452110 subtest ("enforce-retry-stateful" , test_enforce_retry_stateful );
2146- if (!(get_test_ech_mode ( ctx_peer , 1 ) != TEST_ECH_NONE && get_test_ech_mode ( ctx , 0 ) != TEST_ECH_NONE )) {
2111+ if (!(ctx_peer -> ech . server . create_opener != NULL && test_client_ech_configs . base != NULL )) {
21472112 subtest ("hrr-stateless-handshake" , test_hrr_stateless_handshake );
21482113 subtest ("enforce-retry-stateless" , test_enforce_retry_stateless );
21492114 subtest ("stateless-hrr-aad-change" , test_stateless_hrr_aad_change );
@@ -2165,26 +2130,24 @@ static void test_all_handshakes(void)
21652130 ctx -> sign_certificate = & client_sc ;
21662131 }
21672132
2168- struct {
2169- ptls_ech_create_opener_t * create_opener ;
2170- ptls_hpke_cipher_suite_t * * client_ciphers ;
2171- } orig_ech = {ctx_peer -> ech .server .create_opener , ctx -> ech .client .ciphers };
2133+ ptls_ech_create_opener_t * orig_create_opener = ctx_peer -> ech .server .create_opener ;
2134+ int client_supports_ech = ctx -> ech .client .ciphers != NULL ;
21722135
21732136 /* first run tests wo. ECH */
21742137 ctx_peer -> ech .server .create_opener = NULL ;
2175- ctx -> ech .client .ciphers = NULL ;
21762138 subtest ("no-ech" , test_all_handshakes_core );
2177- ctx_peer -> ech .server .create_opener = orig_ech .create_opener ;
2178- ctx -> ech .client .ciphers = orig_ech .client_ciphers ;
2139+ ctx_peer -> ech .server .create_opener = orig_create_opener ;
21792140
2180- if (get_test_ech_mode (ctx_peer , 1 ) != TEST_ECH_NONE && get_test_ech_mode (ctx , 0 ) != TEST_ECH_NONE ) {
2141+ if (orig_create_opener != NULL && client_supports_ech ) {
2142+ test_client_ech_configs = ptls_iovec_init (ECH_CONFIG_LIST , sizeof (ECH_CONFIG_LIST ) - 1 );
21812143 subtest ("ech" , test_all_handshakes_core );
21822144 if (ctx != ctx_peer ) {
2183- ctx -> ech . client . ciphers = NULL ;
2145+ test_client_ech_configs = ptls_iovec_init ( NULL , 0 ) ;
21842146 subtest ("ech (server-only)" , test_all_handshakes_core );
2185- ctx -> ech . client . ciphers = orig_ech . client_ciphers ;
2147+ test_client_ech_configs = ptls_iovec_init ( ECH_CONFIG_LIST , sizeof ( ECH_CONFIG_LIST ) - 1 ) ;
21862148 }
21872149 subtest ("ech-config-mismatch" , test_ech_config_mismatch );
2150+ test_client_ech_configs = ptls_iovec_init (NULL , 0 );
21882151 }
21892152
21902153 ctx_peer -> sign_certificate = sc_orig ;
0 commit comments