Commit ca134d55 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Philippe Raoult's fix to handle wildcard certificate name checks

parent ec24efda
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -672,6 +672,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'",