/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/

#include "curl_setup.h"

#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
    defined(USE_WOLFSSL) || defined(USE_SCHANNEL)

#include <curl/curl.h>
#include "urldata.h"
#include "strcase.h"
#include "hostcheck.h"
#include "vtls/vtls.h"
#include "sendf.h"
#include "inet_pton.h"
#include "curl_base64.h"
#include "x509asn1.h"

/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"

/* ASN.1 OIDs. */
static const char       cnOID[] = "2.5.4.3";    /* Common name. */
static const char       sanOID[] = "2.5.29.17"; /* Subject alternative name. */

static const curl_OID   OIDtable[] = {
  { "1.2.840.10040.4.1",        "dsa" },
  { "1.2.840.10040.4.3",        "dsa-with-sha1" },
  { "1.2.840.10045.2.1",        "ecPublicKey" },
  { "1.2.840.10045.3.0.1",      "c2pnb163v1" },
  { "1.2.840.10045.4.1",        "ecdsa-with-SHA1" },
  { "1.2.840.10046.2.1",        "dhpublicnumber" },
  { "1.2.840.113549.1.1.1",     "rsaEncryption" },
  { "1.2.840.113549.1.1.2",     "md2WithRSAEncryption" },
  { "1.2.840.113549.1.1.4",     "md5WithRSAEncryption" },
  { "1.2.840.113549.1.1.5",     "sha1WithRSAEncryption" },
  { "1.2.840.113549.1.1.10",    "RSASSA-PSS" },
  { "1.2.840.113549.1.1.14",    "sha224WithRSAEncryption" },
  { "1.2.840.113549.1.1.11",    "sha256WithRSAEncryption" },
  { "1.2.840.113549.1.1.12",    "sha384WithRSAEncryption" },
  { "1.2.840.113549.1.1.13",    "sha512WithRSAEncryption" },
  { "1.2.840.113549.2.2",       "md2" },
  { "1.2.840.113549.2.5",       "md5" },
  { "1.3.14.3.2.26",            "sha1" },
  { cnOID,                      "CN" },
  { "2.5.4.4",                  "SN" },
  { "2.5.4.5",                  "serialNumber" },
  { "2.5.4.6",                  "C" },
  { "2.5.4.7",                  "L" },
  { "2.5.4.8",                  "ST" },
  { "2.5.4.9",                  "streetAddress" },
  { "2.5.4.10",                 "O" },
  { "2.5.4.11",                 "OU" },
  { "2.5.4.12",                 "title" },
  { "2.5.4.13",                 "description" },
  { "2.5.4.17",                 "postalCode" },
  { "2.5.4.41",                 "name" },
  { "2.5.4.42",                 "givenName" },
  { "2.5.4.43",                 "initials" },
  { "2.5.4.44",                 "generationQualifier" },
  { "2.5.4.45",                 "X500UniqueIdentifier" },
  { "2.5.4.46",                 "dnQualifier" },
  { "2.5.4.65",                 "pseudonym" },
  { "1.2.840.113549.1.9.1",     "emailAddress" },
  { "2.5.4.72",                 "role" },
  { sanOID,                     "subjectAltName" },
  { "2.5.29.18",                "issuerAltName" },
  { "2.5.29.19",                "basicConstraints" },
  { "2.16.840.1.101.3.4.2.4",   "sha224" },
  { "2.16.840.1.101.3.4.2.1",   "sha256" },
  { "2.16.840.1.101.3.4.2.2",   "sha384" },
  { "2.16.840.1.101.3.4.2.3",   "sha512" },
  { (const char *) NULL,        (const char *) NULL }
};

/*
 * Lightweight ASN.1 parser.
 * In particular, it does not check for syntactic/lexical errors.
 * It is intended to support certificate information gathering for SSL backends
 * that offer a mean to get certificates as a whole, but do not supply
 * entry points to get particular certificate sub-fields.
 * Please note there is no pretention here to rewrite a full SSL library.
 */

static const char *getASN1Element(curl_asn1Element *elem,
                                  const char *beg, const char *end)
  WARN_UNUSED_RESULT;

