diff options
author | Emilia Kasper <emilia@openssl.org> | 2015-09-10 16:32:51 +0200 |
---|---|---|
committer | Emilia Kasper <emilia@openssl.org> | 2015-09-28 16:00:25 +0200 |
commit | e711da714b0add2c9c3cb67a8c2500002fff9105 (patch) | |
tree | ac9dc16c15de5c38f313eed7fbbbbf9a3db49e9a | |
parent | 51cbee35162aecb4ca37ea9688461c79f975aff5 (diff) | |
download | openssl-e711da714b0add2c9c3cb67a8c2500002fff9105.tar.gz |
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 <matt@openssl.org>
-rw-r--r-- | ssl/s3_clnt.c | 23 |
1 files 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 |