diff --git a/meta-oe/recipes-crypto/botan/botan/CVE-2026-32884.patch b/meta-oe/recipes-crypto/botan/botan/CVE-2026-32884.patch
new file mode 100644
index 0000000000..f207ee2caa
--- /dev/null
+++ b/meta-oe/recipes-crypto/botan/botan/CVE-2026-32884.patch
@@ -0,0 +1,171 @@
+From cbc8b341ea4b38c388e89682b86da107a9fdc38c Mon Sep 17 00:00:00 2001
+From: Jack Lloyd <jack@randombit.net>
+Date: Sun, 15 Mar 2026 11:17:22 -0400
+Subject: [PATCH] Fix name constraint DNS check when falling back to CN
+
+When verifying name constraints which restrict the set of allowed DNS names, the
+logic would first check the Subject Alternative Name if available, but if the
+SAN is absent then it would check the CN field of the issued name since that is
+a common fallback for DNS names when the SAN is missing.
+
+However this check failed to properly canonicalize the potential DNS name in the
+CN, allowing a mis-issued cert with a mixed-case CN field and absent SAN to
+bypass any imposed excludedSubtrees rules.
+
+CVE: CVE-2026-32884
+Upstream-Status: Backport [https://github.com/randombit/botan/commit/db8baebd92bded036da6faf8bf3c324b67de9cf4]
+Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
+---
+ src/lib/x509/name_constraint.cpp              | 16 +++++++---
+ .../Invalid_DNS_Excluded_Mixed_Case_CN.crt    | 19 ++++++++++++
+ .../Root_DNS_Excluded_Mixed_Case_CN.crt       | 19 ++++++++++++
+ src/tests/test_name_constraint.cpp            | 29 +++++++++++++++++++
+ 4 files changed, 79 insertions(+), 4 deletions(-)
+ create mode 100644 src/tests/data/x509/name_constraint/Invalid_DNS_Excluded_Mixed_Case_CN.crt
+ create mode 100644 src/tests/data/x509/name_constraint/Root_DNS_Excluded_Mixed_Case_CN.crt
+
+diff --git a/src/lib/x509/name_constraint.cpp b/src/lib/x509/name_constraint.cpp
+index e767624..8708b95 100644
+--- a/src/lib/x509/name_constraint.cpp
++++ b/src/lib/x509/name_constraint.cpp
+@@ -19,6 +19,14 @@ namespace Botan {
+ 
+ class DER_Encoder;
+ 
++namespace {
++
++std::string canonicalize_dns_name(std::string_view name) {
++   return tolower_string(name);
++}
++
++}  // namespace
++
+ std::string GeneralName::type() const {
+    switch(m_type) {
+       case NameType::Unknown:
+@@ -75,7 +83,7 @@ void GeneralName::decode_from(BER_Decoder& ber) {
+       m_type = NameType::DNS;
+       // Store it in case insensitive form so we don't have to do it
+       // again while matching
+-      m_name.emplace<DNS_IDX>(tolower_string(ASN1::to_string(obj)));
++      m_name.emplace<DNS_IDX>(canonicalize_dns_name(ASN1::to_string(obj)));
+    } else if(obj.is_a(6, ASN1_Class::ContextSpecific)) {
+       m_type = NameType::URI;
+       m_name.emplace<URI_IDX>(ASN1::to_string(obj));
+@@ -174,7 +182,7 @@ GeneralName::MatchResult GeneralName::matches(const X509_Certificate& cert) cons
+          // Check CN instead...
+          for(const std::string& cn : dn.get_attribute("CN")) {
+             if(!string_to_ipv4(cn).has_value()) {
+-               score.add(matches_dns(cn, constraint));
++               score.add(matches_dns(canonicalize_dns_name(cn), constraint));
+             }
+          }
+       }
+@@ -421,7 +429,7 @@ bool NameConstraints::is_permitted(const X509_Certificate& cert, bool reject_unk
+                   return false;
+                }
+             } else {
+-               if(!is_permitted_dns_name(cn)) {
++               if(!is_permitted_dns_name(canonicalize_dns_name(cn))) {
+                   return false;
+                }
+             }
+@@ -540,7 +548,7 @@ bool NameConstraints::is_excluded(const X509_Certificate& cert, bool reject_unkn
+                   return true;
+                }
+             } else {
+-               if(is_excluded_dns_name(cn)) {
++               if(is_excluded_dns_name(canonicalize_dns_name(cn))) {
+                   return true;
+                }
+             }
+diff --git a/src/tests/data/x509/name_constraint/Invalid_DNS_Excluded_Mixed_Case_CN.crt b/src/tests/data/x509/name_constraint/Invalid_DNS_Excluded_Mixed_Case_CN.crt
+new file mode 100644
+index 0000000..fe2c773
+--- /dev/null
++++ b/src/tests/data/x509/name_constraint/Invalid_DNS_Excluded_Mixed_Case_CN.crt
+@@ -0,0 +1,19 @@
++-----BEGIN CERTIFICATE-----
++MIIDCTCCAfGgAwIBAgIUAbjRT6B+WHVf1Wo9JdFHlHegF1cwDQYJKoZIhvcNAQEL
++BQAwFzEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTI2MDMxNTE0NTM1MloXDTI3
++MDMxNTE0NTM1MlowFzEVMBMGA1UEAwwMU3ViLkVWSUwuQ09NMIIBIjANBgkqhkiG
++9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsn1rve+kuZJd2udT4QEnjdws+YRT+lJI+rG/
++4OpljAcxQywCc6oHDY4ouaqOKdhT9+luvqRVSEnH3JfczT/D+wZD+gBOlgUqsmXp
++QasD8HSyHWdjyaLrkZuBGICoUZTh9a7ZOPuIQ2sblxOvBm3klndpSpXJC6sJsWAk
++tyU+5WdNz+ncTC82sFSY0YQLC2QvxckEP6Jxi4I+h9vANtWXCk6CRz/kT4dY3cD4
++VBFtAy+vUVYUZnLi48fEYlMt4rP64OerY7hjw8gE+66rmUQPml4+DAek+xJtL4Sl
++Q0SGytWE9tJb1zzICv4TNvj/+IKmbK4BCu7fVjOd2C64zNFTywIDAQABo00wSzAJ
++BgNVHRMEAjAAMB0GA1UdDgQWBBS6hC1DrVlXAq/GWDYl/UQbP4TmLTAfBgNVHSME
++GDAWgBQPZ2Gp3izLTRAUzQKCKRLbM5OA2DANBgkqhkiG9w0BAQsFAAOCAQEAcWBy
++f9+tJDDj7T7z4QziZnxIfKP7x7uP9wAlYGRpKcbbW6SHAg6DA1V5GBWHendkg1hb
++Nywy7pUFgJ0xlJ7KYr76Ylfa1BTUPT+gExJWvSmsg8WSQ4q3bOMVB1qRxWDv/8KY
++ZOT03KEzLyGL6ia9r/UFw1jibxS26Ff6qCE9EhDLA/4z0D/+9QzdLATuzSn/SLSR
++wtarLaWhCfOSpfRrekYhaSndG45BCKpUd99iWt1HA4LyjZe8/8cxsRkD8klaCalG
++8pRp+PolijzmYsrEXuG22Bq2idgxHTRvw8l4rBQrSdMWuWqqTdIpFIUrXNft0a5f
++d8RmhI6PZlPL43OCxw==
++-----END CERTIFICATE-----
+diff --git a/src/tests/data/x509/name_constraint/Root_DNS_Excluded_Mixed_Case_CN.crt b/src/tests/data/x509/name_constraint/Root_DNS_Excluded_Mixed_Case_CN.crt
+new file mode 100644
+index 0000000..503206f
+--- /dev/null
++++ b/src/tests/data/x509/name_constraint/Root_DNS_Excluded_Mixed_Case_CN.crt
+@@ -0,0 +1,19 @@
++-----BEGIN CERTIFICATE-----
++MIIDGjCCAgKgAwIBAgIUJj5ZhECZYOzt5qWnoN8DMcZzlzgwDQYJKoZIhvcNAQEL
++BQAwFzEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTI2MDMxNTE0NTM1MloXDTM2
++MDMxMjE0NTM1MlowFzEVMBMGA1UEAwwMVGVzdCBSb290IENBMIIBIjANBgkqhkiG
++9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtEqBgRHixpRodBHeqXrcttdKD3tpGG+S67tM
++WT1h+572k6EFIZ9RVfYokH32sNFNz8LNI5FwKKFTf/WaVhMdsqxaMrf/+06UzKdw
++7dKz+Q5uLGrygv6opSVqhojkjLZH78zmEER0Gba4Ac4FGq5pjafA2jtoIMDyQ2SV
++IpOy932WCajQL6IM20yHPQAsr0c0hoFP4RdbJPuiEVPfZv95VjEwwV0zMBFmiICk
++gItEDfiexBHEIvXAGNBModMHaBhUDzHZp0X7gNW/MD2ieiQGoLTyG/t7sKv0J3zV
++LnUpXVIrmHSIkGVfuc5EFOlq6OXZ/J29VjPEnVVeZARDhgyGRQIDAQABo14wXDAP
++BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQPZ2Gp3izLTRAUzQKCKRLbM5OA2DAO
++BgNVHQ8BAf8EBAMCAQYwGgYDVR0eAQH/BBAwDqEMMAqCCGV2aWwuY29tMA0GCSqG
++SIb3DQEBCwUAA4IBAQA5RLYaZWVxFIKpZRM5ZBk4fDDlAvRl7NVhMeQO3DMyyIzw
++Bp7IIEgH0I6PlL4/02SzSaqUuVVXYyO1LhbgBlFnE1h818zz+jN06i0lUemuXGAo
++wnHBwLW+V/r0JBm4BbnbneCYHUFS07sfR9IjQqV9Futp2WILwieZ7Ib96xGuX96L
++f6pxYEd82rYSXa/K14HvMKXkzC3qe72V+/E1GOPZqzlbZFriYfRUHUOY6P7LjcWl
++3Z+aUQcG8vEHbJjTd+ZZzP2PICjLKgaX1acpBOUR6pelHgcUmuR3z86V/DD8TWsH
++BHDLLBxTje/8fL0PR4qo4r4F+2Cj+hXnY/TFVQ+W
++-----END CERTIFICATE-----
+diff --git a/src/tests/test_name_constraint.cpp b/src/tests/test_name_constraint.cpp
+index 61aff53..5daa343 100644
+--- a/src/tests/test_name_constraint.cpp
++++ b/src/tests/test_name_constraint.cpp
+@@ -69,6 +69,35 @@ class Name_Constraint_Tests final : public Test {
+ 
+ BOTAN_REGISTER_TEST("x509", "x509_path_name_constraint", Name_Constraint_Tests);
+ 
++// Verify that DNS constraints are case-insensitive also when falling back to the CN
++class Name_Constraint_Excluded_CN_Case_Test final : public Test {
++   public:
++      std::vector<Test::Result> run() override {
++         Test::Result result("X509v3 Name Constraints: excluded DNS with mixed-case CN and no SAN");
++
++         const Botan::X509_Certificate root(
++            Test::data_file("x509/name_constraint/Root_DNS_Excluded_Mixed_Case_CN.crt"));
++         const Botan::X509_Certificate leaf(
++            Test::data_file("x509/name_constraint/Invalid_DNS_Excluded_Mixed_Case_CN.crt"));
++
++         Botan::Certificate_Store_In_Memory trusted;
++         trusted.add_certificate(root);
++
++         const Botan::Path_Validation_Restrictions restrictions(false, 80);
++         const auto validation_time = Botan::calendar_point(2026, 6, 1, 0, 0, 0).to_std_timepoint();
++
++         const auto path_result = Botan::x509_path_validate(
++            leaf, restrictions, trusted, "" /* hostname */, Botan::Usage_Type::UNSPECIFIED, validation_time);
++
++         result.test_eq(
++            "validation result", path_result.result_string(), "Certificate does not pass name constraint");
++
++         return {result};
++      }
++};
++
++BOTAN_REGISTER_TEST("x509", "x509_name_constraint_excluded_cn_case", Name_Constraint_Excluded_CN_Case_Test);
++
+ #endif
+ 
+ }  // namespace
diff --git a/meta-oe/recipes-crypto/botan/botan_3.10.0.bb b/meta-oe/recipes-crypto/botan/botan_3.10.0.bb
index b613dd2a04..0986a76557 100644
--- a/meta-oe/recipes-crypto/botan/botan_3.10.0.bb
+++ b/meta-oe/recipes-crypto/botan/botan_3.10.0.bb
@@ -7,6 +7,7 @@ SECTION = "libs"
 SRC_URI = "https://botan.randombit.net/releases/Botan-${PV}.tar.xz \
            file://CVE-2026-32877.patch \
            file://CVE-2026-32883.patch \
+           file://CVE-2026-32884.patch \
            "
 SRC_URI[sha256sum] = "fde194236f6d5434f136ea0a0627f6cc9d26af8b96e9f1e1c7d8c82cd90f4f24"
 