static const char *getASN1Element(curl_asn1Element *elem,
                                  const char *beg, const char *end)
{
  unsigned char b;
  unsigned long len;
  curl_asn1Element lelem;

  /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg'
     ending at `end'.
     Returns a pointer in source string after the parsed element, or NULL
     if an error occurs. */
  if(!beg || !end || beg >= end || !*beg ||
     (size_t)(end - beg) > CURL_ASN1_MAX)
    return NULL;

  /* Process header byte. */
  elem->header = beg;
  b = (unsigned char) *beg++;
  elem->constructed = (b & 0x20) != 0;
  elem->class = (b >> 6) & 3;
  b &= 0x1F;
  if(b == 0x1F)
    return NULL; /* Long tag values not supported here. */
  elem->tag = b;

  /* Process length. */
  if(beg >= end)
    return NULL;
  b = (unsigned char) *beg++;
  if(!(b & 0x80))
    len = b;
  else if(!(b &= 0x7F)) {
    /* Unspecified length. Since we have all the data, we can determine the
       effective length by skipping element until an end element is found. */
    if(!elem->constructed)
      return NULL;
    elem->beg = beg;
    while(beg < end && *beg) {
      beg = getASN1Element(&lelem, beg, end);
      if(!beg)
        return NULL;
    }
    if(beg >= end)
      return NULL;
    elem->end = beg;
    return beg + 1;
  }
  else if((unsigned)b > (size_t)(end - beg))
    return NULL; /* Does not fit in source. */
  else {
    /* Get long length. */
    len = 0;
    do {
      if(len & 0xFF000000L)
        return NULL;  /* Lengths > 32 bits are not supported. */
      len = (len << 8) | (unsigned char) *beg++;
    } while(--b);
  }
  if(len > (size_t)(end - beg))
    return NULL;  /* Element data does not fit in source. */
  elem->beg = beg;
  elem->end = beg + len;
  return elem->end;
}

/*
 * Search the null terminated OID or OID identifier in local table.
 * Return the table entry pointer or NULL if not found.
 */
static const curl_OID * searchOID(const char *oid)
{
  const curl_OID *op;
  for(op = OIDtable; op->numoid; op++)
    if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
      return op;

  return NULL;
}

/*
 * Convert an ASN.1 Boolean value into its string representation.  Return the
 * dynamically allocated string, or NULL if source is not an ASN.1 Boolean
 * value.
 */

static const char *bool2str(const char *beg, const char *end)
{
  if(end - beg != 1)
    return NULL;
  return strdup(*beg? "TRUE": "FALSE");
}

/*
 * Convert an ASN.1 octet string to a printable string.
 * Return the dynamically allocated string, or NULL if an error occurs.
 */
static const char *octet2str(const char *beg, const char *end)
{
  size_t n = end - beg;
  char *buf = NULL;

  if(n <= (SIZE_T_MAX - 1) / 3) {
    buf = malloc(3 * n + 1);
    if(buf)
      for(n = 0; beg < end; n += 3)
        msnprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
  }
  return buf;
}

static const char *bit2str(const char *beg, const char *end)
{
  /* Convert an ASN.1 bit string to a printable string.
     Return the dynamically allocated string, or NULL if an error occurs. */

  if(++beg > end)
    return NULL;
  return octet2str(beg, end);
}

/*
 * Convert an ASN.1 integer value into its string representation.
 * Return the dynamically allocated string, or NULL if source is not an
 * ASN.1 integer value.
 */
static const char *int2str(const char *beg, const char *end)
{
  unsigned long val = 0;
  size_t n = end - beg;

  if(!n)
    return NULL;

  if(n > 4)
    return octet2str(beg, end);

  /* Represent integers <= 32-bit as a single value. */
  if(*beg & 0x80)
    val = ~val;

  do
    val = (val << 8) | *(const unsigned char *) beg++;
  while(beg < end);
  return curl_maprintf("%s%lx", val >= 10? "0x": "", val);
}

/*
 * Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
 * destination buffer dynamically. The allocation size will normally be too
 * large: this is to avoid buffer overflows.
 * Terminate the string with a nul byte and return the converted
 * string length.
 */
static ssize_t
utf8asn1str(char **to, int type, const char *from, const char *end)
{
  size_t inlength = end - from;
  int size = 1;
  size_t outlength;
  char *buf;

  *to = NULL;
  switch(type) {
  case CURL_ASN1_BMP_STRING:
    size = 2;
    break;
  case CURL_ASN1_UNIVERSAL_STRING:
    size = 4;
    break;
  case CURL_ASN1_NUMERIC_STRING:
  case CURL_ASN1_PRINTABLE_STRING:
  case CURL_ASN1_TELETEX_STRING:
  case CURL_ASN1_IA5_STRING:
  case CURL_ASN1_VISIBLE_STRING:
  case CURL_ASN1_UTF8_STRING:
    break;
  default:
    return -1;  /* Conversion not supported. */
  }

  if(inlength % size)
    return -1;  /* Length inconsistent with character size. */
  if(inlength / size > (SIZE_T_MAX - 1) / 4)
    return -1;  /* Too big. */
  buf = malloc(4 * (inlength / size) + 1);
  if(!buf)
    return -1;  /* Not enough memory. */

  if(type == CURL_ASN1_UTF8_STRING) {
    /* Just copy. */
    outlength = inlength;
    if(outlength)
      memcpy(buf, from, outlength);
  }
  else {
    for(outlength = 0; from < end;) {
      int charsize;
      unsigned int wc;

      wc = 0;
      switch(size) {
      case 4:
        wc = (wc << 8) | *(const unsigned char *) from++;
        wc = (wc << 8) | *(const unsigned char *) from++;
        /* FALLTHROUGH */
      case 2:
        wc = (wc << 8) | *(const unsigned char *) from++;
        /* FALLTHROUGH */
      default: /* case 1: */
        wc = (wc << 8) | *(const unsigned char *) from++;
      }
      charsize = 1;
      if(wc >= 0x00000080) {
        if(wc >= 0x00000800) {
          if(wc >= 0x00010000) {
            if(wc >= 0x00200000) {
              free(buf);
              return -1;        /* Invalid char. size for target encoding. */
            }
            buf[outlength + 3] = (char) (0x80 | (wc & 0x3F));
            wc = (wc >> 6) | 0x00010000;
            charsize++;
          }
          buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
          wc = (wc >> 6) | 0x00000800;
          charsize++;
        }
        buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
        wc = (wc >> 6) | 0x000000C0;
        charsize++;
      }
      buf[outlength] = (char) wc;
      outlength += charsize;
    }
  }
  buf[outlength] = '\0';
  *to = buf;
  return outlength;
}

/*
 * Convert an ASN.1 String into its UTF-8 string representation.
 * Return the dynamically allocated string, or NULL if an error occurs.
 */
static const char *string2str(int type, const char *beg, const char *end)
{
  char *buf;
  if(utf8asn1str(&buf, type, beg, end) < 0)
    return NULL;
  return buf;
}

/*
 * Decimal ASCII encode unsigned integer `x' into the buflen sized buffer at
 * buf.  Return the total number of encoded digits, even if larger than
 * `buflen'.
 */
static size_t encodeUint(char *buf, size_t buflen, unsigned int x)
{
  size_t i = 0;
  unsigned int y = x / 10;

  if(y) {
    i = encodeUint(buf, buflen, y);
    x -= y * 10;
  }
  if(i < buflen)
    buf[i] = (char) ('0' + x);
  i++;
  if(i < buflen)
    buf[i] = '\0';      /* Store a terminator if possible. */
  return i;
}

/*
 * Convert an ASN.1 OID into its dotted string representation.
 * Store the result in th `n'-byte buffer at `buf'.
 * Return the converted string length, or 0 on errors.
 */
static size_t encodeOID(char *buf, size_t buflen,
                        const char *beg, const char *end)
{
  size_t i;
  unsigned int x;
  unsigned int y;

  /* Process the first two numbers. */
  y = *(const unsigned char *) beg++;
  x = y / 40;
  y -= x * 40;
  i = encodeUint(buf, buflen, x);
  if(i < buflen)
    buf[i] = '.';
  i++;
  if(i >= buflen)
    i += encodeUint(NULL, 0, y);
  else
    i += encodeUint(buf + i, buflen - i, y);

  /* Process the trailing numbers. */
  while(beg < end) {
    if(i < buflen)
      buf[i] = '.';
    i++;
    x = 0;
    do {
      if(x & 0xFF000000)
        return 0;
      y = *(const unsigned char *) beg++;
      x = (x << 7) | (y & 0x7F);
    } while(y & 0x80);
    if(i >= buflen)
      i += encodeUint(NULL, 0, x);
    else
      i += encodeUint(buf + i, buflen - i, x);
  }
  if(i < buflen)
    buf[i] = '\0';
  return i;
}

/*
 * Convert an ASN.1 OID into its dotted or symbolic string representation.
 * Return the dynamically allocated string, or NULL if an error occurs.
 */

static const char *OID2str(const char *beg, const char *end, bool symbolic)
{
  char *buf = NULL;
  if(beg < end) {
    size_t buflen = encodeOID(NULL, 0, beg, end);
    if(buflen) {
      buf = malloc(buflen + 1); /* one extra for the zero byte */
      if(buf) {
        encodeOID(buf, buflen, beg, end);
        buf[buflen] = '\0';

        if(symbolic) {
          const curl_OID *op = searchOID(buf);
          if(op) {
            free(buf);
            buf = strdup(op->textoid);
          }
        }
      }
    }
  }
  return buf;
}

static const char *GTime2str(const char *beg, const char *end)
{
  const char *tzp;
  const char *fracp;
  char sec1, sec2;
  size_t fracl;
  size_t tzl;
  const char *sep = "";

  /* Convert an ASN.1 Generalized time to a printable string.
     Return the dynamically allocated string, or NULL if an error occurs. */

  for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++)
    ;

  /* Get seconds digits. */
  sec1 = '0';
  switch(fracp - beg - 12) {
  case 0:
    sec2 = '0';
    break;
  case 2:
    sec1 = fracp[-2];
    /* FALLTHROUGH */
  case 1:
    sec2 = fracp[-1];
    break;
  default:
    return NULL;
  }

  /* Scan for timezone, measure fractional seconds. */
  tzp = fracp;
  fracl = 0;
  if(fracp < end && (*fracp == '.' || *fracp == ',')) {
    fracp++;
    do
      tzp++;
    while(tzp < end && *tzp >= '0' && *tzp <= '9');
    /* Strip leading zeroes in fractional seconds. */
    for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--)
      ;
  }

  /* Process timezone. */
  if(tzp >= end)
    ;           /* Nothing to do. */
  else if(*tzp == 'Z') {
    tzp = " GMT";
    end = tzp + 4;
  }
  else {
    sep = " ";
    tzp++;
  }

  tzl = end - tzp;
  return curl_maprintf("%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s",
                       beg, beg + 4, beg + 6,
                       beg + 8, beg + 10, sec1, sec2,
                       fracl? ".": "", fracl, fracp,
                       sep, tzl, tzp);
}

