]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Restrict the number of supported groups/sig algs
authorMatt Caswell <matt@openssl.org>
Tue, 3 Mar 2026 12:30:24 +0000 (12:30 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 6 Mar 2026 10:32:21 +0000 (10:32 +0000)
We restrict the number of supported groups and sig algs that the server
is willing to accept from the client to 128 (for both). Any more than
this are simply ignored. This number is significantly more than the total
amount of current codepoints assigned by IANA for these extensions.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
MergeDate: Fri Mar  6 10:33:03 2026
(Merged from https://github.com/openssl/openssl/pull/30263)

ssl/ssl_local.h
ssl/statem/extensions_srvr.c
ssl/t1_lib.c

index e91e910b1d150a3b2ee1240e00ae39de3b614dcd..8a48c2099a99e9ce2cf874d3f62cda46d83e20c5 100644 (file)
@@ -2794,7 +2794,7 @@ int tls_choose_sigalg(SSL_CONNECTION *s, int fatalerrs);
 __owur long ssl_get_algorithm2(SSL_CONNECTION *s);
 __owur int tls12_copy_sigalgs(SSL_CONNECTION *s, WPACKET *pkt,
     const uint16_t *psig, size_t psiglen);
-__owur int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen);
+__owur int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen, size_t maxnum);
 __owur int tls1_save_sigalgs(SSL_CONNECTION *s, PACKET *pkt, int cert);
 __owur int tls1_process_sigalgs(SSL_CONNECTION *s);
 __owur int tls1_set_peer_legacy_sigalg(SSL_CONNECTION *s, const EVP_PKEY *pkey);
index 97c7fc961191799b9ddb7f063864f197e153314c..6c84518fae19e3e6eb8c23ca0ed62e86e6a45f0d 100644 (file)
@@ -19,6 +19,7 @@
 
 #define COOKIE_STATE_FORMAT_VERSION 1
 
+#define MAX_SUPPORTED_GROUPS 128
 #define MAX_KEY_SHARES 16
 
 /*
@@ -1225,9 +1226,16 @@ int tls_parse_ctos_supported_groups(SSL_CONNECTION *s, PACKET *pkt,
         OPENSSL_free(s->ext.peer_supportedgroups);
         s->ext.peer_supportedgroups = NULL;
         s->ext.peer_supportedgroups_len = 0;
+        /*
+         * We only pay attention to the first 128 supported groups and ignore
+         * any beyond that limit. Theoretically this could cause problems if
+         * the client also uses one of these groups (say in a key share extension)
+         * - but why would any valid client be sending such a huge supported
+         * groups list?
+         */
         if (!tls1_save_u16(&supported_groups_list,
                 &s->ext.peer_supportedgroups,
-                &s->ext.peer_supportedgroups_len)) {
+                &s->ext.peer_supportedgroups_len, MAX_SUPPORTED_GROUPS)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
             return 0;
         }
index ec7a7b643b5196b7ca65cdeaf95922bb94201c33..1f2ede5d926795b90952a0a810cdc79c1fd8fae3 100644 (file)
@@ -29,6 +29,8 @@
 #include "quic/quic_local.h"
 #include <openssl/ct.h>
 
+#define MAX_SIGALGS 128
+
 static const SIGALG_LOOKUP *find_sig_alg(SSL_CONNECTION *s, X509 *x, EVP_PKEY *pkey);
 static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, const SIGALG_LOOKUP *lu);
 
@@ -3673,7 +3675,7 @@ static int tls1_set_shared_sigalgs(SSL_CONNECTION *s)
     return 1;
 }
 
-int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen)
+int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen, size_t maxnum)
 {
     unsigned int stmp;
     size_t size, i;
@@ -3687,6 +3689,13 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen)
 
     size >>= 1;
 
+    /*
+     * We ignore any entries in the list larger than the maximum number we
+     * will accept.
+     */
+    if (size > maxnum)
+        size = maxnum;
+
     if ((buf = OPENSSL_malloc_array(size, sizeof(*buf))) == NULL)
         return 0;
     for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++)
@@ -3713,12 +3722,16 @@ int tls1_save_sigalgs(SSL_CONNECTION *s, PACKET *pkt, int cert)
     if (s->cert == NULL)
         return 0;
 
+    /*
+     * We restrict the number of signature algorithms we are willing to process
+     * to 128. Any beyond this number are simply ignored.
+     */
     if (cert)
         return tls1_save_u16(pkt, &s->s3.tmp.peer_cert_sigalgs,
-            &s->s3.tmp.peer_cert_sigalgslen);
+            &s->s3.tmp.peer_cert_sigalgslen, MAX_SIGALGS);
     else
         return tls1_save_u16(pkt, &s->s3.tmp.peer_sigalgs,
-            &s->s3.tmp.peer_sigalgslen);
+            &s->s3.tmp.peer_sigalgslen, MAX_SIGALGS);
 }
 
 /* Set preferred digest for each key type */