[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#959469: buster-pu: package openssl/1.1.1g-1



On 2021-03-22 19:52:00 [+0100], To Kurt Roeckx wrote:
> > I will prepare 1.1.1k for unstable, do buster-security based on
> > 1.1.1d-0+deb10u5 and then come back with an updated pu :)

New round. I prepared a pu for Buster based on OpenSSL 1.1.1k. The
unstable release migrated to testing. I am not aware of any regressions
so far.
Please find attached a diff against the last proposed pu, based on
1.1.1j.
I will also reply to this mail with a diff against the current version
in buster-pu.

Sebastian
diff --git a/CHANGES b/CHANGES
index 1ab64b35c9a48..7d0129e687652 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,50 @@
  https://github.com/openssl/openssl/commits/ and pick the appropriate
  release branch.
 
+ Changes between 1.1.1j and 1.1.1k [25 Mar 2021]
+
+  *) Fixed a problem with verifying a certificate chain when using the
+     X509_V_FLAG_X509_STRICT flag. This flag enables additional security checks
+     of the certificates present in a certificate chain. It is not set by
+     default.
+
+     Starting from OpenSSL version 1.1.1h a check to disallow certificates in
+     the chain that have explicitly encoded elliptic curve parameters was added
+     as an additional strict check.
+
+     An error in the implementation of this check meant that the result of a
+     previous check to confirm that certificates in the chain are valid CA
+     certificates was overwritten. This effectively bypasses the check
+     that non-CA certificates must not be able to issue other certificates.
+
+     If a "purpose" has been configured then there is a subsequent opportunity
+     for checks that the certificate is a valid CA.  All of the named "purpose"
+     values implemented in libcrypto perform this check.  Therefore, where
+     a purpose is set the certificate chain will still be rejected even when the
+     strict flag has been used. A purpose is set by default in libssl client and
+     server certificate verification routines, but it can be overridden or
+     removed by an application.
+
+     In order to be affected, an application must explicitly set the
+     X509_V_FLAG_X509_STRICT verification flag and either not set a purpose
+     for the certificate verification or, in the case of TLS client or server
+     applications, override the default purpose.
+     (CVE-2021-3450)
+     [Tomáš Mráz]
+
+  *) Fixed an issue where an OpenSSL TLS server may crash if sent a maliciously
+     crafted renegotiation ClientHello message from a client. If a TLSv1.2
+     renegotiation ClientHello omits the signature_algorithms extension (where
+     it was present in the initial ClientHello), but includes a
+     signature_algorithms_cert extension then a NULL pointer dereference will
+     result, leading to a crash and a denial of service attack.
+
+     A server is only vulnerable if it has TLSv1.2 and renegotiation enabled
+     (which is the default configuration). OpenSSL TLS clients are not impacted
+     by this issue.
+     (CVE-2021-3449)
+     [Peter Kästle and Samuel Sapalski]
+
  Changes between 1.1.1i and 1.1.1j [16 Feb 2021]
 
   *) Fixed the X509_issuer_and_serial_hash() function. It attempts to
diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
index 3a24d551359bd..41648c952667f 100644
--- a/Configurations/unix-Makefile.tmpl
+++ b/Configurations/unix-Makefile.tmpl
@@ -917,8 +917,8 @@ ERROR_REBUILD=
           done )
 
 ordinals:
