provided parameters found in legacy CH
diff --git a/lib/picotls.c b/lib/picotls.c
index 78fa0f1..1355ed7 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -286,6 +286,7 @@
 #define MAX_CLIENT_CIPHERS 32
 
 struct st_ptls_client_hello_t {
+    uint16_t legacy_version;
     const uint8_t *random_bytes;
     ptls_iovec_t legacy_session_id;
     struct {
@@ -331,7 +332,8 @@
             size_t count;
         } identities;
         unsigned ke_modes;
-        int early_data_indication;
+        unsigned early_data_indication : 1;
+        unsigned is_last_extension : 1;
     } psk;
     ptls_raw_extension_t unknown_extensions[MAX_UNKNOWN_EXTENSIONS + 1];
     unsigned status_request : 1;
@@ -3144,14 +3146,12 @@
     uint16_t exttype = 0;
     int ret;
 
-    { /* check protocol version */
-        uint16_t protver;
-        if ((ret = ptls_decode16(&protver, &src, end)) != 0)
-            goto Exit;
-        if (protver != 0x0303) {
-            ret = PTLS_ALERT_HANDSHAKE_FAILURE;
-            goto Exit;
-        }
+    /* decode protocol version (do not bare to decode something older than TLS 1.0) */
+    if ((ret = ptls_decode16(&ch->legacy_version, &src, end)) != 0)
+        goto Exit;
+    if (ch->legacy_version < 0x0301) {
+        ret = PTLS_ALERT_PROTOCOL_VERSION;
+        goto Exit;
     }
 
     /* skip random */
@@ -3201,6 +3201,7 @@
 
     /* decode extensions */
     decode_extensions(src, end, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, &exttype, {
+        ch->psk.is_last_extension = 0;
         if (tls->ctx->on_extension != NULL &&
             (ret = tls->ctx->on_extension->cb(tls->ctx->on_extension, tls, PTLS_HANDSHAKE_TYPE_CLIENT_HELLO, exttype,
                                               ptls_iovec_init(src, end - src)) != 0))
@@ -3379,6 +3380,7 @@
                     goto Exit;
                 }
             });
+            ch->psk.is_last_extension = 1;
         } break;
         case PTLS_EXTENSION_TYPE_PSK_KEY_EXCHANGE_MODES:
             ptls_decode_block(src, end, 1, {
@@ -3405,37 +3407,6 @@
         src = end;
     });
 
-    /* check if client hello make sense */
-    if (is_supported_version(ch->selected_version)) {
-        if (!(ch->compression_methods.count == 1 && ch->compression_methods.ids[0] == 0)) {
-            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
-            goto Exit;
-        }
-        /* esni */
-        if (ch->esni.cipher != NULL) {
-            if (ch->key_shares.base == NULL) {
-                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
-                goto Exit;
-            }
-        }
-        /* pre-shared key */
-        if (ch->psk.hash_end != NULL) {
-            /* PSK must be the last extension */
-            if (exttype != PTLS_EXTENSION_TYPE_PRE_SHARED_KEY) {
-                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
-                goto Exit;
-            }
-        } else {
-            if (ch->psk.early_data_indication) {
-                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
-                goto Exit;
-            }
-        }
-    } else {
-        ret = PTLS_ALERT_PROTOCOL_VERSION;
-        goto Exit;
-    }
-
     ret = 0;
 Exit:
     return ret;
@@ -3633,7 +3604,7 @@
                               additional_extensions                                                                                \
                           } while (0);                                                                                             \
                       })
-    struct st_ptls_client_hello_t ch = {NULL,   {NULL}, {NULL},     0,     {NULL}, {NULL},   {NULL}, {{0}},
+    struct st_ptls_client_hello_t ch = {0, NULL,   {NULL}, {NULL},     0,     {NULL}, {NULL},   {NULL}, {{0}},
                                         {NULL}, {NULL}, {{{NULL}}}, {{0}}, {{0}},  {{NULL}}, {NULL}, {{UINT16_MAX}}};
     struct {
         ptls_key_exchange_algorithm_t *algorithm;
@@ -3648,6 +3619,47 @@
     if ((ret = decode_client_hello(tls, &ch, message.base + PTLS_HANDSHAKE_HEADER_SIZE, message.base + message.len, properties)) !=
         0)
         goto Exit;
+
+    /* check if ClientHello makes sense */
+    if (!(ch.legacy_version == 0x0303 && is_supported_version(ch.selected_version))) {
+        if (!is_second_flight && tls->ctx->on_client_hello != NULL) {
+            ptls_on_client_hello_parameters_t params = {
+                .server_name = ch.server_name,
+                .raw_message = message,
+                .negotiated_protocols = {ch.alpn.list, ch.alpn.count},
+                .incompatible_version = 1,
+            };
+            if ((ret = tls->ctx->on_client_hello->cb(tls->ctx->on_client_hello, tls, &params)) != 0)
+                goto Exit;
+        }
+        ret = PTLS_ALERT_PROTOCOL_VERSION;
+        goto Exit;
+    }
+    if (!(ch.compression_methods.count == 1 && ch.compression_methods.ids[0] == 0)) {
+        ret = PTLS_ALERT_ILLEGAL_PARAMETER;
+        goto Exit;
+    }
+    /* esni */
+    if (ch.esni.cipher != NULL) {
+        if (ch.key_shares.base == NULL) {
+            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
+            goto Exit;
+        }
+    }
+    /* pre-shared key */
+    if (ch.psk.hash_end != NULL) {
+        /* PSK must be the last extension */
+        if (!ch.psk.is_last_extension) {
+            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
+            goto Exit;
+        }
+    } else {
+        if (ch.psk.early_data_indication) {
+            ret = PTLS_ALERT_ILLEGAL_PARAMETER;
+            goto Exit;
+        }
+    }
+
     if (tls->ctx->require_dhe_on_psk)
         ch.psk.ke_modes &= ~(1u << PTLS_PSK_KE_MODE_PSK);