From e711da714b0add2c9c3cb67a8c2500002fff9105 Mon Sep 17 00:00:00 2001 From: Emilia Kasper Date: Thu, 10 Sep 2015 16:32:51 +0200 Subject: [PATCH] RT2772: accept empty SessionTicket RFC 5077 section 3.3 says: If the server determines that it does not want to include a ticket after it has included the SessionTicket extension in the ServerHello, then it sends a zero-length ticket in the NewSessionTicket handshake message. Previously the client would fail upon attempting to allocate a zero-length buffer. Now, we have the client ignore the empty ticket and keep the existing session. Reviewed-by: Matt Caswell --- ssl/s3_clnt.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 036a531d7c..2c93bd0dff 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 -- GitLab