From abf18d97bdd0a78d4f64ba4f2d62db8ea96f3c98 Mon Sep 17 00:00:00 2001
From: Rahul Jain <rahul.jain@suse.com>
Date: Wed, 15 Apr 2026 13:54:47 +0530
Subject: [PATCH] Fix CVE-2026-35331: constraints plugin X.509 name constraints

---
 .../constraints/constraints_validator.c       | 21 ++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
 
diff --git a/src/libstrongswan/plugins/constraints/constraints_validator.c b/src/libstrongswan/plugins/constraints/constraints_validator.c
index 62ccc71..569d3a1 100644
--- a/src/libstrongswan/plugins/constraints/constraints_validator.c
+++ b/src/libstrongswan/plugins/constraints/constraints_validator.c
@@ -51,6 +51,18 @@ static bool check_pathlen(x509_t *issuer, int pathlen)
 	return TRUE;
 }
 
+/**
+ * Check if the constraint and ID strings match case-insensitively
+ */
+static bool string_matches(chunk_t constraint, chunk_t id)
+{
+	/* make sure the two strings have actually the same length */
+	return constraint.len == id.len &&
+		   memchr(constraint.ptr, 0, constraint.len) == NULL &&
+		   memchr(id.ptr, 0, id.len) == NULL &&
+		   strncasecmp(constraint.ptr, id.ptr, constraint.len) == 0;
+}
+
 /**
  * Check if a FQDN/RFC822 constraint matches (suffix match)
  */
@@ -61,7 +73,7 @@ static bool suffix_matches(identification_t *constraint, identification_t *id)
 	c = constraint->get_encoding(constraint);
 	i = id->get_encoding(id);
 
-	return i.len >= c.len && chunk_equals(c, chunk_skip(i, i.len - c.len));
+	return i.len >= c.len && string_matches(c, chunk_skip(i, i.len - c.len));
 }
 
 /**
@@ -106,6 +118,13 @@ static bool name_constraint_matches(identification_t *constraint,
 	type = constraint->get_type(constraint);
 	if (type == ID_DER_ASN1_DN)
 	{
+		if (!permitted)
+		{
+			DBG1(DBG_CFG, "excluded %N NameConstraint not supported",
+				 id_type_names, type);
+			/* we have to return TRUE to let the constraint fail */
+			return TRUE;
+		}
 		matches = dn_matches(constraint, cert->get_subject(cert));
 		if (matches != permitted)
 		{
-- 
2.50.0

