h2o / picotls

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

Possible integer overflow when checking obfuscated ticket age #509

Open huitema opened 6 months ago

huitema commented 6 months ago

The obfuscated ticket age is computed using the formula:

        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 computation of delta mixes 32 bit and 64 bit integers. Subtracting issue_at (64 bit) from now (64 bit) works -- there is a code further up protecting these parameters. Subtracting age_add (32 bit) from identity->obfuscated_ticket_age(32 bit) would work if the result was int32, but may produce unexpected results if the compiler decides to convert the data to int64_t.

Unexpected behavior can happen if age_add is large, e.g., one day, 86,400,000 millisecond, and the obfuscated ticket age is smaller than that, which can happen in 2% of cases.