diff --git a/0088-CVE-2020-1971.patch b/0088-CVE-2020-1971.patch new file mode 100644 index 0000000..6a4f9ba --- /dev/null +++ b/0088-CVE-2020-1971.patch @@ -0,0 +1,240 @@ +From f22d7684aed13a9ae9ea6554b7a3e52fdfa4f193 Mon Sep 17 00:00:00 2001 +From: tb <> +Date: Tue, 8 Dec 2020 15:06:42 +0000 +Subject: [PATCH] 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 + +[ mikhailnov: ported to v3.2.0, changed src/lib/libcrypto/x509/x509_genn.c to src/lib/libcrypto/x509v3/v3_genn.c ] +--- + src/lib/libcrypto/asn1/asn1.h | 3 +- + src/lib/libcrypto/asn1/asn1_err.c | 3 +- + src/lib/libcrypto/asn1/asn1_lib.c | 4 ++- + src/lib/libcrypto/asn1/tasn_dec.c | 22 ++++++++++++- + src/lib/libcrypto/asn1/tasn_enc.c | 21 +++++++++++- + src/lib/libcrypto/x509v3/v3_genn.c | 52 ++++++++++++++++++++++++++---- + 6 files changed, 94 insertions(+), 11 deletions(-) + +diff --git a/src/lib/libcrypto/asn1/asn1.h b/src/lib/libcrypto/asn1/asn1.h +index 0a8da415fb..76c294ada8 100644 +--- a/src/lib/libcrypto/asn1/asn1.h ++++ b/src/lib/libcrypto/asn1/asn1.h +@@ -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/src/lib/libcrypto/asn1/asn1_err.c b/src/lib/libcrypto/asn1/asn1_err.c +index 5cc355084f..e2c56deb5b 100644 +--- a/src/lib/libcrypto/asn1/asn1_err.c ++++ b/src/lib/libcrypto/asn1/asn1_err.c +@@ -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/src/lib/libcrypto/asn1/asn1_lib.c b/src/lib/libcrypto/asn1/asn1_lib.c +index 5dc520c428..d760cccd4d 100644 +--- a/src/lib/libcrypto/asn1/asn1_lib.c ++++ b/src/lib/libcrypto/asn1/asn1_lib.c +@@ -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/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c +index 70dc355ca1..4b08e90404 100644 +--- a/src/lib/libcrypto/asn1/tasn_dec.c ++++ b/src/lib/libcrypto/asn1/tasn_dec.c +@@ -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/src/lib/libcrypto/asn1/tasn_enc.c b/src/lib/libcrypto/asn1/tasn_enc.c +index d103c4d096..5d95f035ef 100644 +--- a/src/lib/libcrypto/asn1/tasn_enc.c ++++ b/src/lib/libcrypto/asn1/tasn_enc.c +@@ -61,6 +61,7 @@ + + #include + #include ++#include + #include + + 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); +diff --git a/src/lib/libcrypto/x509v3/v3_genn.c b/src/lib/libcrypto/x509v3/v3_genn.c +index 848006acf4..dadf6f1e40 100644 +--- a/src/lib/libcrypto/x509v3/v3_genn.c ++++ b/src/lib/libcrypto/x509v3/v3_genn.c +@@ -117,16 +117,17 @@ OTHERNAME_free(OTHERNAME *a) + ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it); + } + ++/* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */ + static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = { + { +- .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, ++ .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL, + .tag = 0, + .offset = offsetof(EDIPARTYNAME, nameAssigner), + .field_name = "nameAssigner", + .item = &DIRECTORYSTRING_it, + }, + { +- .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL, ++ .flags = ASN1_TFLG_EXPLICIT, + .tag = 1, + .offset = offsetof(EDIPARTYNAME, partyName), + .field_name = "partyName", +@@ -324,6 +325,37 @@ GENERAL_NAME_dup(GENERAL_NAME *a) + return ASN1_item_dup(&GENERAL_NAME_it, a); + } + ++static int ++EDIPARTYNAME_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b) ++{ ++ int res; ++ ++ /* ++ * Shouldn't be possible in a valid GENERAL_NAME, but we handle it ++ * anyway. OTHERNAME_cmp treats NULL != NULL, so we do the same here. ++ */ ++ if (a == NULL || b == NULL) ++ return -1; ++ if (a->nameAssigner == NULL && b->nameAssigner != NULL) ++ return -1; ++ if (a->nameAssigner != NULL && b->nameAssigner == NULL) ++ return 1; ++ /* If we get here, both have nameAssigner set or both unset. */ ++ if (a->nameAssigner != NULL) { ++ res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner); ++ if (res != 0) ++ return res; ++ } ++ /* ++ * partyName is required, so these should never be NULL. We treat it in ++ * the same way as the a == NULL || b == NULL case above. ++ */ ++ if (a->partyName == NULL || b->partyName == NULL) ++ return -1; ++ ++ return ASN1_STRING_cmp(a->partyName, b->partyName); ++} ++ + /* Returns 0 if they are equal, != 0 otherwise. */ + int + GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) +@@ -334,8 +366,11 @@ GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) + return -1; + switch (a->type) { + case GEN_X400: ++ result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); ++ break; ++ + case GEN_EDIPARTY: +- result = ASN1_TYPE_cmp(a->d.other, b->d.other); ++ result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName); + break; + + case GEN_OTHERNAME: +@@ -384,8 +419,11 @@ GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) + { + switch (type) { + case GEN_X400: ++ a->d.x400Address = value; ++ break; ++ + case GEN_EDIPARTY: +- a->d.other = value; ++ a->d.ediPartyName = value; + break; + + case GEN_OTHERNAME: +@@ -420,8 +458,10 @@ GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) + *ptype = a->type; + switch (a->type) { + case GEN_X400: ++ return a->d.x400Address; ++ + case GEN_EDIPARTY: +- return a->d.other; ++ return a->d.ediPartyName; + + case GEN_OTHERNAME: + return a->d.otherName; diff --git a/0089-CVE-2021-3712.patch b/0089-CVE-2021-3712.patch new file mode 100644 index 0000000..2cea2ea --- /dev/null +++ b/0089-CVE-2021-3712.patch @@ -0,0 +1,67 @@ +From 89d74f9b9c8c0b042e81aecb6c286253a51659d8 Mon Sep 17 00:00:00 2001 +From: benno <> +Date: Fri, 20 Aug 2021 19:54:16 +0000 +Subject: [PATCH] In LibreSSL, printing a certificate can result in a crash in + X509_CERT_AUX_print(). + +Commit in -current: + +CVSROOT: /cvs +Module name: src +Changes by: schwarze@cvs.openbsd.org 2021/07/10 11:45:16 + +Modified files: + lib/libcrypto/asn1: t_x509a.c + +Log message: +Fix a read buffer overrun in X509_CERT_AUX_print(3), +which by implication also affects X509_print(3). + +The ASN1_STRING_get0_data(3) manual explitely cautions the reader +that the data is not necessarily NUL-terminated, and the function +X509_alias_set1(3) does not sanitize the data passed into it in +any way either, so we must assume the alias->data field is merely +a byte array and not necessarily a string in the sense of the C +language. + +I found this bug while writing manual pages for these functions. + +OK tb@ + +As an aside, note that the function still produces incomplete and +misleading results when the data contains a NUL byte in the middle +and that error handling is consistently absent throughout, even +though the function provides an "int" return value obviously intended +to be 1 for success and 0 for failure, and even though this function +is called by another function that also wants to return 1 for success +and 0 for failure and even does so in many of its code paths, though +not in others. But let's stay focussed. Many things would be nice +to have in the wide wild world, but a buffer overflow must not be +allowed to remain in our backyard. + +This is patches/6.8/common/029_x509.patch.sig +--- + src/lib/libcrypto/asn1/t_x509a.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/lib/libcrypto/asn1/t_x509a.c b/src/lib/libcrypto/asn1/t_x509a.c +index fd68211b84..173465b295 100644 +--- a/src/lib/libcrypto/asn1/t_x509a.c ++++ b/src/lib/libcrypto/asn1/t_x509a.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: t_x509a.c,v 1.8 2014/07/11 08:44:47 jsing Exp $ */ ++/* $OpenBSD: t_x509a.c,v 1.8.18.1 2021/08/20 19:54:16 benno Exp $ */ + /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. + */ +@@ -105,8 +105,8 @@ X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) + } else + BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); + if (aux->alias) +- BIO_printf(out, "%*sAlias: %s\n", indent, "", +- aux->alias->data); ++ BIO_printf(out, "%*sAlias: %.*s\n", indent, "", ++ aux->alias->length, aux->alias->data); + if (aux->keyid) { + BIO_printf(out, "%*sKey Id: ", indent, ""); + for (i = 0; i < aux->keyid->length; i++) diff --git a/libressl.spec b/libressl.spec index d864a07..db1e722 100644 --- a/libressl.spec +++ b/libressl.spec @@ -76,7 +76,11 @@ Summary: LibreSSL utils and libs coexisting with OpenSSL Name: libressl Version: 3.2.0 +<<<<<<< HEAD Release: 4 +======= +Release: 8 +>>>>>>> eefcab4b5314a0da4734f85dda5c100fc98fbcbd # The code is distributed under ISC license except of original OpenSSL code License: ISC and BSD-like Group: System/Base @@ -199,6 +203,19 @@ Patch0084: 0084-ssl-drop-mac_flags-field.patch Patch0085: 0085-ssl-support-IV-increments-for-GOST-CTR-OMAC-ciphersu.patch Patch0086: 0086-kdftree-add-support-for-TLSTREE-rekeying-algorithm.patch Patch0087: 0087-ssl-add-support-for-TLSTREE-rekeying.patch +# https://www.opennet.ru/opennews/art.shtml?num=54233 +# https://github.com/libressl-portable/openbsd/commit/f22d7684aed13a9ae9ea6554b7a3e52fdfa4f193 +# From LibreSSL 3.2.3 +Patch0088: 0088-CVE-2020-1971.patch +# https://www.opennet.ru/opennews/art.shtml?num=55683 +# https://github.com/libressl-portable/openbsd/commit/89d74f9b9c8c0b042e81aecb6c286253a51659d8 +# From LibreSSL 3.2.6 +Patch0089: 0089-CVE-2021-3712.patch + +# TODO: +# https://www.opennet.ru/opennews/art.shtml?num=54774 +# https://github.com/libressl-portable/openbsd/commit/5f00b800749f246861e892a17d9012bd25fc06ba (LibreSSL 3.2.5) +# Code is different in our version, investigation if backport is required is required. # Patches for portable, from lumag@ # ( for i in *PORTABLE*.patch ; do echo Patch$(echo $i | awk -F '-' '{print $2}'): $i ; done ) | sed -e 's,^Patch0,Patch2,g' | sort -h @@ -217,7 +234,7 @@ Patch2100: PORTABLE-0100-fixup-build.patch # versioning their symbols will or may allow them to coexist Patch2200: PORTABLE-2200-SUSE-extra-symver.patch -# From https://www.mitchr.me/SS/exampleCode/openssl.html +# From https://www.mitchr.me/SS/exampleCode/openssl.html Source20: test.c Source22: test2.c # From import/openssl, originates from Fedora @@ -306,7 +323,7 @@ Provides: %{mklibname ssl_libressl -d} = %{EVRD} # devel(libfoo) are RPM_VENDOR_MANDRIVA-specific in RPM 5 # TODO: probably no real need in emulating devel(libfoo) %if 0%{?mdvver} -%if %{?_lib} == "lib64" +%if "%{?_lib}" == "lib64" %define b64 (64bit) %else %define b64 %{nil} @@ -366,6 +383,9 @@ Provides: nc = %{EVRD} # the default candidate to be installed as "netcat". %if %{mdvver} > 201610 Provides: netcat = %{EVRD} +# other netcats were removed due to their upstreams being dead +Obsoletes: netcat-gnu < 0.7.2 +Obsoletes: netcat-traditional < 111 %else # keep old default in rosa2016.1 Provides: netcat = 1.0 @@ -427,16 +447,17 @@ sh -x update.sh export CFLAGS="$CFLAGS -DX509_CONF_FILE='\"%{_openssldir}/libressl.cnf\"'" #autoreconf -if #Source21 # static libs are required for tests target in Makefile +cp -fv /usr/share/libtool/config/config.* . %configure \ --enable-nc \ --enable-static \ --with-openssldir=%{_openssldir} -%make +%make_build %install set +f # explicitly enable shell globbing -%makeinstall_std +%make_install # Some ideas about mans are from ALT Linux spec install -m 0644 apps/nc/nc.1 %{buildroot}%{_mandir}/man1/nc.1