diff options
author | Theo Buehler <tb@cvs.openbsd.org> | 2020-12-08 15:06:43 +0000 |
---|---|---|
committer | Theo Buehler <tb@cvs.openbsd.org> | 2020-12-08 15:06:43 +0000 |
commit | 8b2f57152e74fd65c748fae4903308ea5e753ed8 (patch) | |
tree | b5d69347425fc0d1efcfd948944f4b16e83f0d97 /lib/libcrypto/asn1 | |
parent | d2f2c3b4bd1b760bbf580a7142554e51ac4bf827 (diff) |
Fix a NULL dereference in GENERAL_NAME_cmp()
Comparing two GENERAL_NAME structures containing an EDIPARTYNAME can lead
to a crash. This enables a denial of service attack for an attacker who can
control both sides of the comparison.
Issue reported to OpenSSL on Nov 9 by David Benjamin.
OpenSSL shared the information with us on Dec 1st.
Fix from Matt Caswell (OpenSSL) with a few small tweaks.
ok jsing
Diffstat (limited to 'lib/libcrypto/asn1')
-rw-r--r-- | lib/libcrypto/asn1/asn1.h | 3 | ||||
-rw-r--r-- | lib/libcrypto/asn1/asn1_err.c | 3 | ||||
-rw-r--r-- | lib/libcrypto/asn1/asn1_lib.c | 4 | ||||
-rw-r--r-- | lib/libcrypto/asn1/tasn_dec.c | 22 | ||||
-rw-r--r-- | lib/libcrypto/asn1/tasn_enc.c | 21 |
5 files changed, 48 insertions, 5 deletions
diff --git a/lib/libcrypto/asn1/asn1.h b/lib/libcrypto/asn1/asn1.h index 0a8da415fb4..76c294ada8c 100644 --- a/lib/libcrypto/asn1/asn1.h +++ b/lib/libcrypto/asn1/asn1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1.h,v 1.53 2018/11/30 04:51:19 jeremy Exp $ */ +/* $OpenBSD: asn1.h,v 1.54 2020/12/08 15:06:42 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1137,6 +1137,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_BAD_OBJECT_HEADER 102 #define ASN1_R_BAD_PASSWORD_READ 103 #define ASN1_R_BAD_TAG 104 +#define ASN1_R_BAD_TEMPLATE 230 #define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 #define ASN1_R_BN_LIB 105 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 diff --git a/lib/libcrypto/asn1/asn1_err.c b/lib/libcrypto/asn1/asn1_err.c index 5cc355084f0..e2c56deb5ba 100644 --- a/lib/libcrypto/asn1/asn1_err.c +++ b/lib/libcrypto/asn1/asn1_err.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_err.c,v 1.21 2018/03/29 02:29:24 inoguchi Exp $ */ +/* $OpenBSD: asn1_err.c,v 1.22 2020/12/08 15:06:42 tb Exp $ */ /* ==================================================================== * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * @@ -85,6 +85,7 @@ static ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) , "bad object header"}, {ERR_REASON(ASN1_R_BAD_PASSWORD_READ) , "bad password read"}, {ERR_REASON(ASN1_R_BAD_TAG) , "bad tag"}, + {ERR_REASON(ASN1_R_BAD_TEMPLATE) , "bad template"}, {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), "bmpstring is wrong length"}, {ERR_REASON(ASN1_R_BN_LIB) , "bn lib"}, {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"}, diff --git a/lib/libcrypto/asn1/asn1_lib.c b/lib/libcrypto/asn1/asn1_lib.c index 5dc520c428e..d760cccd4d9 100644 --- a/lib/libcrypto/asn1/asn1_lib.c +++ b/lib/libcrypto/asn1/asn1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_lib.c,v 1.44 2018/11/17 09:34:11 tb Exp $ */ +/* $OpenBSD: asn1_lib.c,v 1.45 2020/12/08 15:06:42 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -388,6 +388,8 @@ ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) { int i; + if (a == NULL || b == NULL) + return -1; i = (a->length - b->length); if (i == 0) { i = memcmp(a->data, b->data, a->length); diff --git a/lib/libcrypto/asn1/tasn_dec.c b/lib/libcrypto/asn1/tasn_dec.c index 70dc355ca1f..4b08e90404a 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.37 2019/04/01 15:48:04 jsing Exp $ */ +/* $OpenBSD: tasn_dec.c,v 1.38 2020/12/08 15:06:42 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -210,6 +210,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, break; case ASN1_ITYPE_MSTRING: + /* + * It never makes sense for multi-strings to have implicit + * tagging, so if tag != -1, then this looks like an error in + * the template. + */ + if (tag != -1) { + ASN1error(ASN1_R_BAD_TEMPLATE); + goto err; + } + p = *in; /* Just read in tag and class */ ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, @@ -245,6 +255,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, it, tag, aclass, opt, ctx); case ASN1_ITYPE_CHOICE: + /* + * It never makes sense for CHOICE types to have implicit + * tagging, so if tag != -1, then this looks like an error in + * the template. + */ + if (tag != -1) { + ASN1error(ASN1_R_BAD_TEMPLATE); + goto err; + } + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) goto auxerr; diff --git a/lib/libcrypto/asn1/tasn_enc.c b/lib/libcrypto/asn1/tasn_enc.c index d103c4d096a..5d95f035ef2 100644 --- a/lib/libcrypto/asn1/tasn_enc.c +++ b/lib/libcrypto/asn1/tasn_enc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tasn_enc.c,v 1.22 2019/04/01 15:48:04 jsing Exp $ */ +/* $OpenBSD: tasn_enc.c,v 1.23 2020/12/08 15:06:42 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -61,6 +61,7 @@ #include <openssl/asn1.h> #include <openssl/asn1t.h> +#include <openssl/err.h> #include <openssl/objects.h> static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, @@ -152,9 +153,27 @@ ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, break; case ASN1_ITYPE_MSTRING: + /* + * It never makes sense for multi-strings to have implicit + * tagging, so if tag != -1, then this looks like an error in + * the template. + */ + if (tag != -1) { + ASN1error(ASN1_R_BAD_TEMPLATE); + return 0; + } return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); case ASN1_ITYPE_CHOICE: + /* + * It never makes sense for CHOICE types to have implicit + * tagging, so if tag != -1, then this looks like an error in + * the template. + */ + if (tag != -1) { + ASN1error(ASN1_R_BAD_TEMPLATE); + return 0; + } if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) return 0; i = asn1_get_choice_selector(pval, it); |