/*
 *  Convert an ASN.1 UTC time to a printable string.
 * Return the dynamically allocated string, or NULL if an error occurs.
 */
static const char *UTime2str(const char *beg, const char *end)
{
  const char *tzp;
  size_t tzl;
  const char *sec;

  for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++)
    ;
  /* Get the seconds. */
  sec = beg + 10;
  switch(tzp - sec) {
  case 0:
    sec = "00";
  case 2:
    break;
  default:
    return NULL;
  }

  /* Process timezone. */
  if(tzp >= end)
    return NULL;
  if(*tzp == 'Z') {
    tzp = "GMT";
    end = tzp + 3;
  }
  else
    tzp++;

  tzl = end - tzp;
  return curl_maprintf("%u%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s",
                       20 - (*beg >= '5'), beg, beg + 2, beg + 4,
                       beg + 6, beg + 8, sec,
                       tzl, tzp);
}

/*
 * Convert an ASN.1 element to a printable string.
 * Return the dynamically allocated string, or NULL if an error occurs.
 */
static const char *ASN1tostr(curl_asn1Element *elem, int type)
{
  if(elem->constructed)
    return NULL; /* No conversion of structured elements. */

  if(!type)
    type = elem->tag;   /* Type not forced: use element tag as type. */

  switch(type) {
  case CURL_ASN1_BOOLEAN:
    return bool2str(elem->beg, elem->end);
  case CURL_ASN1_INTEGER:
  case CURL_ASN1_ENUMERATED:
    return int2str(elem->beg, elem->end);
  case CURL_ASN1_BIT_STRING:
    return bit2str(elem->beg, elem->end);
  case CURL_ASN1_OCTET_STRING:
    return octet2str(elem->beg, elem->end);
  case CURL_ASN1_NULL:
    return strdup("");
  case CURL_ASN1_OBJECT_IDENTIFIER:
    return OID2str(elem->beg, elem->end, TRUE);
  case CURL_ASN1_UTC_TIME:
    return UTime2str(elem->beg, elem->end);
  case CURL_ASN1_GENERALIZED_TIME:
    return GTime2str(elem->beg, elem->end);
  case CURL_ASN1_UTF8_STRING:
  case CURL_ASN1_NUMERIC_STRING:
  case CURL_ASN1_PRINTABLE_STRING:
  case CURL_ASN1_TELETEX_STRING:
  case CURL_ASN1_IA5_STRING:
  case CURL_ASN1_VISIBLE_STRING:
  case CURL_ASN1_UNIVERSAL_STRING:
  case CURL_ASN1_BMP_STRING:
    return string2str(type, elem->beg, elem->end);
  }

  return NULL;   /* Unsupported. */
}

