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:
parent
a3a940702a
commit
641257ea08
@ -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 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user