]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
x509/name_constraints: make types_with_empty_intersection a bitmask
authorAlexander Sosedkin <asosedkin@redhat.com>
Wed, 4 Feb 2026 17:31:37 +0000 (18:31 +0100)
committerAlexander Sosedkin <asosedkin@redhat.com>
Mon, 9 Feb 2026 11:59:26 +0000 (12:59 +0100)
Signed-off-by: Alexander Sosedkin <asosedkin@redhat.com>
lib/x509/name_constraints.c

index de20dd8ef4159dbf0da6758e5489f969be0fad6b..1d78d1bc50f87fc137565cc4d8c14b158aeb9d5f 100644 (file)
@@ -275,6 +275,7 @@ static enum name_constraint_relation compare_ip_ncs(const gnutls_datum_t *n1,
 
 static inline bool is_supported_type(unsigned type)
 {
+       /* all of these should be under GNUTLS_SAN_MAX (intersect bitmasks) */
        return type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
               type == GNUTLS_SAN_IPADDRESS;
 }
@@ -683,6 +684,21 @@ name_constraints_node_new(gnutls_x509_name_constraints_t nc, unsigned type,
        return tmp;
 }
 
+static int
+name_constraints_node_list_union(gnutls_x509_name_constraints_t nc,
+                                struct name_constraints_node_list_st *nodes,
+                                struct name_constraints_node_list_st *nodes2);
+
+#define type_bitmask_t uint8_t /* increase if GNUTLS_SAN_MAX grows */
+#define type_bitmask_set(mask, t) ((mask) |= (1u << (t)))
+#define type_bitmask_clr(mask, t) ((mask) &= ~(1u << (t)))
+#define type_bitmask_in(mask, t) ((mask) & (1u << (t)))
+/* C99-compatible compile-time assertions; gnutls_int.h undefines verify */
+typedef char assert_san_max[(GNUTLS_SAN_MAX < 8) ? 1 : -1];
+typedef char assert_dnsname[(GNUTLS_SAN_DNSNAME <= GNUTLS_SAN_MAX) ? 1 : -1];
+typedef char assert_rfc822[(GNUTLS_SAN_RFC822NAME <= GNUTLS_SAN_MAX) ? 1 : -1];
+typedef char assert_ipaddr[(GNUTLS_SAN_IPADDRESS <= GNUTLS_SAN_MAX) ? 1 : -1];
+
 /*-
  * @brief name_constraints_node_list_intersect:
  * @nc: %gnutls_x509_name_constraints_t
@@ -710,12 +726,9 @@ static int name_constraints_node_list_intersect(
                                                         .capacity = 0 };
        static const unsigned char universal_ip[32] = { 0 };
 
-       /* temporary array to see, if we need to add universal excluded constraints
-        * (see phase 3 for details)
-        * indexed directly by (gnutls_x509_subject_alt_name_t enum - 1) */
-       unsigned char types_with_empty_intersection[GNUTLS_SAN_MAX];
-       memset(types_with_empty_intersection, 0,
-              sizeof(types_with_empty_intersection));
+       /* bitmask to see if we need to add universal excluded constraints
+        * (see phase 3 for details) */
+       type_bitmask_t types_with_empty_intersection = 0;
 
        if (permitted->size == 0 || permitted2->size == 0)
                return 0;
@@ -741,7 +754,8 @@ static int name_constraints_node_list_intersect(
                                // note the possibility of empty intersection for this type
                                // if we add something to the intersection in phase 2,
                                // we will reset this flag back to 0 then
-                               types_with_empty_intersection[t->type - 1] = 1;
+                               type_bitmask_set(types_with_empty_intersection,
+                                                t->type);
                                found = t2;
                                break;
                        }
@@ -798,8 +812,8 @@ static int name_constraints_node_list_intersect(
                                                GNUTLS_E_INTERNAL_ERROR);
                                }
                                // we will not add universal excluded constraint for this type
-                               types_with_empty_intersection[tmp->type - 1] =
-                                       0;
+                               type_bitmask_clr(types_with_empty_intersection,
+                                                tmp->type);
                                // add intersection node to PERMITTED
                                ret = name_constraints_node_list_add(permitted,
                                                                     tmp);
@@ -827,7 +841,7 @@ static int name_constraints_node_list_intersect(
         * excluded constraint with universal wildcard
         * (since the intersection of permitted is now empty). */
        for (type = 1; type <= GNUTLS_SAN_MAX; type++) {
-               if (types_with_empty_intersection[type - 1] == 0)
+               if (!type_bitmask_in(types_with_empty_intersection, type))
                        continue;
                _gnutls_hard_log(
                        "Adding universal excluded name constraint for type %d.\n",
@@ -871,6 +885,11 @@ cleanup:
        return ret;
 }
 
+#undef type_bitmask_t
+#undef type_bitmask_set
+#undef type_bitmask_clr
+#undef type_bitmask_in
+
 static int
 name_constraints_node_list_union(gnutls_x509_name_constraints_t nc,
                                 struct name_constraints_node_list_st *nodes,