/*
 * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at
 * `buf'.  Return the total string length, even if larger than `buflen'.
 */
static ssize_t encodeDN(char *buf, size_t buflen, curl_asn1Element *dn)
{
  curl_asn1Element rdn;
  curl_asn1Element atv;
  curl_asn1Element oid;
  curl_asn1Element value;
  size_t l = 0;
  const char *p1;
  const char *p2;
  const char *p3;
  const char *str;

  for(p1 = dn->beg; p1 < dn->end;) {
    p1 = getASN1Element(&rdn, p1, dn->end);
    if(!p1)
      return -1;
    for(p2 = rdn.beg; p2 < rdn.end;) {
      p2 = getASN1Element(&atv, p2, rdn.end);
      if(!p2)
        return -1;
      p3 = getASN1Element(&oid, atv.beg, atv.end);
      if(!p3)
        return -1;
      if(!getASN1Element(&value, p3, atv.end))
        return -1;
      str = ASN1tostr(&oid, 0);
      if(!str)
        return -1;

      /* Encode delimiter.
         If attribute has a short uppercase name, delimiter is ", ". */
      if(l) {
        for(p3 = str; isupper(*p3); p3++)
          ;
        for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
          if(l < buflen)
            buf[l] = *p3;
          l++;
        }
      }

      /* Encode attribute name. */
      for(p3 = str; *p3; p3++) {
        if(l < buflen)
          buf[l] = *p3;
        l++;
      }
      free((char *) str);

      /* Generate equal sign. */
      if(l < buflen)
        buf[l] = '=';
      l++;

      /* Generate value. */
      str = ASN1tostr(&value, 0);
      if(!str)
        return -1;
      for(p3 = str; *p3; p3++) {
        if(l < buflen)
          buf[l] = *p3;
        l++;
      }
      free((char *) str);
    }
  }

  return l;
}

