From: Matt Caswell Date: Thu, 11 Jun 2015 00:30:06 +0000 (+0100) Subject: More ssl_session_dup fixes X-Git-Tag: OpenSSL_1_0_0s~6 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=db96b5ab761fb97633dde9aec62c0032743e88f8;p=oweals%2Fopenssl.git 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: Tim Hudson --- diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 1fb682a9b3..9fcb6326de 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -238,12 +238,36 @@ 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 + */ +#ifndef OPENSSL_NO_PSK + dest->psk_identity_hint = NULL; + dest->psk_identity = NULL; +#endif + dest->ciphers = NULL; +#ifndef OPENSSL_NO_TLSEXT + dest->tlsext_hostname = NULL; +# ifndef OPENSSL_NO_EC + dest->tlsext_ecpointformatlist = NULL; + dest->tlsext_ellipticcurvelist = NULL; +# endif #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); + + if (src->peer != NULL) + CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); #ifndef OPENSSL_NO_PSK if (src->psk_identity_hint) { @@ -251,33 +275,19 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) if (dest->psk_identity_hint == NULL) { goto err; } - } else { - dest->psk_identity_hint = NULL; } if (src->psk_identity) { dest->psk_identity = BUF_strdup(src->psk_identity); if (dest->psk_identity == NULL) { goto err; } - } else { - dest->psk_identity = NULL; } #endif - if (src->sess_cert != NULL) - CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); - - 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, @@ -285,18 +295,12 @@ 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; } # ifndef OPENSSL_NO_EC if (src->tlsext_ecpointformatlist) { @@ -305,8 +309,6 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) src->tlsext_ecpointformatlist_length); if (dest->tlsext_ecpointformatlist == NULL) goto err; - dest->tlsext_ecpointformatlist_length = - src->tlsext_ecpointformatlist_length; } if (src->tlsext_ellipticcurvelist) { dest->tlsext_ellipticcurvelist = @@ -314,18 +316,17 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) src->tlsext_ellipticcurvelist_length); if (dest->tlsext_ellipticcurvelist == NULL) goto err; - dest->tlsext_ellipticcurvelist_length = - src->tlsext_ellipticcurvelist_length; } # endif #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;