From 29801bef00ecc0f23c0bac4cd333b269cd2c1af4 Mon Sep 17 00:00:00 2001
From: Alexander Sosedkin <asosedkin@redhat.com>
Date: Wed, 15 Apr 2026 16:02:19 +0200
Subject: [PATCH] x509: prevent fallback on oversized SAN

Passing oversized SAN did not preclude CN (or DN email) fallback
during verification, which is an RFC 6125 6.4.4 violation.

Now oversized SAN are skipped over,
but prevent the fallback from happening.

Reported-by: Haruto Kimura (Stella)
Reported-by: Joshua Rogers of AISLE Research Team <joshua@joshua.hu>
Fixes: #1825
Fixes: #1849
Fixes: CVE-2026-42013
Fixes: GNUTLS-SA-2026-04-27-8
CVSS: 6.5 Moderate CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N
Signed-off-by: Alexander Sosedkin <asosedkin@redhat.com>
CVE: CVE-2026-42013
Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls/-/commit/29801bef00ecc0f23c0bac4cd333b269cd2c1af4]

Signed-off-by: Jakub Szczudlo <jakub.szczudlo@nokia.com>
---
 lib/x509/email-verify.c    | 14 ++++++++++++++
 lib/x509/hostname-verify.c | 14 ++++++++++++++
 2 files changed, 28 insertions(+)

--- a/lib/x509/email-verify.c
+++ b/lib/x509/email-verify.c
@@ -75,6 +75,20 @@ unsigned gnutls_x509_crt_check_email(gnu
 		ret = gnutls_x509_crt_get_subject_alt_name(
 			cert, i, rfc822name, &rfc822namesize, NULL);
 
+		if (ret < 0) {
+			if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
+				/* oversized SAN; proceed without DN fallback */
+				_gnutls_debug_log("oversized SAN ignored, "
+						  "disabling DN fallback\n");
+				dn_fallback_allowed = false;
+				ret = 0;
+				continue;
+			}
+			if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+				gnutls_assert();
+			break;
+		}
+
 		if (ret == GNUTLS_SAN_RFC822NAME) {
 			dn_fallback_allowed = false;
 
--- a/lib/x509/hostname-verify.c
+++ b/lib/x509/hostname-verify.c
@@ -213,6 +213,20 @@ hostname_fallback:
 		ret = gnutls_x509_crt_get_subject_alt_name(cert, i, dnsname,
 							   &dnsnamesize, NULL);
 
+		if (ret < 0) {
+			if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
+				/* oversized SAN; proceed without CN fallback */
+				_gnutls_debug_log("oversized SAN ignored, "
+						  "disabling CN fallback\n");
+				cn_fallback_allowed = false;
+				ret = 0;
+				continue;
+			}
+			if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+				gnutls_assert();
+			break;
+		}
+
 		if (PRECLUDES_CN_FALLBACK(ret))
 			cn_fallback_allowed = false;
 
