mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
parent
72646c2e48
commit
fe7590f729
91
configure.ac
91
configure.ac
@ -149,7 +149,7 @@ AC_SUBST(PKGADD_VENDOR)
|
|||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl initialize all the info variables
|
dnl initialize all the info variables
|
||||||
curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,cyassl,axtls,winssl,darwinssl} )"
|
curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,mbedtls,cyassl,axtls,winssl,darwinssl} )"
|
||||||
curl_ssh_msg="no (--with-libssh2)"
|
curl_ssh_msg="no (--with-libssh2)"
|
||||||
curl_zlib_msg="no (--with-zlib)"
|
curl_zlib_msg="no (--with-zlib)"
|
||||||
curl_gss_msg="no (--with-gssapi)"
|
curl_gss_msg="no (--with-gssapi)"
|
||||||
@ -1976,6 +1976,93 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ----------------------------------------------------
|
||||||
|
dnl check for mbedTLS
|
||||||
|
dnl ----------------------------------------------------
|
||||||
|
|
||||||
|
OPT_MBEDTLS=no
|
||||||
|
|
||||||
|
_cppflags=$CPPFLAGS
|
||||||
|
_ldflags=$LDFLAGS
|
||||||
|
AC_ARG_WITH(mbedtls,dnl
|
||||||
|
AC_HELP_STRING([--with-mbedtls=PATH],[where to look for mbedTLS, PATH points to the installation root])
|
||||||
|
AC_HELP_STRING([--without-mbedtls], [disable mbedTLS detection]),
|
||||||
|
OPT_MBEDTLS=$withval)
|
||||||
|
|
||||||
|
if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
||||||
|
|
||||||
|
if test X"$OPT_MBEDTLS" != Xno; then
|
||||||
|
|
||||||
|
if test "$OPT_MBEDTLS" = "yes"; then
|
||||||
|
OPT_MBEDTLS=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$OPT_MBEDTLS" ; then
|
||||||
|
dnl check for lib first without setting any new path
|
||||||
|
|
||||||
|
AC_CHECK_LIB(mbedtls, mbedtls_havege_init,
|
||||||
|
dnl libmbedtls found, set the variable
|
||||||
|
[
|
||||||
|
AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled])
|
||||||
|
AC_SUBST(USE_MBEDTLS, [1])
|
||||||
|
MBEDTLS_ENABLED=1
|
||||||
|
USE_MBEDTLS="yes"
|
||||||
|
curl_ssl_msg="enabled (mbedTLS)"
|
||||||
|
], [], -lmbedx509 -lmbedcrypto)
|
||||||
|
fi
|
||||||
|
|
||||||
|
addld=""
|
||||||
|
addlib=""
|
||||||
|
addcflags=""
|
||||||
|
mbedtlslib=""
|
||||||
|
|
||||||
|
if test "x$USE_MBEDTLS" != "xyes"; then
|
||||||
|
dnl add the path and test again
|
||||||
|
addld=-L$OPT_MBEDTLS/lib$libsuff
|
||||||
|
addcflags=-I$OPT_MBEDTLS/include
|
||||||
|
mbedtlslib=$OPT_MBEDTLS/lib$libsuff
|
||||||
|
|
||||||
|
LDFLAGS="$LDFLAGS $addld"
|
||||||
|
if test "$addcflags" != "-I/usr/include"; then
|
||||||
|
CPPFLAGS="$CPPFLAGS $addcflags"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_LIB(mbedtls, mbedtls_ssl_init,
|
||||||
|
[
|
||||||
|
AC_DEFINE(USE_MBEDTLS, 1, [if mbedTLS is enabled])
|
||||||
|
AC_SUBST(USE_MBEDTLS, [1])
|
||||||
|
MBEDTLS_ENABLED=1
|
||||||
|
USE_MBEDTLS="yes"
|
||||||
|
curl_ssl_msg="enabled (mbedTLS)"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
CPPFLAGS=$_cppflags
|
||||||
|
LDFLAGS=$_ldflags
|
||||||
|
], -lmbedx509 -lmbedcrypto)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$USE_MBEDTLS" = "xyes"; then
|
||||||
|
AC_MSG_NOTICE([detected mbedTLS])
|
||||||
|
|
||||||
|
LIBS="-lmbedtls -lmbedx509 -lmbedcrypto $LIBS"
|
||||||
|
|
||||||
|
if test -n "$mbedtlslib"; then
|
||||||
|
dnl when shared libs were found in a path that the run-time
|
||||||
|
dnl linker doesn't search through, we need to add it to
|
||||||
|
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
||||||
|
dnl due to this
|
||||||
|
if test "x$cross_compiling" != "xyes"; then
|
||||||
|
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$mbedtlslib"
|
||||||
|
export LD_LIBRARY_PATH
|
||||||
|
AC_MSG_NOTICE([Added $mbedtlslib to LD_LIBRARY_PATH])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi dnl mbedTLS not disabled
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
dnl ----------------------------------------------------
|
dnl ----------------------------------------------------
|
||||||
dnl check for CyaSSL
|
dnl check for CyaSSL
|
||||||
dnl ----------------------------------------------------
|
dnl ----------------------------------------------------
|
||||||
@ -2300,7 +2387,7 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$POLARSSL_ENABLED$AXTLS_ENABLED$CYASSL_ENABLED$WINSSL_ENABLED$DARWINSSL_ENABLED" = "x"; then
|
if test "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$POLARSSL_ENABLED$MBEDTLS_ENABLED$AXTLS_ENABLED$CYASSL_ENABLED$WINSSL_ENABLED$DARWINSSL_ENABLED" = "x"; then
|
||||||
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.])
|
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.])
|
||||||
AC_MSG_WARN([Use --with-ssl, --with-gnutls, --with-polarssl, --with-cyassl, --with-nss, --with-axtls, --with-winssl, or --with-darwinssl to address this.])
|
AC_MSG_WARN([Use --with-ssl, --with-gnutls, --with-polarssl, --with-cyassl, --with-nss, --with-axtls, --with-winssl, or --with-darwinssl to address this.])
|
||||||
else
|
else
|
||||||
|
@ -629,6 +629,7 @@ CURLSSLBACKEND_CYASSL 7.34.0
|
|||||||
CURLSSLBACKEND_DARWINSSL 7.34.0
|
CURLSSLBACKEND_DARWINSSL 7.34.0
|
||||||
CURLSSLBACKEND_GNUTLS 7.34.0
|
CURLSSLBACKEND_GNUTLS 7.34.0
|
||||||
CURLSSLBACKEND_GSKIT 7.34.0
|
CURLSSLBACKEND_GSKIT 7.34.0
|
||||||
|
CURLSSLBACKEND_MBEDTLS 7.46.0
|
||||||
CURLSSLBACKEND_NONE 7.34.0
|
CURLSSLBACKEND_NONE 7.34.0
|
||||||
CURLSSLBACKEND_NSS 7.34.0
|
CURLSSLBACKEND_NSS 7.34.0
|
||||||
CURLSSLBACKEND_OPENSSL 7.34.0
|
CURLSSLBACKEND_OPENSSL 7.34.0
|
||||||
|
@ -2076,7 +2076,8 @@ typedef enum {
|
|||||||
CURLSSLBACKEND_CYASSL = 7,
|
CURLSSLBACKEND_CYASSL = 7,
|
||||||
CURLSSLBACKEND_SCHANNEL = 8,
|
CURLSSLBACKEND_SCHANNEL = 8,
|
||||||
CURLSSLBACKEND_DARWINSSL = 9,
|
CURLSSLBACKEND_DARWINSSL = 9,
|
||||||
CURLSSLBACKEND_AXTLS = 10
|
CURLSSLBACKEND_AXTLS = 10,
|
||||||
|
CURLSSLBACKEND_MBEDTLS = 11
|
||||||
} curl_sslbackend;
|
} curl_sslbackend;
|
||||||
|
|
||||||
/* Information about the SSL library used and the respective internal SSL
|
/* Information about the SSL library used and the respective internal SSL
|
||||||
|
@ -22,11 +22,13 @@
|
|||||||
|
|
||||||
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
|
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
|
||||||
vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
|
vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
|
||||||
vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c
|
vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c \
|
||||||
|
vtls/mbedtls.c
|
||||||
|
|
||||||
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
||||||
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \
|
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \
|
||||||
vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h
|
vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \
|
||||||
|
vtls/mbedtls.h
|
||||||
|
|
||||||
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||||
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
||||||
|
@ -605,7 +605,7 @@ int netware_init(void);
|
|||||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||||
|
|
||||||
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
|
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
|
||||||
defined(USE_POLARSSL) || defined(USE_AXTLS) || \
|
defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \
|
||||||
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
||||||
defined(USE_DARWINSSL) || defined(USE_GSKIT)
|
defined(USE_DARWINSSL) || defined(USE_GSKIT)
|
||||||
#define USE_SSL /* SSL support has been enabled */
|
#define USE_SSL /* SSL support has been enabled */
|
||||||
|
@ -1394,7 +1394,8 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
|
#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
|
||||||
defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS)
|
defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
|
||||||
|
defined(USE_MBEDTLS)
|
||||||
/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
|
/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
|
||||||
It should be made to query the generic SSL layer instead. */
|
It should be made to query the generic SSL layer instead. */
|
||||||
static int https_getsock(struct connectdata *conn,
|
static int https_getsock(struct connectdata *conn,
|
||||||
|
@ -93,7 +93,15 @@
|
|||||||
#include <gnutls/gnutls.h>
|
#include <gnutls/gnutls.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_POLARSSL
|
#ifdef USE_MBEDTLS
|
||||||
|
|
||||||
|
#include <mbedtls/ssl.h>
|
||||||
|
#include <mbedtls/version.h>
|
||||||
|
#include <mbedtls/entropy.h>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
|
||||||
|
#elif defined USE_POLARSSL
|
||||||
|
|
||||||
#include <polarssl/ssl.h>
|
#include <polarssl/ssl.h>
|
||||||
#include <polarssl/version.h>
|
#include <polarssl/version.h>
|
||||||
#if POLARSSL_VERSION_NUMBER<0x01010000
|
#if POLARSSL_VERSION_NUMBER<0x01010000
|
||||||
@ -102,6 +110,7 @@
|
|||||||
#include <polarssl/entropy.h>
|
#include <polarssl/entropy.h>
|
||||||
#include <polarssl/ctr_drbg.h>
|
#include <polarssl/ctr_drbg.h>
|
||||||
#endif /* POLARSSL_VERSION_NUMBER<0x01010000 */
|
#endif /* POLARSSL_VERSION_NUMBER<0x01010000 */
|
||||||
|
|
||||||
#endif /* USE_POLARSSL */
|
#endif /* USE_POLARSSL */
|
||||||
|
|
||||||
#ifdef USE_CYASSL
|
#ifdef USE_CYASSL
|
||||||
@ -280,6 +289,19 @@ struct ssl_connect_data {
|
|||||||
#endif
|
#endif
|
||||||
ssl_connect_state connecting_state;
|
ssl_connect_state connecting_state;
|
||||||
#endif /* USE_GNUTLS */
|
#endif /* USE_GNUTLS */
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ssl_context ssl;
|
||||||
|
mbedtls_ssl_session ssn;
|
||||||
|
int server_fd;
|
||||||
|
mbedtls_x509_crt cacert;
|
||||||
|
mbedtls_x509_crt clicert;
|
||||||
|
mbedtls_x509_crl crl;
|
||||||
|
mbedtls_pk_context pk;
|
||||||
|
ssl_connect_state connecting_state;
|
||||||
|
mbedtls_ssl_config config;
|
||||||
|
#endif /* USE_MBEDTLS */
|
||||||
#ifdef USE_POLARSSL
|
#ifdef USE_POLARSSL
|
||||||
ctr_drbg_context ctr_drbg;
|
ctr_drbg_context ctr_drbg;
|
||||||
entropy_context entropy;
|
entropy_context entropy;
|
||||||
|
753
lib/vtls/mbedtls.c
Normal file
753
lib/vtls/mbedtls.c
Normal file
@ -0,0 +1,753 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||||
|
* Copyright (C) 2012 - 2015, 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
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Source file for all mbedTSL-specific code for the TLS/SSL layer. No code
|
||||||
|
* but vtls.c should ever call or use these functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "curl_setup.h"
|
||||||
|
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
|
||||||
|
#include <mbedtls/net.h>
|
||||||
|
#include <mbedtls/ssl.h>
|
||||||
|
#include <mbedtls/certs.h>
|
||||||
|
#include <mbedtls/x509.h>
|
||||||
|
#include <mbedtls/version.h>
|
||||||
|
|
||||||
|
#include <mbedtls/error.h>
|
||||||
|
#include <mbedtls/entropy.h>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "sendf.h"
|
||||||
|
#include "inet_pton.h"
|
||||||
|
#include "mbedtls.h"
|
||||||
|
#include "vtls.h"
|
||||||
|
#include "parsedate.h"
|
||||||
|
#include "connect.h" /* for the connect timeout */
|
||||||
|
#include "select.h"
|
||||||
|
#include "rawstr.h"
|
||||||
|
#include "polarssl_threadlock.h"
|
||||||
|
|
||||||
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
|
#include <curl/mprintf.h>
|
||||||
|
#include "curl_memory.h"
|
||||||
|
/* The last #include file should be: */
|
||||||
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
/* apply threading? */
|
||||||
|
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||||
|
#define THREADING_SUPPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(THREADING_SUPPORT)
|
||||||
|
static mbedtls_entropy_context entropy;
|
||||||
|
|
||||||
|
static int entropy_init_initialized = 0;
|
||||||
|
|
||||||
|
/* start of entropy_init_mutex() */
|
||||||
|
static void entropy_init_mutex(mbedtls_entropy_context *ctx)
|
||||||
|
{
|
||||||
|
/* lock 0 = entropy_init_mutex() */
|
||||||
|
polarsslthreadlock_lock_function(0);
|
||||||
|
if(entropy_init_initialized == 0) {
|
||||||
|
mbedtls_entropy_init(ctx);
|
||||||
|
entropy_init_initialized = 1;
|
||||||
|
}
|
||||||
|
polarsslthreadlock_unlock_function(0);
|
||||||
|
}
|
||||||
|
/* end of entropy_init_mutex() */
|
||||||
|
|
||||||
|
/* start of entropy_func_mutex() */
|
||||||
|
static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
/* lock 1 = entropy_func_mutex() */
|
||||||
|
polarsslthreadlock_lock_function(1);
|
||||||
|
ret = mbedtls_entropy_func(data, output, len);
|
||||||
|
polarsslthreadlock_unlock_function(1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* end of entropy_func_mutex() */
|
||||||
|
|
||||||
|
#endif /* THREADING_SUPPORT */
|
||||||
|
|
||||||
|
/* Define this to enable lots of debugging for mbedTLS */
|
||||||
|
#undef MBEDTLS_DEBUG
|
||||||
|
|
||||||
|
#ifdef MBEDTLS_DEBUG
|
||||||
|
static void mbedtls_debug(void *context, int level, const char *line)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data = NULL;
|
||||||
|
|
||||||
|
if(!context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
data = (struct SessionHandle *)context;
|
||||||
|
|
||||||
|
infof(data, "%s", line);
|
||||||
|
(void) level;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ALPN for http2? */
|
||||||
|
#ifdef USE_NGHTTP2
|
||||||
|
# undef HAS_ALPN
|
||||||
|
# ifdef MBEDTLS_SSL_ALPN
|
||||||
|
# define HAS_ALPN
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static Curl_recv mbedtls_recv;
|
||||||
|
static Curl_send mbedtls_send;
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
mbedtls_connect_step1(struct connectdata *conn,
|
||||||
|
int sockindex)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
|
||||||
|
|
||||||
|
bool sni = TRUE; /* default is SNI enabled */
|
||||||
|
int ret = -1;
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct in6_addr addr;
|
||||||
|
#else
|
||||||
|
struct in_addr addr;
|
||||||
|
#endif
|
||||||
|
void *old_session = NULL;
|
||||||
|
size_t old_session_size = 0;
|
||||||
|
char errorbuf[128];
|
||||||
|
errorbuf[0]=0;
|
||||||
|
|
||||||
|
/* mbedTLS only supports SSLv3 and TLSv1 */
|
||||||
|
if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
|
||||||
|
failf(data, "mbedTLS does not support SSLv2");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
|
||||||
|
sni = FALSE; /* SSLv3 has no SNI */
|
||||||
|
|
||||||
|
#ifdef THREADING_SUPPORT
|
||||||
|
entropy_init_mutex(&entropy);
|
||||||
|
|
||||||
|
if((ret = mbedtls_ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex,
|
||||||
|
&entropy, connssl->ssn.id,
|
||||||
|
connssl->ssn.length)) != 0) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
|
||||||
|
-ret, errorbuf);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
mbedtls_entropy_init(&connssl->entropy);
|
||||||
|
mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
|
||||||
|
|
||||||
|
ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func,
|
||||||
|
&connssl->entropy, connssl->ssn.id,
|
||||||
|
connssl->ssn.id_len);
|
||||||
|
if(ret) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
|
||||||
|
-ret, errorbuf);
|
||||||
|
}
|
||||||
|
#endif /* THREADING_SUPPORT */
|
||||||
|
|
||||||
|
/* Load the trusted CA */
|
||||||
|
memset(&connssl->cacert, 0, sizeof(mbedtls_x509_crt));
|
||||||
|
|
||||||
|
if(data->set.str[STRING_SSL_CAFILE]) {
|
||||||
|
ret = mbedtls_x509_crt_parse_file(&connssl->cacert,
|
||||||
|
data->set.str[STRING_SSL_CAFILE]);
|
||||||
|
|
||||||
|
if(ret<0) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
|
||||||
|
data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
|
||||||
|
|
||||||
|
if(data->set.ssl.verifypeer)
|
||||||
|
return CURLE_SSL_CACERT_BADFILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data->set.str[STRING_SSL_CAPATH]) {
|
||||||
|
ret = mbedtls_x509_crt_parse_path(&connssl->cacert,
|
||||||
|
data->set.str[STRING_SSL_CAPATH]);
|
||||||
|
|
||||||
|
if(ret<0) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
|
||||||
|
data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
|
||||||
|
|
||||||
|
if(data->set.ssl.verifypeer)
|
||||||
|
return CURLE_SSL_CACERT_BADFILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the client certificate */
|
||||||
|
memset(&connssl->clicert, 0, sizeof(mbedtls_x509_crt));
|
||||||
|
|
||||||
|
if(data->set.str[STRING_CERT]) {
|
||||||
|
ret = mbedtls_x509_crt_parse_file(&connssl->clicert,
|
||||||
|
data->set.str[STRING_CERT]);
|
||||||
|
|
||||||
|
if(ret) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
|
||||||
|
data->set.str[STRING_CERT], -ret, errorbuf);
|
||||||
|
|
||||||
|
return CURLE_SSL_CERTPROBLEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the client private key */
|
||||||
|
if(data->set.str[STRING_KEY]) {
|
||||||
|
mbedtls_pk_init(&connssl->pk);
|
||||||
|
ret = mbedtls_pk_parse_keyfile(&connssl->pk, data->set.str[STRING_KEY],
|
||||||
|
data->set.str[STRING_KEY_PASSWD]);
|
||||||
|
if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA))
|
||||||
|
ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||||
|
|
||||||
|
if(ret) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
|
||||||
|
data->set.str[STRING_KEY], -ret, errorbuf);
|
||||||
|
|
||||||
|
return CURLE_SSL_CERTPROBLEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the CRL */
|
||||||
|
memset(&connssl->crl, 0, sizeof(mbedtls_x509_crl));
|
||||||
|
|
||||||
|
if(data->set.str[STRING_SSL_CRLFILE]) {
|
||||||
|
ret = mbedtls_x509_crl_parse_file(&connssl->crl,
|
||||||
|
data->set.str[STRING_SSL_CRLFILE]);
|
||||||
|
|
||||||
|
if(ret) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
|
||||||
|
data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
|
||||||
|
|
||||||
|
return CURLE_SSL_CRL_BADFILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
infof(data, "mbedTLS: Connecting to %s:%d\n",
|
||||||
|
conn->host.name, conn->remote_port);
|
||||||
|
|
||||||
|
|
||||||
|
mbedtls_ssl_config_init(&connssl->config);
|
||||||
|
|
||||||
|
mbedtls_ssl_init(&connssl->ssl);
|
||||||
|
if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) {
|
||||||
|
failf(data, "mbedTLS: ssl_init failed");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
ret = mbedtls_ssl_config_defaults(&connssl->config,
|
||||||
|
MBEDTLS_SSL_IS_CLIENT,
|
||||||
|
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||||
|
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||||
|
if(ret) {
|
||||||
|
failf(data, "mbedTLS: ssl_config failed");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(data->set.ssl.version) {
|
||||||
|
case CURL_SSLVERSION_SSLv3:
|
||||||
|
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||||
|
MBEDTLS_SSL_MINOR_VERSION_0);
|
||||||
|
infof(data, "mbedTLS: Forced min. SSL Version to be SSLv3\n");
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||||
|
MBEDTLS_SSL_MINOR_VERSION_1);
|
||||||
|
infof(data, "mbedTLS: Forced min. SSL Version to be TLS 1.0\n");
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||||
|
MBEDTLS_SSL_MINOR_VERSION_2);
|
||||||
|
infof(data, "mbedTLS: Forced min. SSL Version to be TLS 1.1\n");
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||||
|
MBEDTLS_SSL_MINOR_VERSION_3);
|
||||||
|
infof(data, "mbedTLS: Forced min. SSL Version to be TLS 1.2\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||||
|
|
||||||
|
mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random,
|
||||||
|
&connssl->ctr_drbg);
|
||||||
|
mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex],
|
||||||
|
mbedtls_net_send,
|
||||||
|
mbedtls_net_recv,
|
||||||
|
NULL /* rev_timeout() */);
|
||||||
|
|
||||||
|
mbedtls_ssl_conf_ciphersuites(&connssl->config,
|
||||||
|
mbedtls_ssl_list_ciphersuites());
|
||||||
|
if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) {
|
||||||
|
memcpy(&connssl->ssn, old_session, old_session_size);
|
||||||
|
infof(data, "mbedTLS re-using session\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_ssl_set_session(&connssl->ssl,
|
||||||
|
&connssl->ssn);
|
||||||
|
|
||||||
|
mbedtls_ssl_conf_ca_chain(&connssl->config,
|
||||||
|
&connssl->cacert,
|
||||||
|
&connssl->crl);
|
||||||
|
|
||||||
|
if(data->set.str[STRING_KEY]) {
|
||||||
|
mbedtls_ssl_conf_own_cert(&connssl->config,
|
||||||
|
&connssl->clicert, &connssl->pk);
|
||||||
|
}
|
||||||
|
if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) &&
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
!Curl_inet_pton(AF_INET6, conn->host.name, &addr) &&
|
||||||
|
#endif
|
||||||
|
sni && mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) {
|
||||||
|
infof(data, "WARNING: failed to configure "
|
||||||
|
"server name indication (SNI) TLS extension\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_ALPN
|
||||||
|
if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
|
||||||
|
if(data->set.ssl_enable_alpn) {
|
||||||
|
static const char* protocols[] = {
|
||||||
|
NGHTTP2_PROTO_VERSION_ID, ALPN_HTTP_1_1, NULL
|
||||||
|
};
|
||||||
|
mbedtls_ssl_conf_alpn_protocols(&connssl->config, protocols);
|
||||||
|
infof(data, "ALPN, offering %s, %s\n", protocols[0],
|
||||||
|
protocols[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MBEDTLS_DEBUG
|
||||||
|
mbedtls_ssl_conf_dbg(&connssl->ssl, mbedtls_debug, data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
connssl->connecting_state = ssl_connect_2;
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
mbedtls_connect_step2(struct connectdata *conn,
|
||||||
|
int sockindex)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
|
||||||
|
char buffer[1024];
|
||||||
|
|
||||||
|
#ifdef HAS_ALPN
|
||||||
|
const char* next_protocol;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char errorbuf[128];
|
||||||
|
errorbuf[0] = 0;
|
||||||
|
|
||||||
|
conn->recv[sockindex] = mbedtls_recv;
|
||||||
|
conn->send[sockindex] = mbedtls_send;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
if(!(ret = mbedtls_ssl_handshake(&connssl->ssl)))
|
||||||
|
break;
|
||||||
|
else if(ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||||
|
ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||||
|
#ifdef MBEDTLS_ERROR_C
|
||||||
|
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||||
|
#endif /* MBEDTLS_ERROR_C */
|
||||||
|
failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s",
|
||||||
|
-ret, errorbuf);
|
||||||
|
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||||
|
connssl->connecting_state = ssl_connect_2_reading;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||||
|
connssl->connecting_state = ssl_connect_2_writing;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
failf(data, "SSL_connect failed with error %d.", ret);
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
|
||||||
|
mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
|
||||||
|
);
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl);
|
||||||
|
|
||||||
|
if(ret && data->set.ssl.verifypeer) {
|
||||||
|
if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
|
||||||
|
failf(data, "Cert verify failed: BADCERT_EXPIRED");
|
||||||
|
|
||||||
|
if(ret & MBEDTLS_X509_BADCERT_REVOKED) {
|
||||||
|
failf(data, "Cert verify failed: BADCERT_REVOKED");
|
||||||
|
return CURLE_SSL_CACERT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
|
||||||
|
failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
|
||||||
|
|
||||||
|
if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
|
||||||
|
failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
|
||||||
|
|
||||||
|
return CURLE_PEER_FAILED_VERIFICATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mbedtls_ssl_get_peer_cert(&(connssl->ssl))) {
|
||||||
|
/* If the session was resumed, there will be no peer certs */
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
|
if(mbedtls_x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
|
||||||
|
mbedtls_ssl_get_peer_cert(&(connssl->ssl))) != -1)
|
||||||
|
infof(data, "Dumping cert info:\n%s\n", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_ALPN
|
||||||
|
if(data->set.ssl_enable_alpn) {
|
||||||
|
next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl);
|
||||||
|
|
||||||
|
if(next_protocol != NULL) {
|
||||||
|
infof(data, "ALPN, server accepted to use %s\n", next_protocol);
|
||||||
|
|
||||||
|
if(strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
|
||||||
|
NGHTTP2_PROTO_VERSION_ID_LEN)) {
|
||||||
|
conn->negnpn = CURL_HTTP_VERSION_2_0;
|
||||||
|
}
|
||||||
|
else if(strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
|
||||||
|
conn->negnpn = CURL_HTTP_VERSION_1_1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infof(data, "ALPN, server did not agree to a protocol\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
connssl->connecting_state = ssl_connect_3;
|
||||||
|
infof(data, "SSL connected\n");
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
mbedtls_connect_step3(struct connectdata *conn,
|
||||||
|
int sockindex)
|
||||||
|
{
|
||||||
|
CURLcode retcode = CURLE_OK;
|
||||||
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
void *old_ssl_sessionid = NULL;
|
||||||
|
mbedtls_ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn;
|
||||||
|
int incache;
|
||||||
|
|
||||||
|
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||||
|
|
||||||
|
/* Save the current session data for possible re-use */
|
||||||
|
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
|
||||||
|
if(incache) {
|
||||||
|
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||||
|
infof(data, "old SSL session ID is stale, removing\n");
|
||||||
|
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
||||||
|
incache = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!incache) {
|
||||||
|
void *new_session = malloc(sizeof(mbedtls_ssl_session));
|
||||||
|
|
||||||
|
if(new_session) {
|
||||||
|
memcpy(new_session, our_ssl_sessionid,
|
||||||
|
sizeof(mbedtls_ssl_session));
|
||||||
|
|
||||||
|
retcode = Curl_ssl_addsessionid(conn, new_session,
|
||||||
|
sizeof(mbedtls_ssl_session));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
retcode = CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(retcode) {
|
||||||
|
failf(data, "failed to store ssl session");
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connssl->connecting_state = ssl_connect_done;
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t mbedtls_send(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
const void *mem,
|
||||||
|
size_t len,
|
||||||
|
CURLcode *curlcode)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
ret = mbedtls_ssl_write(&conn->ssl[sockindex].ssl,
|
||||||
|
(unsigned char *)mem, len);
|
||||||
|
|
||||||
|
if(ret < 0) {
|
||||||
|
*curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
|
||||||
|
CURLE_AGAIN : CURLE_SEND_ERROR;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_mbedtls_close_all(struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
|
||||||
|
{
|
||||||
|
/* mbedtls_rsa_free(&conn->ssl[sockindex].rsa); */
|
||||||
|
mbedtls_x509_crt_free(&conn->ssl[sockindex].clicert);
|
||||||
|
mbedtls_x509_crt_free(&conn->ssl[sockindex].cacert);
|
||||||
|
mbedtls_x509_crl_free(&conn->ssl[sockindex].crl);
|
||||||
|
mbedtls_ssl_free(&conn->ssl[sockindex].ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t mbedtls_recv(struct connectdata *conn,
|
||||||
|
int num,
|
||||||
|
char *buf,
|
||||||
|
size_t buffersize,
|
||||||
|
CURLcode *curlcode)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
ssize_t len = -1;
|
||||||
|
|
||||||
|
memset(buf, 0, buffersize);
|
||||||
|
ret = mbedtls_ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf,
|
||||||
|
buffersize);
|
||||||
|
|
||||||
|
if(ret <= 0) {
|
||||||
|
if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ?
|
||||||
|
CURLE_AGAIN : CURLE_RECV_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ret;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curl_mbedtls_session_free(void *ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Curl_mbedtls_version(char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
unsigned int version = mbedtls_version_get_number();
|
||||||
|
return snprintf(buffer, size, "mbedTLS/%d.%d.%d", version>>24,
|
||||||
|
(version>>16)&0xff, (version>>8)&0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
mbedtls_connect_common(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
bool nonblocking,
|
||||||
|
bool *done)
|
||||||
|
{
|
||||||
|
CURLcode retcode;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
curl_socket_t sockfd = conn->sock[sockindex];
|
||||||
|
long timeout_ms;
|
||||||
|
int what;
|
||||||
|
|
||||||
|
/* check if the connection has already been established */
|
||||||
|
if(ssl_connection_complete == connssl->state) {
|
||||||
|
*done = TRUE;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ssl_connect_1==connssl->connecting_state) {
|
||||||
|
/* Find out how much more time we're allowed */
|
||||||
|
timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||||
|
|
||||||
|
if(timeout_ms < 0) {
|
||||||
|
/* no need to continue if time already is up */
|
||||||
|
failf(data, "SSL connection timeout");
|
||||||
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
|
}
|
||||||
|
retcode = mbedtls_connect_step1(conn, sockindex);
|
||||||
|
if(retcode)
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(ssl_connect_2 == connssl->connecting_state ||
|
||||||
|
ssl_connect_2_reading == connssl->connecting_state ||
|
||||||
|
ssl_connect_2_writing == connssl->connecting_state) {
|
||||||
|
|
||||||
|
/* check allowed time left */
|
||||||
|
timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||||
|
|
||||||
|
if(timeout_ms < 0) {
|
||||||
|
/* no need to continue if time already is up */
|
||||||
|
failf(data, "SSL connection timeout");
|
||||||
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if ssl is expecting something, check if it's available. */
|
||||||
|
if(connssl->connecting_state == ssl_connect_2_reading
|
||||||
|
|| connssl->connecting_state == ssl_connect_2_writing) {
|
||||||
|
|
||||||
|
curl_socket_t writefd = ssl_connect_2_writing==
|
||||||
|
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||||
|
curl_socket_t readfd = ssl_connect_2_reading==
|
||||||
|
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||||
|
|
||||||
|
what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
|
||||||
|
if(what < 0) {
|
||||||
|
/* fatal error */
|
||||||
|
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
else if(0 == what) {
|
||||||
|
if(nonblocking) {
|
||||||
|
*done = FALSE;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* timeout */
|
||||||
|
failf(data, "SSL connection timeout");
|
||||||
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* socket is readable or writable */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run transaction, and return to the caller if it failed or if
|
||||||
|
* this connection is part of a multi handle and this loop would
|
||||||
|
* execute again. This permits the owner of a multi handle to
|
||||||
|
* abort a connection attempt before step2 has completed while
|
||||||
|
* ensuring that a client using select() or epoll() will always
|
||||||
|
* have a valid fdset to wait on.
|
||||||
|
*/
|
||||||
|
retcode = mbedtls_connect_step2(conn, sockindex);
|
||||||
|
if(retcode || (nonblocking &&
|
||||||
|
(ssl_connect_2 == connssl->connecting_state ||
|
||||||
|
ssl_connect_2_reading == connssl->connecting_state ||
|
||||||
|
ssl_connect_2_writing == connssl->connecting_state)))
|
||||||
|
return retcode;
|
||||||
|
|
||||||
|
} /* repeat step2 until all transactions are done. */
|
||||||
|
|
||||||
|
if(ssl_connect_3==connssl->connecting_state) {
|
||||||
|
retcode = mbedtls_connect_step3(conn, sockindex);
|
||||||
|
if(retcode)
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ssl_connect_done==connssl->connecting_state) {
|
||||||
|
connssl->state = ssl_connection_complete;
|
||||||
|
conn->recv[sockindex] = mbedtls_recv;
|
||||||
|
conn->send[sockindex] = mbedtls_send;
|
||||||
|
*done = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*done = FALSE;
|
||||||
|
|
||||||
|
/* Reset our connect state machine */
|
||||||
|
connssl->connecting_state = ssl_connect_1;
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode
|
||||||
|
Curl_mbedtls_connect_nonblocking(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
bool *done)
|
||||||
|
{
|
||||||
|
return mbedtls_connect_common(conn, sockindex, TRUE, done);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CURLcode
|
||||||
|
Curl_mbedtls_connect(struct connectdata *conn,
|
||||||
|
int sockindex)
|
||||||
|
{
|
||||||
|
CURLcode retcode;
|
||||||
|
bool done = FALSE;
|
||||||
|
|
||||||
|
retcode = mbedtls_connect_common(conn, sockindex, FALSE, &done);
|
||||||
|
if(retcode)
|
||||||
|
return retcode;
|
||||||
|
|
||||||
|
DEBUGASSERT(done);
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return 0 error initializing SSL
|
||||||
|
* return 1 SSL initialized successfully
|
||||||
|
*/
|
||||||
|
int mbedtls_init(void)
|
||||||
|
{
|
||||||
|
return polarsslthreadlock_thread_setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mbedtls_cleanup(void)
|
||||||
|
{
|
||||||
|
(void)polarsslthreadlock_thread_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_MBEDTLS */
|
73
lib/vtls/mbedtls.h
Normal file
73
lib/vtls/mbedtls.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#ifndef HEADER_CURL_MBEDTLS_H
|
||||||
|
#define HEADER_CURL_MBEDTLS_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
#include "curl_setup.h"
|
||||||
|
|
||||||
|
#ifdef USE_MBEDTLS
|
||||||
|
|
||||||
|
/* Called on first use mbedTLS, setup threading if supported */
|
||||||
|
int mbedtls_init(void);
|
||||||
|
void mbedtls_cleanup(void);
|
||||||
|
|
||||||
|
|
||||||
|
CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex);
|
||||||
|
|
||||||
|
CURLcode Curl_mbedtls_connect_nonblocking(struct connectdata *conn,
|
||||||
|
int sockindex,
|
||||||
|
bool *done);
|
||||||
|
|
||||||
|
/* tell mbedTLS to close down all open information regarding connections (and
|
||||||
|
thus session ID caching etc) */
|
||||||
|
void Curl_mbedtls_close_all(struct SessionHandle *data);
|
||||||
|
|
||||||
|
/* close a SSL connection */
|
||||||
|
void Curl_mbedtls_close(struct connectdata *conn, int sockindex);
|
||||||
|
|
||||||
|
void Curl_mbedtls_session_free(void *ptr);
|
||||||
|
size_t Curl_mbedtls_version(char *buffer, size_t size);
|
||||||
|
int Curl_mbedtls_shutdown(struct connectdata *conn, int sockindex);
|
||||||
|
|
||||||
|
/* API setup for mbedTLS */
|
||||||
|
#define curlssl_init() mbedtls_init()
|
||||||
|
#define curlssl_cleanup() mbedtls_cleanup()
|
||||||
|
#define curlssl_connect Curl_mbedtls_connect
|
||||||
|
#define curlssl_connect_nonblocking Curl_mbedtls_connect_nonblocking
|
||||||
|
#define curlssl_session_free(x) Curl_mbedtls_session_free(x)
|
||||||
|
#define curlssl_close_all Curl_mbedtls_close_all
|
||||||
|
#define curlssl_close Curl_mbedtls_close
|
||||||
|
#define curlssl_shutdown(x,y) 0
|
||||||
|
#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN)
|
||||||
|
#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN)
|
||||||
|
#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
|
||||||
|
#define curlssl_version Curl_mbedtls_version
|
||||||
|
#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
|
||||||
|
|
||||||
|
/* This might cause libcurl to use a weeker random!
|
||||||
|
TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that
|
||||||
|
*/
|
||||||
|
#define curlssl_random(x,y,z) (x=x, y=y, z=z, CURLE_NOT_BUILT_IN)
|
||||||
|
|
||||||
|
#endif /* USE_MBEDTLS */
|
||||||
|
#endif /* HEADER_CURL_MBEDTLS_H */
|
@ -24,7 +24,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#ifdef USE_POLARSSL
|
#if (defined USE_POLARSSL) || (defined USE_MBEDTLS)
|
||||||
|
|
||||||
#if defined(USE_THREADS_POSIX)
|
#if defined(USE_THREADS_POSIX)
|
||||||
# define POLARSSL_MUTEX_T pthread_mutex_t
|
# define POLARSSL_MUTEX_T pthread_mutex_t
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "cyassl.h" /* CyaSSL versions */
|
#include "cyassl.h" /* CyaSSL versions */
|
||||||
#include "schannel.h" /* Schannel SSPI version */
|
#include "schannel.h" /* Schannel SSPI version */
|
||||||
#include "darwinssl.h" /* SecureTransport (Darwin) version */
|
#include "darwinssl.h" /* SecureTransport (Darwin) version */
|
||||||
|
#include "mbedtls.h" /* mbedTLS versions */
|
||||||
|
|
||||||
#ifndef MAX_PINNED_PUBKEY_SIZE
|
#ifndef MAX_PINNED_PUBKEY_SIZE
|
||||||
#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
|
#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
|
||||||
|
Loading…
Reference in New Issue
Block a user