summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hwang <danielleehwang@gmail.com>2015-09-12 14:35:12 -0700
committerDaniel Stenberg <daniel@haxx.se>2015-09-19 23:17:39 +0200
commit30c131f51f605d35e5d90f4be1727045fef17351 (patch)
treec8a10cadd384d52586895c6ed3be9033827f5b33
parentc979a3d0c45f141f2c728a994c3358f6e696519f (diff)
downloadgnurl-30c131f51f605d35e5d90f4be1727045fef17351.tar.gz
gnurl-30c131f51f605d35e5d90f4be1727045fef17351.tar.bz2
gnurl-30c131f51f605d35e5d90f4be1727045fef17351.zip
ssl: add server cert's "sha256//" hash to verbose
Add a "pinnedpubkey" section to the "Server Certificate" verbose Bug: https://github.com/bagder/curl/issues/410 Reported-by: W. Mark Kubacki Closes #430 Closes #410
-rw-r--r--lib/vtls/cyassl.c3
-rw-r--r--lib/vtls/gskit.c2
-rw-r--r--lib/vtls/gtls.c7
-rw-r--r--lib/vtls/nss.c3
-rw-r--r--lib/vtls/openssl.c7
-rw-r--r--lib/vtls/vtls.c43
-rw-r--r--lib/vtls/vtls.h3
7 files changed, 37 insertions, 31 deletions
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index 3ded7f11d..052996e14 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -434,7 +434,8 @@ cyassl_connect_step2(struct connectdata *conn,
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
}
- result = Curl_pin_peer_pubkey(data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+ result = Curl_pin_peer_pubkey(data,
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY],
(const unsigned char *)pubkey->header,
(size_t)(pubkey->end - pubkey->header));
if(result) {
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index d884bd4c4..a5b7ea203 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -874,7 +874,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
Curl_parseX509(&x509, cert, certend);
p = &x509.subjectPublicKeyInfo;
- result = Curl_pin_peer_pubkey(ptr, p->header, p->end - p->header);
+ result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header);
if(result) {
failf(data, "SSL: public key does not match pinned public key!");
return result;
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index c54dfc1d2..5f7041a30 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -724,7 +724,8 @@ gtls_connect_step1(struct connectdata *conn,
return CURLE_OK;
}
-static CURLcode pkp_pin_peer_pubkey(gnutls_x509_crt_t cert,
+static CURLcode pkp_pin_peer_pubkey(struct SessionHandle *data,
+ gnutls_x509_crt_t cert,
const char *pinnedpubkey)
{
/* Scratch */
@@ -769,7 +770,7 @@ static CURLcode pkp_pin_peer_pubkey(gnutls_x509_crt_t cert,
/* End Gyrations */
/* The one good exit point */
- result = Curl_pin_peer_pubkey(pinnedpubkey, buff1, len1);
+ result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
} while(0);
if(NULL != key)
@@ -1152,7 +1153,7 @@ gtls_connect_step3(struct connectdata *conn,
ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(ptr) {
- result = pkp_pin_peer_pubkey(x509_cert, ptr);
+ result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
if(result != CURLE_OK) {
failf(data, "SSL: public key does not match pinned public key!");
gnutls_x509_crt_deinit(x509_cert);
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 09214a52b..c8bd0cef6 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -973,8 +973,7 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
if(cert_der) {
/* compare the public key with the pinned public key */
- result = Curl_pin_peer_pubkey(pinnedpubkey,
- cert_der->data,
+ result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data,
cert_der->len);
SECITEM_FreeItem(cert_der, PR_TRUE);
}
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index a5103cd42..998ab2bac 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -2420,7 +2420,8 @@ static CURLcode get_cert_chain(struct connectdata *conn,
* Heavily modified from:
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
*/
-static CURLcode pkp_pin_peer_pubkey(X509* cert, const char *pinnedpubkey)
+static CURLcode pkp_pin_peer_pubkey(struct SessionHandle *data, X509* cert,
+ const char *pinnedpubkey)
{
/* Scratch */
int len1 = 0, len2 = 0;
@@ -2465,7 +2466,7 @@ static CURLcode pkp_pin_peer_pubkey(X509* cert, const char *pinnedpubkey)
/* End Gyrations */
/* The one good exit point */
- result = Curl_pin_peer_pubkey(pinnedpubkey, buff1, len1);
+ result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
} while(0);
/* https://www.openssl.org/docs/crypto/buffer.html */
@@ -2629,7 +2630,7 @@ static CURLcode servercert(struct connectdata *conn,
ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
- result = pkp_pin_peer_pubkey(connssl->server_cert, ptr);
+ result = pkp_pin_peer_pubkey(data, connssl->server_cert, ptr);
if(result)
failf(data, "SSL: public key does not match pinned public key!");
}
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 01bbc6130..692ff5c9e 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -765,7 +765,8 @@ static CURLcode pubkey_pem_to_der(const char *pem,
* Generic pinned public key check.
*/
-CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
+CURLcode Curl_pin_peer_pubkey(struct SessionHandle *data,
+ const char *pinnedpubkey,
const unsigned char *pubkey, size_t pubkeylen)
{
FILE *fp;
@@ -775,9 +776,10 @@ CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
CURLcode pem_read;
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
#ifdef curlssl_sha256sum
- size_t pinkeylen;
- char *pinkeycopy, *begin_pos, *end_pos;
- unsigned char *sha256sumdigest = NULL, *expectedsha256sumdigest = NULL;
+ CURLcode encode;
+ size_t encodedlen, pinkeylen;
+ char *encoded, *pinkeycopy, *begin_pos, *end_pos;
+ unsigned char *sha256sumdigest = NULL;
#endif
/* if a path wasn't specified, don't pin */
@@ -796,11 +798,21 @@ CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
curlssl_sha256sum(pubkey, pubkeylen,
sha256sumdigest, SHA256_DIGEST_LENGTH);
+ encode = Curl_base64_encode(data, (char *)sha256sumdigest,
+ SHA256_DIGEST_LENGTH, &encoded, &encodedlen);
+ Curl_safefree(sha256sumdigest);
+
+ if(!encode) {
+ infof(data, "\t pinnedpubkey: sha256//%s\n", encoded);
+ }
+ else
+ return encode;
+
/* it starts with sha256//, copy so we can modify it */
pinkeylen = strlen(pinnedpubkey) + 1;
pinkeycopy = malloc(pinkeylen);
if(!pinkeycopy) {
- Curl_safefree(sha256sumdigest);
+ Curl_safefree(encoded);
return CURLE_OUT_OF_MEMORY;
}
memcpy(pinkeycopy, pinnedpubkey, pinkeylen);
@@ -815,20 +827,11 @@ CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
if(end_pos)
end_pos[0] = '\0';
- /* decode base64 pinnedpubkey, 8 is length of "sha256//" */
- pem_read = Curl_base64_decode(begin_pos + 8,
- &expectedsha256sumdigest, &size);
- /* if not valid base64, don't bother comparing or freeing */
- if(!pem_read) {
- /* compare sha256 digests directly */
- if(SHA256_DIGEST_LENGTH == size &&
- !memcmp(sha256sumdigest, expectedsha256sumdigest,
- SHA256_DIGEST_LENGTH)) {
- result = CURLE_OK;
- Curl_safefree(expectedsha256sumdigest);
- break;
- }
- Curl_safefree(expectedsha256sumdigest);
+ /* compare base64 sha256 digests, 8 is the length of "sha256//" */
+ if(encodedlen == strlen(begin_pos + 8) &&
+ !memcmp(encoded, begin_pos + 8, encodedlen)) {
+ result = CURLE_OK;
+ break;
}
/*
@@ -840,7 +843,7 @@ CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
begin_pos = strstr(end_pos, "sha256//");
}
} while(end_pos && begin_pos);
- Curl_safefree(sha256sumdigest);
+ Curl_safefree(encoded);
Curl_safefree(pinkeycopy);
return result;
}
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index 2349e5b93..d6224903a 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -117,7 +117,8 @@ CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* Check pinned public key. */
-CURLcode Curl_pin_peer_pubkey(const char *pinnedpubkey,
+CURLcode Curl_pin_peer_pubkey(struct SessionHandle *data,
+ const char *pinnedpubkey,
const unsigned char *pubkey, size_t pubkeylen);
bool Curl_ssl_cert_status_request(void);