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
This commit is contained in:
Stephan Mühlstrasser 2018-04-13 14:04:11 +02:00 коммит произвёл Daniel Stenberg
Родитель a3f385393a
Коммит b0a50227c0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
1 изменённых файлов: 46 добавлений и 4 удалений

Просмотреть файл

@ -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;