h2o / picotls

TLS 1.3 implementation in C (master supports RFC8446 as well as draft-26, -27, -28)
527 stars 140 forks source link

Ticket issued time does not compensate for RTT #510

Open huitema opened 6 months ago

huitema commented 6 months ago

The freshness defined in RFC8446 defends against 0RTT replay. The implementation in picotls follows the RFC closely, but does not use the RTT to compensate for the "ticket age". This effectively disables 0RTT is the RTT is larger than 10 seconds, and prevents use of 0RTT in space communication when the delay is often measured in minutes or tens of minutes.

From RFC8446, section 8.3:

adjusted_creation_time = creation_time + estimated_RTT
expected_arrival_time = adjusted_creation_time + clients_ticket_age

Then: "_When a new ClientHello is received, the expected_arrivaltime is then compared against the current server wall clock time and if they differ by more than a certain amount, 0-RTT is rejected, though the 1-RTT handshake can be allowed to complete."

Picotls does not adjust the timer. The "issued_at" parameter is set in the first 8 bytes of the ticket as:

ptls_buffer_push64(buf, ctx->get_time->cb(ctx->get_time));

The comparison in try_psk_handshake is written as:

       *accept_early_data = 0;
        if (ch->psk.early_data_indication && can_accept_early_data) {
            /* accept early-data if abs(diff) between the reported age and the actual age is within += 10 seconds */
            int64_t delta = (now - issue_at) - (identity->obfuscated_ticket_age - age_add);
            if (delta < 0)
                delta = -delta;
            if (tls->ctx->max_early_data_size != 0 && delta <= PTLS_EARLY_DATA_MAX_DELAY)
                *accept_early_data = 1;
        }

The constant PTLS_EARLY_DATA_MAX_DELAY is set to 10 seconds. With that code, 0RTT will always be disabled if the RTT is larger than 10 seconds.