diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 036a531d7c996f9d43ae92b7fd8b19b8f54be7d4..2c93bd0dff9a08e526594803a414d729113eca94 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -2195,6 +2195,7 @@ int ssl3_get_new_session_ticket(SSL *s) { int ok, al, ret = 0; unsigned int ticklen; + unsigned long ticket_lifetime_hint; long n; PACKET pkt; @@ -2212,6 +2213,18 @@ int ssl3_get_new_session_ticket(SSL *s) goto f_err; } + if (!PACKET_get_net_4(&pkt, &ticket_lifetime_hint) + || !PACKET_get_net_2(&pkt, &ticklen) + || PACKET_remaining(&pkt) != ticklen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + /* Server is allowed to change its mind and send an empty ticket. */ + if (ticklen == 0) + return 1; + if (s->session->session_id_length > 0) { int i = s->session_ctx->session_cache_mode; SSL_SESSION *new_sess; @@ -2243,15 +2256,9 @@ int ssl3_get_new_session_ticket(SSL *s) s->session = new_sess; } - if (!PACKET_get_net_4(&pkt, &s->session->tlsext_tick_lifetime_hint) - || !PACKET_get_net_2(&pkt, &ticklen) - || PACKET_remaining(&pkt) != ticklen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); - goto f_err; - } OPENSSL_free(s->session->tlsext_tick); s->session->tlsext_ticklen = 0; + s->session->tlsext_tick = OPENSSL_malloc(ticklen); if (!s->session->tlsext_tick) { SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); @@ -2262,6 +2269,8 @@ int ssl3_get_new_session_ticket(SSL *s) SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); goto f_err; } + + s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; s->session->tlsext_ticklen = ticklen; /* * There are two ways to detect a resumed ticket session. One is to set