Commit 473322ec authored by Patrick Monnerat's avatar Patrick Monnerat
Browse files

Implement pinned public key in GSKit backend

parent 89e543f3
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2014, 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
@@ -804,6 +804,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
  const gsk_cert_data_elem *p;
  const char *cert = (const char *) NULL;
  const char *certend;
  const char *ptr;
  int i;
  CURLcode cc;

@@ -857,6 +858,23 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
    }
  }

  /* Check pinned public key. */
  ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
  if(cc == CURLE_OK && ptr) {
    curl_X509certificate x509;
    curl_asn1Element *p;

    if(!cert)
      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
    Curl_parseX509(&x509, cert, certend);
    p = &x509.subjectPublicKeyInfo;
    cc = Curl_pin_peer_pubkey(ptr, p->header, p->end - p->header);
    if(cc != CURLE_OK) {
      failf(data, "SSL: public key does not match pinned public key!");
      return cc;
    }
  }

  connssl->connecting_state = ssl_connect_done;
  return CURLE_OK;
}
+12 −3
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ const char * Curl_getASN1Element(curl_asn1Element * elem,
    return (const char *) NULL;

  /* Process header byte. */
  elem->header = beg;
  b = (unsigned char) *beg++;
  elem->constructed = (b & 0x20) != 0;
  elem->class = (b >> 6) & 3;
@@ -682,6 +683,7 @@ void Curl_parseX509(curl_X509certificate * cert,
     Syntax is assumed to have already been checked by the SSL backend.
     See RFC 5280. */

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

@@ -701,6 +703,7 @@ void Curl_parseX509(curl_X509certificate * cert,
  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 = Curl_getASN1Element(&elem, beg, end);
@@ -720,15 +723,19 @@ void Curl_parseX509(curl_X509certificate * cert,
  /* Get subject. */
  beg = Curl_getASN1Element(&cert->subject, beg, end);
  /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
  beg = Curl_getASN1Element(&elem, beg, end);
  beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
  ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
                            elem.beg, elem.end);
  Curl_getASN1Element(&cert->subjectPublicKey, ccp, elem.end);
                            cert->subjectPublicKeyInfo.beg,
                            cert->subjectPublicKeyInfo.end);
  Curl_getASN1Element(&cert->subjectPublicKey, ccp,
                      cert->subjectPublicKeyInfo.end);
  /* 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 = Curl_getASN1Element(&elem, beg, end);
@@ -771,6 +778,7 @@ static const char * dumpAlgo(curl_asn1Element * param,
  /* Get algorithm parameters and return algorithm name. */

  beg = Curl_getASN1Element(&oid, beg, end);
  param->header = NULL;
  param->tag = 0;
  param->beg = param->end = end;
  if(beg < end)
@@ -1140,6 +1148,7 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
  }

  /* 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
+3 −1
Original line number Diff line number Diff line
@@ -76,8 +76,9 @@

/* ASN.1 parsed element. */
typedef struct {
  const char *  header;         /* Pointer to header byte. */
  const char *  beg;            /* Pointer to element data. */
  const char *  end;            /* Pointer to 1st byte after element data. */
  const char *  end;            /* Pointer to 1st byte after element. */
  unsigned char class;          /* ASN.1 element class. */
  unsigned char tag;            /* ASN.1 element tag. */
  bool          constructed;    /* Element is constructed. */
@@ -102,6 +103,7 @@ typedef struct {
  curl_asn1Element      notBefore;
  curl_asn1Element      notAfter;
  curl_asn1Element      subject;
  curl_asn1Element      subjectPublicKeyInfo;
  curl_asn1Element      subjectPublicKeyAlgorithm;
  curl_asn1Element      subjectPublicKey;
  curl_asn1Element      issuerUniqueID;