/*
 * Convert an ASN.1 distinguished name into a printable string.
 * Return the dynamically allocated string, or NULL if an error occurs.
 */
static const char *DNtostr(curl_asn1Element *dn)
{
  char *buf = NULL;
  ssize_t buflen = encodeDN(NULL, 0, dn);

  if(buflen >= 0) {
    buf = malloc(buflen + 1);
    if(buf) {
      encodeDN(buf, buflen + 1, dn);
      buf[buflen] = '\0';
    }
  }
  return buf;
}

/*
 * ASN.1 parse an X509 certificate into structure subfields.
 * Syntax is assumed to have already been checked by the SSL backend.
 * See RFC 5280.
 */
int Curl_parseX509(curl_X509certificate *cert,
                   const char *beg, const char *end)
{
  curl_asn1Element elem;
  curl_asn1Element tbsCertificate;
  const char *ccp;
  static const char defaultVersion = 0;  /* v1. */

  cert->certificate.header = NULL;
  cert->certificate.beg = beg;
  cert->certificate.end = end;

  /* Get the sequence content. */
  if(!getASN1Element(&elem, beg, end))
    return -1;  /* Invalid bounds/size. */
  beg = elem.beg;
  end = elem.end;

  /* Get tbsCertificate. */
  beg = getASN1Element(&tbsCertificate, beg, end);
  if(!beg)
    return -1;
  /* Skip the signatureAlgorithm. */
  beg = getASN1Element(&cert->signatureAlgorithm, beg, end);
  if(!beg)
    return -1;
  /* Get the signatureValue. */
  if(!getASN1Element(&cert->signature, beg, end))
    return -1;

  /* Parse TBSCertificate. */
  beg = tbsCertificate.beg;
  end = tbsCertificate.end;
  /* Get optional version, get serialNumber. */
  cert->version.header = NULL;
  cert->version.beg = &defaultVersion;
  cert->version.end = &defaultVersion + sizeof(defaultVersion);
  beg = getASN1Element(&elem, beg, end);
  if(!beg)
    return -1;
  if(elem.tag == 0) {
    if(!getASN1Element(&cert->version, elem.beg, elem.end))
      return -1;
    beg = getASN1Element(&elem, beg, end);
    if(!beg)
      return -1;
  }
  cert->serialNumber = elem;
  /* Get signature algorithm. */
  beg = getASN1Element(&cert->signatureAlgorithm, beg, end);
  /* Get issuer. */
  beg = getASN1Element(&cert->issuer, beg, end);
  if(!beg)
    return -1;
  /* Get notBefore and notAfter. */
  beg = getASN1Element(&elem, beg, end);
  if(!beg)
    return -1;
  ccp = getASN1Element(&cert->notBefore, elem.beg, elem.end);
  if(!ccp)
    return -1;
  if(!getASN1Element(&cert->notAfter, ccp, elem.end))
    return -1;
  /* Get subject. */
  beg = getASN1Element(&cert->subject, beg, end);
  if(!beg)
    return -1;
  /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
  beg = getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
  if(!beg)
    return -1;
  ccp = getASN1Element(&cert->subjectPublicKeyAlgorithm,
                       cert->subjectPublicKeyInfo.beg,
                       cert->subjectPublicKeyInfo.end);
  if(!ccp)
    return -1;
  if(!getASN1Element(&cert->subjectPublicKey, ccp,
                     cert->subjectPublicKeyInfo.end))
    return -1;
  /* Get optional issuerUiqueID, subjectUniqueID and extensions. */
  cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
  cert->extensions.tag = elem.tag = 0;
  cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL;
  cert->issuerUniqueID.beg = cert->issuerUniqueID.end = "";
  cert->subjectUniqueID.beg = cert->subjectUniqueID.end = "";
  cert->extensions.header = NULL;
  cert->extensions.beg = cert->extensions.end = "";
  if(beg < end) {
    beg = getASN1Element(&elem, beg, end);
    if(!beg)
      return -1;
  }
  if(elem.tag == 1) {
    cert->issuerUniqueID = elem;
    if(beg < end) {
      beg = getASN1Element(&elem, beg, end);
      if(!beg)
        return -1;
    }
  }
  if(elem.tag == 2) {
    cert->subjectUniqueID = elem;
    if(beg < end) {
      beg = getASN1Element(&elem, beg, end);
      if(!beg)
        return -1;
    }
  }
  if(elem.tag == 3)
    if(!getASN1Element(&cert->extensions, elem.beg, elem.end))
      return -1;
  return 0;
}


