aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Glanzmann <thomas@glanzmann.de>2016-01-06 07:00:11 +0100
committerDaniel Stenberg <daniel@haxx.se>2016-01-10 00:17:26 +0100
commitbf93a1217ce3cc336d75a3b0cb0c1a7ed6a05cb3 (patch)
treea0343d959a69b4396b3260dd1d761cc453556ac7
parent5da7461a55ea681829820d8268728e88b7ceb3f6 (diff)
mbedtls: implement CURLOPT_PINNEDPUBLICKEY
-rw-r--r--docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.35
-rw-r--r--lib/vtls/mbedtls.c53
-rw-r--r--lib/vtls/mbedtls.h2
3 files changed, 57 insertions, 3 deletions
diff --git a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
index 80397f716..bae1eaa72 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 cfebedf53..05af46212 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2016, 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
@@ -141,6 +141,53 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
1024, /* RSA min key len */
};
+/* See https://tls.mbed.org/discussions/generic/
+ howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
+*/
+#define RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
+#define ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
+
+#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+ RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
+
+static int
+mbedtls_verify_pinned_crt(void *p, mbedtls_x509_crt *crt,
+ int depth, unsigned int *flags)
+{
+ struct SessionHandle *data = p;
+ unsigned char pubkey[PUB_DER_MAX_BYTES];
+ int ret;
+ int size;
+ 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, PUB_DER_MAX_BYTES);
+ 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[PUB_DER_MAX_BYTES - 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;
@@ -636,6 +683,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 b930c1000..de386285d 100644
--- a/lib/vtls/mbedtls.h
+++ b/lib/vtls/mbedtls.h
@@ -7,6 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
+ * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
@@ -63,6 +64,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