From b0a50227c07654e47598c90fe55cee1c890cc4a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= Date: Fri, 13 Apr 2018 14:04:11 +0200 Subject: openssl: fix subjectAltName check on non-ASCII platforms Curl_cert_hostcheck operates with the host character set, therefore the ASCII subjectAltName string retrieved with OpenSSL must be converted to the host encoding before comparison. Closes #2493 --- lib/vtls/openssl.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 988fd3506..80e9bf940 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -1323,6 +1323,51 @@ static void Curl_ossl_close_all(struct Curl_easy *data) /* ====================================================== */ +/* + * Match subjectAltName against the host name. This requires a conversion + * in CURL_DOES_CONVERSIONS builds. + */ +static bool subj_alt_hostcheck(struct Curl_easy *data, + const char *match_pattern, const char *hostname, + const char *dispname) +#ifdef CURL_DOES_CONVERSIONS +{ + bool res = FALSE; + + /* Curl_cert_hostcheck uses host encoding, but we get ASCII from + OpenSSl. + */ + char *match_pattern2 = strdup(match_pattern); + + if(match_pattern2) { + if(Curl_convert_from_network(data, match_pattern2, + strlen(match_pattern2)) == CURLE_OK) { + if(Curl_cert_hostcheck(match_pattern2, hostname)) { + res = TRUE; + infof(data, + " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + dispname, match_pattern2); + } + } + free(match_pattern2); + } + else { + failf(data, + "SSL: out of memory when allocating temporary for subjectAltName"); + } + return res; +} +#else +{ + if(Curl_cert_hostcheck(match_pattern, hostname)) { + infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + dispname, match_pattern); + return TRUE; + } + return FALSE; +} +#endif + /* Quote from RFC2818 section 3.1 "Server Identity" @@ -1422,11 +1467,8 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) if((altlen == strlen(altptr)) && /* if this isn't true, there was an embedded zero in the name string and we cannot match it. */ - Curl_cert_hostcheck(altptr, hostname)) { + subj_alt_hostcheck(data, altptr, hostname, dispname)) { dnsmatched = TRUE; - infof(data, - " subjectAltName: host \"%s\" matched cert's \"%s\"\n", - dispname, altptr); } break; -- cgit v1.2.1