git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 3/3] imap-send: only check the CN if no SAN DNS names are present

From
brian m. carlson <sandals@crustytoothpaste.net>
Date
Sep 8, 2026, 01:28 UTC
Message-ID
<ap9kv-ORyzzeUiqb@fruit.crustytoothpaste.net>
In-Reply-To
<20260907211210.2621693-4-dev+git@drbeat.li>
On 2026-09-07 at 21:12:10, Beat Bolli wrote:
Show 12 quoted lines
> 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.

Show 29 quoted lines
> 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).

Show 7 quoted lines
>  		}
>  		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
Previous: Beat BolliNext: Beat Bolli
Message 3 of 11 in “imap-send: future proofing and two correctness fixes”
  1. 0/3 imap-send: future proofing and two correctness fixesBeat Bolli, Sep 7, 2026
  2. 3/3 imap-send: only check the CN if no SAN DNS names are presentBeat Bolli, Sep 7, 2026
  3. brian m. carlsonSep 8, 2026
  4. 2/3 imap-send: don't expect an ASN1_STRING to be NUL-terminatedBeat Bolli, Sep 7, 2026
  5. Junio C HamanoSep 8, 2026
  6. Patrick SteinhardtSep 8, 2026
  7. 1/3 imap-send: prepare for OpenSSL 4.1Beat Bolli, Sep 7, 2026
  8. Junio C HamanoSep 8, 2026
  9. Patrick SteinhardtSep 8, 2026
  10. Beat BolliSep 14, 2026
  11. Patrick SteinhardtSep 23, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.