From: Matt Caswell Date: Tue, 17 Jan 2017 10:43:37 +0000 (+0000) Subject: Add support for the age_add field X-Git-Tag: OpenSSL_1_1_1-pre1~2571 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=fc24f0bf45085c0f6272af8bb3ff03602face505;p=oweals%2Fopenssl.git Add support for the age_add field Update SSL_SESSION to store the age_add and use it where needed. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2259) --- diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index 401aeb5eaf..ced6a51f4b 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c @@ -55,6 +55,7 @@ typedef struct { long verify_result; ASN1_OCTET_STRING *tlsext_hostname; long tlsext_tick_lifetime_hint; + long tlsext_tick_age_add; ASN1_OCTET_STRING *tlsext_tick; #ifndef OPENSSL_NO_PSK ASN1_OCTET_STRING *psk_identity_hint; @@ -89,7 +90,8 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = { #ifndef OPENSSL_NO_SRP ASN1_EXP_OPT(SSL_SESSION_ASN1, srp_username, ASN1_OCTET_STRING, 12), #endif - ASN1_EXP_OPT(SSL_SESSION_ASN1, flags, ZLONG, 13) + ASN1_EXP_OPT(SSL_SESSION_ASN1, flags, ZLONG, 13), + ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick_age_add, ZLONG, 14) } static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1) @@ -190,6 +192,7 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) } if (in->ext.tick_lifetime_hint > 0) as.tlsext_tick_lifetime_hint = in->ext.tick_lifetime_hint; + as.tlsext_tick_age_add = in->ext.tick_age_add; #ifndef OPENSSL_NO_PSK ssl_session_sinit(&as.psk_identity_hint, &psk_identity_hint, in->psk_identity_hint); @@ -326,6 +329,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, #endif ret->ext.tick_lifetime_hint = as->tlsext_tick_lifetime_hint; + ret->ext.tick_age_add = as->tlsext_tick_age_add; if (as->tlsext_tick) { ret->ext.tick = as->tlsext_tick->data; ret->ext.ticklen = as->tlsext_tick->length; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 7e5246c9f3..e9bb4455f1 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -574,6 +574,7 @@ struct ssl_session_st { size_t ticklen; /* Session ticket length */ /* Session lifetime hint in seconds */ unsigned long tick_lifetime_hint; + uint32_t tick_age_add; int tick_identity; } ext; # ifndef OPENSSL_NO_SRP diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index c6a8124c9e..366462ee85 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -694,6 +694,11 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, now = (uint32_t)time(NULL); ages = now - (uint32_t)s->session->time; + if (s->session->ext.tick_lifetime_hint < ages) { + /* Ticket is too old. Ignore it. */ + return 1; + } + /* * Calculate age in ms. We're just doing it to nearest second. Should be * good enough. @@ -708,7 +713,11 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx, return 1; } - /* TODO(TLS1.3): Obfuscate the age here */ + /* + * Obfuscate the age. Overflow here is fine, this addition is supposed to + * be mod 2^32. + */ + agems += s->session->ext.tick_age_add; cipher = ssl3_get_cipher_by_id(s->session->cipher_id); if (cipher == NULL) { diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index d5d622c1c5..3bcd5902c1 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -48,6 +48,7 @@ */ #include +#include #include "../ssl_locl.h" #include "statem_locl.h" #include @@ -2195,12 +2196,12 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) { int al; unsigned int ticklen; - unsigned long ticket_lifetime_hint, add_age; + unsigned long ticket_lifetime_hint, age_add; unsigned int sess_len; RAW_EXTENSION *exts = NULL; if (!PACKET_get_net_4(pkt, &ticket_lifetime_hint) - || (SSL_IS_TLS13(s) && !PACKET_get_net_4(pkt, &add_age)) + || (SSL_IS_TLS13(s) && !PACKET_get_net_4(pkt, &age_add)) || !PACKET_get_net_2(pkt, &ticklen) || (!SSL_IS_TLS13(s) && PACKET_remaining(pkt) != ticklen) || (SSL_IS_TLS13(s) && (ticklen == 0 @@ -2243,6 +2244,12 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session = new_sess; } + /* + * Technically the cast to long here is not guaranteed by the C standard - + * but we use it elsewhere, so this should be ok. + */ + s->session->time = (long)time(NULL); + OPENSSL_free(s->session->ext.tick); s->session->ext.tick = NULL; s->session->ext.ticklen = 0; @@ -2259,6 +2266,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) } s->session->ext.tick_lifetime_hint = ticket_lifetime_hint; + s->session->ext.tick_age_add = age_add; s->session->ext.ticklen = ticklen; if (SSL_IS_TLS13(s)) { diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 20e521a9d6..98171b948c 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -3250,6 +3250,12 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) uint32_t age_add; } age_add_u; + if (SSL_IS_TLS13(s)) { + if (RAND_bytes(age_add_u.age_add_c, sizeof(age_add_u)) <= 0) + goto err; + s->session->ext.tick_age_add = age_add_u.age_add; + } + /* get session encoding length */ slen_full = i2d_SSL_SESSION(s->session, NULL); /* @@ -3341,10 +3347,6 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) sizeof(tctx->ext.tick_key_name)); } - if (SSL_IS_TLS13(s) && RAND_bytes(age_add_u.age_add_c, - sizeof(age_add_u)) <= 0) - goto err; - /* * Ticket lifetime hint (advisory only): We leave this unspecified * for resumed session (for simplicity), and guess that tickets for