Okay, since the version with the Subject Alt Name checking moved out of the
> if(m == 0 || ret != NIL){
is actually the prettier version, here is the diff for that solution.
Happy New Year,
Peter.diff '--color=auto' -ur alpine-2.26+dfsg.orig/imap/src/osdep/unix/ssl_unix.c alpine-2.26+dfsg/imap/src/osdep/unix/ssl_unix.c
--- alpine-2.26+dfsg.orig/imap/src/osdep/unix/ssl_unix.c 2022-06-03 02:14:00.475274788 +0200
+++ alpine-2.26+dfsg/imap/src/osdep/unix/ssl_unix.c 2025-12-31 18:08:48.165038377 +0100
@@ -554,29 +554,34 @@
/* Method 2, use cname */
if(m == 0 || ret != NIL){
cname = X509_get_subject_name(cert);
- for(j = 0, ret = NIL; j < X509_NAME_entry_count(cname) && ret == NIL; j++){
- if((e = X509_NAME_get_entry(cname, j)) != NULL){
- X509_NAME_get_text_by_OBJ(cname, X509_NAME_ENTRY_get_object(e), buf, sizeof(buf));
- s = (char *) buf;
- }
- else s = NIL;
- if (s != NIL) {
- /* host name matches pattern? */
- ret = ssl_compare_hostnames (host,s) ? NIL :
- "Server name does not match certificate";
- ext = NIL;
- /* if mismatch, see if in extensions */
- if (ret && (ext = X509_get_ext_d2i (cert,NID_subject_alt_name,NIL,NIL)) &&
- (n = sk_GENERAL_NAME_num (ext)))
- /* older versions of OpenSSL use "ia5" instead of dNSName */
- for (i = 0; ret && (i < n); i++)
- if ((name = sk_GENERAL_NAME_value (ext,i)) &&
- (name->type = GEN_DNS) && (s = name->d.ia5->data) &&
- ssl_compare_hostnames (host,s)) ret = NIL;
- if(ext) GENERAL_NAMES_free(ext);
- }
- }
+ for(j = 0, ret = NIL; j < X509_NAME_entry_count(cname) && ret == NIL; j++)
+ if((e = X509_NAME_get_entry(cname, j)) != NULL){
+ X509_NAME_get_text_by_OBJ(cname, X509_NAME_ENTRY_get_object(e), buf, sizeof(buf));
+ s = (char *) buf;
+ /* host name matches pattern? */
+ ret = ssl_compare_hostnames (host,s) ? NIL :
+ "Server name does not match certificate";
+ }
+ else s = NIL;
}
+ if (ext = X509_get_ext_d2i (cert,NID_subject_alt_name,NIL,NIL))
+ n = sk_GENERAL_NAME_num (ext);
+ else
+ n = 0;
+ if (ret == NIL && s == NIL)
+ if (n)
+ /* This value will be used when none of the alt names match either */
+ ret = "Server name does not match certificate";
+ else
+ ret = "Unable to locate common name in certificate";
+ /* if no CN or mismatch, see if in extensions */
+ if (ret && n)
+ /* older versions of OpenSSL use "ia5" instead of dNSName */
+ for (i = 0; ret && (i < n); i++)
+ if ((name = sk_GENERAL_NAME_value (ext,i)) &&
+ (name->type = GEN_DNS) && (s = name->d.ia5->data) &&
+ ssl_compare_hostnames (host,s)) ret = NIL;
+ if(ext) GENERAL_NAMES_free(ext);
if (ret == NIL
#ifndef OPENSSL_1_1_0
@@ -585,9 +590,6 @@
&& !X509_get_subject_name(cert))
ret = "No name in certificate";
- if (ret == NIL && s == NIL)
- ret = "Unable to locate common name in certificate";
-
return ret;
}