Commit 7d4475bdf2 for openssl.org

commit 7d4475bdf251bae7ed504e96230dcf12d7329f6d
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Fri Jun 19 15:58:59 2026 +0200

    statem: fail handshake if there is  memory failure in negotiate_dhe

    Previously this just resulted in the skip of the group but such failure
    should result in a proper error. This is not a big issue but it impacts
    mfail tests so it would be good to fail.

    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Reviewed-by: Daniel Kubec <kubec@openssl.foundation>
    MergeDate: Tue Jun 30 08:54:47 2026
    (Merged from https://github.com/openssl/openssl/pull/31618)

diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index f9ece09df3..0b220965c1 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -201,6 +201,8 @@ EXT_RETURN tls_construct_ctos_srp(SSL_CONNECTION *s, WPACKET *pkt,
  * with the sole exception of psk-ke resumption, provided the client is sure
  * that the server will not want elect a full handshake. The check type then
  * indicates whether ECDHE or FFDHE negotiation should be performed.
+ *
+ * It returns 1 if negotiation is supported, 0 if it's not and -1 on error.
  */
 static int negotiate_dhe(SSL_CONNECTION *s, dhe_check_t check_type,
     int min_version, int max_version)
@@ -214,6 +216,8 @@ static int negotiate_dhe(SSL_CONNECTION *s, dhe_check_t check_type,

     /* See if we support any EC or FFDHE ciphersuites */
     cipher_stack = SSL_get1_supported_ciphers(ssl);
+    if (cipher_stack == NULL)
+        return -1;
     end = sk_SSL_CIPHER_num(cipher_stack);
     for (i = 0; i < end; i++) {
         const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
@@ -263,15 +267,20 @@ EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL_CONNECTION *s, WPACKET *pkt,
 {
     const unsigned char *pformats;
     size_t num_formats;
-    int reason, min_version, max_version;
+    int reason, min_version, max_version, dhe_result;

     reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL);
     if (reason != 0) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, reason);
         return EXT_RETURN_FAIL;
     }
-    if (!negotiate_dhe(s, ptfmt_check, min_version, max_version))
+    dhe_result = negotiate_dhe(s, ptfmt_check, min_version, max_version);
+    if (dhe_result == 0)
         return EXT_RETURN_NOT_SENT;
+    if (dhe_result < 0) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        return EXT_RETURN_FAIL;
+    }

     tls1_get_formatlist(s, &pformats, &num_formats);
     if (num_formats == 0)
@@ -314,7 +323,11 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt,
      */
     use_ecdhe = negotiate_dhe(s, ecdhe_check, min_version, max_version);
     use_ffdhe = negotiate_dhe(s, ffdhe_check, min_version, max_version);
-    if (!use_ecdhe && !use_ffdhe
+    if (use_ecdhe < 0 || use_ffdhe < 0) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        return EXT_RETURN_FAIL;
+    }
+    if (use_ecdhe == 0 && use_ffdhe == 0
         && (dtls ? DTLS_VERSION_LE(max_version, DTLS1_2_VERSION)
                  : (max_version <= TLS1_2_VERSION)))
         return EXT_RETURN_NOT_SENT;