/*
 * Copy at most 64-characters, terminate with a newline and returns the
 * effective number of stored characters.
 */
static size_t copySubstring(char *to, const char *from)
{
  size_t i;
  for(i = 0; i < 64; i++) {
    to[i] = *from;
    if(!*from++)
      break;
  }

  to[i++] = '\n';
  return i;
}

static const char *dumpAlgo(curl_asn1Element *param,
                            const char *beg, const char *end)
{
  curl_asn1Element oid;

  /* Get algorithm parameters and return algorithm name. */

  beg = getASN1Element(&oid, beg, end);
  if(!beg)
    return NULL;
  param->header = NULL;
  param->tag = 0;
  param->beg = param->end = end;
  if(beg < end)
    if(!getASN1Element(param, beg, end))
      return NULL;
  return OID2str(oid.beg, oid.end, TRUE);
}

static void do_pubkey_field(struct Curl_easy *data, int certnum,
                            const char *label, curl_asn1Element *elem)
{
  const char *output;

  /* Generate a certificate information record for the public key. */

  output = ASN1tostr(elem, 0);
  if(output) {
    if(data->set.ssl.certinfo)
      Curl_ssl_push_certinfo(data, certnum, label, output);
    if(!certnum)
      infof(data, "   %s: %s\n", label, output);
    free((char *) output);
  }
}

