Skip to content

Commit 74137b7

Browse files
committed
Merge branch 'bb/imap-send-openssl-4.0-prep'
"imap-send" used to use functions whose use is going to be removed with OpenSSL 4.0; rewrite them using public API that has been available since OpenSSL 1.1 since 2016 or so. * bb/imap-send-openssl-4.0-prep: imap-send: move common code into function host_matches() imap-send: use the OpenSSL API to access the subject common name imap-send: use the OpenSSL API to access the subject alternative names
2 parents 133a880 + 6392a0b commit 74137b7

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

imap-send.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,14 @@ static int ssl_socket_connect(struct imap_socket *sock UNUSED,
219219

220220
#else
221221

222-
static int host_matches(const char *host, const char *pattern)
222+
static int host_matches(const char *host, const ASN1_STRING *asn1_str)
223223
{
224+
const char *pattern = (const char *)ASN1_STRING_get0_data(asn1_str);
225+
226+
/* embedded NUL characters may open a security hole */
227+
if (memchr(pattern, '\0', ASN1_STRING_length(asn1_str)))
228+
return 0;
229+
224230
if (pattern[0] == '*' && pattern[1] == '.') {
225231
pattern += 2;
226232
if (!(host = strchr(host, '.')))
@@ -233,9 +239,13 @@ static int host_matches(const char *host, const char *pattern)
233239

234240
static int verify_hostname(X509 *cert, const char *hostname)
235241
{
236-
int len;
242+
#if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
243+
const X509_NAME *subj;
244+
#else
237245
X509_NAME *subj;
238-
char cname[1000];
246+
#endif
247+
const X509_NAME_ENTRY *cname_entry;
248+
const ASN1_STRING *cname;
239249
int i, found;
240250
STACK_OF(GENERAL_NAME) *subj_alt_names;
241251

@@ -244,10 +254,11 @@ static int verify_hostname(X509 *cert, const char *hostname)
244254
if ((subj_alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL))) {
245255
int num_subj_alt_names = sk_GENERAL_NAME_num(subj_alt_names);
246256
for (i = 0; !found && i < num_subj_alt_names; i++) {
257+
int ntype;
247258
GENERAL_NAME *subj_alt_name = sk_GENERAL_NAME_value(subj_alt_names, i);
248-
if (subj_alt_name->type == GEN_DNS &&
249-
strlen((const char *)subj_alt_name->d.ia5->data) == (size_t)subj_alt_name->d.ia5->length &&
250-
host_matches(hostname, (const char *)(subj_alt_name->d.ia5->data)))
259+
ASN1_STRING *subj_alt_str = GENERAL_NAME_get0_value(subj_alt_name, &ntype);
260+
261+
if (ntype == GEN_DNS && host_matches(hostname, subj_alt_str))
251262
found = 1;
252263
}
253264
sk_GENERAL_NAME_pop_free(subj_alt_names, GENERAL_NAME_free);
@@ -258,12 +269,14 @@ static int verify_hostname(X509 *cert, const char *hostname)
258269
/* try the common name */
259270
if (!(subj = X509_get_subject_name(cert)))
260271
return error("cannot get certificate subject");
261-
if ((len = X509_NAME_get_text_by_NID(subj, NID_commonName, cname, sizeof(cname))) < 0)
272+
if ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, -1)) < 0 ||
273+
(cname_entry = X509_NAME_get_entry(subj, i)) == NULL ||
274+
(cname = X509_NAME_ENTRY_get_data(cname_entry)) == NULL)
262275
return error("cannot get certificate common name");
263-
if (strlen(cname) == (size_t)len && host_matches(hostname, cname))
276+
if (host_matches(hostname, cname))
264277
return 0;
265278
return error("certificate owner '%s' does not match hostname '%s'",
266-
cname, hostname);
279+
ASN1_STRING_get0_data(cname), hostname);
267280
}
268281

269282
static int ssl_socket_connect(struct imap_socket *sock,

0 commit comments

Comments
 (0)