-	( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b util/mkdef.pl crypto update )
-	( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b util/mkdef.pl ssl update )
+	$(PERL) $(SRCDIR)/util/mkdef.pl crypto update
+	$(PERL) $(SRCDIR)/util/mkdef.pl ssl update
 
 test_ordinals:
 	( cd test; \
diff --git a/NEWS b/NEWS
index 3cce525066457..05991a0c214a9 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,14 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 1.1.1j and OpenSSL 1.1.1k [25 Mar 2021]
+
+      o Fixed a problem with verifying a certificate chain when using the
+        X509_V_FLAG_X509_STRICT flag (CVE-2021-3450)
+      o Fixed an issue where an OpenSSL TLS server may crash if sent a
+        maliciously crafted renegotiation ClientHello message from a client
+        (CVE-2021-3449)
+
   Major changes between OpenSSL 1.1.1i and OpenSSL 1.1.1j [16 Feb 2021]
 
       o Fixed a NULL pointer deref in the X509_issuer_and_serial_hash()
diff --git a/README b/README
index da5629f92c819..b92a8bd3a4b59 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
 
- OpenSSL 1.1.1j 16 Feb 2021
+ OpenSSL 1.1.1k 25 Mar 2021
 
- Copyright (c) 1998-2020 The OpenSSL Project
+ Copyright (c) 1998-2021 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
  All rights reserved.
 
diff --git a/apps/s_cb.c b/apps/s_cb.c
index 6406ddfb9e1b2..dee1b2e5b4f65 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -934,7 +934,8 @@ static int set_cert_cb(SSL *ssl, void *arg)
                 if (!SSL_build_cert_chain(ssl, 0))
                     return 0;
             } else if (exc->chain != NULL) {
-                SSL_set1_chain(ssl, exc->chain);
+                if (!SSL_set1_chain(ssl, exc->chain))
+                    return 0;
             }
         }
         exc = exc->prev;
