we can say that ECH is used whenever ECH AEAD context is available
diff --git a/include/picotls.h b/include/picotls.h
index d4024c7..118549b 100644
--- a/include/picotls.h
+++ b/include/picotls.h
@@ -632,7 +632,6 @@
const uint8_t *list;
size_t count;
} server_certificate_types;
- unsigned ech_is_inner_ch : 1;
/**
* set to 1 if ClientHello is too old (or too new) to be handled by picotls
*/
diff --git a/lib/picotls.c b/lib/picotls.c
index 61a2d41..9b257f9 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -3721,12 +3721,12 @@
}
/* Wrapper function for invoking the on_client_hello callback, taking an exhaustive list of parameters as arguments. The intention
-* is to not miss setting them as we add new parameters to the struct. */
+ * is to not miss setting them as we add new parameters to the struct. */
static inline int call_on_client_hello_cb(ptls_t *tls, ptls_iovec_t server_name, ptls_iovec_t raw_message, ptls_iovec_t *alpns,
size_t num_alpns, const uint16_t *sig_algos, size_t num_sig_algos,
const uint16_t *cert_comp_algos, size_t num_cert_comp_algos,
const uint16_t *cipher_suites, size_t num_cipher_suites, const uint8_t *server_cert_types,
- size_t num_server_cert_types, int ech, int incompatible_version)
+ size_t num_server_cert_types, int incompatible_version)
{
if (tls->ctx->on_client_hello == NULL)
return 0;
@@ -3738,7 +3738,6 @@
{cert_comp_algos, num_cert_comp_algos},
{cipher_suites, num_cipher_suites},
{server_cert_types, num_server_cert_types},
- ech,
incompatible_version};
return tls->ctx->on_client_hello->cb(tls->ctx->on_client_hello, tls, ¶ms);
}
@@ -3762,7 +3761,7 @@
if (!is_second_flight) {
int ret;
if ((ret = call_on_client_hello_cb(tls_cbarg, ch->server_name, raw_message, ch->alpn.list, ch->alpn.count, NULL, 0,
- NULL, 0, NULL, 0, NULL, 0, 0, 1)) != 0)
+ NULL, 0, NULL, 0, NULL, 0, 1)) != 0)
return ret;
}
return PTLS_ALERT_PROTOCOL_VERSION;
@@ -4022,7 +4021,7 @@
enum { HANDSHAKE_MODE_FULL, HANDSHAKE_MODE_PSK, HANDSHAKE_MODE_PSK_DHE } mode;
size_t psk_index = SIZE_MAX;
ptls_iovec_t pubkey = {0}, ecdh_secret = {0};
- int accept_early_data = 0, accept_ech = 0, is_second_flight = tls->state == PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO, ret;
+ int accept_early_data = 0, is_second_flight = tls->state == PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO, ret;
ptls_buffer_init(&ech.ch_inner, "", 0);
@@ -4100,7 +4099,6 @@
if ((ret = check_client_hello_constraints(tls->ctx, ch, is_second_flight ? tls->client_random.inner : NULL, 1,
message, tls)) != 0)
goto Exit;
- accept_ech = 1;
if (!is_second_flight)
memcpy(tls->client_random.inner, ch->random_bytes, PTLS_HELLO_RANDOM_SIZE);
}
@@ -4120,8 +4118,7 @@
if ((ret = call_on_client_hello_cb(tls, server_name, message, ch->alpn.list, ch->alpn.count, ch->signature_algorithms.list,
ch->signature_algorithms.count, ch->cert_compression_algos.list,
ch->cert_compression_algos.count, ch->client_ciphers.list, ch->client_ciphers.count,
- ch->server_certificate_types.list, ch->server_certificate_types.count, accept_ech, 0)) !=
- 0)
+ ch->server_certificate_types.list, ch->server_certificate_types.count, 0)) != 0)
goto Exit;
if (!certificate_type_exists(ch->server_certificate_types.list, ch->server_certificate_types.count,
tls->ctx->use_raw_public_keys ? PTLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY
@@ -4214,7 +4211,7 @@
/* Either send a stateless retry (w. cookies) or a stateful one. When sending the latter, run the state machine. At the
* moment, stateless retry is disabled when ECH is used (do we need to support it?). */
- int retry_uses_cookie = properties != NULL && properties->server.retry_uses_cookie && !accept_ech;
+ int retry_uses_cookie = properties != NULL && properties->server.retry_uses_cookie && !ptls_is_ech_handshake(tls);
if (!retry_uses_cookie) {
key_schedule_transform_post_ch1hash(tls->key_schedule);
key_schedule_extract(tls->key_schedule, ptls_iovec_init(NULL, 0));
@@ -4224,7 +4221,7 @@
tls->key_schedule, key_share.algorithm != NULL ? NULL : negotiated_group,
{
ptls_buffer_t *sendbuf = emitter->buf;
- if (accept_ech) {
+ if (ptls_is_ech_handshake(tls)) {
buffer_push_extension(sendbuf, PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO, {
if ((ret = ptls_buffer_reserve(sendbuf, 8)) != 0)
goto Exit;
@@ -4268,14 +4265,12 @@
}
},
{
- if (ech_confirm_off != 0) {
- assert(accept_ech);
- if ((ret = ech_calc_confirmation(
- tls->key_schedule, emitter->buf->base + ech_confirm_off, tls->client_random.inner,
- ECH_CONFIRMATION_HRR,
- ptls_iovec_init(emitter->buf->base + sh_start_off, emitter->buf->off - sh_start_off))) != 0)
- goto Exit;
- }
+ if (ech_confirm_off != 0 &&
+ (ret = ech_calc_confirmation(
+ tls->key_schedule, emitter->buf->base + ech_confirm_off, tls->client_random.inner,
+ ECH_CONFIRMATION_HRR,
+ ptls_iovec_init(emitter->buf->base + sh_start_off, emitter->buf->off - sh_start_off))) != 0)
+ goto Exit;
});
if (retry_uses_cookie) {
if ((ret = push_change_cipher_spec(tls, emitter)) != 0)
@@ -4365,7 +4360,7 @@
{
tls->ctx->random_bytes(emitter->buf->base + emitter->buf->off, PTLS_HELLO_RANDOM_SIZE);
/* when accepting CHInner, last 8 byte of SH.random is zero for the handshake transcript */
- if (accept_ech) {
+ if (ptls_is_ech_handshake(tls)) {
ech_confirm_off = emitter->buf->off + PTLS_HELLO_RANDOM_SIZE - 8;
memset(emitter->buf->base + ech_confirm_off, 0, 8);
}
@@ -4384,14 +4379,11 @@
}
},
{
- if (ech_confirm_off != 0) {
- assert(accept_ech);
- if ((ret = ech_calc_confirmation(
- tls->key_schedule, emitter->buf->base + ech_confirm_off, tls->client_random.inner,
- ECH_CONFIRMATION_SERVER_HELLO,
- ptls_iovec_init(emitter->buf->base + sh_start_off, emitter->buf->off - sh_start_off))) != 0)
- goto Exit;
- }
+ if (ech_confirm_off != 0 && (ret = ech_calc_confirmation(tls->key_schedule, emitter->buf->base + ech_confirm_off,
+ tls->client_random.inner, ECH_CONFIRMATION_SERVER_HELLO,
+ ptls_iovec_init(emitter->buf->base + sh_start_off,
+ emitter->buf->off - sh_start_off))) != 0)
+ goto Exit;
});
}
@@ -4508,11 +4500,6 @@
}
Exit:
- /* acceptance of ECH is signalled as the persistence of the ech AEAD context */
- if (!accept_ech && tls->server.ech.aead != NULL) {
- ptls_aead_free(tls->server.ech.aead);
- tls->server.ech.aead = NULL;
- }
free(pubkey.base);
if (ecdh_secret.base != NULL) {
ptls_clear_memory(ecdh_secret.base, ecdh_secret.len);