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>
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user