diff --git a/apps/s_time.c b/apps/s_time.c
index 628e65b26e19c..1235e545c20a5 100644
--- a/apps/s_time.c
+++ b/apps/s_time.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -263,7 +263,8 @@ int s_time_main(int argc, char **argv)
          nConn, totalTime, ((double)nConn / totalTime), bytes_read);
     printf
         ("%d connections in %ld real seconds, %ld bytes read per connection\n",
-         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);
+         nConn, (long)time(NULL) - finishtime + maxtime,
+         nConn > 0 ? bytes_read / nConn : 0l);
 
     /*
      * Now loop and time connections using the same session id over and over
diff --git a/crypto/asn1/asn1_par.c b/crypto/asn1/asn1_par.c
index 3f10c7cb94c56..a32fa47f2206b 100644
--- a/crypto/asn1/asn1_par.c
+++ b/crypto/asn1/asn1_par.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -325,6 +325,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
                 }
                 if (BIO_puts(bp, "]") <= 0)
                     goto end;
+                dump_cont = 0;
             }
 
             if (!nl) {
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
index 6222c99074de8..d7d7d80eea912 100644
--- a/crypto/asn1/bio_ndef.c
+++ b/crypto/asn1/bio_ndef.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -113,6 +113,8 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
     ndef_aux = *(NDEF_SUPPORT **)parg;
 
     derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    if (derlen < 0)
+        return 0;
     if ((p = OPENSSL_malloc(derlen)) == NULL) {
         ASN1err(ASN1_F_NDEF_PREFIX, ERR_R_MALLOC_FAILURE);
         return 0;
diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c
index 49e9ce1af33b0..84a3b7dbec757 100644
--- a/crypto/engine/eng_devcrypto.c
+++ b/crypto/engine/eng_devcrypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -758,8 +758,9 @@ static int devcrypto_unload(ENGINE *e)
 void engine_load_devcrypto_int()
 {
     ENGINE *e = NULL;
+    int fd;
 
-    if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
+    if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
 #ifndef ENGINE_DEVCRYPTO_DEBUG
         if (errno != ENOENT)
 #endif
@@ -767,6 +768,18 @@ void engine_load_devcrypto_int()
         return;
     }
 
+#ifdef CRIOGET
+    if (ioctl(fd, CRIOGET, &cfd) < 0) {
+        fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno));
+        close(fd);
+        cfd = -1;
+        return;
+    }
+    close(fd);
+#else
+    cfd = fd;
+#endif
+
     if ((e = ENGINE_new()) == NULL
         || !ENGINE_set_destroy_function(e, devcrypto_unload)) {
         ENGINE_free(e);
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 0843caf4f0a4f..e3c165d48e082 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
diff --git a/crypto/modes/cbc128.c b/crypto/modes/cbc128.c
index c85e37c6a546d..15a14be70872d 100644
--- a/crypto/modes/cbc128.c
+++ b/crypto/modes/cbc128.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -69,6 +69,7 @@ void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
         in += 16;
         out += 16;
     }
+    if (ivec != iv)
         memcpy(ivec, iv, 16);
 }
 
@@ -114,6 +115,7 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
                 out += 16;
             }
         }
+        if (ivec != iv)
             memcpy(ivec, iv, 16);
     } else {
         if (STRICT_ALIGNMENT &&
diff --git a/crypto/modes/gcm128.c b/crypto/modes/gcm128.c
index 0c0bf3cda5b5d..8304efff48be0 100644
--- a/crypto/modes/gcm128.c
+++ b/crypto/modes/gcm128.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2010-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -1385,8 +1385,8 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
                 else
                     ctx->Yi.d[3] = ctr;
                 for (i = 0; i < 16 / sizeof(size_t); ++i) {
-                    size_t c = in[i];
-                    out[i] = c ^ ctx->EKi.t[i];
+                    size_t c = in_t[i];
+                    out_t[i] = c ^ ctx->EKi.t[i];
                     ctx->Xi.t[i] ^= c;
                 }
                 GCM_MUL(ctx);
diff --git a/crypto/o_time.c b/crypto/o_time.c
index 3502edda6238f..3fa70c45af833 100644
--- a/crypto/o_time.c
+++ b/crypto/o_time.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -133,8 +133,8 @@ int OPENSSL_gmtime_diff(int *pday, int *psec,
 static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
                       long *pday, int *psec)
 {
-    int offset_hms, offset_day;
-    long time_jd;
+    int offset_hms;
+    long offset_day, time_jd;
     int time_year, time_month, time_day;
     /* split offset into days and day seconds */
     offset_day = offset_sec / SECS_PER_DAY;
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index ba3a29e584685..5c72fad8ca263 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -432,9 +432,13 @@ int RAND_poll(void)
 RAND_POOL *rand_pool_new(int entropy_requested, int secure,
                          size_t min_len, size_t max_len)
 {
-    RAND_POOL *pool = OPENSSL_zalloc(sizeof(*pool));
+    RAND_POOL *pool;
     size_t min_alloc_size = RAND_POOL_MIN_ALLOCATION(secure);
 
+    if (!RUN_ONCE(&rand_init, do_rand_init))
+        return NULL;
+
+    pool = OPENSSL_zalloc(sizeof(*pool));
     if (pool == NULL) {
         RANDerr(RAND_F_RAND_POOL_NEW, ERR_R_MALLOC_FAILURE);
         return NULL;
diff --git a/crypto/rsa/rsa_ssl.c b/crypto/rsa/rsa_ssl.c
index ecdb3cee1fa35..e1c755ae460ba 100644
--- a/crypto/rsa/rsa_ssl.c
+++ b/crypto/rsa/rsa_ssl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 0c71b2e8b4adc..20a36e763c5db 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -524,15 +524,19 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                 ret = 1;
             break;
         }
-        if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) && num > 1) {
+        if (ret > 0
+            && (ctx->param->flags & X509_V_FLAG_X509_STRICT) && num > 1) {
             /* Check for presence of explicit elliptic curve parameters */
             ret = check_curve(x);
-            if (ret < 0)
+            if (ret < 0) {
                 ctx->error = X509_V_ERR_UNSPECIFIED;
-            else if (ret == 0)
+                ret = 0;
+            } else if (ret == 0) {
                 ctx->error = X509_V_ERR_EC_KEY_EXPLICIT_PARAMS;
             }
-        if ((x->ex_flags & EXFLAG_CA) == 0
+        }
+        if (ret > 0
+            && (x->ex_flags & EXFLAG_CA) == 0
             && x->ex_pathlen != -1
             && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) {
             ctx->error = X509_V_ERR_INVALID_EXTENSION;
diff --git a/debian/changelog b/debian/changelog
index 45bfdb99fe8d9..9d1b9d6590ab9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,16 @@
-openssl (1.1.1j-0+deb10u1) buster; urgency=medium
+openssl (1.1.1k-0+deb10u1) buster; urgency=medium
 
   * New upstream version
+    - CVE-2021-3450 (CA certificate check bypass with X509_V_FLAG_X509_STRICT).
   * Update symbol list.
 
- -- Sebastian Andrzej Siewior <sebastian@breakpoint.cc>  Tue, 23 Feb 2021 23:13:13 +0100
+ -- Sebastian Andrzej Siewior <sebastian@breakpoint.cc>  Fri, 26 Mar 2021 21:49:22 +0100
+
+openssl (1.1.1d-0+deb10u6) buster-security; urgency=medium
+
+  * CVE-2021-3449 (NULL pointer deref in signature_algorithms processing).
+
+ -- Sebastian Andrzej Siewior <sebastian@breakpoint.cc>  Tue, 23 Mar 2021 00:08:47 +0100
 
 openssl (1.1.1d-0+deb10u5) buster-security; urgency=medium
 
diff --git a/debian/patches/c_rehash-compat.patch b/debian/patches/c_rehash-compat.patch
index 1ed5050f07d22..5606691bb9f9f 100644
--- a/debian/patches/c_rehash-compat.patch
+++ b/debian/patches/c_rehash-compat.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] also create old hash for compatibility
  1 file changed, 14 insertions(+), 6 deletions(-)
 
 diff --git a/tools/c_rehash.in b/tools/c_rehash.in
-index 421fd892086f..5ad1ab1d655f 100644
+index fa7c6c9fef91..a7e538a72d7d 100644
 --- a/tools/c_rehash.in
 +++ b/tools/c_rehash.in
 @@ -17,8 +17,6 @@ my $prefix = {- quotify1($config{prefix}) -};
@@ -46,7 +46,7 @@ index 421fd892086f..5ad1ab1d655f 100644
  sub link_hash_cert {
  		my $fname = $_[0];
 +		my $x509hash = $_[1] || '-subject_hash';
- 		$fname =~ s/'/'\\''/g;
+ 		$fname =~ s/\"/\\\"/g;
  		my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
  		chomp $hash;
 @@ -198,10 +196,20 @@ sub link_hash_cert {
diff --git a/debian/patches/man-section.patch b/debian/patches/man-section.patch
index 982e16a14a2a2..002015b628ab1 100644
--- a/debian/patches/man-section.patch
+++ b/debian/patches/man-section.patch
@@ -8,7 +8,7 @@ Subject: man-section
  2 files changed, 6 insertions(+), 3 deletions(-)
 
 diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
-index 3a24d551359b..d0c90cb2546c 100644
+index 41648c952667..e013d464bd73 100644
 --- a/Configurations/unix-Makefile.tmpl
 +++ b/Configurations/unix-Makefile.tmpl
 @@ -281,7 +281,8 @@ HTMLDIR=$(DOCDIR)/html
diff --git a/fuzz/x509.c b/fuzz/x509.c
index 1a20ca21db543..ceaec0797b438 100644
--- a/fuzz/x509.c
+++ b/fuzz/x509.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL licenses, (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index cd5c23217a51b..0cd6b2f948585 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -39,8 +39,8 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-# define OPENSSL_VERSION_NUMBER  0x101010afL
-# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1j  16 Feb 2021"
+# define OPENSSL_VERSION_NUMBER  0x101010bfL
+# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1k  25 Mar 2021"
 
 /*-
  * The macros below are to be used for shared library (.so, .dll, ...)
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 4511b52c9afcb..b256a4b93503e 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  * Copyright 2005 Nokia. All rights reserved.
  *
@@ -4629,6 +4629,7 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
 
         OPENSSL_clear_free(s->s3->tmp.psk, psklen);
         s->s3->tmp.psk = NULL;
+        s->s3->tmp.psklen = 0;
         if (!s->method->ssl3_enc->generate_master_secret(s,
                     s->session->master_key, pskpms, pskpmslen,
                     &s->session->master_key_length)) {
@@ -4658,8 +4659,10 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
         else
             OPENSSL_cleanse(pms, pmslen);
     }
-    if (s->server == 0)
+    if (s->server == 0) {
         s->s3->tmp.pms = NULL;
+        s->s3->tmp.pmslen = 0;
+    }
     return ret;
 }
 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 98057921f8406..58f8f3c14cfa0 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  * Copyright 2005 Nokia. All rights reserved.
  *
@@ -779,8 +779,10 @@ SSL *SSL_new(SSL_CTX *ctx)
         s->ext.ecpointformats =
             OPENSSL_memdup(ctx->ext.ecpointformats,
                            ctx->ext.ecpointformats_len);
-        if (!s->ext.ecpointformats)
+        if (!s->ext.ecpointformats) {
+            s->ext.ecpointformats_len = 0;
             goto err;
+        }
         s->ext.ecpointformats_len =
             ctx->ext.ecpointformats_len;
     }
@@ -789,8 +791,10 @@ SSL *SSL_new(SSL_CTX *ctx)
             OPENSSL_memdup(ctx->ext.supportedgroups,
                            ctx->ext.supportedgroups_len
                                 * sizeof(*ctx->ext.supportedgroups));
-        if (!s->ext.supportedgroups)
+        if (!s->ext.supportedgroups) {
+            s->ext.supportedgroups_len = 0;
             goto err;
+        }
         s->ext.supportedgroups_len = ctx->ext.supportedgroups_len;
     }
 #endif
@@ -800,8 +804,10 @@ SSL *SSL_new(SSL_CTX *ctx)
 
     if (s->ctx->ext.alpn) {
         s->ext.alpn = OPENSSL_malloc(s->ctx->ext.alpn_len);
-        if (s->ext.alpn == NULL)
+        if (s->ext.alpn == NULL) {
+            s->ext.alpn_len = 0;
             goto err;
+        }
         memcpy(s->ext.alpn, s->ctx->ext.alpn, s->ctx->ext.alpn_len);
         s->ext.alpn_len = s->ctx->ext.alpn_len;
     }
@@ -2834,6 +2840,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
     OPENSSL_free(ctx->ext.alpn);
     ctx->ext.alpn = OPENSSL_memdup(protos, protos_len);
     if (ctx->ext.alpn == NULL) {
+        ctx->ext.alpn_len = 0;
         SSLerr(SSL_F_SSL_CTX_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
         return 1;
     }
@@ -2853,6 +2860,7 @@ int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
     OPENSSL_free(ssl->ext.alpn);
     ssl->ext.alpn = OPENSSL_memdup(protos, protos_len);
     if (ssl->ext.alpn == NULL) {
+        ssl->ext.alpn_len = 0;
         SSLerr(SSL_F_SSL_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
         return 1;
     }
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 9f51a6eb28d9a..e1a3b1db67a10 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -336,6 +336,8 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_construct_stoc_key_share, tls_construct_ctos_key_share,
         final_key_share
     },
+#else
+    INVALID_EXTENSION,
 #endif
     {
         /* Must be after key_share */
@@ -1137,6 +1139,7 @@ static int init_sig_algs(SSL *s, unsigned int context)
     /* Clear any signature algorithms extension received */
     OPENSSL_free(s->s3->tmp.peer_sigalgs);
     s->s3->tmp.peer_sigalgs = NULL;
+    s->s3->tmp.peer_sigalgslen = 0;
 
     return 1;
 }
@@ -1146,6 +1149,7 @@ static int init_sig_algs_cert(SSL *s, unsigned int context)
     /* Clear any signature algorithms extension received */
     OPENSSL_free(s->s3->tmp.peer_cert_sigalgs);
     s->s3->tmp.peer_cert_sigalgs = NULL;
+    s->s3->tmp.peer_cert_sigalgslen = 0;
 
     return 1;
 }
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index bcce0f1d9534b..ce8a75794c3ad 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -816,6 +816,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt,
         OPENSSL_free(s->psksession_id);
         s->psksession_id = OPENSSL_memdup(id, idlen);
         if (s->psksession_id == NULL) {
+            s->psksession_id_len = 0;
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR);
             return EXT_RETURN_FAIL;
@@ -1375,6 +1376,7 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context,
         OPENSSL_free(s->ext.peer_ecpointformats);
         s->ext.peer_ecpointformats = OPENSSL_malloc(ecpointformats_len);
         if (s->ext.peer_ecpointformats == NULL) {
+            s->ext.peer_ecpointformats_len = 0;
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
             return 0;
@@ -1492,8 +1494,13 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
         s->ext.scts_len = (uint16_t)size;
         if (size > 0) {
             s->ext.scts = OPENSSL_malloc(size);
-            if (s->ext.scts == NULL
-                    || !PACKET_copy_bytes(pkt, s->ext.scts, size)) {
+            if (s->ext.scts == NULL) {
+                s->ext.scts_len = 0;
+                SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SCT,
+                         ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+            if (!PACKET_copy_bytes(pkt, s->ext.scts, size)) {
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SCT,
                          ERR_R_INTERNAL_ERROR);
                 return 0;
@@ -1592,6 +1599,7 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
     OPENSSL_free(s->ext.npn);
     s->ext.npn = OPENSSL_malloc(selected_len);
     if (s->ext.npn == NULL) {
+        s->ext.npn_len = 0;
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_NPN,
                  ERR_R_INTERNAL_ERROR);
         return 0;
@@ -1632,6 +1640,7 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
     OPENSSL_free(s->s3->alpn_selected);
     s->s3->alpn_selected = OPENSSL_malloc(len);
     if (s->s3->alpn_selected == NULL) {
+        s->s3->alpn_selected_len = 0;
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN,
                  ERR_R_INTERNAL_ERROR);
         return 0;
@@ -1663,6 +1672,7 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
         s->session->ext.alpn_selected =
             OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len);
         if (s->session->ext.alpn_selected == NULL) {
+            s->session->ext.alpn_selected_len = 0;
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN,
                      ERR_R_INTERNAL_ERROR);
             return 0;
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index d84cc0460f4e2..de58f1a4b7e9f 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -2462,6 +2462,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
         s->s3->tmp.ctype_len = 0;
         OPENSSL_free(s->pha_context);
         s->pha_context = NULL;
+        s->pha_context_len = 0;
 
         if (!PACKET_get_length_prefixed_1(pkt, &reqctx) ||
             !PACKET_memdup(&reqctx, &s->pha_context, &s->pha_context_len)) {
@@ -2771,16 +2772,17 @@ int tls_process_cert_status_body(SSL *s, PACKET *pkt)
     }
     s->ext.ocsp.resp = OPENSSL_malloc(resplen);
     if (s->ext.ocsp.resp == NULL) {
+        s->ext.ocsp.resp_len = 0;
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY,
                  ERR_R_MALLOC_FAILURE);
         return 0;
     }
+    s->ext.ocsp.resp_len = resplen;
     if (!PACKET_copy_bytes(pkt, s->ext.ocsp.resp, resplen)) {
         SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY,
                  SSL_R_LENGTH_MISMATCH);
         return 0;
     }
-    s->ext.ocsp.resp_len = resplen;
 
     return 1;
 }
@@ -2905,6 +2907,7 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt)
     if (psklen > PSK_MAX_PSK_LEN) {
         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
                  SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+        psklen = PSK_MAX_PSK_LEN;   /* Avoid overrunning the array on cleanse */
         goto err;
     } else if (psklen == 0) {
         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
@@ -3350,9 +3353,11 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt)
  err:
     OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
     s->s3->tmp.pms = NULL;
+    s->s3->tmp.pmslen = 0;
 #ifndef OPENSSL_NO_PSK
     OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
     s->s3->tmp.psk = NULL;
+    s->s3->tmp.psklen = 0;
 #endif
     return 0;
 }
@@ -3427,6 +3432,7 @@ int tls_client_key_exchange_post_work(SSL *s)
  err:
     OPENSSL_clear_free(pms, pmslen);
     s->s3->tmp.pms = NULL;
+    s->s3->tmp.pmslen = 0;
     return 0;
 }
 
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index cf45a40ce4e3e..fec12f613004e 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  * Copyright 2005 Nokia. All rights reserved.
  *
