x509asn1: remove code for WANT_VERIFYHOST

No code ever sets this anymore since we dropped gskit

Follow-up to 78d6232f1f

Closes #12804
This commit is contained in:
Daniel Stenberg 2024-01-26 11:00:21 +01:00
parent a3a940702a
commit 641257ea08
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -1257,183 +1257,3 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
#endif /* WANT_EXTRACT_CERTINFO */
#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */
#ifdef WANT_VERIFYHOST
static const char *checkOID(const char *beg, const char *end,
const char *oid)
{
struct Curl_asn1Element e;
const char *ccp;
const char *p;
bool matched;
/* Check if first ASN.1 element at `beg' is the given OID.
Return a pointer in the source after the OID if found, else NULL. */
ccp = getASN1Element(&e, beg, end);
if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
return NULL;
p = OID2str(e.beg, e.end, FALSE);
if(!p)
return NULL;
matched = !strcmp(p, oid);
free((char *) p);
return matched? ccp: NULL;
}
CURLcode Curl_verifyhost(struct Curl_cfilter *cf,
struct Curl_easy *data,
const char *beg, const char *end)
{
struct ssl_connect_data *connssl = cf->ctx;
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
struct Curl_X509certificate cert;
struct Curl_asn1Element dn;
struct Curl_asn1Element elem;
struct Curl_asn1Element ext;
struct Curl_asn1Element name;
const char *p;
const char *q;
char *dnsname;
int matched = -1;
size_t addrlen = (size_t) -1;
ssize_t len;
size_t hostlen;
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
struct in_addr addr;
#endif
/* Verify that connection server matches info in X509 certificate at
`beg'..`end'. */
if(!conn_config->verifyhost)
return CURLE_OK;
if(Curl_parseX509(&cert, beg, end))
return CURLE_PEER_FAILED_VERIFICATION;
hostlen = strlen(connssl->peer.hostname);
/* Get the server IP address. */
#ifdef ENABLE_IPV6
if(cf->conn->bits.ipv6_ip &&
Curl_inet_pton(AF_INET6, connssl->peer.hostname, &addr))
addrlen = sizeof(struct in6_addr);
else
#endif
if(Curl_inet_pton(AF_INET, connssl->peer.hostname, &addr))
addrlen = sizeof(struct in_addr);
/* Process extensions. */
for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) {
p = getASN1Element(&ext, p, cert.extensions.end);
if(!p)
return CURLE_PEER_FAILED_VERIFICATION;
/* Check if extension is a subjectAlternativeName. */
ext.beg = checkOID(ext.beg, ext.end, sanOID);
if(ext.beg) {
ext.beg = getASN1Element(&elem, ext.beg, ext.end);
if(!ext.beg)
return CURLE_PEER_FAILED_VERIFICATION;
/* Skip critical if present. */
if(elem.tag == CURL_ASN1_BOOLEAN) {
ext.beg = getASN1Element(&elem, ext.beg, ext.end);
if(!ext.beg)
return CURLE_PEER_FAILED_VERIFICATION;
}
/* Parse the octet string contents: is a single sequence. */
if(!getASN1Element(&elem, elem.beg, elem.end))
return CURLE_PEER_FAILED_VERIFICATION;
/* Check all GeneralNames. */
for(q = elem.beg; matched != 1 && q < elem.end;) {
q = getASN1Element(&name, q, elem.end);
if(!q)
break;
switch(name.tag) {
case 2: /* DNS name. */
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,
connssl->peer.hostname, hostlen);
else
matched = 0;
free(dnsname);
break;
case 7: /* IP address. */
matched = (size_t)(name.end - name.beg) == addrlen &&
!memcmp(&addr, name.beg, addrlen);
break;
}
}
}
}
switch(matched) {
case 1:
/* an alternative name matched the server hostname */
infof(data, " subjectAltName: %s matched", connssl->dispname);
return CURLE_OK;
case 0:
/* an alternative name field existed, but didn't match and then
we MUST fail */
infof(data, " subjectAltName does not match %s", connssl->dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
/* Process subject. */
name.header = NULL;
name.beg = name.end = "";
q = cert.subject.beg;
/* we have to look to the last occurrence of a commonName in the
distinguished one to get the most significant one. */
while(q < cert.subject.end) {
q = getASN1Element(&dn, q, cert.subject.end);
if(!q)
break;
for(p = dn.beg; p < dn.end;) {
p = getASN1Element(&elem, p, dn.end);
if(!p)
return CURLE_PEER_FAILED_VERIFICATION;
/* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */
elem.beg = checkOID(elem.beg, elem.end, cnOID);
if(elem.beg)
name = elem; /* Latch CN. */
}
}
/* Check the CN if found. */
if(!getASN1Element(&elem, name.beg, name.end))
failf(data, "SSL: unable to obtain common name from peer certificate");
else {
len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end);
if(len < 0) {
free(dnsname);
return CURLE_OUT_OF_MEMORY;
}
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,
len, connssl->peer.hostname, hostlen)) {
infof(data, " common name: %s (matched)", dnsname);
free(dnsname);
return CURLE_OK;
}
else
failf(data, "SSL: certificate subject name '%s' does not match "
"target host name '%s'", dnsname, connssl->dispname);
free(dnsname);
}
return CURLE_PEER_FAILED_VERIFICATION;
}
#endif /* WANT_VERIFYHOST */