static void do_pubkey(struct Curl_easy *data, int certnum,
                      const char *algo, curl_asn1Element *param,
                      curl_asn1Element *pubkey)
{
  curl_asn1Element elem;
  curl_asn1Element pk;
  const char *p;

  /* Generate all information records for the public key. */

  /* Get the public key (single element). */
  if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end))
    return;

  if(strcasecompare(algo, "rsaEncryption")) {
    const char *q;
    unsigned long len;

    p = getASN1Element(&elem, pk.beg, pk.end);
    if(!p)
      return;

    /* Compute key length. */
    for(q = elem.beg; !*q && q < elem.end; q++)
      ;
    len = (unsigned long)((elem.end - q) * 8);
    if(len) {
      unsigned int i;
      for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1)
        len--;
    }
    if(len > 32)
      elem.beg = q;     /* Strip leading zero bytes. */
    if(!certnum)
      infof(data, "   RSA Public Key (%lu bits)\n", len);
    if(data->set.ssl.certinfo) {
      q = curl_maprintf("%lu", len);
      if(q) {
        Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
        free((char *) q);
      }
    }
    /* Generate coefficients. */
    do_pubkey_field(data, certnum, "rsa(n)", &elem);
    if(!getASN1Element(&elem, p, pk.end))
      return;
    do_pubkey_field(data, certnum, "rsa(e)", &elem);
  }
  else if(strcasecompare(algo, "dsa")) {
    p = getASN1Element(&elem, param->beg, param->end);
    if(p) {
      do_pubkey_field(data, certnum, "dsa(p)", &elem);
      p = getASN1Element(&elem, p, param->end);
      if(p) {
        do_pubkey_field(data, certnum, "dsa(q)", &elem);
        if(getASN1Element(&elem, p, param->end)) {
          do_pubkey_field(data, certnum, "dsa(g)", &elem);
          do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
        }
      }
    }
  }
  else if(strcasecompare(algo, "dhpublicnumber")) {
    p = getASN1Element(&elem, param->beg, param->end);
    if(p) {
      do_pubkey_field(data, certnum, "dh(p)", &elem);
      if(getASN1Element(&elem, param->beg, param->end)) {
        do_pubkey_field(data, certnum, "dh(g)", &elem);
        do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
      }
    }
  }
}