@@ -2178,6 +2178,7 @@ int tls_handle_alpn(SSL *s)
             OPENSSL_free(s->s3->alpn_selected);
             s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
             if (s->s3->alpn_selected == NULL) {
+                s->s3->alpn_selected_len = 0;
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_HANDLE_ALPN,
                          ERR_R_INTERNAL_ERROR);
                 return 0;
@@ -2853,9 +2854,16 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
         if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) {
             OPENSSL_free(s->pha_context);
             s->pha_context_len = 32;
-            if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL
-                    || RAND_bytes(s->pha_context, s->pha_context_len) <= 0
-                    || !WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) {
+            if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL) {
+                s->pha_context_len = 0;
+                SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+                         SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
+                         ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+            if (RAND_bytes(s->pha_context, s->pha_context_len) <= 0
+                    || !WPACKET_sub_memcpy_u8(pkt, s->pha_context,
+                                              s->pha_context_len)) {
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                          SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
                          ERR_R_INTERNAL_ERROR);
@@ -2969,6 +2977,7 @@ static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt)
     OPENSSL_cleanse(psk, psklen);
 
     if (s->s3->tmp.psk == NULL) {
+        s->s3->tmp.psklen = 0;
         SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                  SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, ERR_R_MALLOC_FAILURE);
         return 0;
