1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

Implement pinned public key in GSKit backend

This commit is contained in:
Patrick Monnerat 2014-10-14 14:58:26 +02:00
parent 89e543f383
commit 473322ec66
3 changed files with 34 additions and 5 deletions

View File

@ -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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * 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 gsk_cert_data_elem *p;
const char *cert = (const char *) NULL; const char *cert = (const char *) NULL;
const char *certend; const char *certend;
const char *ptr;
int i; int i;
CURLcode cc; 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; connssl->connecting_state = ssl_connect_done;
return CURLE_OK; return CURLE_OK;
} }

View File

@ -122,6 +122,7 @@ const char * Curl_getASN1Element(curl_asn1Element * elem,
return (const char *) NULL; return (const char *) NULL;
/* Process header byte. */ /* Process header byte. */
elem->header = beg;
b = (unsigned char) *beg++; b = (unsigned char) *beg++;
elem->constructed = (b & 0x20) != 0; elem->constructed = (b & 0x20) != 0;
elem->class = (b >> 6) & 3; 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. Syntax is assumed to have already been checked by the SSL backend.
See RFC 5280. */ See RFC 5280. */
cert->certificate.header = NULL;
cert->certificate.beg = beg; cert->certificate.beg = beg;
cert->certificate.end = end; cert->certificate.end = end;
@ -701,6 +703,7 @@ void Curl_parseX509(curl_X509certificate * cert,
beg = tbsCertificate.beg; beg = tbsCertificate.beg;
end = tbsCertificate.end; end = tbsCertificate.end;
/* Get optional version, get serialNumber. */ /* Get optional version, get serialNumber. */
cert->version.header = NULL;
cert->version.beg = &defaultVersion; cert->version.beg = &defaultVersion;
cert->version.end = &defaultVersion + sizeof defaultVersion;; cert->version.end = &defaultVersion + sizeof defaultVersion;;
beg = Curl_getASN1Element(&elem, beg, end); beg = Curl_getASN1Element(&elem, beg, end);
@ -720,15 +723,19 @@ void Curl_parseX509(curl_X509certificate * cert,
/* Get subject. */ /* Get subject. */
beg = Curl_getASN1Element(&cert->subject, beg, end); beg = Curl_getASN1Element(&cert->subject, beg, end);
/* Get subjectPublicKeyAlgorithm and subjectPublicKey. */ /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
beg = Curl_getASN1Element(&elem, beg, end); beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm, ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
elem.beg, elem.end); cert->subjectPublicKeyInfo.beg,
Curl_getASN1Element(&cert->subjectPublicKey, ccp, elem.end); cert->subjectPublicKeyInfo.end);
Curl_getASN1Element(&cert->subjectPublicKey, ccp,
cert->subjectPublicKeyInfo.end);
/* Get optional issuerUiqueID, subjectUniqueID and extensions. */ /* Get optional issuerUiqueID, subjectUniqueID and extensions. */
cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0; cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
cert->extensions.tag = elem.tag = 0; cert->extensions.tag = elem.tag = 0;
cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL;
cert->issuerUniqueID.beg = cert->issuerUniqueID.end = ""; cert->issuerUniqueID.beg = cert->issuerUniqueID.end = "";
cert->subjectUniqueID.beg = cert->subjectUniqueID.end = ""; cert->subjectUniqueID.beg = cert->subjectUniqueID.end = "";
cert->extensions.header = NULL;
cert->extensions.beg = cert->extensions.end = ""; cert->extensions.beg = cert->extensions.end = "";
if(beg < end) if(beg < end)
beg = Curl_getASN1Element(&elem, 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. */ /* Get algorithm parameters and return algorithm name. */
beg = Curl_getASN1Element(&oid, beg, end); beg = Curl_getASN1Element(&oid, beg, end);
param->header = NULL;
param->tag = 0; param->tag = 0;
param->beg = param->end = end; param->beg = param->end = end;
if(beg < end) if(beg < end)
@ -1140,6 +1148,7 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
} }
/* Process subject. */ /* Process subject. */
name.header = NULL;
name.beg = name.end = ""; name.beg = name.end = "";
q = cert.subject.beg; q = cert.subject.beg;
/* we have to look to the last occurrence of a commonName in the /* we have to look to the last occurrence of a commonName in the

View File

@ -76,8 +76,9 @@
/* ASN.1 parsed element. */ /* ASN.1 parsed element. */
typedef struct { typedef struct {
const char * header; /* Pointer to header byte. */
const char * beg; /* Pointer to element data. */ 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 class; /* ASN.1 element class. */
unsigned char tag; /* ASN.1 element tag. */ unsigned char tag; /* ASN.1 element tag. */
bool constructed; /* Element is constructed. */ bool constructed; /* Element is constructed. */
@ -102,6 +103,7 @@ typedef struct {
curl_asn1Element notBefore; curl_asn1Element notBefore;
curl_asn1Element notAfter; curl_asn1Element notAfter;
curl_asn1Element subject; curl_asn1Element subject;
curl_asn1Element subjectPublicKeyInfo;
curl_asn1Element subjectPublicKeyAlgorithm; curl_asn1Element subjectPublicKeyAlgorithm;
curl_asn1Element subjectPublicKey; curl_asn1Element subjectPublicKey;
curl_asn1Element issuerUniqueID; curl_asn1Element issuerUniqueID;