From 4e6630d3335856b56c1c7bec6c0e7f6e892c25bf Mon Sep 17 00:00:00 2001
From: importbot <releng@rockylinux.org>
Date: Wed, 9 Oct 2024 20:46:33 +0000
Subject: [PATCH] import openssl-1.1.1k-14.el8_6

---
 .openssl.checksum                             |   2 +-
 ...enssl-1.1.1-cleanup-peer-point-reneg.patch |   8 +-
 ...nssl-1.1.1-fix-ssl-select-next-proto.patch | 255 ++++++++++++++++++
 SPECS/openssl.spec                            |  35 ++-
 4 files changed, 279 insertions(+), 21 deletions(-)
 create mode 100644 SOURCES/openssl-1.1.1-fix-ssl-select-next-proto.patch

diff --git a/.openssl.checksum b/.openssl.checksum
index 1a0d399..6b585f3 100644
--- a/.openssl.checksum
+++ b/.openssl.checksum
@@ -1 +1 @@
-dc072a144f8e63b314f20f3ef95f9d371f51dcf31417449831adeedd48f86020
+c97b10d6a034e025a19ec8443ef7c80755e3a407fe29a77dda95af958b199eed
diff --git a/SOURCES/openssl-1.1.1-cleanup-peer-point-reneg.patch b/SOURCES/openssl-1.1.1-cleanup-peer-point-reneg.patch
index a98d34e..8ea99e0 100644
--- a/SOURCES/openssl-1.1.1-cleanup-peer-point-reneg.patch
+++ b/SOURCES/openssl-1.1.1-cleanup-peer-point-reneg.patch
@@ -1,13 +1,11 @@
 diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl/statem/extensions.c
 --- openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg	2021-03-25 14:28:38.000000000 +0100
 +++ openssl-1.1.1k/ssl/statem/extensions.c	2021-06-24 16:16:19.526181743 +0200
-@@ -42,6 +42,9 @@ static int tls_parse_certificate_authori
+@@ -42,6 +42,7 @@ static int tls_parse_certificate_authori
  #ifndef OPENSSL_NO_SRP
  static int init_srp(SSL *s, unsigned int context);
  #endif
-+#ifndef OPENSSL_NO_EC
 +static int init_ec_point_formats(SSL *s, unsigned int context);
-+#endif
  static int init_etm(SSL *s, unsigned int context);
  static int init_ems(SSL *s, unsigned int context);
  static int final_ems(SSL *s, unsigned int context, int sent);
@@ -20,11 +18,10 @@ diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl
          tls_construct_stoc_ec_pt_formats, tls_construct_ctos_ec_pt_formats,
          final_ec_pt_formats
      },
