]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
x509: fix incorrect handling in name constraints merging
authorchenjianhu <chenjianhu@kylinos.cn>
Fri, 1 Aug 2025 09:18:23 +0000 (17:18 +0800)
committerDaiki Ueno <ueno@gnu.org>
Mon, 18 Aug 2025 06:04:47 +0000 (15:04 +0900)
As mentioned in commit ca573d65 ("x509: Fix asymmetry in name
constraints intersection", 2016-07-29), the
_gnutls_name_constraints_intersect function exhibited an
asymmetry in name constraints intersection behavior, specifically
manifested as:
1. Nodes of unique types in PERMITTED (absent in PERMITTED2) were
   preserved
2. Nodes of unique types in PERMITTED2 (absent in PERMITTED) were
   discarded

A 'used' flag was introduced, where if a node from PERMITTED2 was
   not used for the intersection, it would be copied to PERMITTED.

However,an unresolved edge case persisted:
- When 'removed.size > 0', the 'used' flag was unconditionally set
to 1
- This prevented copying of PERMITTED2 nodes with unique types

Signed-off-by: chenjianhu <chenjianhu@kylinos.cn>
Modified-by: Daiki Ueno <ueno@gnu.org>
lib/x509/name_constraints.c
tests/name-constraints-merge.c

index 3c6e3063033fd0a77e37676f958b3c9e70f3e0cb..2be6a2aaa681fc7cdfac32c310ee66d0dd515a39 100644 (file)
@@ -414,7 +414,10 @@ static int name_constraints_node_list_intersect(
                                gnutls_assert();
                                goto cleanup;
                        }
-                       used = 1;
+
+                       if (t->type == t2->type)
+                               used = 1;
+
                        // if intersection is not empty
                        if (tmp !=
                            NULL) { // intersection for this type is not empty
index 03b3243cc7573221b143ae07f0db82a9f5ab4143..70376aaa7499b42c5f2310084a705d8529be0365 100644 (file)
@@ -418,6 +418,61 @@ void doit(void)
        gnutls_x509_name_constraints_deinit(nc1);
        gnutls_x509_name_constraints_deinit(nc2);
 
+       /* 5: variant of suite 0: after moving rfc822Name (ccc.com)
+        * from NC1 to NC2, dNSName (xxx.ccc.com) should still be
+        * rejected.
+        *
+        * NC1: permitted DNS org
+        *      permitted DNS ccc.com
+        * NC2: permitted DNS org
+        *      permitted email ccc.com
+        *      permitted DNS aaa.bbb.ccc.com
+        */
+       suite = 5;
+
+       ret = gnutls_x509_name_constraints_init(&nc1);
+       check_for_error(ret);
+
+       ret = gnutls_x509_name_constraints_init(&nc2);
+       check_for_error(ret);
+
+       set_name("org", &name);
+       ret = gnutls_x509_name_constraints_add_permitted(
+               nc1, GNUTLS_SAN_DNSNAME, &name);
+       check_for_error(ret);
+
+       set_name("ccc.com", &name);
+       ret = gnutls_x509_name_constraints_add_permitted(
+               nc1, GNUTLS_SAN_DNSNAME, &name);
+       check_for_error(ret);
+
+       set_name("org", &name);
+       ret = gnutls_x509_name_constraints_add_permitted(
+               nc2, GNUTLS_SAN_DNSNAME, &name);
+       check_for_error(ret);
+
+       set_name("ccc.com", &name);
+       ret = gnutls_x509_name_constraints_add_permitted(
+               nc2, GNUTLS_SAN_RFC822NAME, &name);
+       check_for_error(ret);
+
+       set_name("aaa.bbb.ccc.com", &name);
+       ret = gnutls_x509_name_constraints_add_permitted(
+               nc2, GNUTLS_SAN_DNSNAME, &name);
+       check_for_error(ret);
+
+       ret = _gnutls_x509_name_constraints_merge(nc1, nc2);
+       check_for_error(ret);
+
+       /* check intersection of permitted */
+       set_name("xxx.ccc.com", &name);
+       ret = gnutls_x509_name_constraints_check(nc1, GNUTLS_SAN_DNSNAME,
+                                                &name);
+       check_test_result(suite, ret, NAME_REJECTED, &name);
+
+       gnutls_x509_name_constraints_deinit(nc1);
+       gnutls_x509_name_constraints_deinit(nc2);
+
        /* Test footer */
 
        if (debug)