@@ -3508,6 +3517,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
 #ifndef OPENSSL_NO_PSK
     OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
     s->s3->tmp.psk = NULL;
+    s->s3->tmp.psklen = 0;
 #endif
     return MSG_PROCESS_ERROR;
 }
@@ -4117,6 +4127,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
             s->session->ext.alpn_selected =
                 OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len);
             if (s->session->ext.alpn_selected == NULL) {
+                s->session->ext.alpn_selected_len = 0;
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                          SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
                          ERR_R_MALLOC_FAILURE);
diff --git a/test/recipes/70-test_renegotiation.t b/test/recipes/70-test_renegotiation.t
index 734f1cd21e6d0..a8162189edcdc 100644
--- a/test/recipes/70-test_renegotiation.t
+++ b/test/recipes/70-test_renegotiation.t
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -38,7 +38,7 @@ my $proxy = TLSProxy::Proxy->new(
 $proxy->clientflags("-no_tls1_3");
 $proxy->reneg(1);
 $proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
-plan tests => 3;
+plan tests => 4;
 ok(TLSProxy::Message->success(), "Basic renegotiation");
 
 #Test 2: Client does not send the Reneg SCSV. Reneg should fail
@@ -77,6 +77,20 @@ SKIP: {
        "Check ClientHello version is the same");
 }
 
