diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2015-03-19 14:00:23 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2015-03-19 14:00:23 +0000 |
commit | 836b495106f594955b58752d134d1fdfdc8973b1 (patch) | |
tree | 7822387262a7d3bef9e0cd5e3fe209b4f0b5c5c6 /lib/libcrypto/asn1 | |
parent | 5ee002f51cf23a40109eb29a0600077fe8edc54b (diff) |
Fix several crash causing defects from OpenSSL.
These include:
CVE-2015-0209 - Use After Free following d2i_ECPrivatekey error
CVE-2015-0286 - Segmentation fault in ASN1_TYPE_cmp
CVE-2015-0287 - ASN.1 structure reuse memory corruption
CVE-2015-0289 - PKCS7 NULL pointer dereferences
Several other issues did not apply or were already fixed.
Refer to https://www.openssl.org/news/secadv_20150319.txt
joint work with beck, doug, guenther, jsing, miod
Diffstat (limited to 'lib/libcrypto/asn1')
-rw-r--r-- | lib/libcrypto/asn1/a_int.c | 6 | ||||
-rw-r--r-- | lib/libcrypto/asn1/a_set.c | 4 | ||||
-rw-r--r-- | lib/libcrypto/asn1/a_type.c | 6 | ||||
-rw-r--r-- | lib/libcrypto/asn1/d2i_pr.c | 4 | ||||
-rw-r--r-- | lib/libcrypto/asn1/d2i_pu.c | 4 | ||||
-rw-r--r-- | lib/libcrypto/asn1/n_pkey.c | 10 | ||||
-rw-r--r-- | lib/libcrypto/asn1/tasn_dec.c | 27 | ||||
-rw-r--r-- | lib/libcrypto/asn1/x_x509.c | 16 |
8 files changed, 52 insertions, 25 deletions
diff --git a/lib/libcrypto/asn1/a_int.c b/lib/libcrypto/asn1/a_int.c index fe6ce5ee9f7..af5d64d0568 100644 --- a/lib/libcrypto/asn1/a_int.c +++ b/lib/libcrypto/asn1/a_int.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_int.c,v 1.25 2015/02/10 08:33:10 jsing Exp $ */ +/* $OpenBSD: a_int.c,v 1.26 2015/03/19 14:00:22 tedu Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -268,7 +268,7 @@ c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len) err: ASN1err(ASN1_F_C2I_ASN1_INTEGER, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) + if (a == NULL || *a != ret) M_ASN1_INTEGER_free(ret); return (NULL); } @@ -335,7 +335,7 @@ d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length) err: ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) + if (a == NULL || *a != ret) M_ASN1_INTEGER_free(ret); return (NULL); } diff --git a/lib/libcrypto/asn1/a_set.c b/lib/libcrypto/asn1/a_set.c index ba4f28be34d..63d55c3714c 100644 --- a/lib/libcrypto/asn1/a_set.c +++ b/lib/libcrypto/asn1/a_set.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_set.c,v 1.16 2014/07/11 08:44:47 jsing Exp $ */ +/* $OpenBSD: a_set.c,v 1.17 2015/03/19 14:00:22 tedu Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -225,7 +225,7 @@ d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, const unsigned char **pp, long length, return ret; err: - if (ret != NULL && (a == NULL || *a != ret)) { + if (a == NULL || *a != ret) { if (free_func != NULL) sk_OPENSSL_BLOCK_pop_free(ret, free_func); else diff --git a/lib/libcrypto/asn1/a_type.c b/lib/libcrypto/asn1/a_type.c index 7c732cfec5f..38b3c65beb0 100644 --- a/lib/libcrypto/asn1/a_type.c +++ b/lib/libcrypto/asn1/a_type.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_type.c,v 1.15 2015/02/10 08:33:10 jsing Exp $ */ +/* $OpenBSD: a_type.c,v 1.16 2015/03/19 14:00:22 tedu Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -119,7 +119,9 @@ ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b) case V_ASN1_OBJECT: result = OBJ_cmp(a->value.object, b->value.object); break; - + case V_ASN1_BOOLEAN: + result = a->value.boolean - b->value.boolean; + break; case V_ASN1_NULL: result = 0; /* They do not have content. */ break; diff --git a/lib/libcrypto/asn1/d2i_pr.c b/lib/libcrypto/asn1/d2i_pr.c index 14f08e1380a..68d02177c42 100644 --- a/lib/libcrypto/asn1/d2i_pr.c +++ b/lib/libcrypto/asn1/d2i_pr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: d2i_pr.c,v 1.13 2015/02/11 03:19:37 doug Exp $ */ +/* $OpenBSD: d2i_pr.c,v 1.14 2015/03/19 14:00:22 tedu Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -118,7 +118,7 @@ d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) return (ret); err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) + if (a == NULL || *a != ret) EVP_PKEY_free(ret); return (NULL); } diff --git a/lib/libcrypto/asn1/d2i_pu.c b/lib/libcrypto/asn1/d2i_pu.c index df6fea4af52..e917356254a 100644 --- a/lib/libcrypto/asn1/d2i_pu.c +++ b/lib/libcrypto/asn1/d2i_pu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: d2i_pu.c,v 1.12 2014/07/11 08:44:47 jsing Exp $ */ +/* $OpenBSD: d2i_pu.c,v 1.13 2015/03/19 14:00:22 tedu Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -130,7 +130,7 @@ d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) return (ret); err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) + if (a == NULL || *a != ret) EVP_PKEY_free(ret); return (NULL); } diff --git a/lib/libcrypto/asn1/n_pkey.c b/lib/libcrypto/asn1/n_pkey.c index bb369fde6ec..d3a7431356a 100644 --- a/lib/libcrypto/asn1/n_pkey.c +++ b/lib/libcrypto/asn1/n_pkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: n_pkey.c,v 1.25 2015/02/11 04:00:39 jsing Exp $ */ +/* $OpenBSD: n_pkey.c,v 1.26 2015/03/19 14:00:22 tedu Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -340,11 +340,11 @@ d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, return NULL; } - if ((enckey->os->length != 11) || (strncmp("private-key", - (char *)enckey->os->data, 11) != 0)) { + /* XXX 11 == strlen("private-key") */ + if (enckey->os->length != 11 || + memcmp("private-key", enckey->os->data, 11) != 0) { ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING); - NETSCAPE_ENCRYPTED_PKEY_free(enckey); - return NULL; + goto err; } if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) { ASN1err(ASN1_F_D2I_RSA_NET, diff --git a/lib/libcrypto/asn1/tasn_dec.c b/lib/libcrypto/asn1/tasn_dec.c index 791a10a9c04..7d61a6a2338 100644 --- a/lib/libcrypto/asn1/tasn_dec.c +++ b/lib/libcrypto/asn1/tasn_dec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tasn_dec.c,v 1.25 2015/02/14 15:23:57 miod Exp $ */ +/* $OpenBSD: tasn_dec.c,v 1.26 2015/03/19 14:00:22 tedu Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -238,8 +238,16 @@ ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) goto auxerr; - /* Allocate structure */ - if (!*pval && !ASN1_item_ex_new(pval, it)) { + if (*pval) { + /* Free up and zero CHOICE value if initialised */ + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + tt = it->templates + i; + pchptr = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchptr, tt); + asn1_set_choice_selector(pval, -1, it); + } + } else if (!ASN1_item_ex_new(pval, it)) { ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); goto err; @@ -325,6 +333,19 @@ ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) goto auxerr; + /* Free up and zero any ADB found */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + if (tt->flags & ASN1_TFLG_ADB_MASK) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + goto err; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + } + /* Get each field entry */ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { const ASN1_TEMPLATE *seqtt; diff --git a/lib/libcrypto/asn1/x_x509.c b/lib/libcrypto/asn1/x_x509.c index 70d38221b6b..168c2c0fcd5 100644 --- a/lib/libcrypto/asn1/x_x509.c +++ b/lib/libcrypto/asn1/x_x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x_x509.c,v 1.23 2015/02/11 04:00:39 jsing Exp $ */ +/* $OpenBSD: x_x509.c,v 1.24 2015/03/19 14:00:22 tedu Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -313,16 +313,20 @@ d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) /* Save start position */ q = *pp; - ret = d2i_X509(a, pp, length); + ret = d2i_X509(NULL, pp, length); /* If certificate unreadable then forget it */ if (!ret) return NULL; /* update length */ length -= *pp - q; - if (!length) - return ret; - if (!d2i_X509_CERT_AUX(&ret->aux, pp, length)) - goto err; + if (length > 0) { + if (!d2i_X509_CERT_AUX(&ret->aux, pp, length)) + goto err; + } + if (a != NULL) { + X509_free(*a); + *a = ret; + } return ret; err: |