CURLcode Curl_extract_certinfo(struct connectdata *conn,
                               int certnum,
                               const char *beg,
                               const char *end)
{
  curl_X509certificate cert;
  struct Curl_easy *data = conn->data;
  curl_asn1Element param;
  const char *ccp;
  char *cp1;
  size_t cl1;
  char *cp2;
  CURLcode result;
  unsigned long version;
  size_t i;
  size_t j;

  if(!data->set.ssl.certinfo)
    if(certnum)
      return CURLE_OK;

  /* Prepare the certificate information for curl_easy_getinfo(). */

  /* Extract the certificate ASN.1 elements. */
  if(Curl_parseX509(&cert, beg, end))
    return CURLE_PEER_FAILED_VERIFICATION;

  /* Subject. */
  ccp = DNtostr(&cert.subject);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
  if(!certnum)
    infof(data, "%2d Subject: %s\n", certnum, ccp);
  free((char *) ccp);

  /* Issuer. */
  ccp = DNtostr(&cert.issuer);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
  if(!certnum)
    infof(data, "   Issuer: %s\n", ccp);
  free((char *) ccp);

  /* Version (always fits in less than 32 bits). */
  version = 0;
  for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
    version = (version << 8) | *(const unsigned char *) ccp;
  if(data->set.ssl.certinfo) {
    ccp = curl_maprintf("%lx", version);
    if(!ccp)
      return CURLE_OUT_OF_MEMORY;
    Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
    free((char *) ccp);
  }
  if(!certnum)
    infof(data, "   Version: %lu (0x%lx)\n", version + 1, version);

  /* Serial number. */
  ccp = ASN1tostr(&cert.serialNumber, 0);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
  if(!certnum)
    infof(data, "   Serial Number: %s\n", ccp);
  free((char *) ccp);

  /* Signature algorithm .*/
  ccp = dumpAlgo(&param, cert.signatureAlgorithm.beg,
                 cert.signatureAlgorithm.end);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
  if(!certnum)
    infof(data, "   Signature Algorithm: %s\n", ccp);
  free((char *) ccp);

  /* Start Date. */
  ccp = ASN1tostr(&cert.notBefore, 0);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
  if(!certnum)
    infof(data, "   Start Date: %s\n", ccp);
  free((char *) ccp);

  /* Expire Date. */
  ccp = ASN1tostr(&cert.notAfter, 0);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
  if(!certnum)
    infof(data, "   Expire Date: %s\n", ccp);
  free((char *) ccp);

  /* Public Key Algorithm. */
  ccp = dumpAlgo(&param, cert.subjectPublicKeyAlgorithm.beg,
                 cert.subjectPublicKeyAlgorithm.end);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
  if(!certnum)
    infof(data, "   Public Key Algorithm: %s\n", ccp);
  do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
  free((char *) ccp);

  /* Signature. */
  ccp = ASN1tostr(&cert.signature, 0);
  if(!ccp)
    return CURLE_OUT_OF_MEMORY;
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
  if(!certnum)
    infof(data, "   Signature: %s\n", ccp);
  free((char *) ccp);

  /* Generate PEM certificate. */
  result = Curl_base64_encode(data, cert.certificate.beg,
                              cert.certificate.end - cert.certificate.beg,
                              &cp1, &cl1);
  if(result)
    return result;
  /* Compute the number of characters in final certificate string. Format is:
     -----BEGIN CERTIFICATE-----\n
     <max 64 base64 characters>\n
     .
     .
     .
     -----END CERTIFICATE-----\n
   */
  i = 28 + cl1 + (cl1 + 64 - 1) / 64 + 26;
  cp2 = malloc(i + 1);
  if(!cp2) {
    free(cp1);
    return CURLE_OUT_OF_MEMORY;
  }
  /* Build the certificate string. */
  i = copySubstring(cp2, "-----BEGIN CERTIFICATE-----");
  for(j = 0; j < cl1; j += 64)
    i += copySubstring(cp2 + i, cp1 + j);
  i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
  cp2[i] = '\0';
  free(cp1);
  if(data->set.ssl.certinfo)
    Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
  if(!certnum)
    infof(data, "%s\n", cp2);
  free(cp2);
  return CURLE_OK;
}

#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL */

#if defined(USE_GSKIT)

static const char *checkOID(const char *beg, const char *end,
                            const char *oid)
{
  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 connectdata *conn,
                         const char *beg, const char *end)
{
  struct Curl_easy *data = conn->data;
  curl_X509certificate cert;
  curl_asn1Element dn;
  curl_asn1Element elem;
  curl_asn1Element ext;
  curl_asn1Element name;
  const char *p;
  const char *q;
  char *dnsname;
  int matched = -1;
  size_t addrlen = (size_t) -1;
  ssize_t len;
  const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
                                                conn->host.name;
  const char * const dispname = SSL_IS_PROXY()?
                                  conn->http_proxy.host.dispname:
                                  conn->host.dispname;
#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(!SSL_CONN_CONFIG(verifyhost))
    return CURLE_OK;

  if(Curl_parseX509(&cert, beg, end))
    return CURLE_PEER_FAILED_VERIFICATION;

  /* Get the server IP address. */
#ifdef ENABLE_IPV6
  if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, hostname, &addr))
    addrlen = sizeof(struct in6_addr);
  else
#endif
  if(Curl_inet_pton(AF_INET, 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, hostname);
          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, "\t subjectAltName: %s matched\n", dispname);
    return CURLE_OK;
  case 0:
    /* an alternative name field existed, but didn't match and then
       we MUST fail */
    infof(data, "\t subjectAltName does not match %s\n", 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, hostname)) {
      infof(data, "\t common name: %s (matched)\n", dnsname);
      free(dnsname);
      return CURLE_OK;
    }
    else
      failf(data, "SSL: certificate subject name '%s' does not match "
            "target host name '%s'", dnsname, dispname);
    free(dnsname);
  }

  return CURLE_PEER_FAILED_VERIFICATION;
}

#endif /* USE_GSKIT */
