hostcheck: reduce strlen calls on chained certificates

Closes #8428
This commit is contained in:
Henrik Holst 2022-02-10 21:04:52 +01:00 committed by Daniel Stenberg
parent 0bd50335fe
commit 65c6e37fe3
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
6 changed files with 52 additions and 33 deletions

View file

@ -72,14 +72,15 @@ static bool pmatch(const char *hostname, size_t hostlen,
* Return TRUE on a match. FALSE if not.
*/
static bool hostmatch(const char *hostname, const char *pattern,
static bool hostmatch(const char *hostname,
size_t hostlen,
const char *pattern,
size_t patternlen)
{
const char *pattern_label_end, *wildcard, *hostname_label_end;
size_t prefixlen, suffixlen;
/* normalize pattern and hostname by stripping off trailing dots */
size_t hostlen = strlen(hostname);
DEBUGASSERT(patternlen);
if(hostname[hostlen-1]=='.')
hostlen--;
@ -129,10 +130,10 @@ static bool hostmatch(const char *hostname, const char *pattern,
* Curl_cert_hostcheck() returns TRUE if a match and FALSE if not.
*/
bool Curl_cert_hostcheck(const char *match, size_t matchlen,
const char *hostname)
const char *hostname, size_t hostlen)
{
if(match && *match && hostname && *hostname)
return hostmatch(hostname, match, matchlen);
return hostmatch(hostname, hostlen, match, matchlen);
return FALSE;
}

View file

@ -26,6 +26,6 @@
/* returns TRUE if there's a match */
bool Curl_cert_hostcheck(const char *match_pattern, size_t matchlen,
const char *hostname);
const char *hostname, size_t hostlen);
#endif /* HEADER_CURL_HOSTCHECK_H */

View file

@ -1615,13 +1615,14 @@ static bool subj_alt_hostcheck(struct Curl_easy *data,
const char *match_pattern,
size_t matchlen,
const char *hostname,
size_t hostlen,
const char *dispname)
{
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)dispname;
(void)data;
#endif
if(Curl_cert_hostcheck(match_pattern, matchlen, hostname)) {
if(Curl_cert_hostcheck(match_pattern, matchlen, hostname, hostlen)) {
infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"",
dispname, match_pattern);
return TRUE;
@ -1668,6 +1669,7 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
const char * const hostname = SSL_HOST_NAME();
const char * const dispname = SSL_HOST_DISPNAME();
size_t hostlen = strlen(hostname);
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
@ -1730,7 +1732,9 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
if((altlen == strlen(altptr)) &&
/* if this isn't true, there was an embedded zero in the name
string and we cannot match it. */
subj_alt_hostcheck(data, altptr, altlen, hostname, dispname)) {
subj_alt_hostcheck(data,
altptr,
altlen, hostname, hostlen, dispname)) {
dnsmatched = TRUE;
}
break;
@ -1822,7 +1826,8 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
"SSL: unable to obtain common name from peer certificate");
result = CURLE_PEER_FAILED_VERIFICATION;
}
else if(!Curl_cert_hostcheck((const char *)peer_CN, peerlen, hostname)) {
else if(!Curl_cert_hostcheck((const char *)peer_CN,
peerlen, hostname, hostlen)) {
failf(data, "SSL: certificate subject name '%s' does not match "
"target host name '%s'", peer_CN, dispname);
result = CURLE_PEER_FAILED_VERIFICATION;

View file

@ -465,6 +465,7 @@ static CURLcode verify_host(struct Curl_easy *data,
CURLcode result = CURLE_PEER_FAILED_VERIFICATION;
TCHAR *cert_hostname_buff = NULL;
size_t cert_hostname_buff_index = 0;
size_t hostlen = strlen(conn_hostname);
DWORD len = 0;
DWORD actual_len = 0;
@ -521,7 +522,7 @@ static CURLcode verify_host(struct Curl_easy *data,
}
else {
if(Curl_cert_hostcheck(cert_hostname, strlen(cert_hostname),
conn_hostname)) {
conn_hostname, hostlen)) {
infof(data,
"schannel: connection hostname (%s) validated "
"against certificate name (%s)",

View file

@ -1275,6 +1275,7 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
ssize_t len;
const char * const hostname = SSL_HOST_NAME();
const char * const dispname = SSL_HOST_DISPNAME();
size_t hostlen = strlen(hostname);
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
@ -1330,7 +1331,8 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
name.beg, name.end);
if(len > 0 && (size_t)len == strlen(dnsname))
matched = Curl_cert_hostcheck(dnsname, (size_t)len, hostname);
matched = Curl_cert_hostcheck(dnsname,
(size_t)len, hostname, hostlen);
else
matched = 0;
free(dnsname);
@ -1389,7 +1391,8 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
}
if(strlen(dnsname) != (size_t) len) /* Nul byte in string ? */
failf(data, "SSL: illegal cert name field");
else if(Curl_cert_hostcheck((const char *) dnsname, hostname)) {
else if(Curl_cert_hostcheck((const char *) dnsname,
len, hostname, hostlen)) {
infof(data, " common name: %s (matched)", dnsname);
free(dnsname);
return CURLE_OK;