-@@ -1164,6 +1165,17 @@ static int init_srp(SSL *s, unsigned int
+@@ -1164,6 +1165,15 @@ static int init_srp(SSL *s, unsigned int
  }
  #endif
  
-+#ifndef OPENSSL_NO_EC
 +static int init_ec_point_formats(SSL *s, unsigned int context)
 +{
 +	    OPENSSL_free(s->ext.peer_ecpointformats);
@@ -33,7 +30,6 @@ diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl
 +
 +	    return 1;
 +}
-+#endif
 +
  static int init_etm(SSL *s, unsigned int context)
  {
diff --git a/SOURCES/openssl-1.1.1-fix-ssl-select-next-proto.patch b/SOURCES/openssl-1.1.1-fix-ssl-select-next-proto.patch
new file mode 100644
index 0000000..4ddc940
--- /dev/null
+++ b/SOURCES/openssl-1.1.1-fix-ssl-select-next-proto.patch
@@ -0,0 +1,255 @@
+From d1d4b56fe0c9a4200276d630f62108e1165e0990 Mon Sep 17 00:00:00 2001
+From: Maurizio Barbaro <mbarbaro@redhat.com>
+Date: Mon, 16 Sep 2024 10:53:53 +0200
+Subject: [PATCH] Backport openssl: SSL_select_next_proto buffer overread from 3.2
+
+Ensure that the provided client list is non-NULL and starts with a valid
+entry. When called from the ALPN callback the client list should already
+have been validated by OpenSSL so this should not cause a problem. When
+called from the NPN callback the client list is locally configured and
+will not have already been validated. Therefore SSL_select_next_proto
+should not assume that it is correctly formatted.
+
+We implement stricter checking of the client protocol list. We also do the
+same for the server list while we are about it.
+
+CVE-2024-5535
+
+From: Matt Caswell <matt@openssl.org>
+Date: Fri, 31 May 2024 11:14:33 +0100
+Merged from: https://github.com/openssl/openssl/pull/24717.
+
+Backported-by: Maurizio Barbaro <mbarbaro@redhat.com> 
+we did't ported test changes because rely on internal testing framework.
+
+---
+ doc/man3/SSL_CTX_set_alpn_select_cb.pod | 28 +++++++----
+ ssl/ssl_lib.c                           | 64 +++++++++++++++----------
+ ssl/statem/extensions_clnt.c            | 30 +++++++++++-
+ ssl/statem/extensions_srvr.c            |  3 +-
+ 4 files changed, 89 insertions(+), 36 deletions(-)
+
+diff --git a/doc/man3/SSL_CTX_set_alpn_select_cb.pod b/doc/man3/SSL_CTX_set_alpn_select_cb.pod
+index e90caec..a3f8dfd 100644
+--- a/doc/man3/SSL_CTX_set_alpn_select_cb.pod
++++ b/doc/man3/SSL_CTX_set_alpn_select_cb.pod
+@@ -43,7 +43,7 @@ SSL_select_next_proto, SSL_get0_alpn_selected, SSL_get0_next_proto_negotiated
+                            const unsigned char *server,
+                            unsigned int server_len,
+                            const unsigned char *client,
+-                           unsigned int client_len)
++                           unsigned int client_len);
+  void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
+                              unsigned *len);
+ 
+@@ -52,7 +52,8 @@ SSL_select_next_proto, SSL_get0_alpn_selected, SSL_get0_next_proto_negotiated
+ SSL_CTX_set_alpn_protos() and SSL_set_alpn_protos() are used by the client to
+ set the list of protocols available to be negotiated. The B<protos> must be in
+ protocol-list format, described below. The length of B<protos> is specified in
+-B<protos_len>.
++B<protos_len>. Setting B<protos_len> to 0 clears any existing list of ALPN
++protocols and no ALPN extension will be sent to the server.
+ 
+ SSL_CTX_set_alpn_select_cb() sets the application callback B<cb> used by a
+ server to select which protocol to use for the incoming connection. When B<cb>
+@@ -73,9 +74,16 @@ B<server_len> and B<client>, B<client_len> must be in the protocol-list format
+ described below. The first item in the B<server>, B<server_len> list that
+ matches an item in the B<client>, B<client_len> list is selected, and returned
+ in B<out>, B<outlen>. The B<out> value will point into either B<server> or
+-B<client>, so it should be copied immediately. If no match is found, the first
+-item in B<client>, B<client_len> is returned in B<out>, B<outlen>. This
+-function can also be used in the NPN callback.
++B<client>, so it should be copied immediately. The client list must include at
++least one valid (nonempty) protocol entry in the list.
++
++The SSL_select_next_proto() helper function can be useful from either the ALPN
++callback or the NPN callback (described below). If no match is found, the first
++item in B<client>, B<client_len> is returned in B<out>, B<outlen> and
++B<OPENSSL_NPN_NO_OVERLAP> is returned. This can be useful when implementating
++the NPN callback. In the ALPN case, the value returned in B<out> and B<outlen>
++must be ignored if B<OPENSSL_NPN_NO_OVERLAP> has been returned from
++SSL_select_next_proto().
+ 
+ SSL_CTX_set_next_proto_select_cb() sets a callback B<cb> that is called when a
+ client needs to select a protocol from the server's provided list, and a
+@@ -85,9 +93,10 @@ must be set to point to the selected protocol (which may be within B<in>).
+ The length of the protocol name must be written into B<outlen>. The
+ server's advertised protocols are provided in B<in> and B<inlen>. The
+ callback can assume that B<in> is syntactically valid. The client must
+-select a protocol. It is fatal to the connection if this callback returns
+-a value other than B<SSL_TLSEXT_ERR_OK>. The B<arg> parameter is the pointer
+-set via SSL_CTX_set_next_proto_select_cb().
++select a protocol (although it may be an empty, zero length protocol). It is
++fatal to the connection if this callback returns a value other than
++B<SSL_TLSEXT_ERR_OK> or if the zero length protocol is selected. The B<arg>
++parameter is the pointer set via SSL_CTX_set_next_proto_select_cb().
+ 
+ SSL_CTX_set_next_protos_advertised_cb() sets a callback B<cb> that is called
+ when a TLS server needs a list of supported protocols for Next Protocol
+@@ -149,7 +158,8 @@ A match was found and is returned in B<out>, B<outlen>.
+ =item OPENSSL_NPN_NO_OVERLAP
+ 
+ No match was found. The first item in B<client>, B<client_len> is returned in
+-B<out>, B<outlen>.
++B<out>, B<outlen> (or B<NULL> and 0 in the case where the first entry in
++B<client> is invalid).
+ 
+ =back
+ 
+diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
+index c71c686..21e6c45 100644
+--- a/ssl/ssl_lib.c
++++ b/ssl/ssl_lib.c
+@@ -2739,38 +2739,54 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+                           unsigned int server_len,
+                           const unsigned char *client, unsigned int client_len)
+ {
+-    unsigned int i, j;
+-    const unsigned char *result;
+-    int status = OPENSSL_NPN_UNSUPPORTED;
++    PACKET cpkt, csubpkt, spkt, ssubpkt;
++    if (!PACKET_buf_init(&cpkt, client, client_len)
++            || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt)
++            || PACKET_remaining(&csubpkt) == 0) {
++        *out = NULL;
++        *outlen = 0;
++        return OPENSSL_NPN_NO_OVERLAP;
++    }
++
++    /*
++     * Set the default opportunistic protocol. Will be overwritten if we find
++     * a match.
++     */
++    *out = (unsigned char *)PACKET_data(&csubpkt);
++    *outlen = (unsigned char)PACKET_remaining(&csubpkt);
+ 
+     /*
+      * For each protocol in server preference order, see if we support it.
+      */
+-    for (i = 0; i < server_len;) {
+-        for (j = 0; j < client_len;) {
+-            if (server[i] == client[j] &&
+-                memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
+-                /* We found a match */
+-                result = &server[i];
+-                status = OPENSSL_NPN_NEGOTIATED;
+-                goto found;
++    if (PACKET_buf_init(&spkt, server, server_len)) {
++       while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) {
++            if (PACKET_remaining(&ssubpkt) == 0)
++                continue; /* Invalid - ignore it */
++            if (PACKET_buf_init(&cpkt, client, client_len)) {
++                while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) {
++                    if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt),
++                                     PACKET_remaining(&ssubpkt))) {
++                        /* We found a match */
++                        *out = (unsigned char *)PACKET_data(&ssubpkt);
++                        *outlen = (unsigned char)PACKET_remaining(&ssubpkt);
++                        return OPENSSL_NPN_NEGOTIATED;
++                    }
++                }
++                /* Ignore spurious trailing bytes in the client list */
++            } else {
++                /* This should never happen */
++                return OPENSSL_NPN_NO_OVERLAP;
+             }
+-            j += client[j];
+-            j++;
+         }
+-        i += server[i];
+-        i++;
++        /* Ignore spurious trailing bytes in the server list */
+     }
+ 
+-    /* There's no overlap between our protocols and the server's list. */
+-    result = client;
+-    status = OPENSSL_NPN_NO_OVERLAP;
+-
+- found:
+-    *out = (unsigned char *)result + 1;
+-    *outlen = result[0];
+-    return status;
+-}
++    /*
++     * There's no overlap between our protocols and the server's list. We use
++     * the default opportunistic protocol selected earlier
++     */
++    return OPENSSL_NPN_NO_OVERLAP;
++ } 
+ 
+ #ifndef OPENSSL_NO_NEXTPROTONEG
+ /*
+diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
+index ce8a757..cfde733 100644
+--- a/ssl/statem/extensions_clnt.c
++++ b/ssl/statem/extensions_clnt.c
+@@ -1585,8 +1585,8 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
+     if (s->ctx->ext.npn_select_cb(s, &selected, &selected_len,
+                                   PACKET_data(pkt),
+                                   PACKET_remaining(pkt),
+-                                  s->ctx->ext.npn_select_cb_arg) !=
+-             SSL_TLSEXT_ERR_OK) {
++                                  s->ctx->ext.npn_select_cb_arg) != SSL_TLSEXT_ERR_OK
++           || selected_len == 0) {           
+         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_STOC_NPN,
+                  SSL_R_BAD_EXTENSION);
+         return 0;
+@@ -1617,6 +1617,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
+                         size_t chainidx)
+ {
+     size_t len;
++    PACKET confpkt, protpkt;
++    int valid = 0;
+ 
+     /* We must have requested it. */
+     if (!s->s3->alpn_sent) {
+@@ -1637,6 +1639,30 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
+                  SSL_R_BAD_EXTENSION);
+         return 0;
+     }
++
++    /* It must be a protocol that we sent */
++    if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) {
++        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, 
++                 ERR_R_INTERNAL_ERROR);
++        return 0;
++    }
++    while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) {
++        if (PACKET_remaining(&protpkt) != len)
++            continue;
++        if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) {
++            /* Valid protocol found */
++            valid = 1;
++            break;
++        }
++    }
++
++    if (!valid) {
++        /* The protocol sent from the server does not match one we advertised */
++        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_ALPN,
++                 SSL_R_BAD_EXTENSION);
++        return 0;
++    }
++
+     OPENSSL_free(s->s3->alpn_selected);
+     s->s3->alpn_selected = OPENSSL_malloc(len);
+     if (s->s3->alpn_selected == NULL) {
+diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
+index 3c7395c..4e3cbf8 100644
+--- a/ssl/statem/extensions_srvr.c
++++ b/ssl/statem/extensions_srvr.c
+@@ -1559,9 +1559,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt,
+             return EXT_RETURN_FAIL;
+         }
+         s->s3->npn_seen = 1;
++        return EXT_RETURN_SENT;
+     }
+ 
+-    return EXT_RETURN_SENT;
++    return EXT_RETURN_NOT_SENT;
+ }
+ #endif
+ 
+-- 
+2.46.0
+
diff --git a/SPECS/openssl.spec b/SPECS/openssl.spec
index 3adc841..6f98819 100644
--- a/SPECS/openssl.spec
+++ b/SPECS/openssl.spec
@@ -22,7 +22,7 @@
 Summary: Utilities from the general purpose cryptography library with TLS implementation
 Name: openssl
 Version: 1.1.1k