+SKIP: {
+    skip "TLSv1.2 disabled", 1
+        if disabled("tls1_2");
+
+    #Test 4: Test for CVE-2021-3449. client_sig_algs instead of sig_algs in
+    #        resumption ClientHello
+    $proxy->clear();
+    $proxy->filter(\&sigalgs_filter);
+    $proxy->clientflags("-tls1_2");
+    $proxy->reneg(1);
+    $proxy->start();
+    ok(TLSProxy::Message->fail(), "client_sig_algs instead of sig_algs");
+}
+
 sub reneg_filter
 {
     my $proxy = shift;
@@ -96,3 +110,23 @@ sub reneg_filter
         }
     }
 }
+
+sub sigalgs_filter
+{
+    my $proxy = shift;
+    my $cnt = 0;
+
+    # We're only interested in the second ClientHello message
+    foreach my $message (@{$proxy->message_list}) {
+        if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
+            next if ($cnt++ == 0);
+
+            my $sigs = pack "C10", 0x00, 0x08,
+                            # rsa_pkcs_sha{256,384,512,1}
+                            0x04, 0x01,  0x05, 0x01,  0x06, 0x01,  0x02, 0x01;
+            $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS_CERT, $sigs);
+            $message->delete_extension(TLSProxy::Message::EXT_SIG_ALGS);
+            $message->repack();
+        }
+    }
+}
diff --git a/test/rsa_test.c b/test/rsa_test.c
index 11e373cceb1b3..be6db029410c3 100644
--- a/test/rsa_test.c
+++ b/test/rsa_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -304,7 +304,7 @@ static int test_rsa_sslv23(int idx)
 static int test_rsa_oaep(int idx)
 {
     int ret = 0;
-    RSA *key;
+    RSA *key = NULL;
     unsigned char ptext[256];
     unsigned char ctext[256];
     static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
diff --git a/test/verify_extra_test.c b/test/verify_extra_test.c
index 010403e74ac20..b9959e0c6665c 100644
--- a/test/verify_extra_test.c
+++ b/test/verify_extra_test.c
@@ -140,10 +140,22 @@ static int test_alt_chains_cert_forgery(void)
 
     i = X509_verify_cert(sctx);
 
-    if (i == 0 && X509_STORE_CTX_get_error(sctx) == X509_V_ERR_INVALID_CA) {
+    if (i != 0 || X509_STORE_CTX_get_error(sctx) != X509_V_ERR_INVALID_CA)
+        goto err;
+
+    /* repeat with X509_V_FLAG_X509_STRICT */
+    X509_STORE_CTX_cleanup(sctx);
+    X509_STORE_set_flags(store, X509_V_FLAG_X509_STRICT);
+
+    if (!X509_STORE_CTX_init(sctx, store, x, untrusted))
+        goto err;
+
+    i = X509_verify_cert(sctx);
+
+    if (i == 0 && X509_STORE_CTX_get_error(sctx) == X509_V_ERR_INVALID_CA)
         /* This is the result we were expecting: Test passed */
         ret = 1;
-    }
+
  err:
     X509_STORE_CTX_free(sctx);
     X509_free(x);
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
index 421fd892086f9..fa7c6c9fef91a 100644
--- a/tools/c_rehash.in
+++ b/tools/c_rehash.in
@@ -1,7 +1,7 @@
 #!{- $config{HASHBANGPERL} -}
 
 # {- join("\n# ", @autowarntext) -}
-# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -161,7 +161,7 @@ sub check_file {
 
 sub link_hash_cert {
 		my $fname = $_[0];
-		$fname =~ s/'/'\\''/g;
+		$fname =~ s/\"/\\\"/g;
 		my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
 		chomp $hash;
 		chomp $fprint;
diff --git a/util/perl/TLSProxy/Message.pm b/util/perl/TLSProxy/Message.pm
index 10b61560746a9..c3c480669c66f 100644
--- a/util/perl/TLSProxy/Message.pm
+++ b/util/perl/TLSProxy/Message.pm
@@ -1,4 +1,4 @@
-# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -448,7 +448,7 @@ sub ciphersuite
 }
 
 #Update all the underlying records with the modified data from this message
-#Note: Only supports re-encrypting for TLSv1.3
+#Note: Only supports TLSv1.3 and ETM encryption
 sub repack
 {
     my $self = shift;
@@ -490,15 +490,38 @@ sub repack
         # (If a length override is ever needed to construct invalid packets,
         #  use an explicit override field instead.)
         $rec->decrypt_len(length($rec->decrypt_data));
-        $rec->len($rec->len + length($msgdata) - $old_length);
-        # Only support re-encryption for TLSv1.3.
-        if (TLSProxy::Proxy->is_tls13() && $rec->encrypted()) {
+        # Only support re-encryption for TLSv1.3 and ETM.
+        if ($rec->encrypted()) {
+            if (TLSProxy::Proxy->is_tls13()) {
                 #Add content type (1 byte) and 16 tag bytes
                 $rec->data($rec->decrypt_data
                     .pack("C", TLSProxy::Record::RT_HANDSHAKE).("\0"x16));
+            } elsif ($rec->etm()) {
+                my $data = $rec->decrypt_data;
+                #Add padding
+                my $padval = length($data) % 16;
+                $padval = 15 - $padval;
+                for (0..$padval) {
+                    $data .= pack("C", $padval);
+                }
+
+                #Add MAC. Assumed to be 20 bytes
+                foreach my $macval (0..19) {
+                    $data .= pack("C", $macval);
+                }
+
+                if ($rec->version() >= TLSProxy::Record::VERS_TLS_1_1) {
+                    #Explicit IV
+                    $data = ("\0"x16).$data;
+                }
+                $rec->data($data);
+            } else {
+                die "Unsupported encryption: No ETM";
+            }
         } else {
             $rec->data($rec->decrypt_data);
         }
+        $rec->len(length($rec->data));
 
         #Update the fragment len in case we changed it above
         ${$self->message_frag_lens}[0] = length($msgdata)

Reply to: