diff options
| author | Beat Bolli <dev+git@drbeat.li> | 2026-03-11 23:10:27 +0100 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2026-03-11 15:25:15 -0700 |
| commit | 6392a0b75d979ba8e23c85d57b85779aace25370 (patch) | |
| tree | ca3413af8554813920b33e00bca012af4e10676c | |
| parent | 08fd302fc4b8eaf0bb32856231a5fb46430e3c7e (diff) | |
| download | git-6392a0b75d979ba8e23c85d57b85779aace25370.tar.xz | |
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>
| -rw-r--r-- | imap-send.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/imap-send.c b/imap-send.c index 2a904314dd..af02c6a689 100644 --- a/imap-send.c +++ b/imap-send.c @@ -219,8 +219,14 @@ static int ssl_socket_connect(struct imap_socket *sock UNUSED, #else -static int host_matches(const char *host, const char *pattern) +static int host_matches(const char *host, const ASN1_STRING *asn1_str) { + const char *pattern = (const char *)ASN1_STRING_get0_data(asn1_str); + + /* embedded NUL characters may open a security hole */ + if (memchr(pattern, '\0', ASN1_STRING_length(asn1_str))) + return 0; + if (pattern[0] == '*' && pattern[1] == '.') { pattern += 2; if (!(host = strchr(host, '.'))) @@ -252,10 +258,7 @@ 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 && - strlen((const char *)ASN1_STRING_get0_data(subj_alt_str)) == - ASN1_STRING_length(subj_alt_str) && - host_matches(hostname, (const char *)ASN1_STRING_get0_data(subj_alt_str))) + if (ntype == GEN_DNS && host_matches(hostname, subj_alt_str)) found = 1; } sk_GENERAL_NAME_pop_free(subj_alt_names, GENERAL_NAME_free); @@ -270,8 +273,7 @@ static int verify_hostname(X509 *cert, const char *hostname) (cname_entry = X509_NAME_get_entry(subj, i)) == NULL || (cname = X509_NAME_ENTRY_get_data(cname_entry)) == NULL) return error("cannot get certificate common name"); - if (strlen((const char *)ASN1_STRING_get0_data(cname)) == ASN1_STRING_length(cname) && - host_matches(hostname, (const char *)ASN1_STRING_get0_data(cname))) + if (host_matches(hostname, cname)) return 0; return error("certificate owner '%s' does not match hostname '%s'", ASN1_STRING_get0_data(cname), hostname); |
