]> granicus.if.org Git - curl/commitdiff
mbedtls: implement CURLOPT_PINNEDPUBLICKEY
authorThomas Glanzmann <thomas@glanzmann.de>
Wed, 6 Jan 2016 06:00:11 +0000 (07:00 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Sat, 9 Jan 2016 23:17:26 +0000 (00:17 +0100)
docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
lib/vtls/mbedtls.c
lib/vtls/mbedtls.h

index 80397f716d9bb755e883770ec3cd3b98d9ddfd08..bae1eaa72d3779b0918a2b9d4a0af0ca0361f345 100644 (file)
@@ -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.
index cfebedf5337e0d75d0895d4142a1f4b044ae8b45..05af462129c47684ebfa2978bd7106652922ed70 100644 (file)
@@ -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;
index b930c10006cf0f1abc96c02d7c7e7452624ba536..de386285df9f571f0e2581e7de7870863f6886d2 100644 (file)
@@ -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