Merge branch 'f22' into f21

This commit is contained in:
Tomas Mraz 2015-06-15 17:10:14 +02:00
commit c0a499bb31
6 changed files with 472 additions and 1 deletions

View File

@ -0,0 +1,103 @@
diff -up openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read openssl-1.0.1e/crypto/x509/x509_vfy.c
--- openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read 2015-05-25 12:03:41.000000000 +0200
+++ openssl-1.0.1e/crypto/x509/x509_vfy.c 2015-06-09 15:01:51.688640453 +0200
@@ -1702,49 +1702,92 @@ int X509_cmp_time(const ASN1_TIME *ctm,
ASN1_TIME atm;
long offset;
char buff1[24],buff2[24],*p;
- int i,j;
+ int i, j, remaining;
p=buff1;
- i=ctm->length;
+ remaining=ctm->length;
str=(char *)ctm->data;
+ /*
+ * Note that the following (historical) code allows much more slack in the
+ * time format than RFC5280. In RFC5280, the representation is fixed:
+ * UTCTime: YYMMDDHHMMSSZ
+ * GeneralizedTime: YYYYMMDDHHMMSSZ
+ */
if (ctm->type == V_ASN1_UTCTIME)
{
- if ((i < 11) || (i > 17)) return 0;
+ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+ int min_length = sizeof("YYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
memcpy(p,str,10);
p+=10;
str+=10;
+ remaining -= 10;
}
else
{
- if (i < 13) return 0;
+ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+ int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
memcpy(p,str,12);
p+=12;
str+=12;
+ remaining -= 12;
}
if ((*str == 'Z') || (*str == '-') || (*str == '+'))
{ *(p++)='0'; *(p++)='0'; }
else
{
+ /* SS (seconds) */
+ if (remaining < 2)
+ return 0;
*(p++)= *(str++);
*(p++)= *(str++);
- /* Skip any fractional seconds... */
- if (*str == '.')
+ remaining -= 2;
+ /*
+ * Skip any (up to three) fractional seconds...
+ * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+ * Can we just kill them altogether?
+ */
+ if (remaining && *str == '.')
{
str++;
- while ((*str >= '0') && (*str <= '9')) str++;
+ remaining--;
+ for (i = 0; i < 3 && remaining; i++, str++, remaining--)
+ {
+ if (*str < '0' || *str > '9')
+ break;
+ }
}
}
*(p++)='Z';
*(p++)='\0';
+ /* We now need either a terminating 'Z' or an offset. */
+ if (!remaining)
+ return 0;
if (*str == 'Z')
+ {
+ if (remaining != 1)
+ return 0;
offset=0;
+ }
else
{
+ /* (+-)HHMM */
if ((*str != '+') && (*str != '-'))
return 0;
+ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+ if (remaining != 5)
+ return 0;
+ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+ return 0;
offset=((str[1]-'0')*10+(str[2]-'0'))*60;
offset+=(str[3]-'0')*10+(str[4]-'0');
if (*str == '-')

View File

@ -0,0 +1,55 @@
diff -up openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.missing-content openssl-1.0.1e/crypto/pkcs7/pk7_doit.c
--- openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.missing-content 2015-05-25 12:03:41.000000000 +0200
+++ openssl-1.0.1e/crypto/pkcs7/pk7_doit.c 2015-06-09 15:21:21.377951520 +0200
@@ -472,6 +472,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
switch (i)
{
case NID_pkcs7_signed:
+ /*
+ * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
+ * field and optional content.
+ * data_body is NULL if that structure has no (=detached) content
+ * or if the contentType is wrong (i.e., not "data").
+ */
data_body=PKCS7_get_octet_string(p7->d.sign->contents);
if (!PKCS7_is_detached(p7) && data_body == NULL)
{
@@ -484,6 +490,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
case NID_pkcs7_signedAndEnveloped:
rsk=p7->d.signed_and_enveloped->recipientinfo;
md_sk=p7->d.signed_and_enveloped->md_algs;
+ /* data_body is NULL if the optional EncryptedContent is missing. */
data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
@@ -496,6 +503,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
case NID_pkcs7_enveloped:
rsk=p7->d.enveloped->recipientinfo;
enc_alg=p7->d.enveloped->enc_data->algorithm;
+ /* data_body is NULL if the optional EncryptedContent is missing. */
data_body=p7->d.enveloped->enc_data->enc_data;
evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
if (evp_cipher == NULL)
@@ -509,6 +517,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
goto err;
}
+ /* Detached content must be supplied via in_bio instead. */
+ if (data_body == NULL && in_bio == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ goto err;
+ }
+
/* We will be checking the signature */
if (md_sk != NULL)
{
@@ -665,7 +680,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE
}
#if 1
- if (PKCS7_is_detached(p7) || (in_bio != NULL))
+ if (in_bio != NULL)
{
bio=in_bio;
}

View File

@ -0,0 +1,12 @@
diff -up openssl-1.0.1e/crypto/cms/cms_smime.c.unknown-hash openssl-1.0.1e/crypto/cms/cms_smime.c
--- openssl-1.0.1e/crypto/cms/cms_smime.c.unknown-hash 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/cms/cms_smime.c 2015-06-09 16:07:16.001516190 +0200
@@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *up
BIO_free(f);
f = tbio;
}
- while (f != upto);
+ while (f && f != upto);
}
else
BIO_free_all(f);

View File

@ -1,3 +1,34 @@
diff -up openssl-1.0.1e/crypto/asn1/x_x509.c.use-after-free openssl-1.0.1e/crypto/asn1/x_x509.c
--- openssl-1.0.1e/crypto/asn1/x_x509.c.use-after-free 2013-02-11 16:26:04.000000000 +0100
+++ openssl-1.0.1e/crypto/asn1/x_x509.c 2015-06-11 11:14:52.581856349 +0200
@@ -170,8 +170,14 @@ X509 *d2i_X509_AUX(X509 **a, const unsig
{
const unsigned char *q;
X509 *ret;
+ int freeret = 0;
+
/* Save start position */
q = *pp;
+
+ if(!a || *a == NULL) {
+ freeret = 1;
+ }
ret = d2i_X509(a, pp, length);
/* If certificate unreadable then forget it */
if(!ret) return NULL;
@@ -181,7 +187,11 @@ X509 *d2i_X509_AUX(X509 **a, const unsig
if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
return ret;
err:
- X509_free(ret);
+ if(freeret) {
+ X509_free(ret);
+ if (a)
+ *a = NULL;
+ }
return NULL;
}
diff -up openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free openssl-1.0.1k/crypto/ec/ec_asn1.c diff -up openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free openssl-1.0.1k/crypto/ec/ec_asn1.c
--- openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free 2014-10-15 15:49:54.000000000 +0200 --- openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free 2014-10-15 15:49:54.000000000 +0200
+++ openssl-1.0.1k/crypto/ec/ec_asn1.c 2015-03-19 17:28:03.349627040 +0100 +++ openssl-1.0.1k/crypto/ec/ec_asn1.c 2015-03-19 17:28:03.349627040 +0100
@ -25,3 +56,27 @@ diff -up openssl-1.0.1k/crypto/ec/ec_asn1.c.use-after-free openssl-1.0.1k/crypto
EC_KEY_free(ret); EC_KEY_free(ret);
ret = NULL; ret = NULL;
} }
@@ -1377,8 +1377,6 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, con
ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
return NULL;
}
- if (a)
- *a = ret;
}
else
ret = *a;
@@ -1386,9 +1384,14 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, con
if (!d2i_ECPKParameters(&ret->group, in, len))
{
ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
+ if (a == NULL || *a != ret)
+ EC_KEY_free(ret);
return NULL;
}
+ if (a)
+ *a = ret;
+
return ret;
}

View File

@ -0,0 +1,231 @@
diff -up openssl-1.0.1k/ssl/ssl_err.c.ticket-race openssl-1.0.1k/ssl/ssl_err.c
--- openssl-1.0.1k/ssl/ssl_err.c.ticket-race 2015-06-15 17:06:22.699702477 +0200
+++ openssl-1.0.1k/ssl/ssl_err.c 2015-06-15 17:06:22.704702592 +0200
@@ -245,6 +245,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
{ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"},
{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"},
+{ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"},
{ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"},
diff -up openssl-1.0.1k/ssl/ssl.h.ticket-race openssl-1.0.1k/ssl/ssl.h
--- openssl-1.0.1k/ssl/ssl.h.ticket-race 2015-06-15 17:06:22.700702500 +0200
+++ openssl-1.0.1k/ssl/ssl.h 2015-06-15 17:06:22.704702592 +0200
@@ -2203,6 +2203,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_READ 223
#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187
#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188
+#define SSL_F_SSL_SESSION_DUP 348
#define SSL_F_SSL_SESSION_NEW 189
#define SSL_F_SSL_SESSION_PRINT_FP 190
#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312
diff -up openssl-1.0.1k/ssl/ssl_locl.h.ticket-race openssl-1.0.1k/ssl/ssl_locl.h
--- openssl-1.0.1k/ssl/ssl_locl.h.ticket-race 2015-06-15 17:06:22.543698865 +0200
+++ openssl-1.0.1k/ssl/ssl_locl.h 2015-06-15 17:06:22.705702616 +0200
@@ -831,6 +831,7 @@ void ssl_sess_cert_free(SESS_CERT *sc);
int ssl_set_peer_cert_type(SESS_CERT *c, int type);
int ssl_get_new_session(SSL *s, int session);
int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
ssl_cipher_id);
diff -up openssl-1.0.1k/ssl/ssl_sess.c.ticket-race openssl-1.0.1k/ssl/ssl_sess.c
--- openssl-1.0.1k/ssl/ssl_sess.c.ticket-race 2015-01-08 15:00:56.000000000 +0100
+++ openssl-1.0.1k/ssl/ssl_sess.c 2015-06-15 17:06:22.705702616 +0200
@@ -224,6 +224,146 @@ SSL_SESSION *SSL_SESSION_new(void)
return(ss);
}
+/*
+ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
+ * ticket == 0 then no ticket information is duplicated, otherwise it is.
+ */
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+{
+ SSL_SESSION *dest;
+
+ dest = OPENSSL_malloc(sizeof(*src));
+ if (dest == NULL)
+ {
+ goto err;
+ }
+ memcpy(dest, src, sizeof(*dest));
+
+ /*
+ * 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;
+#ifndef OPENSSL_NO_SRP
+ dest->srp_username = NULL;
+#endif
+ 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)
+ {
+ dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint);
+ if (dest->psk_identity_hint == NULL)
+ {
+ goto err;
+ }
+ }
+ if (src->psk_identity)
+ {
+ dest->psk_identity = BUF_strdup(src->psk_identity);
+ if (dest->psk_identity == NULL)
+ {
+ goto err;
+ }
+ }
+#endif
+
+ if(src->ciphers != NULL)
+ {
+ dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
+ if (dest->ciphers == NULL)
+ goto err;
+ }
+
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
+ &dest->ex_data, &src->ex_data))
+ {
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (src->tlsext_hostname)
+ {
+ dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
+ if (dest->tlsext_hostname == NULL)
+ {
+ goto err;
+ }
+ }
+# ifndef OPENSSL_NO_EC
+ if (src->tlsext_ecpointformatlist)
+ {
+ dest->tlsext_ecpointformatlist =
+ BUF_memdup(src->tlsext_ecpointformatlist,
+ src->tlsext_ecpointformatlist_length);
+ if (dest->tlsext_ecpointformatlist == NULL)
+ goto err;
+ }
+ if (src->tlsext_ellipticcurvelist)
+ {
+ dest->tlsext_ellipticcurvelist =
+ BUF_memdup(src->tlsext_ellipticcurvelist,
+ src->tlsext_ellipticcurvelist_length);
+ if (dest->tlsext_ellipticcurvelist == NULL)
+ goto err;
+ }
+# endif
+#endif
+
+ if (ticket != 0)
+ {
+ 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;
+ }
+
+#ifndef OPENSSL_NO_SRP
+ if (src->srp_username)
+ {
+ dest->srp_username = BUF_strdup(src->srp_username);
+ if (dest->srp_username == NULL)
+ {
+ goto err;
+ }
+ }
+#endif
+
+ return dest;
+err:
+ SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
+ SSL_SESSION_free(dest);
+ return NULL;
+}
+
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
{
if(len)
diff -up openssl-1.0.1k/ssl/s3_clnt.c.ticket-race openssl-1.0.1k/ssl/s3_clnt.c
--- openssl-1.0.1k/ssl/s3_clnt.c.ticket-race 2015-06-15 17:06:22.700702500 +0200
+++ openssl-1.0.1k/ssl/s3_clnt.c 2015-06-15 17:06:37.434043557 +0200
@@ -2191,6 +2191,44 @@ int ssl3_get_new_session_ticket(SSL *s)
}
p=d=(unsigned char *)s->init_msg;
+
+ if (s->session->session_id_length > 0)
+ {
+ int i = s->session_ctx->session_cache_mode;
+ SSL_SESSION *new_sess;
+ /*
+ * We reused an existing session, so we need to replace it with a new
+ * one
+ */
+ if (i & SSL_SESS_CACHE_CLIENT)
+ {
+ /*
+ * Remove the old session from the cache
+ */
+ if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
+ {
+ if (s->session_ctx->remove_session_cb != NULL)
+ s->session_ctx->remove_session_cb(s->session_ctx,
+ s->session);
+ }
+ else
+ {
+ /* We carry on if this fails */
+ SSL_CTX_remove_session(s->session_ctx, s->session);
+ }
+ }
+
+ if ((new_sess = ssl_session_dup(s->session, 0)) == 0)
+ {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+
+ SSL_SESSION_free(s->session);
+ s->session = new_sess;
+ }
+
n2l(p, s->session->tlsext_tick_lifetime_hint);
n2s(p, ticklen);
/* ticket_lifetime_hint + ticket_length + ticket */

View File

@ -23,7 +23,7 @@
Summary: Utilities from the general purpose cryptography library with TLS implementation Summary: Utilities from the general purpose cryptography library with TLS implementation
Name: openssl Name: openssl
Version: 1.0.1k Version: 1.0.1k
Release: 9%{?dist} Release: 10%{?dist}
Epoch: 1 Epoch: 1
# We have to remove certain patented algorithms from the openssl source # We have to remove certain patented algorithms from the openssl source
# tarball with the hobble-openssl script which is included below. # tarball with the hobble-openssl script which is included below.
@ -98,6 +98,10 @@ Patch105: openssl-1.0.1k-cve-2015-0289.patch
Patch106: openssl-1.0.1e-cve-2015-0293.patch Patch106: openssl-1.0.1e-cve-2015-0293.patch
Patch107: openssl-1.0.1k-alt-chains.patch Patch107: openssl-1.0.1k-alt-chains.patch
Patch108: openssl-1.0.1k-cve-2015-4000.patch Patch108: openssl-1.0.1k-cve-2015-4000.patch
Patch109: openssl-1.0.1e-cve-2015-1789.patch
Patch110: openssl-1.0.1e-cve-2015-1790.patch
Patch111: openssl-1.0.1k-cve-2015-1791.patch
Patch112: openssl-1.0.1e-cve-2015-1792.patch
License: OpenSSL License: OpenSSL
Group: System Environment/Libraries Group: System Environment/Libraries
@ -229,6 +233,10 @@ cp %{SOURCE12} %{SOURCE13} crypto/ec/
%patch106 -p1 -b .ssl2-assert %patch106 -p1 -b .ssl2-assert
%patch107 -p1 -b .alt-chains %patch107 -p1 -b .alt-chains
%patch108 -p1 -b .logjam %patch108 -p1 -b .logjam
%patch109 -p1 -b .oob-read
%patch110 -p1 -b .missing-content
%patch111 -p1 -b .ticket-race
%patch112 -p1 -b .unknown-hash
sed -i 's/SHLIB_VERSION_NUMBER "1.0.0"/SHLIB_VERSION_NUMBER "%{version}"/' crypto/opensslv.h sed -i 's/SHLIB_VERSION_NUMBER "1.0.0"/SHLIB_VERSION_NUMBER "%{version}"/' crypto/opensslv.h
@ -496,6 +504,13 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.*
%postun libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig
%changelog %changelog
* Mon Jun 15 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-10
- fix CVE-2015-1789 - out-of-bounds read in X509_cmp_time
- fix CVE-2015-1790 - PKCS7 crash with missing EncryptedContent
- fix CVE-2015-1791 - race condition handling NewSessionTicket
- fix CVE-2015-1792 - CMS verify infinite loop with unknown hash function
- add missing parts of CVE-2015-0209 fix for corectness although unexploitable
* Fri May 29 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-9 * Fri May 29 2015 Tomáš Mráz <tmraz@redhat.com> 1.0.1k-9
- fix CVE-2015-4000 - prevent the logjam attack on client - restrict - fix CVE-2015-4000 - prevent the logjam attack on client - restrict
the DH key size to at least 768 bits (limit will be increased in future) the DH key size to at least 768 bits (limit will be increased in future)