From: Alexander Sosedkin Date: Mon, 16 Mar 2026 14:29:40 +0000 (+0100) Subject: x509/name-constraints: compare domain names case-insensitive X-Git-Tag: 3.8.13^2~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19f6508647bdcd3ce21130201e484d7ca6d962c5;p=thirdparty%2Fgnutls.git x509/name-constraints: compare domain names case-insensitive RFC 5280 7.2: > When comparing DNS names for equality, conforming implementations > MUST perform a case-insensitive exact match on the entire DNS name. > When evaluating name constraints, conforming implementations MUST > perform a case-insensitive exact match on a label-by-label basis. Domain name comparison during name constraints processing was case-sensitive. For excluded name constraints, this could lead to incorrectly accepting domain names that should've been rejected. The code for comparing domain names and domain name parts of emails has been modified to perform case-insensitive comparison instead. Reported-by: Oleh Konko Reported-by: Joshua Rogers of AISLE Research Team Fixes: #1223 Fixes: #1803 Fixes: #1852 Fixes: CVE-2026-3833 Fixes: GNUTLS-SA-2026-04-29-5 CVSS: 7.4 High CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N Signed-off-by: Alexander Sosedkin --- diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c index a897284516..410022239d 100644 --- a/lib/x509/name_constraints.c +++ b/lib/x509/name_constraints.c @@ -35,6 +35,7 @@ #include "x509_int.h" #include "x509_ext_int.h" #include +#include "c-strcase.h" #include "ip.h" #include "ip-in-cidr.h" @@ -100,7 +101,7 @@ enum name_constraint_relation { NC_SORTS_AFTER = 2 /* unrelated constraints */ }; -/* A helper to compare just a pair of strings with this rich comparison */ +/* Helpers to compare just a pair of strings with this rich comparison */ static enum name_constraint_relation compare_strings(const void *n1, size_t n1_len, const void *n2, size_t n2_len) { @@ -116,6 +117,22 @@ compare_strings(const void *n1, size_t n1_len, const void *n2, size_t n2_len) return NC_EQUAL; } +static enum name_constraint_relation +compare_strings_case_insensitive(const void *n1, size_t n1_len, const void *n2, + size_t n2_len) +{ + int r = c_strncasecmp(n1, n2, MIN(n1_len, n2_len)); + if (r < 0) + return NC_SORTS_BEFORE; + if (r > 0) + return NC_SORTS_AFTER; + if (n1_len < n2_len) + return NC_SORTS_BEFORE; + if (n1_len > n2_len) + return NC_SORTS_AFTER; + return NC_EQUAL; +} + /* Rich-compare DNS names. Example order/relationships: * z.x.a INCLUDED_BY x.a BEFORE y.a INCLUDED_BY a BEFORE x.b BEFORE y.b */ static enum name_constraint_relation compare_dns_names(const gnutls_datum_t *n1, @@ -141,8 +158,8 @@ static enum name_constraint_relation compare_dns_names(const gnutls_datum_t *n1, while (j && n2->data[j - 1] != '.') j--; - rel = compare_strings(&n1->data[i], i_end - i, &n2->data[j], - j_end - j); + rel = compare_strings_case_insensitive(&n1->data[i], i_end - i, + &n2->data[j], j_end - j); if (rel == NC_SORTS_BEFORE) /* x.a BEFORE y.a */ return NC_SORTS_BEFORE; if (rel == NC_SORTS_AFTER) /* y.a AFTER x.a */