Skip to content

Commit 6392a0b

Browse files
bbolligitster
authored andcommitted
imap-send: move common code into function host_matches()
Move the ASN1_STRING access, the associated cast and the check for embedded NUL bytes into host_matches() to simplify both callers. Reformulate the NUL check using memchr() and add a comment to make it more obvious what it is about. Signed-off-by: Beat Bolli <dev+git@drbeat.li> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 08fd302 commit 6392a0b

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

imap-send.c

Lines changed: 9 additions & 7 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, '.')))
@@ -252,10 +258,7 @@ static int verify_hostname(X509 *cert, const char *hostname)
252258
GENERAL_NAME *subj_alt_name = sk_GENERAL_NAME_value(subj_alt_names, i);
253259
ASN1_STRING *subj_alt_str = GENERAL_NAME_get0_value(subj_alt_name, &ntype);
254260

255-
if (ntype == GEN_DNS &&
256-
strlen((const char *)ASN1_STRING_get0_data(subj_alt_str)) ==
257-
ASN1_STRING_length(subj_alt_str) &&
258-
host_matches(hostname, (const char *)ASN1_STRING_get0_data(subj_alt_str)))
261+
if (ntype == GEN_DNS && host_matches(hostname, subj_alt_str))
259262
found = 1;
260263
}
261264
sk_GENERAL_NAME_pop_free(subj_alt_names, GENERAL_NAME_free);
@@ -270,8 +273,7 @@ static int verify_hostname(X509 *cert, const char *hostname)
270273
(cname_entry = X509_NAME_get_entry(subj, i)) == NULL ||
271274
(cname = X509_NAME_ENTRY_get_data(cname_entry)) == NULL)
272275
return error("cannot get certificate common name");
273-
if (strlen((const char *)ASN1_STRING_get0_data(cname)) == ASN1_STRING_length(cname) &&
274-
host_matches(hostname, (const char *)ASN1_STRING_get0_data(cname)))
276+
if (host_matches(hostname, cname))
275277
return 0;
276278
return error("certificate owner '%s' does not match hostname '%s'",
277279
ASN1_STRING_get0_data(cname), hostname);

0 commit comments

Comments
 (0)