Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package openssl-3 for openSUSE:Factory 
checked in at 2026-04-11 22:24:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openssl-3 (Old)
 and      /work/SRC/openSUSE:Factory/.openssl-3.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openssl-3"

Sat Apr 11 22:24:40 2026 rev:49 rq:1345575 version:3.5.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/openssl-3/openssl-3.changes      2026-03-01 
22:13:37.655011059 +0100
+++ /work/SRC/openSUSE:Factory/.openssl-3.new.21863/openssl-3.changes   
2026-04-11 22:29:23.519796211 +0200
@@ -1,0 +2,41 @@
+Tue Apr  7 20:16:04 UTC 2026 - Lucas Mulling <[email protected]>
+
+- Adapt spec file for immutability via systemd-tmpfiles (jsc#PED-14813)
+- Fix check %{suse_version} > 1600 (jsc#PED-15816)
+
+-------------------------------------------------------------------
+Thu Mar 26 11:28:38 UTC 2026 - Pedro Monreal <[email protected]>
+
+- Security fixes:
+  * CVE-2026-28387: Potential use-after-free in DANE client code
+    (bsc#1260441)
+  * CVE-2026-28388: NULL Pointer Dereference When Processing a
+    Delta (bsc#1260442)
+  * CVE-2026-28389: Possible NULL dereference when processing CMS
+    KeyAgreeRecipientInfo (bsc#1260443)
+  * CVE-2026-31789: Heap buffer overflow in hexadecimal conversion
+    (bsc#1260444)
+  * CVE-2026-31790: Incorrect failure handling in RSA KEM RSASVE
+    encapsulation (bsc#1260445)
+  * CVE-2026-28390: NULL pointer dereference during processing of a crafted CMS
+    EnvelopedData message with KeyTransportRecipientInfo (bsc#1261678)
+  * Add        patches: openssl-CVE-2026-28387.patch
+    openssl-CVE-2026-28388.patch openssl-CVE-2026-28388-tests.patch
+    openssl-CVE-2026-28389.patch openssl-CVE-2026-31789.patch
+    openssl-CVE-2026-31790.patch openssl-CVE-2026-31790-tests.patch
+    openssl-CVE-2026-28390.patch
+- Fix NULL pointer dereference when processing an OCSP response
+  * Add patch openssl-NULL-pointer-dereference-in-ocsp_find_signer_sk.patch
+
+-------------------------------------------------------------------
+Sun Mar 22 20:33:24 UTC 2026 - Lucas Mulling <[email protected]>
+
+- Security fix:
+  * CVE-2026-2673: TLS 1.3 servers may choose unexpected key agreement group 
(bsc#1259652)
+    Added patch openssl-CVE-2026-2673.patch
+    Added patch 
openssl-crypto-mem.c-factor-out-memory-allocation-failure-reporting.patch
+    Added patch openssl-Add-array-memory-allocation-routines.patch
+- Remove showciphers.c in favor of openssl ciphers
+- Use %ldconfig_scriptlets
+
+-------------------------------------------------------------------

Old:
----
  showciphers.c

New:
----
  openssl-Add-array-memory-allocation-routines.patch
  openssl-CVE-2026-2673.patch
  openssl-CVE-2026-28387.patch
  openssl-CVE-2026-28388-tests.patch
  openssl-CVE-2026-28388.patch
  openssl-CVE-2026-28389.patch
  openssl-CVE-2026-28390.patch
  openssl-CVE-2026-31789.patch
  openssl-CVE-2026-31790-tests.patch
  openssl-CVE-2026-31790.patch
  openssl-NULL-pointer-dereference-in-ocsp_find_signer_sk.patch
  openssl-crypto-mem.c-factor-out-memory-allocation-failure-reporting.patch

----------(New B)----------
  New:    Added patch 
openssl-crypto-mem.c-factor-out-memory-allocation-failure-reporting.patch
    Added patch openssl-Add-array-memory-allocation-routines.patch
- Remove showciphers.c in favor of openssl ciphers
  New:  * CVE-2026-2673: TLS 1.3 servers may choose unexpected key agreement 
group (bsc#1259652)
    Added patch openssl-CVE-2026-2673.patch
    Added patch 
openssl-crypto-mem.c-factor-out-memory-allocation-failure-reporting.patch
  New:    EnvelopedData message with KeyTransportRecipientInfo (bsc#1261678)
  * Add patches: openssl-CVE-2026-28387.patch
    openssl-CVE-2026-28388.patch openssl-CVE-2026-28388-tests.patch
  New:  * Add   patches: openssl-CVE-2026-28387.patch
    openssl-CVE-2026-28388.patch openssl-CVE-2026-28388-tests.patch
    openssl-CVE-2026-28389.patch openssl-CVE-2026-31789.patch
  New:  * Add   patches: openssl-CVE-2026-28387.patch
    openssl-CVE-2026-28388.patch openssl-CVE-2026-28388-tests.patch
    openssl-CVE-2026-28389.patch openssl-CVE-2026-31789.patch
  New:    openssl-CVE-2026-28388.patch openssl-CVE-2026-28388-tests.patch
    openssl-CVE-2026-28389.patch openssl-CVE-2026-31789.patch
    openssl-CVE-2026-31790.patch openssl-CVE-2026-31790-tests.patch
  New:    openssl-CVE-2026-31790.patch openssl-CVE-2026-31790-tests.patch
    openssl-CVE-2026-28390.patch
- Fix NULL pointer dereference when processing an OCSP response
  New:    openssl-CVE-2026-28388.patch openssl-CVE-2026-28388-tests.patch
    openssl-CVE-2026-28389.patch openssl-CVE-2026-31789.patch
    openssl-CVE-2026-31790.patch openssl-CVE-2026-31790-tests.patch
  New:    openssl-CVE-2026-28389.patch openssl-CVE-2026-31789.patch
    openssl-CVE-2026-31790.patch openssl-CVE-2026-31790-tests.patch
    openssl-CVE-2026-28390.patch
  New:    openssl-CVE-2026-28389.patch openssl-CVE-2026-31789.patch
    openssl-CVE-2026-31790.patch openssl-CVE-2026-31790-tests.patch
    openssl-CVE-2026-28390.patch
  New:- Fix NULL pointer dereference when processing an OCSP response
  * Add patch openssl-NULL-pointer-dereference-in-ocsp_find_signer_sk.patch
  New:    Added patch openssl-CVE-2026-2673.patch
    Added patch 
openssl-crypto-mem.c-factor-out-memory-allocation-failure-reporting.patch
    Added patch openssl-Add-array-memory-allocation-routines.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openssl-3.spec ++++++
--- /var/tmp/diff_new_pack.ZLIKCp/_old  2026-04-11 22:29:25.051858872 +0200
+++ /var/tmp/diff_new_pack.ZLIKCp/_new  2026-04-11 22:29:25.055859036 +0200
@@ -30,7 +30,7 @@
 %global sle_needs_crypto_policies 1
 %endif
 
-%if 0%{?suse_version} > 1600
+%if 0%{?suse_version} >= 1699
 %global openssl_test_flags HARNESS_JOBS=${RPM_BUILD_NCPUS}
 %endif
 
@@ -51,8 +51,7 @@
 # to get mtime of file:
 Source3:        %{name}.changes
 Source4:        baselibs.conf
-Source5:        showciphers.c
-Source6:        openssl-TESTS-Disable-default-provider-crypto-policies.patch
+Source5:        openssl-TESTS-Disable-default-provider-crypto-policies.patch
 # PATCH-FIX-OPENSUSE: Do not install html docs as it takes ages
 Patch1:         openssl-no-html-docs.patch
 Patch2:         openssl-truststore.patch
@@ -157,7 +156,26 @@
 Patch61:        openssl-CVE-2025-11187.patch
 # PATCH-FIX-UPSTREAM bsc#1256831 CVE-2025-15468: NULL dereference in 
SSL_CIPHER_find() function on unknown cipher ID
 Patch62:        openssl-CVE-2025-15468.patch
-
+# PATCH-FIX_UPSTREAM bsc#1259652 CVE-2026-2673: TLS 1.3 servers may choose 
unexpected key agreement group
+Patch63:        
openssl-crypto-mem.c-factor-out-memory-allocation-failure-reporting.patch
+Patch64:        openssl-Add-array-memory-allocation-routines.patch
+Patch65:        openssl-CVE-2026-2673.patch
+# PATCH-FIX-UPSTREAM CVE-2026-28387: Potential use-after-free in DANE client 
code (bsc#1260441)
+Patch66:        openssl-CVE-2026-28387.patch
+# PATCH-FIX-UPSTREAM CVE-2026-28388: NULL Pointer Dereference When Processing 
a Delta (bsc#1260442)
+Patch67:        openssl-CVE-2026-28388.patch
+Patch68:        openssl-CVE-2026-28388-tests.patch
+# PATCH-FIX-UPSTREAM CVE-2026-28389: Possible NULL dereference when processing 
CMS KeyAgreeRecipientInfo (bsc#1260443)
+Patch69:        openssl-CVE-2026-28389.patch
+# PATCH-FIX-UPSTREAM CVE-2026-31789: Heap buffer overflow in hexadecimal 
conversion (bsc#1260444)
+Patch70:        openssl-CVE-2026-31789.patch
+# PATCH-FIX-UPSTREAM CVE-2026-31790: Incorrect failure handling in RSA KEM 
RSASVE encapsulation (bsc#1260445)
+Patch71:        openssl-CVE-2026-31790.patch
+Patch72:        openssl-CVE-2026-31790-tests.patch
+# PATCH-FIX-UPSTREAM: NULL pointer dereference when processing an OCSP response
+Patch73:        openssl-NULL-pointer-dereference-in-ocsp_find_signer_sk.patch
+# PATCH-FIX-UPSTREAM CVE-2026-28390: NULL pointer dereference during 
processing of a crafted CMS EnvelopedData message with 
KeyTransportRecipientInfo (bsc#1261678)
+Patch74:        openssl-CVE-2026-28390.patch
 # ulp-macros is available according to SUSE version.
 %if 0%{?sle_version} >= 150400 || 0%{?suse_version} >= 1540
 BuildRequires:  ulp-macros
@@ -304,7 +322,7 @@
 %check
 # Relax the crypto-policies requirements and disable the default
 # provider for the test suite regression tests
-patch -p1 < %{SOURCE6}
+patch -p1 < %{SOURCE5}
 export OPENSSL_SYSTEM_CIPHERS_OVERRIDE=xyz_nonexistent_file
 export MALLOC_CHECK_=3
 export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
@@ -334,8 +352,8 @@
 %{nil}
 
 # show ciphers
-gcc -o showciphers %{optflags} -I%{buildroot}%{_includedir} %{SOURCE5} 
-L%{buildroot}%{_libdir} -lssl -lcrypto
-LD_LIBRARY_PATH=%{buildroot}%{_libdir} ./showciphers
+OPENSSL_CONF=/dev/null LD_LIBRARY_PATH=. apps/openssl ciphers
+OPENSSL_CONF=/dev/null LD_LIBRARY_PATH=. apps/openssl ciphers -s
 
 %install
 %{?pack_ipa_dumps}
@@ -363,10 +381,6 @@
 # Make a copy of the default openssl.cnf file
 cp %{buildroot}%{ssletcdir}/openssl.cnf 
%{buildroot}%{ssletcdir}/openssl-orig.cnf
 
-# Create openssl ca-certificates dir required by nodejs regression tests 
[bsc#1207484]
-mkdir -p %{buildroot}%{_localstatedir}/lib/ca-certificates/openssl
-install -d -m 555 %{buildroot}%{_localstatedir}/lib/ca-certificates/openssl
-
 # Remove the fipsmodule.cnf because FIPS module is loaded automatically in 
FIPS mode
 rm -f %{buildroot}%{ssletcdir}/fipsmodule.cnf
 
@@ -388,12 +402,16 @@
 # Do not install demo scripts executable under /usr/share/doc
 find demos -type f -perm /111 -exec chmod 644 {} +
 
-# Place showciphers.c for %%doc macro
-cp %{SOURCE5} .
-
 # Compute the FIPS hmac using the brp-50-generate-fips-hmac script
 export BRP_FIPSHMAC_FILES="%{buildroot}%{_libdir}/libssl.so.%{sover} 
%{buildroot}%{_libdir}/libcrypto.so.%{sover}"
 
+# Install tmpfiles.d and define the configuration for immutable mode 
(jsc#PED-14813)
+install -d %{buildroot}%{_tmpfilesdir}
+cat > %{buildroot}%{_tmpfilesdir}/%{_rname}-%{sover}.conf <<EOF
+d /var/lib/ca-certificates/ 0755 root root - -
+d /var/lib/ca-certificates/openssl/ 0555 root root - -
+EOF
+
 %post -p "/bin/bash"
 if [ "$1" -gt 1 ] ; then
     # Check if the packaged default config file for openssl-3, called 
openssl.cnf,
@@ -407,10 +425,12 @@
     fi
 fi
 
-%pre
-
-%post -n libopenssl3 -p /sbin/ldconfig
+%post -n libopenssl3
+%tmpfiles_create %{_tmpfilesdir}/%{_rname}-%{sover}.conf
+/sbin/ldconfig
+%end
 %postun -n libopenssl3 -p /sbin/ldconfig
+%end
 
 %files -n libopenssl3
 %license LICENSE.txt
@@ -430,8 +450,9 @@
 %config (noreplace) %{ssletcdir}/ct_log_list.cnf
 %dir %{_datadir}/ssl
 %{_datadir}/ssl/misc
-%dir %{_localstatedir}/lib/ca-certificates/
-%dir %{_localstatedir}/lib/ca-certificates/openssl
+%{_tmpfilesdir}/%{_rname}-%{sover}.conf
+%ghost %attr(0755,root,root) %dir %{_localstatedir}/lib/ca-certificates/
+%ghost %attr(0555,root,root) %dir %{_localstatedir}/lib/ca-certificates/openssl
 
 %files -n libopenssl-3-fips-provider
 %{_libdir}/ossl-modules/fips.so
@@ -452,7 +473,6 @@
 %files doc
 %doc README.md
 %doc doc/html/* doc/HOWTO/* demos
-%doc showciphers.c
 %{_mandir}/man3/*
 
 %files


++++++ openssl-Add-array-memory-allocation-routines.patch ++++++
>From fa9b7b930e3e59f5b30de0e8a6755bfaafdd5c49 Mon Sep 17 00:00:00 2001
From: Eugene Syromiatnikov <[email protected]>
Date: Thu, 17 Jul 2025 03:32:02 +0200
Subject: [PATCH] Add array memory allocation routines
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Such routines allow alleviating the need to perform explicit integer
overflow check during allocation size calculation and generally make
the allocations more semantic (as they signify that a collection
of NUM items, each occupying SIZE bytes is being allocated), which paves
the road for additional correctness checks in the future.

Signed-off-by: Eugene Syromiatnikov <[email protected]>

Reviewed-by: Saša Nedvědický <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
Reviewed-by: Neil Horman <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/28059)

Signed-off-by: Lucas Mulling <[email protected]>
---
 crypto/array_alloc.c               | 94 ++++++++++++++++++++++++++++++
 crypto/build.info                  |  2 +-
 doc/man3/OPENSSL_malloc.pod        | 52 ++++++++++++++---
 doc/man3/OPENSSL_secure_malloc.pod | 34 +++++++++--
 include/internal/mem_alloc_utils.h | 37 +++++++++++-
 include/openssl/crypto.h.in        | 31 ++++++++++
 util/libcrypto.num                 |  7 +++
 util/other.syms                    |  7 +++
 8 files changed, 249 insertions(+), 15 deletions(-)
 create mode 100644 crypto/array_alloc.c

Index: openssl-3.5.3/crypto/array_alloc.c
===================================================================
--- /dev/null
+++ openssl-3.5.3/crypto/array_alloc.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * This file provides implementation of various array allocation routines that
+ * perform integer overflow checking for size calculation.
+ */
+
+#include "internal/mem_alloc_utils.h"
+#include <openssl/crypto.h>
+
+void *CRYPTO_malloc_array(size_t num, size_t size, const char *file, int line)
+{
+    size_t bytes;
+
+    if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
+        return NULL;
+
+    return CRYPTO_malloc(bytes, file, line);
+}
+
+void *CRYPTO_calloc(size_t num, size_t size, const char *file, int line)
+{
+    size_t bytes;
+
+    if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
+        return NULL;
+
+    return CRYPTO_zalloc(bytes, file, line);
+}
+
+void *CRYPTO_aligned_alloc_array(size_t num, size_t size, size_t align,
+                                 void **freeptr, const char *file, int line)
+{
+    size_t bytes;
+
+    if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line))) {
+        *freeptr = NULL;
+
+        return NULL;
+    }
+
+    return CRYPTO_aligned_alloc(bytes, align, freeptr, file, line);
+}
+
+void *CRYPTO_realloc_array(void *addr, size_t num, size_t size,
+                           const char *file, int line)
+{
+    size_t bytes;
+
+    if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
+        return NULL;
+
+    return CRYPTO_realloc(addr, bytes, file, line);
+}
+
+void *CRYPTO_clear_realloc_array(void *addr, size_t old_num, size_t num,
+                                 size_t size, const char *file, int line)
+{
+    size_t old_bytes, bytes = 0;
+
+    if (ossl_unlikely(!ossl_size_mul(old_num, size, &old_bytes, file, line)
+                      || !ossl_size_mul(num, size, &bytes, file, line)))
+        return NULL;
+
+    return CRYPTO_clear_realloc(addr, old_bytes, bytes, file, line);
+}
+
+void *CRYPTO_secure_malloc_array(size_t num, size_t size,
+                                 const char *file, int line)
+{
+    size_t bytes;
+
+    if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
+        return NULL;
+
+    return CRYPTO_secure_malloc(bytes, file, line);
+}
+
+void *CRYPTO_secure_calloc(size_t num, size_t size, const char *file, int line)
+{
+    size_t bytes;
+
+    if (ossl_unlikely(!ossl_size_mul(num, size, &bytes, file, line)))
+        return NULL;
+
+    return CRYPTO_secure_zalloc(bytes, file, line);
+}
Index: openssl-3.5.3/crypto/build.info
===================================================================
--- openssl-3.5.3.orig/crypto/build.info
+++ openssl-3.5.3/crypto/build.info
@@ -100,7 +100,7 @@ $UTIL_COMMON=\
         threads_pthread.c threads_win.c threads_none.c initthread.c \
         context.c sparse_array.c asn1_dsa.c packet.c param_build.c \
         param_build_set.c der_writer.c threads_lib.c params_dup.c \
-        time.c params_idx.c
+        time.c params_idx.c array_alloc.c
 
 SOURCE[../libcrypto]=$UTIL_COMMON \
         mem.c mem_sec.c \
Index: openssl-3.5.3/doc/man3/OPENSSL_malloc.pod
===================================================================
--- openssl-3.5.3.orig/doc/man3/OPENSSL_malloc.pod
+++ openssl-3.5.3/doc/man3/OPENSSL_malloc.pod
@@ -4,14 +4,19 @@
 
 OPENSSL_malloc_init,
 OPENSSL_malloc, OPENSSL_aligned_alloc, OPENSSL_zalloc, OPENSSL_realloc,
-OPENSSL_free, OPENSSL_clear_realloc, OPENSSL_clear_free, OPENSSL_cleanse,
-CRYPTO_malloc, CRYPTO_aligned_alloc, CRYPTO_zalloc, CRYPTO_realloc, 
CRYPTO_free,
+OPENSSL_malloc_array, OPENSSL_aligned_alloc_array, OPENSSL_calloc,
+OPENSSL_realloc_array, OPENSSL_free,
+OPENSSL_clear_realloc, OPENSSL_clear_realloc_array,
+OPENSSL_clear_free, OPENSSL_cleanse,
+CRYPTO_malloc, CRYPTO_aligned_alloc, CRYPTO_zalloc,
+CRYPTO_malloc_array, CRYPTO_aligned_alloc_array, CRYPTO_calloc,
+CRYPTO_realloc, CRYPTO_realloc_array, CRYPTO_free,
 OPENSSL_strdup, OPENSSL_strndup,
 OPENSSL_memdup, OPENSSL_strlcpy, OPENSSL_strlcat, OPENSSL_strtoul,
 CRYPTO_strdup, CRYPTO_strndup,
 OPENSSL_mem_debug_push, OPENSSL_mem_debug_pop,
 CRYPTO_mem_debug_push, CRYPTO_mem_debug_pop,
-CRYPTO_clear_realloc, CRYPTO_clear_free,
+CRYPTO_clear_realloc, CRYPTO_clear_realloc_array, CRYPTO_clear_free,
 CRYPTO_malloc_fn, CRYPTO_realloc_fn, CRYPTO_free_fn,
 CRYPTO_get_mem_functions, CRYPTO_set_mem_functions,
 CRYPTO_get_alloc_counts,
@@ -31,6 +36,11 @@ OPENSSL_MALLOC_FD
  void *OPENSSL_aligned_alloc(size_t num, size_t alignment, void **freeptr);
  void *OPENSSL_zalloc(size_t num);
  void *OPENSSL_realloc(void *addr, size_t num);
+ void *OPENSSL_malloc_array(size_t num, size_t size);
+ void *OPENSSL_aligned_alloc_array(size_t num, size_t size, size_t alignment,
+                                   void **freeptr);
+ void *OPENSSL_calloc(size_t num, size_t size);
+ void *OPENSSL_realloc_array(void *addr, size_t num, size_t size);
  void OPENSSL_free(void *addr);
  char *OPENSSL_strdup(const char *str);
  char *OPENSSL_strndup(const char *str, size_t s);
@@ -39,20 +49,30 @@ OPENSSL_MALLOC_FD
  int OPENSSL_strtoul(char *src, char **endptr, int base, unsigned long *num);
  void *OPENSSL_memdup(void *data, size_t s);
  void *OPENSSL_clear_realloc(void *p, size_t old_len, size_t num);
+ void *OPENSSL_clear_realloc_array(void *p, size_t old_len, size_t num,
+                                   size_t size);
  void OPENSSL_clear_free(void *str, size_t num);
  void OPENSSL_cleanse(void *ptr, size_t len);
 
  void *CRYPTO_malloc(size_t num, const char *file, int line);
- void *CRYPTO_aligned_alloc(size_t num, size_t align, void **freeptr, 
+ void *CRYPTO_aligned_alloc(size_t num, size_t align, void **freeptr,
                             const char *file, int line);
  void *CRYPTO_zalloc(size_t num, const char *file, int line);
  void *CRYPTO_realloc(void *p, size_t num, const char *file, int line);
- void CRYPTO_free(void *str, const char *, int);
+ void *CRYPTO_malloc_array(size_t num, size_t size, const char *file, int 
line);
+ void *CRYPTO_aligned_alloc_array(size_t num, size_t size, size_t align,
+                                  void **freeptr, const char *file, int line);
+ void *CRYPTO_calloc(size_t num, size_t size, const char *file, int line);
+ void *CRYPTO_realloc_array(void *p, size_t num, size_t size,
+                            const char *file, int line);
+ void CRYPTO_free(void *str, const char *file, int line);
  char *CRYPTO_strdup(const char *p, const char *file, int line);
  char *CRYPTO_strndup(const char *p, size_t num, const char *file, int line);
  void *CRYPTO_clear_realloc(void *p, size_t old_len, size_t num,
                             const char *file, int line);
- void CRYPTO_clear_free(void *str, size_t num, const char *, int);
+ void *CRYPTO_clear_realloc_array(void *p, size_t old_len, size_t num,
+                                  size_t size, const char *file, int line);
+ void CRYPTO_clear_free(void *str, size_t num, const char *file, int line);
 
  typedef void *(*CRYPTO_malloc_fn)(size_t num, const char *file, int line);
  typedef void *(*CRYPTO_realloc_fn)(void *addr, size_t num, const char *file,
@@ -120,6 +140,15 @@ The old buffer is filled with zero's by
 before ultimately calling OPENSSL_free(). If the argument to OPENSSL_free() is
 NULL, nothing is done.
 
+OPENSSL_malloc_array(), OPENSSL_calloc(), OPENSSL_aligned_alloc_array(),
+OPENSSL_realloc_array(), and OPENSSL_clear_realloc_array() are variants
+of OPENSSL_malloc(), OPENSSL_zalloc(), OPENSSL_aligned_alloc(),
+OPENSSL_realloc(), and OPENSSL_clear_realloc(), respectively, that accept
+an additional parameter, B<size>, which enables memory allocation
+operations for an array of B<num> members B<size> bytes each;
+these functions return an error if multiplication of B<num> and B<size>
+leads to an integer overflow, thus preventing allocations of an incorrect size.
+
 OPENSSL_cleanse() fills B<ptr> of size B<len> with a string of 0's.
 Use OPENSSL_cleanse() with care if the memory is a mapping of a file.
 If the storage controller uses write compression, then it's possible
@@ -195,9 +224,12 @@ CRYPTO_free(), CRYPTO_clear_free() and C
 return no value.
 
 OPENSSL_malloc(), OPENSSL_aligned_alloc(), OPENSSL_zalloc(), OPENSSL_realloc(),
-OPENSSL_clear_realloc(),
+OPENSSL_malloc_array(), OPENSSL_aligned_alloc_array(), OPENSSL_calloc(),
+OPENSSL_realloc_array(),
+OPENSSL_clear_realloc(), OPENSSL_clear_realloc_array(),
 CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_realloc(),
-CRYPTO_clear_realloc(),
+CRYPTO_malloc_array(), CRYPTO_calloc(), CRYPTO_realloc_array(),
+CRYPTO_clear_realloc(), CRYPTO_clear_realloc_array(),
 OPENSSL_strdup(), and OPENSSL_strndup()
 return a pointer to allocated memory or NULL on error.
 
@@ -251,6 +283,10 @@ The memory-leak checking has been deprec
 clang's memory and leak sanitizer.
 OPENSSL_aligned_alloc(), CRYPTO_aligned_alloc(), OPENSSL_strtoul() were
 added in OpenSSL 3.4.
+OPENSSL_malloc_array(), OPENSSL_calloc(), OPENSSL_aligned_alloc_array(),
+OPENSSL_realloc_array(), OPENSSL_clear_realloc_array(), CRYPTO_malloc_array(),
+CRYPTO_calloc(), CRYPTO_aligned_alloc_array(), CRYPTO_realloc_array(),
+CRYPTO_clear_realloc_array() were added in OpenSSL 3.6.
 
 =head1 COPYRIGHT
 
Index: openssl-3.5.3/doc/man3/OPENSSL_secure_malloc.pod
===================================================================
--- openssl-3.5.3.orig/doc/man3/OPENSSL_secure_malloc.pod
+++ openssl-3.5.3/doc/man3/OPENSSL_secure_malloc.pod
@@ -4,8 +4,9 @@
 
 CRYPTO_secure_malloc_init, CRYPTO_secure_malloc_initialized,
 CRYPTO_secure_malloc_done, OPENSSL_secure_malloc, CRYPTO_secure_malloc,
-OPENSSL_secure_zalloc, CRYPTO_secure_zalloc, OPENSSL_secure_free,
-CRYPTO_secure_free, OPENSSL_secure_clear_free,
+OPENSSL_secure_zalloc, CRYPTO_secure_zalloc, OPENSSL_secure_malloc_array,
+CRYPTO_secure_malloc_array, OPENSSL_secure_calloc, CRYPTO_secure_calloc,
+OPENSSL_secure_free, CRYPTO_secure_free, OPENSSL_secure_clear_free,
 CRYPTO_secure_clear_free, OPENSSL_secure_actual_size,
 CRYPTO_secure_allocated,
 CRYPTO_secure_used - secure heap storage
@@ -26,6 +27,14 @@ CRYPTO_secure_used - secure heap storage
  void *OPENSSL_secure_zalloc(size_t num);
  void *CRYPTO_secure_zalloc(size_t num, const char *file, int line);
 
+ void *OPENSSL_secure_malloc_array(size_t num, size_t size);
+ void *CRYPTO_secure_malloc_array(size_t num, size_t size,
+                                  const char *file, int line);
+
+ void *OPENSSL_secure_calloc(size_t num, size_t size);
+ void *CRYPTO_secure_calloc(size_t num, size_t size,
+                            const char *file, int line);
+
  void OPENSSL_secure_free(void* ptr);
  void CRYPTO_secure_free(void *ptr, const char *, int);
 
@@ -80,6 +89,15 @@ OPENSSL_secure_zalloc() and CRYPTO_secur
 OPENSSL_secure_malloc() and CRYPTO_secure_malloc(), respectively,
 except that they call memset() to zero the memory before returning.
 
+OPENSSL_secure_malloc_array(), CRYPTO_secure_malloc_array(),
+OPENSSL_secure_calloc(), and CRYPTO_secure_calloc() are variants
+of OPENSSL_secure_malloc(), CRYPTO_secure_malloc(),
+OPENSSL_secure_zalloc(), and CRYPTO_secure_zalloc(), respectively, that accept
+an additional parameter, B<size>, which enables memory allocation
+operations for an array of B<num> members B<size> bytes each;
+these functions return an error if multiplication of B<num> and B<size>
+leads to an integer overflow, thus preventing allocations of an incorrect size.
+
 OPENSSL_secure_free() releases the memory at C<ptr> back to the heap.
 It must be called with a value previously obtained from
 OPENSSL_secure_malloc().
@@ -116,9 +134,11 @@ CRYPTO_secure_malloc_initialized() retur
 available (that is, if CRYPTO_secure_malloc_init() has been called,
 but CRYPTO_secure_malloc_done() has not been called or failed) or 0 if not.
 
-OPENSSL_secure_malloc() and OPENSSL_secure_zalloc() return a pointer into
-the secure heap of the requested size, or C<NULL> if memory could not be
-allocated.
+OPENSSL_secure_malloc(), CRYPTO_secure_malloc(), OPENSSL_secure_zalloc(),
+CRYPTO_secure_zalloc(), OPENSSL_secure_malloc_array(),
+CRYPTO_secure_malloc_array(), OPENSSL_secure_calloc(), and 
CRYPTO_secure_calloc()
+return a pointer into the secure heap of the requested size,
+or C<NULL> if memory could not be allocated.
 
 CRYPTO_secure_allocated() returns 1 if the pointer is in the secure heap, or 0 
if not.
 
@@ -138,6 +158,10 @@ The OPENSSL_secure_clear_free() function
 The second argument to CRYPTO_secure_malloc_init() was changed from an B<int> 
to
 a B<size_t> in OpenSSL 3.0.
 
+The OPENSSL_secure_malloc_array(), CRYPTO_secure_malloc_array(),
+OPENSSL_secure_calloc(), and CRYPTO_secure_calloc() functions were added
+in OpenSSL 3.6.
+
 =head1 COPYRIGHT
 
 Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.
Index: openssl-3.5.3/include/internal/mem_alloc_utils.h
===================================================================
--- openssl-3.5.3.orig/include/internal/mem_alloc_utils.h
+++ openssl-3.5.3/include/internal/mem_alloc_utils.h
@@ -14,11 +14,18 @@
 #ifndef OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H
 # define OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H
 
+# include <limits.h>
+# include <stdbool.h>
+# include <stdint.h>
+
 # include "internal/common.h"
+# include "internal/safe_math.h"
 
 # include <openssl/cryptoerr.h>
 # include <openssl/err.h>
 
+OSSL_SAFE_MATH_UNSIGNED(size_t, size_t)
+
 /*
  * A helper routine to report memory allocation errors.
  * Similar to the ERR_raise() macro, but accepts explicit file/line arguments,
@@ -41,10 +48,38 @@ ossl_report_alloc_err_ex(const char * co
 }
 
 /* Report a memory allocation failure. */
-static inline void
+static ossl_inline ossl_unused void
 ossl_report_alloc_err(const char * const file, const int line)
 {
     ossl_report_alloc_err_ex(file, line, ERR_R_MALLOC_FAILURE);
 }
 
+/* Report an integer overflow during allocation size calculation. */
+static ossl_inline ossl_unused void
+ossl_report_alloc_err_of(const char * const file, const int line)
+{
+    ossl_report_alloc_err_ex(file, line, CRYPTO_R_INTEGER_OVERFLOW);
+}
+
+/*
+ * Check the result of num and size multiplication for overflow
+ * and set error if it is the case;  return true if there was no overflow,
+ * false if there was.
+ */
+static ossl_inline ossl_unused bool
+ossl_size_mul(const size_t num, const size_t size, size_t *bytes,
+              const char * const file, const int line)
+{
+    int err = 0;
+    *bytes = safe_mul_size_t(num, size, &err);
+
+    if (ossl_unlikely(err != 0)) {
+        ossl_report_alloc_err_of(file, line);
+
+        return false;
+    }
+
+    return true;
+}
+
 #endif /* OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H */
Index: openssl-3.5.3/include/openssl/crypto.h.in
===================================================================
--- openssl-3.5.3.orig/include/openssl/crypto.h.in
+++ openssl-3.5.3/include/openssl/crypto.h.in
@@ -103,13 +103,25 @@ int CRYPTO_atomic_store(uint64_t *dst, u
         CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_zalloc(num) \
         CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_malloc_array(num, size) \
+        CRYPTO_malloc_array(num, size, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_calloc(num, size) \
+        CRYPTO_calloc(num, size, OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_aligned_alloc(num, alignment, freeptr) \
         CRYPTO_aligned_alloc(num, alignment, freeptr, \
                              OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_aligned_alloc_array(num, size, alignment, freeptr) \
+        CRYPTO_aligned_alloc_array(num, size, alignment, freeptr, \
+                               OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_realloc(addr, num) \
         CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_clear_realloc(addr, old_num, num) \
         CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_realloc_array(addr, num, size) \
+        CRYPTO_realloc_array(addr, num, size, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_clear_realloc_array(addr, old_num, num, size) \
+        CRYPTO_clear_realloc_array(addr, old_num, num, size, \
+                               OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_clear_free(addr, num) \
         CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_free(addr) \
@@ -124,6 +136,10 @@ int CRYPTO_atomic_store(uint64_t *dst, u
         CRYPTO_secure_malloc(num, OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_secure_zalloc(num) \
         CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_malloc_array(num, size) \
+        CRYPTO_secure_malloc_array(num, size, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_calloc(num, size) \
+        CRYPTO_secure_calloc(num, size, OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_secure_free(addr) \
         CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE)
 # define OPENSSL_secure_clear_free(addr, num) \
@@ -332,9 +348,16 @@ void CRYPTO_get_mem_functions(CRYPTO_mal
 
 OSSL_CRYPTO_ALLOC void *CRYPTO_malloc(size_t num, const char *file, int line);
 OSSL_CRYPTO_ALLOC void *CRYPTO_zalloc(size_t num, const char *file, int line);
+OSSL_CRYPTO_ALLOC void *CRYPTO_malloc_array(size_t num, size_t size,
+                                            const char *file, int line);
+OSSL_CRYPTO_ALLOC void *CRYPTO_calloc(size_t num, size_t size,
+                                      const char *file, int line);
 OSSL_CRYPTO_ALLOC void *CRYPTO_aligned_alloc(size_t num, size_t align,
                                              void **freeptr, const char *file,
                                              int line);
+OSSL_CRYPTO_ALLOC void *CRYPTO_aligned_alloc_array(size_t num, size_t size,
+                                                   size_t align, void 
**freeptr,
+                                                   const char *file, int line);
 void *CRYPTO_memdup(const void *str, size_t siz, const char *file, int line);
 char *CRYPTO_strdup(const char *str, const char *file, int line);
 char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line);
@@ -343,11 +366,19 @@ void CRYPTO_clear_free(void *ptr, size_t
 void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line);
 void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
                            const char *file, int line);
+void *CRYPTO_realloc_array(void *addr, size_t num, size_t size,
+                           const char *file, int line);
+void *CRYPTO_clear_realloc_array(void *addr, size_t old_num, size_t num,
+                                 size_t size, const char *file, int line);
 
 int CRYPTO_secure_malloc_init(size_t sz, size_t minsize);
 int CRYPTO_secure_malloc_done(void);
 OSSL_CRYPTO_ALLOC void *CRYPTO_secure_malloc(size_t num, const char *file, int 
line);
 OSSL_CRYPTO_ALLOC void *CRYPTO_secure_zalloc(size_t num, const char *file, int 
line);
+OSSL_CRYPTO_ALLOC void *CRYPTO_secure_malloc_array(size_t num, size_t size,
+                                                   const char *file, int line);
+OSSL_CRYPTO_ALLOC void *CRYPTO_secure_calloc(size_t num, size_t size,
+                                             const char *file, int line);
 void CRYPTO_secure_free(void *ptr, const char *file, int line);
 void CRYPTO_secure_clear_free(void *ptr, size_t num,
                               const char *file, int line);
Index: openssl-3.5.3/util/libcrypto.num
===================================================================
--- openssl-3.5.3.orig/util/libcrypto.num
+++ openssl-3.5.3/util/libcrypto.num
@@ -5927,3 +5927,10 @@ OSSL_AA_DIST_POINT_it
 PEM_ASN1_write_bio_ctx                  6054   3_5_0   EXIST::FUNCTION:
 ossl_ctx_legacy_digest_signatures_allowed ?    3_0_1   EXIST::FUNCTION:
 ossl_ctx_legacy_digest_signatures_allowed_set ?        3_0_1   EXIST::FUNCTION:
+CRYPTO_malloc_array                     ?      3_5_0   EXIST::FUNCTION:
+CRYPTO_calloc                           ?      3_5_0   EXIST::FUNCTION:
+CRYPTO_aligned_alloc_array              ?      3_5_0   EXIST::FUNCTION:
+CRYPTO_realloc_array                    ?      3_5_0   EXIST::FUNCTION:
+CRYPTO_clear_realloc_array              ?      3_5_0   EXIST::FUNCTION:
+CRYPTO_secure_malloc_array              ?      3_5_0   EXIST::FUNCTION:
+CRYPTO_secure_calloc                    ?      3_5_0   EXIST::FUNCTION:
Index: openssl-3.5.3/util/other.syms
===================================================================
--- openssl-3.5.3.orig/util/other.syms
+++ openssl-3.5.3/util/other.syms
@@ -426,21 +426,28 @@ OPENSSL_VERSION_BUILD_METADATA
 OPENSSL_VERSION_PRE_RELEASE_STR         define
 OPENSSL_VERSION_BUILD_METADATA_STR      define
 OPENSSL_VERSION_TEXT                    define
+OPENSSL_calloc                          define
 OPENSSL_clear_free                      define
 OPENSSL_clear_realloc                   define
+OPENSSL_clear_realloc_array             define
 OPENSSL_free                            define
 OPENSSL_malloc                          define
+OPENSSL_malloc_array                    define
 OPENSSL_aligned_alloc                   define
+OPENSSL_aligned_alloc_array             define
 OPENSSL_malloc_init                     define
 OPENSSL_mem_debug_pop                   define deprecated 3.0.0
 OPENSSL_mem_debug_push                  define deprecated 3.0.0
 OPENSSL_memdup                          define
 OPENSSL_no_config                       define deprecated 1.1.0
 OPENSSL_realloc                         define
+OPENSSL_realloc_array                   define
 OPENSSL_secure_actual_size              define
 OPENSSL_secure_clear_free               define
 OPENSSL_secure_free                     define
+OPENSSL_secure_calloc                   define
 OPENSSL_secure_malloc                   define
+OPENSSL_secure_malloc_array             define
 OPENSSL_secure_zalloc                   define
 OPENSSL_strdup                          define
 OPENSSL_strndup                         define

++++++ openssl-CVE-2026-2673.patch ++++++
>From 9efd7e9e98a98aaade8121bac8f1e53208c3af33 Mon Sep 17 00:00:00 2001
From: Viktor Dukhovni <[email protected]>
Date: Sun, 15 Feb 2026 22:50:09 +1100
Subject: [PATCH] Fix group tuple handling in DEFAULT expansion

Also fine-tune docs and add tests.

Fixes: #30109
Fixes: CVE-2026-2673

Reviewed-by: Tim Hudson <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Wed Feb 25 11:08:03 2026
(Merged from https://github.com/openssl/openssl/pull/30113)
---
 doc/man3/SSL_CTX_set1_curves.pod | 123 +++++++++++++++-------
 ssl/t1_lib.c                     | 171 ++++++++++++++++---------------
 test/tls13groupselection_test.c  |  65 +++++++++++-
 3 files changed, 235 insertions(+), 124 deletions(-)

Index: openssl-3.5.3/doc/man3/SSL_CTX_set1_curves.pod
===================================================================
--- openssl-3.5.3.orig/doc/man3/SSL_CTX_set1_curves.pod
+++ openssl-3.5.3/doc/man3/SSL_CTX_set1_curves.pod
@@ -40,13 +40,13 @@ SSL_get1_curves, SSL_get_shared_curve, S
 
 For all of the functions below that set the supported groups there must be at
 least one group in the list. A number of these functions identify groups via a
-unique integer NID value. However, support for some groups may be added by
-external providers. In this case there will be no NID assigned for the group.
+unique integer B<NID> value. However, support for some groups may be added by
+external providers. In this case there will be no B<NID> assigned for the 
group.
 When setting such groups applications should use the "list" form of these
 functions (i.e. SSL_CTX_set1_groups_list() and SSL_set1_groups_list()).
 
 SSL_CTX_set1_groups() sets the supported groups for B<ctx> to B<glistlen>
-groups in the array B<glist>. The array consist of all NIDs of supported 
groups.
+groups in the array B<glist>. The array consist of all B<NIDs> of supported 
groups.
 The supported groups for B<TLSv1.3> include:
 B<NID_X9_62_prime256v1>,
 B<NID_secp384r1>,
@@ -73,20 +73,27 @@ B<SSL_OP_CIPHER_SERVER_PREFERENCE> is se
 array determines the selected group. Otherwise, the order is ignored and the
 client's order determines the selection.
 
-For a TLS 1.3 server, the groups determine the selected group, but
-selection is more complex. A TLS 1.3 client sends both a group list as well as 
a
-predicted subset of groups. Choosing a group outside the predicted subset 
incurs
-an extra roundtrip. However, in some situations, the most preferred group may
-not be predicted. OpenSSL considers all supported groups in I<clist> to be 
comparable
-in security and prioritizes avoiding roundtrips above either client or server
-preference order. If an application uses an external provider to extend OpenSSL
-with, e.g., a post-quantum algorithm, this behavior may allow a network 
attacker
-to downgrade connections to a weaker algorithm. It is therefore recommended
-to use SSL_CTX_set1_groups_list() with the ability to specify group tuples.
+For a TLS 1.3 server, the groups determine the selected group, but selection is
+more complex.
+A TLS 1.3 client sends both a group list and predicted keyshares for a subset
+of groups.
+A server choosing a group outside the client's predicted subset incurs an extra
+roundtrip.
+However, in some situations, the most preferred group may not be predicted.
+
+When groups are specified via SSL_CTX_set1_groups() as a list of B<NID>
+values, OpenSSL considers all supported groups in I<clist> to be comparable in
+security and prioritises avoiding roundtrips above either client or server
+preference order.
+If an application uses an external provider to extend OpenSSL with, e.g., a
+post-quantum algorithm, this behavior may allow a network attacker to downgrade
+connections to a weaker algorithm.
+It is therefore recommended to use SSL_CTX_set1_groups_list() instead, making
+it possible to specify group tuples as described below.
 
 SSL_CTX_set1_groups_list() sets the supported groups for B<ctx> to
 string I<list>. In contrast to SSL_CTX_set1_groups(), the names of the
-groups, rather than their NIDs, are used.
+groups, rather than their B<NIDs>, are used.
 
 The commands below list the available groups for TLS 1.2 and TLS 1.3,
 respectively:
@@ -102,30 +109,72 @@ The preferred group names are those defi
 
L<IANA|https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8>.
 
 The I<list> can be used to define several group tuples of comparable security
-levels, and can specify which key shares should be sent by a client.
-The specified list elements can optionally be ignored, if not implemented
+levels, and can specify which predicted key shares should be sent by a client.
+Group tuples are used by OpenSSL TLS servers to decide whether to request a
+stronger keyshare than those predicted by sending a Hello Retry Request
+(B<HRR>) even if some of the predicted groups are supported.
+OpenSSL clients ignore tuple boundaries, and pay attenion only to the overall
+order of I<list> elements and which groups are selected as predicted keyshares
+as described below.
+
+The specified list elements can optionally be ignored if not implemented
 (listing unknown groups otherwise results in error).
-It is also possible to specify the built-in default set of groups, and to 
explicitly
-remove a group from that list.
+It is also possible to specify the built-in default set of groups, and to
+explicitly remove a group from that list.
 
-In its simplest form, the string I<list> is just a colon separated list
-of group names, for example "P-521:P-384:P-256:X25519:ffdhe2048". The first
-group listed will also be used for the B<key_share> sent by a client in a
-TLSv1.3 B<ClientHello>. For servers note the discussion above. The list should
-be in order of preference with the most preferred group first.
-
-Group tuples of comparable security are defined by separating them from each
-other by a tuple separator C</>. Keyshares to be sent by a client are specified
-by prepending a C<*> to the group name, while any C<*> will be ignored by a
-server. The following string I<list> for example defines three tuples when
-used on the server-side, and triggers the generation of three key shares
-when used on the client-side: P-521:*P-256/*P-384/*X25519:P-384:ffdhe2048.
-
-If a group name is preceded with the C<?> character, it will be ignored if an
-implementation is missing. If a group name is preceded with the C<-> 
character, it
-will be removed from the list of groups if present (including not sending a
-key share for this group), ignored otherwise. The pseudo group name
-C<DEFAULT> can be used to select the OpenSSL built-in default list of groups.
+In its simplest legacy form, the string I<list> is just a colon separated list
+of group names, for example "P-521:P-384:P-256:X25519:ffdhe2048".
+The first group listed will in this case be used as the sole predicted
+B<key_share> sent by a client in a TLSv1.3 B<ClientHello>.
+The list should be in order of preference with the most preferred group first.
+
+A more expressive syntax supports definition of group tuples of comparable
+security by separating them from each other with C</> characters.
+
+The predicted keyshares to be sent by clients can be explicitly specified by
+adding a C<*> prefix to the associated group name.
+These C<*> prefixes are ignored by servers.
+
+If a group name is prefixed with the C<?> character, it will be ignored if an
+implementation is missing.
+Otherwise, listing an unknown group name will cause a failure to parse the
+I<list>.
+Note that whether a group is known or not may depend on the OpenSSL version,
+how OpenSSL was compiled and/or which providers are loaded.
+Make sure you have the correct spelling of the group name and when in doubt
+prefix it with a C<?> to handle configurations in which it might nevertheless
+be unknown.
+
+If a group name is prefixed with the C<-> character, it will be removed from
+the list of groups specified up to that point.
+It can be added again if specified later.
+Removal of groups that have not been included earlier in the list is silently
+ignored.
+
+The pseudo group name C<DEFAULT> can be used to select the OpenSSL built-in
+default list of groups.
+Prepending one or more groups to C<DEFAULT> using only C<:> separators 
prepends those
+groups to the built-in default list's first tuple.
+Additional tuples can be prepended by use of the C</> separator.
+Appending a set of groups to C<DEFAULT> using only C<:> separators appends 
those
+groups to the built-in default list's last tuple.
+Additional tuples can be appended by use of the C</> separator.
+
+The B<DEFAULT> list selects B<X25519MLKEM768> as one of the predicted 
keyshares.
+In rare cases this can lead to failures or timeouts because the resulting
+larger TLS Client Hello message may no longer fit in a single TCP segment and
+firewall software may erroneously disrupt the TLS handshake.
+If this is an issue or concern, prepending C<?X25519MLKEM768:> without a C<*>
+prefix leads to its occurrence in the default list to be ignored as a 
duplicate,
+and along with that also the keyshare prediction.
+The group will then only be selected by servers that specifically expect it,
+after a Hello Retry Request (HRR).
+Servers that specifically prefer B<X25519MLKEM768>, are much less likely to be
+found behind problematic firewalls.
+
+The following string I<list> for example defines three tuples when used on the
+server-side, and triggers the generation of three key shares when used on the
+client-side: P-521:*P-256/*P-384/*X25519:P-384:ffdhe2048.
 
 For a TLS 1.3 client, all the groups in the string I<list> are added to the
 supported groups extension of a C<ClientHello>, in the order in which they are 
listed,
Index: openssl-3.5.3/ssl/t1_lib.c
===================================================================
--- openssl-3.5.3.orig/ssl/t1_lib.c
+++ openssl-3.5.3/ssl/t1_lib.c
@@ -213,7 +213,7 @@ static const uint16_t suiteb_curves[] =
 
 /* Group list string of the built-in pseudo group DEFAULT_SUITE_B */
 #define SUITE_B_GROUP_NAME "DEFAULT_SUITE_B"
-#define SUITE_B_GROUP_LIST "secp256r1:secp384r1",
+#define SUITE_B_GROUP_LIST "?secp256r1:?secp384r1",
 
 struct provider_ctx_data_st {
     SSL_CTX *ctx;
@@ -1239,8 +1239,8 @@ typedef struct {
     size_t ksidcnt; /* Number of key shares */
     uint16_t *ksid_arr; /* The IDs of the key share groups (flat list) */
     /* Variable to keep state between execution of callback or helper 
functions */
-    size_t tuple_mode; /* Keeps track whether tuple_cb called from 'the top' 
or from gid_cb */
-    int ignore_unknown_default; /* Flag such that unknown groups for 
DEFAULT[_XYZ] are ignored */
+    int inner; /* Are we expanding a DEFAULT list */
+    int first; /* First tuple of possibly nested expansion? */
 } gid_cb_st;
 
 /* Forward declaration of tuple callback function */
@@ -1315,16 +1315,16 @@ static int gid_cb(const char *elem, int
             for (i = 0; i < OSSL_NELEM(default_group_strings); i++) {
                 if ((size_t)len == (strlen(default_group_strings[i].list_name))
                     && OPENSSL_strncasecmp(default_group_strings[i].list_name, 
elem, len) == 0) {
+                    int saved_first;
+
                     /*
                      * We're asked to insert an entire list of groups from a
                      * DEFAULT[_XYZ] 'pseudo group' which we do by
                      * recursively calling this function (indirectly via
                      * CONF_parse_list and tuple_cb); essentially, we treat a 
DEFAULT
                      * group string like a tuple which is appended to the 
current tuple
-                     * rather then starting a new tuple. Variable tuple_mode 
is the flag which
-                     * controls append tuple vs start new tuple.
+                     * rather then starting a new tuple.
                      */
-
                     if (ignore_unknown || remove_group)
                         return -1; /* removal or ignore not allowed here -> 
syntax error */
 
@@ -1349,15 +1349,18 @@ static int gid_cb(const char *elem, int
                            strlen(default_group_strings[i].group_string));
                     
restored_default_group_string[strlen(default_group_strings[i].group_string) +
                                                   restored_prefix_index] = 
'\0';
-                    /* We execute the recursive call */
-                    garg->ignore_unknown_default = 1; /* We ignore unknown 
groups for DEFAULT_XYZ */
-                    /* we enforce group mode (= append tuple) for DEFAULT_XYZ 
group lists */
-                    garg->tuple_mode = 0;
+                    /*
+                     * Append first tuple of result to current tuple, and don't
+                     * terminate the last tuple until we return to a top-level
+                     * tuple_cb.
+                     */
+                    saved_first = garg->first;
+                    garg->inner = garg->first = 1;
                     /* We use the tuple_cb callback to process the pseudo 
group tuple */
                     retval = CONF_parse_list(restored_default_group_string,
                                              TUPLE_DELIMITER_CHARACTER, 1, 
tuple_cb, garg);
-                    garg->tuple_mode = 1; /* next call to tuple_cb will again 
start new tuple */
-                    garg->ignore_unknown_default = 0; /* reset to original 
value */
+                    garg->inner = 0;
+                    garg->first = saved_first;
                     /* We don't need the \0-terminated string anymore */
                     OPENSSL_free(restored_default_group_string);
 
@@ -1377,9 +1380,6 @@ static int gid_cb(const char *elem, int
     if (len == 0)
         return -1; /* Seems we have prefxes without a group name -> syntax 
error */
 
-    if (garg->ignore_unknown_default == 1) /* Always ignore unknown groups for 
DEFAULT[_XYZ] */
-        ignore_unknown = 1;
-
     /* Memory management in case more groups are present compared to initial 
allocation */
     if (garg->gidcnt == garg->gidmax) {
         uint16_t *tmp =
@@ -1455,51 +1455,48 @@ static int gid_cb(const char *elem, int
     }
     /* Remove group (and keyshare) from anywhere in the list if present, 
ignore if not present */
     if (remove_group) {
-        /* Is the current group specified anywhere in the entire list so far? 
*/
-        found_group = 0;
-        for (i = 0; i < garg->gidcnt; i++)
-            if (garg->gid_arr[i] == gid) {
-                found_group = 1;
+        size_t n; /* tuple size */
+
+        j = 0; /* tuple index */
+        k = 0; /* keyshare index */
+        n = garg->tuplcnt_arr[j];
+
+        for (i = 0; i < garg->gidcnt; ++i) {
+            if (garg->gid_arr[i] == gid)
                 break;
-            }
-        /* The group to remove is at position i in the list of (zero indexed) 
groups */
-        if (found_group) {
-            /* We remove that group from its position (which is at i)... */
-            for (j = i; j < (garg->gidcnt - 1); j++)
-                garg->gid_arr[j] = garg->gid_arr[j + 1]; /* ...shift remaining 
groups left ... */
-            garg->gidcnt--; /* ..and update the book keeping for the number of 
groups */
+            /* Skip keyshare slots associated with groups prior to that 
removed */
+            if (k < garg->ksidcnt && garg->gid_arr[i] == garg->ksid_arr[k])
+                ++k;
+            /* Skip to next tuple? */
+            if (j < garg->tplcnt && --n == 0)
+                n = garg->tuplcnt_arr[++j];
+        }
 
-            /*
-             * We also must update the number of groups either in a previous 
tuple (which we
-             * must identify and check whether it becomes empty due to the 
deletion) or in
-             * the current tuple, pending where the deleted group resides
-             */
-            k = 0;
-            for (j = 0; j < garg->tplcnt; j++) {
-                k += garg->tuplcnt_arr[j];
-                /* Remark: i is zero-indexed, k is one-indexed */
-                if (k > i) { /* remove from one of the previous tuples */
-                    garg->tuplcnt_arr[j]--;
-                    break; /* We took care not to have group duplicates, hence 
we can stop here */
-                }
-            }
-            if (k <= i) /* remove from current tuple */
-                garg->tuplcnt_arr[j]--;
+        /* Nothing to remove? */
+        if (i >= garg->gidcnt)
+            goto done;
 
-            /* We also remove the group from the list of keyshares (if 
present) */
-            found_group = 0;
-            for (i = 0; i < garg->ksidcnt; i++)
-                if (garg->ksid_arr[i] == gid) {
-                    found_group = 1;
-                    break;
-                }
-            if (found_group) {
-                /* Found, hence we remove that keyshare from its position 
(which is at i)... */
-                for (j = i; j < (garg->ksidcnt - 1); j++)
-                    garg->ksid_arr[j] = garg->ksid_arr[j + 1]; /* shift 
remaining key shares */
-                /* ... and update the book keeping */
-                garg->ksidcnt--;
-            }
+        garg->gidcnt--;
+        garg->tuplcnt_arr[j]--;
+        memmove(garg->gid_arr + i, garg->gid_arr + i + 1,
+            (garg->gidcnt - i) * sizeof(gid));
+
+        /* Handle keyshare removal */
+        if (k < garg->ksidcnt && garg->ksid_arr[k] == gid) {
+            garg->ksidcnt--;
+            memmove(garg->ksid_arr + k, garg->ksid_arr + k + 1,
+                (garg->ksidcnt - k) * sizeof(gid));
+        }
+
+        /*
+         * Adjust closed or current tuple's group count, if a closed tuple
+         * count reaches zero excise the resulting empty tuple.  The current
+         * (not yet closed) tuple at the end of the list stays even if empty.
+         */
+        if (garg->tuplcnt_arr[j] == 0 && j < garg->tplcnt) {
+            garg->tplcnt--;
+            memmove(garg->tuplcnt_arr + j, garg->tuplcnt_arr + j + 1,
+                (garg->tplcnt - j) * sizeof(size_t));
         }
     } else { /* Processing addition of a single new group */
 
@@ -1515,7 +1512,7 @@ static int gid_cb(const char *elem, int
         /* and update the book keeping for the number of groups in current 
tuple */
         garg->tuplcnt_arr[garg->tplcnt]++;
 
-        /* We memorize if needed that we want to add a key share for the 
current group */
+        /* We want to add a key share for the current group */
         if (add_keyshare)
             garg->ksid_arr[garg->ksidcnt++] = gid;
     }
@@ -1524,6 +1521,34 @@ done:
     return retval;
 }
 
+static int grow_tuples(gid_cb_st *garg)
+{
+    if (garg->tplcnt == garg->tplmax) {
+        size_t *tmp = OPENSSL_realloc_array(garg->tuplcnt_arr,
+            garg->tplmax + GROUPLIST_INCREMENT,
+            sizeof(*garg->tuplcnt_arr));
+
+        if (tmp == NULL)
+            return 0;
+        garg->tplmax += GROUPLIST_INCREMENT;
+        garg->tuplcnt_arr = tmp;
+    }
+    return 1;
+}
+
+static int close_tuple(gid_cb_st *garg)
+{
+    size_t gidcnt = garg->tuplcnt_arr[garg->tplcnt];
+
+    if (gidcnt == 0)
+        return 1;
+    if (!grow_tuples(garg))
+        return 0;
+
+    garg->tuplcnt_arr[++garg->tplcnt] = 0;
+    return 1;
+}
+
 /* Extract and process a tuple of groups */
 static int tuple_cb(const char *tuple, int len, void *arg)
 {
@@ -1537,17 +1562,9 @@ static int tuple_cb(const char *tuple, i
         return 0;
     }
 
-    /* Memory management for tuples */
-    if (garg->tplcnt == garg->tplmax) {
-        size_t *tmp =
-            OPENSSL_realloc(garg->tuplcnt_arr,
-                            (garg->tplmax + GROUPLIST_INCREMENT) * 
sizeof(*garg->tuplcnt_arr));
-
-        if (tmp == NULL)
-            return 0;
-        garg->tplmax += GROUPLIST_INCREMENT;
-        garg->tuplcnt_arr = tmp;
-    }
+    if (garg->inner && !garg->first && !close_tuple(garg))
+        return 0;
+    garg->first = 0;
 
     /* Convert to \0-terminated string */
     restored_tuple_string = OPENSSL_malloc((len + 1 /* \0 */) * sizeof(char));
@@ -1562,15 +1579,8 @@ static int tuple_cb(const char *tuple, i
     /* We don't need the \o-terminated string anymore */
     OPENSSL_free(restored_tuple_string);
 
-    if (garg->tuplcnt_arr[garg->tplcnt] > 0) { /* Some valid groups are 
present in current tuple... */
-        if (garg->tuple_mode) {
-            /* We 'close' the tuple */
-            garg->tplcnt++;
-            garg->tuplcnt_arr[garg->tplcnt] = 0; /* Next tuple is initialized 
to be empty */
-            garg->tuple_mode = 1; /* next call will start a tuple (unless 
overridden in gid_cb) */
-        }
-    }
-
+    if (!garg->inner && !close_tuple(garg))
+        return 0;
     return retval;
 }
 
@@ -1601,8 +1611,6 @@ int tls1_set_groups_list(SSL_CTX *ctx,
     }
 
     memset(&gcb, 0, sizeof(gcb));
-    gcb.tuple_mode = 1; /* We prepare to collect the first tuple */
-    gcb.ignore_unknown_default = 0;
     gcb.gidmax = GROUPLIST_INCREMENT;
     gcb.tplmax = GROUPLIST_INCREMENT;
     gcb.ksidmax = GROUPLIST_INCREMENT;
Index: openssl-3.5.3/test/tls13groupselection_test.c
===================================================================
--- openssl-3.5.3.orig/test/tls13groupselection_test.c
+++ openssl-3.5.3/test/tls13groupselection_test.c
@@ -38,6 +38,12 @@ typedef enum SERVER_RESPONSE {
     SH   = 2
 } SERVER_RESPONSE;
 
+static const char *response_desc[] = {
+    "HRR",
+    "INIT",
+    "SH",
+};
+
 static char *cert = NULL;
 static char *privkey = NULL;
 
@@ -49,6 +55,18 @@ struct tls13groupselection_test_st {
     const enum SERVER_RESPONSE expected_server_response;
 };
 
+
+/*
+ * Tests that probe robust handling of group removal depend on detailed
+ * knowledge of the default group list.  A stable list is needed that does not
+ * depend on future changes in the actual built-in default.
+ */
+#define TEST_DEFLT                       \
+    "?*X25519MLKEM768 / "                \
+    "?*X25519 : ?secp256r1 / "           \
+    "?X448 : ?secp384r1 : ?secp521r1 / " \
+    "?ffdhe2048:?ffdhe3072"
+
 static const struct tls13groupselection_test_st tls13groupselection_tests[] =
     {
 
@@ -348,7 +366,39 @@ static const struct tls13groupselection_
           "X25519",
           SERVER_PREFERENCE,
           NEGOTIATION_FAILURE, INIT
-        }
+        },
+        /* DEFAULT retains tuple structure */
+        { "*X25519:secp256r1",
+            "secp256r1:DEFAULT", /* test 44 */
+            SERVER_PREFERENCE,
+            "secp256r1", HRR },
+#ifndef OPENSSL_NO_DH
+        { "*ffdhe2048:secp256r1",
+            "DEFAULT:ffdhe4096", /* test 45 */
+            CLIENT_PREFERENCE,
+            "secp256r1", HRR },
+        { "x25519:ffdhe2048:*ffdhe4096",
+            "DEFAULT:ffdhe4096", /* test 46 */
+            SERVER_PREFERENCE,
+            "x25519", HRR },
+        /*
+         * The server's second tuple becomes empty after removal
+         * of "secp256r1", the subsequent removal of X448 is
+         * then from the third tuple.
+         */
+        { "*ffdhe2048:secp384r1", /* test 47 */
+            "*X25519:" TEST_DEFLT ":-secp256r1:-X448",
+            SERVER_PREFERENCE,
+            "secp384r1", HRR },
+        /*
+         * The server's last tuple becomes empty after removals,
+         * and then continues to fill.
+         */
+        { "*ffdhe2048:ffdhe4096", /* test 48 */
+            "*X25519:" TEST_DEFLT ":-ffdhe2048:-ffdhe3072:ffdhe4096",
+            SERVER_PREFERENCE,
+            "ffdhe4096", HRR },
+#endif
     };
 
 static void server_response_check_cb(int write_p, int version,
@@ -359,10 +409,12 @@ static void server_response_check_cb(int
     enum SERVER_RESPONSE *server_response = (enum SERVER_RESPONSE *)arg;
     /* Prepare check for HRR */
     const uint8_t *incoming_random = (uint8_t *)buf + 6;
-    const uint8_t magic_HRR_random[32] = { 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 
0x61, 0x11,
-                                           0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 
0xB8, 0x91,
-                                           0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 
0x8C, 0x5E,
-                                           0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 
0x33, 0x9C };
+    const uint8_t magic_HRR_random[32] = {
+        0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
+        0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
+        0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
+        0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
+    };
 
     /* Did a server hello arrive? */
     if (write_p == 0 &&                                /* Incoming data... */
@@ -492,15 +544,16 @@ static int test_groupnegotiation(const s
         group_name_client = SSL_group_to_name(clientssl, 
negotiated_group_client);
         if (!TEST_int_eq(negotiated_group_client, negotiated_group_server))
             goto end;
-        if (!TEST_int_eq((int)current_test_vector->expected_server_response, 
(int)server_response))
+        if 
(!TEST_str_eq(response_desc[current_test_vector->expected_server_response],
+                response_desc[server_response]))
             goto end;
         if (TEST_str_eq(group_name_client, 
current_test_vector->expected_group))
             ok = 1;
     } else {
         TEST_false_or_end(create_ssl_connection(serverssl, clientssl, 
SSL_ERROR_NONE));
-        if (test_type == TEST_NEGOTIATION_FAILURE &&
-                
!TEST_int_eq((int)current_test_vector->expected_server_response,
-                             (int)server_response))
+        if (test_type == TEST_NEGOTIATION_FAILURE
+            && 
!TEST_str_eq(response_desc[current_test_vector->expected_server_response],
+                response_desc[server_response]))
             goto end;
         ok = 1;
     }

++++++ openssl-CVE-2026-28387.patch ++++++
commit 444958deaf450aea819171f97ae69eaedede42c3
Author: Alexandr Nedvedicky <[email protected]>
Date:   Tue Mar 3 13:23:46 2026 +0100

    dane_match_cert() should X509_free() on ->mcert instead
    of OPENSSL_free()
    
    Fixes: 170b735820ac "DANE support for X509_verify_cert()"
    
    Reviewed-by: Eugene Syromiatnikov <[email protected]>
    Reviewed-by: Tomas Mraz <[email protected]>
    Reviewed-by: Paul Dale <[email protected]>
    Reviewed-by: Neil Horman <[email protected]>
    MergeDate: Thu Mar  5 12:37:17 2026
    (Merged from https://github.com/openssl/openssl/pull/30250)
    
    (cherry picked from commit 8b5cd6a682f0f6e7b8bf55137137c567d1899c4a)

diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 8f1b9f58ca..01ce14982d 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -3016,7 +3016,7 @@ static int dane_match_cert(X509_STORE_CTX *ctx, X509 
*cert, int depth)
                     break;
                 }
 
-                OPENSSL_free(dane->mcert);
+                X509_free(dane->mcert);
                 dane->mcert = cert;
                 dane->mdpth = depth;
                 dane->mtlsa = t;

++++++ openssl-CVE-2026-28388-tests.patch ++++++
>From ee5f89352b7bbc768436cce684036c24052a1938 Mon Sep 17 00:00:00 2001
From: Daniel Kubec <[email protected]>
Date: Tue, 17 Mar 2026 11:14:56 +0100
Subject: [PATCH] Added test for CVE-2026-28388
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Reviewed-by: Saša Nedvědický <[email protected]>
Reviewed-by: Tomas Mraz <[email protected]>
MergeDate: Mon Apr  6 19:27:17 2026
(cherry picked from commit dd3544845e206ec8cbcbd756e2d402c57fc5d313)
Signed-off-by: Lucas Mulling <[email protected]>
---
 test/certs/cve-2026-28388-ca.pem   | 19 +++++++++++++++++++
 test/certs/cve-2026-28388-crls.pem | 22 ++++++++++++++++++++++
 test/certs/cve-2026-28388-leaf.pem | 19 +++++++++++++++++++
 test/recipes/25-test_verify.t      | 14 +++++++++++++-
 4 files changed, 73 insertions(+), 1 deletion(-)
 create mode 100644 test/certs/cve-2026-28388-ca.pem
 create mode 100644 test/certs/cve-2026-28388-crls.pem
 create mode 100644 test/certs/cve-2026-28388-leaf.pem

Index: openssl-3.5.3/test/certs/cve-2026-28388-ca.pem
===================================================================
--- /dev/null
+++ openssl-3.5.3/test/certs/cve-2026-28388-ca.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDFTCCAf2gAwIBAgIUOl5NN/jfsuLU9JSGLZAfRzviF+owDQYJKoZIhvcNAQEL
+BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjAzMTcwODE5NDdaFw0yNzAzMTcw
+ODE5NDdaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQD0m4KETjF0c25spNWUiNChWP0GalDL0gVDFbtAoMVF/lvlZEcp
+hcg62ifHJRPntWyVAmH70DAI87cWzl/73QYGaOcMVcH5yEM31BoK83FvhsS3RTPO
+FSrNCHaZrrWuga+QkBmMcR6qX7GF5eb6ASMBsLuuDqbkCRbTJ2ryhYeWF+VFemBF
+pSHpcinSSLvswTVbZiCqmoy0WkK8eiyfLMZA17PgVLQpyPZ3rp5YG5vEZZoqFc/f
+1bCHjwQ7fNdLCEMqPvE/I0mg2skRClb1L1Vieud/jmjL8nVd9I12j1eUOcSKtCkW
+nj4BFa7TRz13sN3LZOFvV774ZaXRJ1GxoAlnAgMBAAGjYzBhMB0GA1UdDgQWBBSt
+UxfaVbV9QMmfwMoImdgi4MZHzTAfBgNVHSMEGDAWgBStUxfaVbV9QMmfwMoImdgi
+4MZHzTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B
+AQsFAAOCAQEA84w49n0pPJlqiD1/mn3pUZ66lBP0fFZiCuV/3YatBZcW+xcboW0Q
+xImYztjZo0i+sQLZOalI4GoBqD77Dv4Qas0QoJZIp0wM8DjE3YcudCr4cpUhT1XC
+ruHVHQA9bY5rW0GsfUBW6/3RbRpiK4SaFG3sUBbXPo0dC2EaLDjpLM7o2UljRrWu
+d/vg6ieKuAicexLxqQLdM4SxjyvBpCwHg/dnMxawSj4Xhks1BHJ0hTLKJGDgfVHh
+ex8+878u6Gf7fAOZa5idWUgTvdt5WHSW5x+Tm/P6LGG3HkM425ZU6BLTCHONoBud
+cOlfWTTuIyweX5TRL5HY3SuO1cpMBpjiAA==
+-----END CERTIFICATE-----
Index: openssl-3.5.3/test/certs/cve-2026-28388-crls.pem
===================================================================
--- /dev/null
+++ openssl-3.5.3/test/certs/cve-2026-28388-crls.pem
@@ -0,0 +1,22 @@
+-----BEGIN X509 CRL-----
+MIIBizB1AgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EXDTI2
+MDMxNzA4MTk0N1oXDTI2MDQxNjA4MTk0N1qgLzAtMB8GA1UdIwQYMBaAFK1TF9pV
+tX1AyZ/AygiZ2CLgxkfNMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBl
+3vVknchCNA/oW0ovtnrE+xQs8yAk3uElooQlw88moTcts2YAcKWl49lnNWZk/RbF
+Zs8m+MUuNb2W861siuvY3EwnSKVaJB2tKPfCRBP4xt+Q0g/Tn5CWxzpzHjQfLT6l
+pvWOwaO7aE6bthX7MQ9XBpnHSPxsbul+MhV5PER11BYZGVh5MH0XxfMI0jDHFh2M
+klTamgaao3TkVOI3OQPgzUx/q0Lz/YoCIH0pYGGP6KTGUX2x7UfD1tcIOcUp6tvO
+6hG3utMgJOpZJl9yMzhG+ZURjbz4MSbBM0FVIaWnBn2VzY1jHGky0nK83IZhiddf
+OohWoSH8tqwrNFZkblAH
+-----END X509 CRL-----
+-----BEGIN X509 CRL-----
+MIIBjjB4AgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EXDTI2
+MDEwODEyMDAwMFoXDTI2MDIwODEyMDAwMFqgMjAwMB8GA1UdIwQYMBaAFK1TF9pV
+tX1AyZ/AygiZ2CLgxkfNMA0GA1UdGwEB/wQDAgEBMA0GCSqGSIb3DQEBCwUAA4IB
+AQCyYxa5iVUFxBpdXgBGSMqkuxJqQzVni8nXK0DiXHfgbTud+HD5Qp/6PX2EQuwK
+SrT0yeNJBU1gxxMMsbdA0yVTPa7N2Ny39mjq/27yBXduiljo3Gs4NLEW9grJRnep
+WOD1cQe3Fea5HlEfUoQJF1WVekF6CnOSqESaDvTAzqpZd7pxU8cuduiRJPin93ki
+1nicQAU/G4Td190+JEAWD3/dJTg2LF6LKrmHiv2ZUTuNsVBfcbhFSoC6FpnjFUAI
+kF8EgJpuBEfqV6erIuT1GD+5p1QGNqdcNl7LO9erJaUFnssJBJtj84iXd7RZARNs
+njcibOSKC9YWgNmZUy0QV5D8
+-----END X509 CRL-----
Index: openssl-3.5.3/test/certs/cve-2026-28388-leaf.pem
===================================================================
--- /dev/null
+++ openssl-3.5.3/test/certs/cve-2026-28388-leaf.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHTCCAgWgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
+IENBMB4XDTI2MDMxNzA4MTk0N1oXDTI3MDMxNzA4MTk0N1owFDESMBAGA1UEAwwJ
+VGVzdCBMZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqx7jpC6+
+nRZ4ol6sShkpv04hGYtt7y+Ns4oIfdQTqo57DItFab8D8cH04zR8NND42MMnsPPn
+Ovh9gv2l1mj9ZfwgXI5PvaKc6CoXvXb0ttekdDUS1iw9g04BxIXTDANxsdSXrCDd
+Npyr1Pxdo3N2fiH6qN9/Lsh7yg0vJW/aJzdvhLcCTFcr89qmCsh17XfcTR0wZJXP
+QdlRib9EK8aa6aKOYmm44SBbuXXyWojhheUaqVuzDj6A0L9opmh/DVXa9bdIN/FX
+CKJB+d60Qxy5pKwpzDDxbCdG2vA1U2cPz8yAgelFG5AmXSHF7Id4G6GTCAY6PbTO
+Jy2Z4I6NY+mj5wIDAQABo3wwejAdBgNVHQ4EFgQUlf2YZ93MvS4kZm7fshosgp+J
+ImkwHwYDVR0jBBgwFoAUrVMX2lW1fUDJn8DKCJnYIuDGR80wCQYDVR0TBAIwADAt
+BgNVHS4EJjAkMCKgIKAehhxodHRwOi8vZXhhbXBsZS5jb20vZGVsdGEucGVtMA0G
+CSqGSIb3DQEBCwUAA4IBAQDoNAQGLS0Juf3i2fhuVQyWIFvNIMElLexeLnnd/y80
+13nsP68ZGT2D3DoHQSz3SL7sNjLBc2CiUVftdaRQ4dNCz8sBY5BRTS5XEGbbTAFZ
+bQUReykuuTy83CGw/JYN6YT/OHcf4gEhUnWtRMCmIz3J/NMRVSRnpV2Ezjltm/Q+
+emFS/QclRhkP6Vu+lwM/nV6uAN8T7Ba68Hym2MN0clozrpoKeqFouB7D0i+iCZMw
+zbac5as0hn7Fm+HGTbfTs2/fqUslvE6PmagepceP37pTSSVmYRmdpOD2cyCb30A+
+nJFGQg7PcacGSL1re65W35XzdU8Si8OYD+PxjDaRbPcP
+-----END CERTIFICATE-----
Index: openssl-3.5.3/test/recipes/25-test_verify.t
===================================================================
--- openssl-3.5.3.orig/test/recipes/25-test_verify.t
+++ openssl-3.5.3/test/recipes/25-test_verify.t
@@ -30,7 +30,7 @@ sub verify {
     run(app([@args]));
 }
 
-plan tests => 202;
+plan tests => 203;
 
 # Canonical success
 ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -595,6 +595,18 @@ ok(!verify("ee-cert-policies-bad", "", [
            "-explicit_policy"),
    "Bad certificate policy");
 
+# CVE-2026-28388
+my $cve_28388_stderr = "cve-2026-28388.err";
+run(app(["openssl", "verify",
+         "-attime", "1739527200",
+         "-CAfile", srctop_file(@certspath, "cve-2026-28388-ca.pem"),
+         "-crl_check", "-use_deltas",
+         "-CRLfile", srctop_file(@certspath, "cve-2026-28388-crls.pem"),
+         srctop_file(@certspath, "cve-2026-28388-leaf.pem")],
+         stderr => $cve_28388_stderr));
+ok(grep(/CRL is not yet valid/, do { open my $fh, '<', $cve_28388_stderr; 
<$fh> }),
+   "CVE-2026-28388");
+
 # CAstore option
 my $rootcertname = "root-cert";
 my $rootcert = srctop_file(@certspath, "${rootcertname}.pem");

++++++ openssl-CVE-2026-28388.patch ++++++
commit 6297bdc962e9f2ecb436e26dc51f4fff653a0a89
Author: Daniel Kubec <[email protected]>
Date:   Tue Mar 17 11:11:22 2026 +0100

    Fix NULL Dereference When Delta CRL Lacks CRL Number Extension
    
    Fixes CVE-2026-28388
    Fixes https://github.com/openssl/srt/issues/77

diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 827a7663aa..f2b88524b6 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1578,6 +1578,8 @@ static int check_delta_base(X509_CRL *delta, X509_CRL 
*base)
     if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
         return 0;
     /* Delta CRL number must exceed full CRL number */
+    if (delta->crl_number == NULL)
+        return 0;
     return ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0;
 }
 

++++++ openssl-CVE-2026-28389.patch ++++++
commit e406df64aea245a4caacf25793df9efa08ea5d8f
Author: Neil Horman <[email protected]>
Date:   Mon Mar 16 13:49:07 2026 -0400

    Fix inadvertent NULL deref in [ec]dh_cms_set_shared_info
    
    Two independent reports indicated a SIGSEGV was possible in CMS
    processing when a crafted CMS EnvelopedData message using A Key
    Agreement Recipient Info field.  If they
    KeyEncryptionAlgorithmIdentifier omits the optional parameter field, The
    referenced funcitons above will attempt to dereference the
    alg->parameter data prior to checking if the paramter field is NULL.
    
    Easy fix, just make sure to check if the field is NULL before accessing
    
    Confirmed to resolve the issues using the reproducers provided in the
    security reports.
    
    Fixes CVE-2026-28389

diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c
index a10df73b10..7478a5dd5e 100644
--- a/crypto/cms/cms_dh.c
+++ b/crypto/cms/cms_dh.c
@@ -94,6 +94,9 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, 
CMS_RecipientInfo *ri)
     if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
         goto err;
 
+    if (alg == NULL || alg->parameter == NULL)
+        goto err;
+
     /*
      * For DH we only have one OID permissible. If ever any more get defined
      * we will need something cleverer.
diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c
index ff8adad616..a5a00ca276 100644
--- a/crypto/cms/cms_ec.c
+++ b/crypto/cms/cms_ec.c
@@ -171,6 +171,9 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, 
CMS_RecipientInfo *ri)
     if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
         return 0;
 
+    if (alg == NULL || alg->parameter == NULL)
+        return 0;
+
     if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
         ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR);
         return 0;

++++++ openssl-CVE-2026-28390.patch ++++++
>From 2e39b7a6993be445fddb9fbce316fa756e0397b6 Mon Sep 17 00:00:00 2001
From: Neil Horman <[email protected]>
Date: Wed, 1 Apr 2026 10:56:44 +0200
Subject: [PATCH] Fix NULL deref in rsa_cms_decrypt
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Very simmilar to CVE-2026-28389, ensure that if we are missing
parameters in RSA-OAEP SourceFunc in CMS KeyTransportRecipientInfo,
we don't segfault when decrypting.

Co-authored-by: Tomas Mraz <[email protected]>

Fixes CVE-2026-28390

Reviewed-by: Saša Nedvědický <[email protected]>
Reviewed-by: Nikola Pajkovsky <[email protected]>
MergeDate: Mon Apr  6 19:06:14 2026
---
 crypto/cms/cms_rsa.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

Index: openssl-3.5.0/crypto/cms/cms_rsa.c
===================================================================
--- openssl-3.5.0.orig/crypto/cms/cms_rsa.c
+++ openssl-3.5.0/crypto/cms/cms_rsa.c
@@ -42,10 +42,13 @@ static int rsa_cms_decrypt(CMS_Recipient
     X509_ALGOR *cmsalg;
     int nid;
     int rv = -1;
-    unsigned char *label = NULL;
+    const unsigned char *label = NULL;
     int labellen = 0;
     const EVP_MD *mgf1md = NULL, *md = NULL;
     RSA_OAEP_PARAMS *oaep;
+    const ASN1_OBJECT *aoid;
+    const void *parameter = NULL;
+    int ptype = 0;
 
     pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
     if (pkctx == NULL)
@@ -75,21 +78,19 @@ static int rsa_cms_decrypt(CMS_Recipient
         goto err;
 
     if (oaep->pSourceFunc != NULL) {
-        X509_ALGOR *plab = oaep->pSourceFunc;
+        X509_ALGOR_get0(&aoid, &ptype, &parameter, oaep->pSourceFunc);
 
-        if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
+        if (OBJ_obj2nid(aoid) != NID_pSpecified) {
             ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_LABEL_SOURCE);
             goto err;
         }
-        if (plab->parameter->type != V_ASN1_OCTET_STRING) {
+        if (ptype != V_ASN1_OCTET_STRING) {
             ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_LABEL);
             goto err;
         }
 
-        label = plab->parameter->value.octet_string->data;
-        /* Stop label being freed when OAEP parameters are freed */
-        plab->parameter->value.octet_string->data = NULL;
-        labellen = plab->parameter->value.octet_string->length;
+        label = ASN1_STRING_get0_data(parameter);
+        labellen = ASN1_STRING_length(parameter);
     }
 
     if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
@@ -98,10 +99,16 @@ static int rsa_cms_decrypt(CMS_Recipient
         goto err;
     if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
         goto err;
-    if (label != NULL
-            && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) {
-        OPENSSL_free(label);
-        goto err;
+    if (label != NULL) {
+        unsigned char *dup_label = OPENSSL_memdup(label, labellen);
+
+        if (dup_label == NULL)
+            goto err;
+
+        if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, dup_label, labellen) <= 0) 
{
+            OPENSSL_free(dup_label);
+            goto err;
+        }
     }
     /* Carry on */
     rv = 1;

++++++ openssl-CVE-2026-31789.patch ++++++
commit c1f14e209519886cd7bc714cee819d8318b2f90f
Author: Igor Ustinov <[email protected]>
Date:   Thu Mar 5 15:47:34 2026 +0100

    Avoid possible buffer overflow in buf2hex conversion
    
    Fixes CVE-2026-31789

diff --git a/crypto/o_str.c b/crypto/o_str.c
index 22d8028beb..c2ec1fc261 100644
--- a/crypto/o_str.c
+++ b/crypto/o_str.c
@@ -299,6 +299,11 @@ static int buf2hexstr_sep(char *str, size_t str_n, size_t 
*strlength,
     int has_sep = (sep != CH_ZERO);
     size_t i, len = has_sep ? buflen * 3 : 1 + buflen * 2;
 
+    if (buflen > (has_sep ? SIZE_MAX / 3 : (SIZE_MAX - 1) / 2)) {
+        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES);
+        return 0;
+    }
+
     if (len == 0)
         ++len;
     if (strlength != NULL)
@@ -344,7 +349,13 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long 
buflen, char sep)
     if (buflen == 0)
         return OPENSSL_zalloc(1);
 
-    tmp_n = (sep != CH_ZERO) ? buflen * 3 : 1 + buflen * 2;
+    if ((sep != CH_ZERO && (size_t)buflen > SIZE_MAX / 3)
+        || (sep == CH_ZERO && (size_t)buflen > (SIZE_MAX - 1) / 2)) {
+        ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES);
+        return NULL;
+    }
+
+    tmp_n = (sep != CH_ZERO) ? (size_t)buflen * 3 : 1 + (size_t)buflen * 2;
     if ((tmp = OPENSSL_malloc(tmp_n)) == NULL)
         return NULL;
 

++++++ openssl-CVE-2026-31790-tests.patch ++++++
commit 5872c416ef46aabc48c2025fd064bedf221aaee0
Author: Nikola Pajkovsky <[email protected]>
Date:   Mon Mar 23 08:41:20 2026 +0100

    rsa_kem: test RSA_public_encrypt() result in RSASVE
    
    RSA_public_encrypt() returns the number of bytes written on success and
    -1 on failure.
    
    Add regression coverage in evp_extra_test using invalid RSA pubkey
    which triggers -1 in RSA_public_encrypt() using encapsulation.
    
    Fixes: https://github.com/openssl/srt/issues/95
    Signed-off-by: Nikola Pajkovsky <[email protected]>

Index: openssl-3.5.0/test/evp_extra_test.c
===================================================================
--- openssl-3.5.0.orig/test/evp_extra_test.c
+++ openssl-3.5.0/test/evp_extra_test.c
@@ -928,6 +928,32 @@ static EVP_PKEY *load_example_ec_key(voi
 #endif
 
 #ifndef OPENSSL_NO_DEPRECATED_3_0
+
+static EVP_PKEY *make_bad_rsa_pubkey(void)
+{
+    RSA *rsa = NULL;
+    BIGNUM *n = NULL, *e = NULL;
+    EVP_PKEY *pkey = NULL;
+
+    /* Deliberately invalid public key: n = 17, e = 17 */
+    if (!TEST_ptr(pkey = EVP_PKEY_new())
+        || !TEST_ptr(rsa = RSA_new())
+        || !TEST_ptr(n = BN_new())
+        || !TEST_ptr(e = BN_new())
+        || !TEST_true(BN_set_word(n, 17))
+        || !TEST_true(BN_set_word(e, 17))
+        || !TEST_true(RSA_set0_key(rsa, n, e, NULL))
+        || !EVP_PKEY_assign_RSA(pkey, rsa))
+        goto err;
+
+    return pkey;
+err:
+    BN_free(n);
+    BN_free(e);
+    RSA_free(rsa);
+    return NULL;
+}
+
 # ifndef OPENSSL_NO_DH
 static EVP_PKEY *load_example_dh_key(void)
 {
@@ -5901,6 +5927,46 @@ static int test_custom_ciph_meth(void)
     return testresult;
 }
 
+static int test_rsasve_kem_with_invalid_pub_key(void)
+{
+    RSA *rsa = NULL;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    unsigned char *ct = NULL;
+    unsigned char *secret = NULL;
+    size_t ctlen = 0, secretlen = 0;
+    int testresult = 0;
+
+    if (nullprov != NULL) {
+        testresult = TEST_skip("Test does not support a non-default library 
context");
+        goto err;
+    }
+
+    if (!TEST_ptr(pkey = make_bad_rsa_pubkey()))
+        goto err;
+
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(testctx, pkey, NULL))
+        || !TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 1)
+        || !TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, "RSASVE"), 1)
+        || !TEST_int_eq(EVP_PKEY_encapsulate(ctx, NULL, &ctlen, NULL, 
&secretlen), 1)
+        || !TEST_ptr(ct = OPENSSL_malloc(ctlen))
+        || !TEST_ptr(secret = OPENSSL_malloc(secretlen)))
+        goto err;
+
+    if (!TEST_int_eq(EVP_PKEY_encapsulate(ctx, ct, &ctlen, secret, 
&secretlen), 0))
+        goto err;
+
+    testresult = 1;
+
+err:
+    OPENSSL_free(secret);
+    OPENSSL_free(ct);
+    EVP_PKEY_CTX_free(ctx);
+    RSA_free(rsa);
+    EVP_PKEY_free(pkey);
+    return testresult;
+}
+
 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
 /* Test we can create a signature keys with an associated ENGINE */
 static int test_signatures_with_engine(int tst)
@@ -6861,6 +6927,7 @@ int setup_tests(void)
     ADD_TEST(test_evp_md_cipher_meth);
     ADD_TEST(test_custom_md_meth);
     ADD_TEST(test_custom_ciph_meth);
+    ADD_TEST(test_rsasve_kem_with_invalid_pub_key);
 
 # ifndef OPENSSL_NO_DYNAMIC_ENGINE
     /* Tests only support the default libctx */

++++++ openssl-CVE-2026-31790.patch ++++++
commit a6cea8781bf8fd53768a8ea3ff2d1120ec644b0d
Author: Nikola Pajkovsky <[email protected]>
Date:   Thu Mar 19 12:16:08 2026 +0100

    rsa_kem: validate RSA_public_encrypt() result in RSASVE
    
    RSA_public_encrypt() returns the number of bytes written on success and
    -1 on failure. With the existing `if (ret)` check, a provider-side RSA KEM
    encapsulation can incorrectly succeed when the underlying RSA public
    encrypt operation fails. In that case the code reports success, returns
    lengths as if encapsulation completed normally, and leaves the freshly
    generated secret available instead of discarding it.
    
    Tighten the success condition so RSASVE only succeeds when
    RSA_public_encrypt() returns a positive value equal to the modulus-sized
    output expected for RSA_NO_PADDING. Any other return value is treated as
    failure, and the generated secret is cleansed before returning.
    
    Fixes CVE: CVE-2026-31790
    Fixes: https://github.com/openssl/srt/issues/95
    Signed-off-by: Nikola Pajkovsky <[email protected]>

diff --git a/providers/implementations/kem/rsa_kem.c 
b/providers/implementations/kem/rsa_kem.c
index f7bf368a0d..74dfafddd9 100644
--- a/providers/implementations/kem/rsa_kem.c
+++ b/providers/implementations/kem/rsa_kem.c
@@ -316,17 +316,19 @@ static int rsasve_generate(PROV_RSA_CTX *prsactx,
         return 0;
 
     /* Step(3): out = RSAEP((n,e), z) */
-    ret = RSA_public_encrypt(nlen, secret, out, prsactx->rsa, RSA_NO_PADDING);
-    if (ret) {
-        ret = 1;
-        if (outlen != NULL)
-            *outlen = nlen;
-        if (secretlen != NULL)
-            *secretlen = nlen;
-    } else {
+    ret = RSA_public_encrypt((int)nlen, secret, out, prsactx->rsa,
+        RSA_NO_PADDING);
+    if (ret <= 0 || ret != (int)nlen) {
         OPENSSL_cleanse(secret, nlen);
+        return 0;
     }
-    return ret;
+
+    if (outlen != NULL)
+        *outlen = nlen;
+    if (secretlen != NULL)
+        *secretlen = nlen;
+
+    return 1;
 }
 
 /**

++++++ openssl-NULL-pointer-dereference-in-ocsp_find_signer_sk.patch ++++++
commit de4bb3bfc7d5d56b2b678bbd90f60c8b440ea287
Author: Alexandr Nedvedicky <[email protected]>
Date:   Tue Mar 17 11:48:41 2026 +0100

    CVE-2026-31791 NULL pointer dereference in ocsp_find_signer_sk() when 
ResponderID byKey is NULL
    
    the issue has been kindly reported and fix contributed by 
[email protected],
    [email protected] and [email protected]

diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c
index 70e670cd63..d2a741c13f 100644
--- a/crypto/ocsp/ocsp_vfy.c
+++ b/crypto/ocsp/ocsp_vfy.c
@@ -199,6 +199,8 @@ static X509 *ocsp_find_signer_sk(const STACK_OF(X509) 
*certs, OCSP_RESPID *id)
     /* Lookup by key hash */
 
     /* If key hash isn't SHA1 length then forget it */
+    if (id->value.byKey == NULL)
+        return NULL;
     if (id->value.byKey->length != SHA_DIGEST_LENGTH)
         return NULL;
     keyhash = id->value.byKey->data;

++++++ 
openssl-crypto-mem.c-factor-out-memory-allocation-failure-reporting.patch ++++++
>From bd1c59739d57ca27162bd582161a5cbddba21999 Mon Sep 17 00:00:00 2001
From: Eugene Syromiatnikov <[email protected]>
Date: Thu, 17 Jul 2025 03:29:35 +0200
Subject: [PATCH] crypto/mem.c: factor out memory allocation failure reporting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Eugene Syromiatnikov <[email protected]>

Reviewed-by: Saša Nedvědický <[email protected]>
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
Reviewed-by: Neil Horman <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/28059)

Signed-off-by: Lucas Mulling <[email protected]>
---
 crypto/mem.c                       | 11 ++-----
 include/internal/mem_alloc_utils.h | 50 ++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 9 deletions(-)
 create mode 100644 include/internal/mem_alloc_utils.h

Index: openssl-3.5.3/crypto/mem.c
===================================================================
--- openssl-3.5.3.orig/crypto/mem.c
+++ openssl-3.5.3/crypto/mem.c
@@ -9,6 +9,7 @@
 
 #include "internal/e_os.h"
 #include "internal/cryptlib.h"
+#include "internal/mem_alloc_utils.h"
 #include "crypto/cryptlib.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -212,15 +213,7 @@ void *CRYPTO_malloc(size_t num, const ch
     if (ptr != NULL)
         return ptr;
  err:
-    /*
-     * ossl_err_get_state_int() in err.c uses CRYPTO_zalloc(num, NULL, 0) for
-     * ERR_STATE allocation. Prevent mem alloc error loop while reporting 
error.
-     */
-    if (file != NULL || line != 0) {
-        ERR_new();
-        ERR_set_debug(file, line, NULL);
-        ERR_set_error(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE, NULL);
-    }
+    ossl_report_alloc_err(file, line);
     return NULL;
 }
 
Index: openssl-3.5.3/include/internal/mem_alloc_utils.h
===================================================================
--- /dev/null
+++ openssl-3.5.3/include/internal/mem_alloc_utils.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Utility overflow checking and reporting functions
+ */
+
+#ifndef OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H
+# define OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H
+
+# include "internal/common.h"
+
+# include <openssl/cryptoerr.h>
+# include <openssl/err.h>
+
+/*
+ * A helper routine to report memory allocation errors.
+ * Similar to the ERR_raise() macro, but accepts explicit file/line arguments,
+ * pre-defines the library to ERR_LIB_CRYPTO, and avoids emitting an error
+ * if both file set to NULL and line set to 0.
+ */
+static ossl_inline ossl_unused void
+ossl_report_alloc_err_ex(const char * const file, const int line,
+                         const int reason)
+{
+    /*
+     * ossl_err_get_state_int() in err.c uses CRYPTO_zalloc(num, NULL, 0) for
+     * ERR_STATE allocation. Prevent mem alloc error loop while reporting 
error.
+     */
+    if (file != NULL || line != 0) {
+        ERR_new();
+        ERR_set_debug(file, line, NULL);
+        ERR_set_error(ERR_LIB_CRYPTO, reason, NULL);
+    }
+}
+
+/* Report a memory allocation failure. */
+static inline void
+ossl_report_alloc_err(const char * const file, const int line)
+{
+    ossl_report_alloc_err_ex(file, line, ERR_R_MALLOC_FAILURE);
+}
+
+#endif /* OSSL_INTERNAL_CHECK_SIZE_OVERFLOW_H */

Reply via email to