curl-library
[PATCH] mbedtls: Implement CURLOPT_PINNEDPUBLICKEY
From: Thomas Glanzmann <thomas_at_glanzmann.de>
Date: Mon, 28 Dec 2015 23:46:32 +0100
Date: Mon, 28 Dec 2015 23:46:32 +0100
--- docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 | 5 ++-- lib/vtls/mbedtls.c | 42 +++++++++++++++++++++++++++++ lib/vtls/mbedtls.h | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 index 80397f7..bae1eaa 100644 --- a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 +++ b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 @@ -91,8 +91,9 @@ footer: .fi .SH AVAILABILITY Added in 7.39.0 for OpenSSL, GnuTLS and GSKit. Added in 7.43.0 for -NSS and wolfSSL/CyaSSL. sha256 support added in 7.44.0 for OpenSSL, -GnuTLS, NSS and wolfSSL/CyaSSL. Other SSL backends not supported. +NSS and wolfSSL/CyaSSL. Added for mbedtls in 7.47.0, sha256 support +added in 7.44.0 for OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL. Other +SSL backends not supported. .SH RETURN VALUE Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or CURLE_OUT_OF_MEMORY if there was insufficient heap space. diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index b9976b1..a6106fb 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -186,6 +186,44 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr = 1024, /* RSA min key len */ }; +static int +mbedtls_verify_pinned_crt(void *p, mbedtls_x509_crt *crt, + int depth, unsigned int *flags) +{ + struct SessionHandle *data = p; + unsigned char pubkey[1024]; + unsigned int i; + int ret; + int size; + unsigned char *pinned_cert = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + /* Skip intermediate and root certificates */ + if (depth){ + return 0; + } + + if(pinned_cert == NULL || crt == NULL) { + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + return 1; + } + + /* Extract pubkey */ + size = mbedtls_pk_write_pubkey_der(&crt->pk, pubkey, 1024); + if(size <= 0) { + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + return 1; + } + + /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer */ + ret = Curl_pin_peer_pubkey(data, pinned_cert, &pubkey[1024 - size], size); + if(ret == CURLE_OK) { + return 0; + } + + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + return 1; +} + static Curl_recv mbedtls_recv; static Curl_send mbedtls_send; @@ -683,6 +721,10 @@ mbedtls_connect_common(struct connectdata *conn, long timeout_ms; int what; + if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { + mbedtls_ssl_conf_verify(&connssl->config, mbedtls_verify_pinned_crt, data); + } + /* check if the connection has already been established */ if(ssl_connection_complete == connssl->state) { *done = TRUE; diff --git a/lib/vtls/mbedtls.h b/lib/vtls/mbedtls.h index b930c10..3cb0dec 100644 --- a/lib/vtls/mbedtls.h +++ b/lib/vtls/mbedtls.h @@ -63,6 +63,7 @@ int Curl_mbedtls_shutdown(struct connectdata *conn, int sockindex); #define curlssl_check_cxn(x) (x=x, -1) #define curlssl_data_pending(x,y) (x=x, y=y, 0) #define CURL_SSL_BACKEND CURLSSLBACKEND_MBEDTLS +#define curlssl_sha256sum(a,b,c,d) mbedtls_sha256(a,b,c,0) /* This might cause libcurl to use a weeker random! TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that -- 2.1.4 ------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.htmlReceived on 2015-12-29