-Release: 12%{?dist}
+Release: 14%{?dist}
 Epoch: 1
 # We have to remove certain patented algorithms from the openssl source
 # tarball with the hobble-openssl script which is included below.
@@ -99,6 +99,9 @@ Patch107: openssl-1.1.1-cve-2023-5678.patch
 # Backport from OpenSSL 3.2/RHEL 9
 # Proper fix for CVE-2020-25659
 Patch108: openssl-1.1.1-pkcs1-implicit-rejection.patch
+# Backport from OpenSSL 3.2
+# Fix for CVE-2024-5535
+Patch109: openssl-1.1.1-fix-ssl-select-next-proto.patch
 
 License: OpenSSL and ASL 2.0
 URL: http://www.openssl.org/
@@ -232,6 +235,7 @@ cp %{SOURCE13} test/
 %patch106 -p1 -b .cve-2023-3817
 %patch107 -p1 -b .cve-2023-5678
 %patch108 -p1 -b .pkcs15imprejection
+%patch109 -p1 -b .cve-2024-5535
 
 %build
 # Figure out which flags we want to use.
@@ -515,49 +519,52 @@ export LD_LIBRARY_PATH
 %postun libs -p /sbin/ldconfig
 
 %changelog
+* Tue Sep 17 2024 Maurizio Barbaro <mbarbaro@redhat.com> - 1:1.1.1k-14
+- Backport fix SSL_select_next proto from OpenSSL 3.2
+  Fix CVE-2024-5535 
+  Resolves: RHEL-45654
+
 * Thu Nov 30 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-12
 - Backport implicit rejection mechanism for RSA PKCS#1 v1.5 to RHEL-8 series
   (a proper fix for CVE-2020-25659)
