Re: [PATCH 3/3] imap-send: only check the CN if no SAN DNS names are present
From: brian m. carlson <hidden>
Date: 2026-09-08 01:28:34
On 2026-09-07 at 21:12:10, Beat Bolli wrote:
Checking the certificate subject's common name may only be done if the
subjectAltNames extension contains no DNS entries. If no SAN DNS name
matches, there's no match.
Per RFC 6125 section 6.4.4[1]:
As noted, a client MUST NOT seek a match for a reference identifier
of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
URI-ID, or any application-specific identifier types supported by the
client.
This change was inspired by a similar commit in the HAProxy project[2].TLS is not supposed to use the CN at all these days and Go's implementation completely ignores it. subjectAltName is supposed to be used in all cases.
quoted hunk ↗ jump to hunk
diff --git a/imap-send.c b/imap-send.c index 9a807cdde8..66d3dbfaa5 100644 --- a/imap-send.c +++ b/imap-send.c@@ -256,11 +256,11 @@ static int verify_hostname(X509 *cert, const char *hostname) #endif const X509_NAME_ENTRY *cname_entry; const ASN1_STRING *cname; - int i, found; + int i, found, has_san_dns; STACK_OF(GENERAL_NAME) *subj_alt_names; /* try the DNS subjectAltNames */ - found = 0; + found = has_san_dns = 0; if ((subj_alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL))) { int num_subj_alt_names = sk_GENERAL_NAME_num(subj_alt_names); for (i = 0; !found && i < num_subj_alt_names; i++) {@@ -268,13 +268,18 @@ static int verify_hostname(X509 *cert, const char *hostname) GENERAL_NAME *subj_alt_name = sk_GENERAL_NAME_value(subj_alt_names, i); ASN1_STRING *subj_alt_str = GENERAL_NAME_get0_value(subj_alt_name, &ntype); - if (ntype == GEN_DNS && host_matches(hostname, subj_alt_str)) - found = 1; + if (ntype == GEN_DNS) { + has_san_dns = 1; + if (host_matches(hostname, subj_alt_str)) + found = 1; + }
This handles certificates with DNS names but not IP addresses. So, for instance, this match wouldn't work for the certificates for 1.1.1.1 (assuming they had public IMAP service).
}
sk_GENERAL_NAME_pop_free(subj_alt_names, GENERAL_NAME_free);
}
if (found)
return 0;
+ if (has_san_dns)
+ return error("none of the subjectAltNames matches hostname '%s'", hostname);I know OpenSSL has built-in hostname verification that can be used as of OpenSSL 1.0.2[0]. Is there a reason we're still doing this by hand? Relying on OpenSSL's verification would mean that (a) we would not have to worry about getting verification wrong in a security-sensitive way and (b) OpenSSL would handle the policy and standards compliance functionality. [0] https://wiki.openssl.org/index.php/Hostname_validation -- brian m. carlson (they/them) Toronto, Ontario, CA
Attachments
- signature.asc [application/pgp-signature] 325 bytes