aboutsummaryrefslogtreecommitdiff
path: root/lib/vtls/cyassl.c
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2015-04-05 01:48:16 -0400
committerJay Satiro <raysatiro@yahoo.com>2015-04-22 17:07:19 -0400
commit0675abbc7572ff6d711a1f325d9b812f98bce78f (patch)
tree8e9ab2f345f2ccc8405e941560cae58d4ac69850 /lib/vtls/cyassl.c
parent26cbd7a1d94d0d0ddb7923bfa2a6771154c93334 (diff)
cyassl: Implement public key pinning
Also add public key extraction example to CURLOPT_PINNEDPUBLICKEY doc.
Diffstat (limited to 'lib/vtls/cyassl.c')
-rw-r--r--lib/vtls/cyassl.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index 4d0a23f23..40dbbe134 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -57,6 +57,7 @@ and that's a problem since options.h hasn't been included yet. */
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "rawstr.h"
+#include "x509asn1.h"
#include "curl_printf.h"
#include <cyassl/ssl.h>
@@ -403,6 +404,44 @@ cyassl_connect_step2(struct connectdata *conn,
}
}
+ if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
+ X509 *x509;
+ const char *x509_der;
+ int x509_der_len;
+ curl_X509certificate x509_parsed;
+ curl_asn1Element *pubkey;
+ CURLcode result;
+
+ x509 = SSL_get_peer_certificate(conssl->handle);
+ if(!x509) {
+ failf(data, "SSL: failed retrieving server certificate");
+ return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ }
+
+ x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
+ if(!x509_der) {
+ failf(data, "SSL: failed retrieving ASN.1 server certificate");
+ return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ }
+
+ memset(&x509_parsed, 0, sizeof x509_parsed);
+ Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len);
+
+ pubkey = &x509_parsed.subjectPublicKeyInfo;
+ if(!pubkey->header || pubkey->end <= pubkey->header) {
+ failf(data, "SSL: failed retrieving public key from server certificate");
+ return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+ }
+
+ result = Curl_pin_peer_pubkey(data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+ (const unsigned char *)pubkey->header,
+ (size_t)(pubkey->end - pubkey->header));
+ if(result) {
+ failf(data, "SSL: public key does not match pinned public key!");
+ return result;
+ }
+ }
+
conssl->connecting_state = ssl_connect_3;
infof(data, "SSL connected\n");