-  Resolves: RHEL-17696
+  Resolves: RHEL-17694
 
 * Wed Nov 15 2023 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-11
 - Fix CVE-2023-5678: Generating excessively long X9.42 DH keys or checking
   excessively long X9.42 DH keys or parameters may be very slow
-  Resolves: RHEL-16538
+  Resolves: RHEL-16536
 
 * Thu Oct 19 2023 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-10
 - Fix CVE-2023-3446: Excessive time spent checking DH keys and parameters
-  Resolves: RHEL-14245
+  Resolves: RHEL-14243
 - Fix CVE-2023-3817: Excessive time spent checking DH q parameter value
-  Resolves: RHEL-14239
+  Resolves: RHEL-14237
 
-* Wed Feb 08 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-9
+* Thu May 04 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-9
 - Fixed Timing Oracle in RSA Decryption
   Resolves: CVE-2022-4304
 - Fixed Double free after calling PEM_read_bio_ex
   Resolves: CVE-2022-4450
 - Fixed Use-after-free following BIO_new_NDEF
   Resolves: CVE-2023-0215
+
+* Wed Feb 08 2023 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-8
 - Fixed X.400 address type confusion in X.509 GeneralName
   Resolves: CVE-2023-0286
 
-* Thu Jul 21 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:1.1.1k-8
-- Fix no-ec build
-  Resolves: rhbz#2071020
-
 * Tue Jul 05 2022 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-7
 - Fix CVE-2022-2097: AES OCB fails to encrypt some bytes on 32-bit x86
   Resolves: CVE-2022-2097
 - Update expired certificates used in the testsuite
-  Resolves: rhbz#2092462
+  Resolves: rhbz#2100554
 - Fix CVE-2022-1292: openssl: c_rehash script allows command injection
-  Resolves: rhbz#2090372
+  Resolves: rhbz#2090371
 - Fix CVE-2022-2068: the c_rehash script allows command injection
-  Resolves: rhbz#2098279
+  Resolves: rhbz#2098278
 
 * Wed Mar 23 2022 Clemens Lang <cllang@redhat.com> - 1:1.1.1k-6
 - Fixes CVE-2022-0778 openssl: Infinite loop in BN_mod_sqrt() reachable when parsing certificates
-- Resolves: rhbz#2067146
+- Resolves: rhbz#2067145
 
 * Tue Nov 16 2021 Sahana Prasad <sahana@redhat.com> - 1:1.1.1k-5
 - Fixes CVE-2021-3712 openssl: Read buffer overruns processing ASN.1 strings
-- 
GitLab