diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2003-01-07 16:33:11 +0000 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2003-01-07 16:33:11 +0000 | 
| commit | ca134d5522c765d60bc2ffd59410a66c4ba2cf19 (patch) | |
| tree | 8738252fc9f6dd6101b60a53c98a2413d1a0818e | |
| parent | ec24efda749df7513aaf994a9ef0d2b3c72eaed7 (diff) | |
Philippe Raoult's fix to handle wildcard certificate name checks
| -rw-r--r-- | lib/ssluse.c | 40 | 
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/ssluse.c b/lib/ssluse.c index a79a9a71b..e24f8cb30 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -673,6 +673,44 @@ static int Curl_ASN1_UTCTIME_output(struct connectdata *conn,  #endif    /* ====================================================== */ +static int +cert_hostcheck(const char *certname, const char *hostname) +{ +  char *tmp; +  const char *certdomain; +   +  if(!certname || +     strlen(certname)<3 || +     !hostname || +     !strlen(hostname)) /* sanity check */ +    return 0; + +  if(strequal(certname, hostname)) /* trivial case */ +    return 1; + +  certdomain = certname + 1; + +  if((certname[0] != '*') || (certdomain[0] != '.')) +    return 0; /* not a wildcard certificate, check failed */ +   +  if(!strchr(certdomain+1, '.')) +    return 0; /* the certificate must have at least another dot in its name */ + +  /* find 'certdomain' within 'hostname' */ +  tmp = strstr(hostname, certdomain); +  if(tmp) { +    /* ok the certname's domain matches the hostname, let's check that it's a +       tail-match */ +    if(strequal(tmp, certdomain)) +      /* looks like a match. Just check we havent swallowed a '.' */ +      return tmp == strchr(hostname, '.'); +    else +      return 0; +  } +  return 0; +} + +/* ====================================================== */  CURLcode  Curl_SSLConnect(struct connectdata *conn)  { @@ -910,7 +948,7 @@ Curl_SSLConnect(struct connectdata *conn)        return CURLE_SSL_PEER_CERTIFICATE;      } -    if (!strequal(peer_CN, conn->hostname)) { +    if (!cert_hostcheck(peer_CN, conn->hostname)) {        if (data->set.ssl.verifyhost > 1) {          failf(data, "SSL: certificate subject name '%s' does not match "                "target host name '%s'",  | 
