Skip to content

Commit 61fd8f1

Browse files
kazuhoclaude
andcommitted
abort with illegal_parameter when SH rejects ECH after HRR accepted it
Per RFC 9849 Section 6.1.5, if HelloRetryRequest confirms ECH acceptance, the ServerHello MUST also confirm it; otherwise the client terminates with an illegal_parameter alert. Previously, the client silently demoted state from ACCEPTED back to OFFERED and fell back to the outer ClientHello. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent ba911a8 commit 61fd8f1

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

lib/picotls.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2831,12 +2831,16 @@ static int client_ech_select_hello(ptls_t *tls, ptls_iovec_t message, size_t con
28312831
if ((ret = ech_calc_confirmation(tls->key_schedule, confirm_hash_expected, tls->ech.inner_client_random, label, message)) !=
28322832
0)
28332833
goto Exit;
2834-
tls->ech.state = ptls_mem_equal(confirm_hash_delivered, confirm_hash_expected, sizeof(confirm_hash_delivered))
2835-
? PTLS_ECH_STATE_ACCEPTED
2836-
: PTLS_ECH_STATE_OFFERED;
2834+
int accepted = ptls_mem_equal(confirm_hash_delivered, confirm_hash_expected, sizeof(confirm_hash_delivered));
28372835
memcpy(message.base + confirm_hash_off, confirm_hash_delivered, sizeof(confirm_hash_delivered));
2838-
if (tls->ech.state == PTLS_ECH_STATE_ACCEPTED)
2836+
if (accepted) {
2837+
tls->ech.state = PTLS_ECH_STATE_ACCEPTED;
28392838
goto Exit;
2839+
} else if (tls->ech.state == PTLS_ECH_STATE_ACCEPTED) {
2840+
/* Per RFC 9849 Section 6.1.5: if HRR confirmed ECH acceptance, ServerHello MUST also confirm it. */
2841+
ret = PTLS_ALERT_ILLEGAL_PARAMETER;
2842+
goto Exit;
2843+
}
28402844
}
28412845

28422846
/* dispose ECH AEAD state to indicate rejection, adopting outer CH for the rest of the handshake */

0 commit comments

Comments
 (0)