Commit 39bcfb12 authored by Matt Caswell's avatar Matt Caswell
Browse files

More ssl_session_dup fixes



Fix error handling in ssl_session_dup, as well as incorrect setting up of
the session ticket. Follow on from CVE-2015-1791.

Thanks to LibreSSL project for reporting these issues.

Conflicts:
	ssl/ssl_sess.c

Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
parent 50d30499
Loading
Loading
Loading
Loading
+20 −19
Original line number Diff line number Diff line
@@ -149,12 +149,22 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
    }
    memcpy(dest, src, sizeof(*dest));

#ifndef OPENSSL_NO_KRB5
    dest->krb5_client_princ_len = src->krb5_client_princ_len;
    if (src->krb5_client_princ_len > 0)
        memcpy(dest->krb5_client_princ, src->krb5_client_princ,
               src->krb5_client_princ_len);
    /*
     * Set the various pointers to NULL so that we can call SSL_SESSION_free in
     * the case of an error whilst halfway through constructing dest
     */
    dest->ciphers = NULL;
#ifndef OPENSSL_NO_TLSEXT
    dest->tlsext_hostname = NULL;
#endif
    dest->tlsext_tick = NULL;
    memset(&dest->ex_data, 0, sizeof(dest->ex_data));

    /* We deliberately don't copy the prev and next pointers */
    dest->prev = NULL;
    dest->next = NULL;

    dest->references = 1;

    if (src->sess_cert != NULL)
        CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
@@ -162,14 +172,10 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
    if (src->peer != NULL)
        CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);

    dest->references = 1;

    if(src->ciphers != NULL) {
        dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
        if (dest->ciphers == NULL)
            goto err;
    } else {
        dest->ciphers = NULL;
    }

    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
@@ -177,27 +183,22 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
        goto err;
    }

    /* We deliberately don't copy the prev and next pointers */
    dest->prev = NULL;
    dest->next = NULL;

#ifndef OPENSSL_NO_TLSEXT
    if (src->tlsext_hostname) {
        dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
        if (dest->tlsext_hostname == NULL) {
            goto err;
        }
    } else {
        dest->tlsext_hostname = NULL;
    }
#endif

    if (ticket != 0) {
        dest->tlsext_tick_lifetime_hint = src->tlsext_tick_lifetime_hint;
        dest->tlsext_ticklen = src->tlsext_ticklen;
        if((dest->tlsext_tick = OPENSSL_malloc(src->tlsext_ticklen)) == NULL) {
        dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
        if(dest->tlsext_tick == NULL)
            goto err;
        }
    } else {
        dest->tlsext_tick_lifetime_hint = 0;
        dest->tlsext_ticklen = 0;
    }

    return dest;