X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Fstatem%2Fextensions_srvr.c;h=076a635d24d0e27b2c6f1675c973315d30e577e3;hb=1ee4b98e695cd041da931c10fbdaf82f0ee0f268;hp=ecfd00b098da489e27342620447565a833c69e97;hpb=28a31a0a10f41ef855cabab4e18c994c44225125;p=oweals%2Fopenssl.git diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index ecfd00b098..076a635d24 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -661,6 +661,18 @@ int tls_parse_ctos_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } + +int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) +{ + if (PACKET_remaining(pkt) != 0) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + return 1; +} + int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) { @@ -669,6 +681,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSL_SESSION *sess = NULL; unsigned int id, i; const EVP_MD *md = NULL; + uint32_t ticket_age = 0, now, agesec, agems; /* * If we have no PSK kex mode that we recognise then we can't resume so @@ -685,16 +698,16 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, for (id = 0; PACKET_remaining(&identities) != 0; id++) { PACKET identity; - unsigned long ticket_age; + unsigned long ticket_agel; int ret; if (!PACKET_get_length_prefixed_2(&identities, &identity) - || !PACKET_get_net_4(&identities, &ticket_age)) { + || !PACKET_get_net_4(&identities, &ticket_agel)) { *al = SSL_AD_DECODE_ERROR; return 0; } - /* TODO(TLS1.3): Should we validate the ticket age? */ + ticket_age = (uint32_t)ticket_agel; ret = tls_decrypt_ticket(s, PACKET_data(&identity), PACKET_remaining(&identity), NULL, 0, &sess); @@ -753,10 +766,37 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } sess->ext.tick_identity = id; + + now = (uint32_t)time(NULL); + agesec = now - (uint32_t)sess->time; + agems = agesec * (uint32_t)1000; + ticket_age -= sess->ext.tick_age_add; + + + /* + * For simplicity we do our age calculations in seconds. If the client does + * it in ms then it could appear that their ticket age is longer than ours + * (our ticket age calculation should always be slightly longer than the + * client's due to the network latency). Therefore we add 1000ms to our age + * calculation to adjust for rounding errors. + */ + if (sess->timeout >= agesec + && agems / (uint32_t)1000 == agesec + && ticket_age <= agems + 1000 + && ticket_age + TICKET_AGE_ALLOWANCE >= agems + 1000) { + /* + * Ticket age is within tolerance and not expired. We allow it for early + * data + */ + s->ext.early_data_ok = 1; + } + + SSL_SESSION_free(s->session); s->session = sess; return 1; err: + SSL_SESSION_free(sess); return 0; } @@ -1090,6 +1130,37 @@ int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, unsigned int context, return 1; } +int tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) +{ + if (context == EXT_TLS1_3_NEW_SESSION_TICKET) { + if (s->max_early_data == 0) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes_u32(pkt, s->max_early_data) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; + } + + if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + int tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) {