From 6fb422b7cbb94a2b8063c6df630b04184414b633 Mon Sep 17 00:00:00 2001 From: Szymon Pusz Date: Sat, 25 Jul 2015 22:07:56 +0200 Subject: [PATCH] mbedTLS 2.x support --- CMakeLists.txt | 17 ++ cmake/Modules/FindmbedTLS.cmake | 17 ++ configure.ac | 30 ++- src/CMakeLists.txt | 2 + src/Makefile.am | 4 + src/config.h.in | 3 + src/crypt.c | 2 +- src/crypt.h | 15 ++ src/ssl.h | 33 ++++ src/ssli_mbedtls.c | 340 ++++++++++++++++++++++++++++++++ 10 files changed, 461 insertions(+), 2 deletions(-) create mode 100644 cmake/Modules/FindmbedTLS.cmake create mode 100644 src/ssli_mbedtls.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b666e3..42e0b3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,9 @@ endif(NOT CMAKE_BUILD_TYPE) option(USE_POLARSSL_TESTCERT "Link to the PolarSSL test certificate and key." OFF) option(USE_POLARSSL_HAVEGE "Use the PolarSSL HAVEGE random generator key." OFF) +option(USE_MBEDTLS_TESTCERT "Link to the mbedTLS test certificate and key." OFF) +option(USE_MBEDTLS_HAVEGE "Use the mbedTLS HAVEGE random generator key." OFF) + option(USE_SHAREDMEMORY_API "Compile with Sharedmemory API support" OFF) if(USE_POLARSSL_TESTCERT OR USE_POLARSSL_HAVEGE) @@ -23,6 +26,12 @@ if(USE_POLARSSL_TESTCERT OR USE_POLARSSL_HAVEGE) endif(SSL MATCHES "openssl" OR SSL MATCHES "gnutls") endif(USE_POLARSSL_TESTCERT OR USE_POLARSSL_HAVEGE) +if(USE_MBEDTLS_TESTCERT OR USE_MBEDTLS_HAVEGE) + if(SSL MATCHES "openssl" OR SSL MATCHES "gnutls" OR SSL MATCHES "polarssl") + message(FATAL_ERROR "Selecting USE_MBEDTLS_TESTCERT or USE_MBEDTLS_HAVEGE implies SSL=mbedtls") + endif(SSL MATCHES "openssl" OR SSL MATCHES "gnutls" OR SSL MATCHES "polarssl") +endif(USE_MBEDTLS_TESTCERT OR USE_MBEDTLS_HAVEGE) + find_package(Libconfig REQUIRED) find_package(ProtobufC REQUIRED) include(CheckFunctionExists) @@ -52,6 +61,14 @@ elseif("${SSL}" STREQUAL "polarssl") set(SSLIMP_INCLUDE_DIR ${POLARSSL_INCLUDE_DIR}) set(SSLIMP_LIBRARY_DIR ${POLARSSL_LIB_DIR}) endif(POLARSSL_FOUND) +elseif("${SSL}" STREQUAL "mbedtls") + find_package(mbedTLS REQUIRED) + if(MBEDTLS_FOUND) + set(USE_MBEDTLS ON) + set(SSLIMP_LIBRARIES ${MBEDTLS_LIBRARIES}) + set(SSLIMP_INCLUDE_DIR ${MBEDTLS_INCLUDE_DIR}) + set(SSLIMP_LIBRARY_DIR ${MBEDTLS_LIB_DIR}) + endif(MBEDTLS_FOUND) elseif("${SSL}" STREQUAL "gnutls") find_package(GnuTLS 3 REQUIRED) if(GNUTLS_FOUND) diff --git a/cmake/Modules/FindmbedTLS.cmake b/cmake/Modules/FindmbedTLS.cmake new file mode 100644 index 0000000..cc02c59 --- /dev/null +++ b/cmake/Modules/FindmbedTLS.cmake @@ -0,0 +1,17 @@ +include(FindPackageHandleStandardArgs) +include(CheckSymbolExists) + +find_path(MBEDTLS_INCLUDE_DIR NAMES "version.h" PATHS /usr/pkg /usr/local /usr PATH_SUFFIXES "include/mbedtls") +find_path(MBEDTLS_LIB_DIR NAMES "libmbedtls.so" "libmbedtls.dylib" "libmbedtls.a" PATHS /usr/pkg /usr/local /usr PATH_SUFFIXES "lib" "lib/${CMAKE_LIBRARY_ARCHITECTURE}") + +if(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIB_DIR) + set(MBEDTLS_LIBRARIES mbedtls) + set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARIES} mbedcrypto) + set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARIES} mbedx509) + check_symbol_exists(MBEDTLS_ZLIB_SUPPORT "${MBEDTLS_INCLUDE_DIR}/version.h" HAVE_ZLIB_SUPPORT) + if(HAVE_ZLIB_SUPPORT) + set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARIES} z) + endif(HAVE_ZLIB_SUPPORT) +endif(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIB_DIR) + +find_package_handle_standard_args(mbedTLS REQUIRED_VARS MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARIES MBEDTLS_LIB_DIR) diff --git a/configure.ac b/configure.ac index 245bccd..3a03f50 100644 --- a/configure.ac +++ b/configure.ac @@ -38,10 +38,12 @@ AC_CANONICAL_HOST AM_SILENT_RULES([yes]) # Configure options. -AC_ARG_WITH([ssl], [AC_HELP_STRING([--with-ssl=@<:@LIB@:>@], [SSL library (openssl|polarssl|gnutls) @<:@default=polarssl@:>@])], [], [with_ssl=polarssl]) +AC_ARG_WITH([ssl], [AC_HELP_STRING([--with-ssl=@<:@LIB@:>@], [SSL library (openssl|polarssl|gnutls|mbedtls) @<:@default=polarssl@:>@])], [], [with_ssl=polarssl]) AC_ARG_ENABLE([shmapi], [AC_HELP_STRING([--enable-shmapi], [compile with Sharedmemory API support @<:@default=no@:>@])],[],[enable_shmapi=no] ) AC_ARG_ENABLE(polarssl-test-cert, [ --enable-polarssl-test-cert Link to PolarSSL test certificate and key @<:@default=no@:>@], [enable_polarssl_test_cert=yes]) AC_ARG_ENABLE(polarssl-havege, [ --enable-polarssl-havege Link to PolarSSL HAVEGE random generator key @<:@default=no@:>@ Default: /dev/urandom], [enable_polarssl_havege=yes]) +AC_ARG_ENABLE(mbedtls-test-cert, [ --enable-mbedtls-test-cert Link to mbedTLS test certificate and key @<:@default=no@:>@], [enable_mbedtls_test_cert=yes]) +AC_ARG_ENABLE(mbedtls-havege, [ --enable-mbedtls-havege Link to mbedTLS HAVEGE random generator key @<:@default=no@:>@ Default: /dev/urandom], [enable_mbedtls_havege=yes]) # Checks for programs. AC_PROG_CC @@ -83,6 +85,31 @@ AS_IF([test "x$with_ssl" = xpolarssl], [ AC_DEFINE([USE_POLARSSL_HAVEGE], [], [Use PolarSSL HAVEGE random generator]) ]) ]) +AS_IF([test "x$with_ssl" = xmbedtls], [ + AC_CHECK_HEADERS([mbedtls/ssl.h], [], [AC_MSG_ERROR([could not find mbedtls/ssl.h])]) + AC_CHECK_HEADERS([mbedtls/version.h], [], [AC_MSG_ERROR([could not find mbedtls/version.h])]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[#if defined(MBEDTLS_ZLIB_SUPPORT) + int x; + #endif + x = 0; + return 0;]])], + [AC_CHECK_LIB([z], [deflate], [], [AC_MSG_ERROR([could not find zlib])])], + []) + AC_CHECK_LIB([mbedtls], [mbedtls_ssl_init], [], [AC_MSG_ERROR([could not find libmbedtls])], [-lmbedcrypto -lmbedx509]) + AC_CHECK_LIB([mbedcrypto], [mbedtls_cipher_setup], [], [AC_MSG_ERROR([could not find libmbedcrypto])], [-lmbedtls -lmbedx509]) + AC_CHECK_LIB([mbedx509], [mbedtls_x509_crt_init], [], [AC_MSG_ERROR([could not find libmbedx509])], [-lmbedcrypto -lmbedtls]) + AC_DEFINE([USE_MBEDTLS], [], [Use mbedTLS]) + AS_IF([test "x$enable_mbedtls_test_cert" = xyes], [ + AC_CHECK_LIB([mbedtls], [test_srv_crt], [], [AC_MSG_ERROR([could not find test_srv_crt])]) + AC_DEFINE([USE_MBEDTLS_TESTCERT], [], [Use mbedTLS test certificate]) + ]) + AS_IF([test "x$enable_mbedtls_havege" = xyes], [ + AC_CHECK_LIB([mbedtls], [havege_init], [], [AC_MSG_ERROR([could not find havege_init])]) + AC_DEFINE([USE_MBEDTLS_HAVEGE], [], [Use mbedTLS HAVEGE random generator]) + ]) +]) AS_IF([test "x$with_ssl" = xopenssl], [ AC_CHECK_HEADERS([openssl/ssl.h], [], [AC_MSG_ERROR([could not find openssl/ssl.h])]) AC_CHECK_LIB([crypto], [BN_init], [], [AC_MSG_ERROR([could not find libcrypto])]) @@ -103,6 +130,7 @@ AS_IF([test "x$with_ssl" = xgnutls], [ AM_CONDITIONAL(USE_OPENSSL, test x$with_ssl = xopenssl) AM_CONDITIONAL(USE_GNUTLS, test x$with_ssl = xgnutls) +AM_CONDITIONAL(USE_MBEDTLS, test x$with_ssl = xmbedtls) AS_IF([test "x$enable_shmapi" != xno], [ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 096ef45..15473d3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,8 @@ if(SSL MATCHES "openssl") list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ssli_openssl.c) elseif(SSL MATCHES "polarssl") list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ssli_polarssl.c) +elseif(SSL MATCHES "mbedtls") + list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ssli_mbedtls.c) elseif(SSL MATCHES "gnutls") list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ssli_gnutls.c) endif(SSL MATCHES "openssl") diff --git a/src/Makefile.am b/src/Makefile.am index d8f476f..3b37ba8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,9 +35,13 @@ else if USE_GNUTLS umurmurd_SOURCES+=ssli_gnutls.c else +if USE_MBEDTLS +umurmurd_SOURCES+=ssli_mbedtls.c +else umurmurd_SOURCES+=ssli_polarssl.c endif endif +endif if USE_SHAREDMEMORY_API umurmurd_SOURCES+=sharedmemory.c diff --git a/src/config.h.in b/src/config.h.in index c0e9283..b8ee850 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -5,6 +5,9 @@ #cmakedefine USE_POLARSSL #cmakedefine USE_POLARSSL_TESTCERT #cmakedefine USE_POLARSSL_HAVEGE +#cmakedefine USE_MBEDTLS +#cmakedefine USE_MBEDTLS_TESTCERT +#cmakedefine USE_MBEDTLS_HAVEGE #cmakedefine USE_SHAREDMEMORY_API diff --git a/src/crypt.c b/src/crypt.c index 0b82cad..4b1b4f4 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -43,7 +43,7 @@ #include "crypt.h" #include "ssl.h" -#ifdef USE_POLARSSL_HAVEGE +#if defined(USE_POLARSSL_HAVEGE) || defined(USE_MBEDTLS_HAVEGE) extern havege_state hs; #endif diff --git a/src/crypt.h b/src/crypt.h index f3a885a..631d6e6 100644 --- a/src/crypt.h +++ b/src/crypt.h @@ -49,6 +49,21 @@ #define CRYPT_AES_ENCRYPT(src, dst, cryptstate) aes_crypt_ecb(&(cryptstate)->encrypt_key, AES_ENCRYPT, (unsigned char *)(src), (unsigned char *)(dst)); #define CRYPT_AES_DECRYPT(src, dst, cryptstate) aes_crypt_ecb(&(cryptstate)->decrypt_key, AES_DECRYPT, (unsigned char *)(src), (unsigned char *)(dst)); +#elif defined(USE_MBEDTLS) + +#include +#include + +#define CRYPT_AES_KEY mbedtls_aes_context +#define AES_BLOCK_SIZE 16 + +#define CRYPT_RANDOM_BYTES(dest, size) RAND_bytes((unsigned char *)(dest), (size)) +#define CRYPT_SET_ENC_KEY(dest, source, size) mbedtls_aes_setkey_enc((dest), (source), (size)); +#define CRYPT_SET_DEC_KEY(dest, source, size) mbedtls_aes_setkey_dec((dest), (source), (size)); + +#define CRYPT_AES_ENCRYPT(src, dst, cryptstate) mbedtls_aes_crypt_ecb(&(cryptstate)->encrypt_key, MBEDTLS_AES_ENCRYPT, (unsigned char *)(src), (unsigned char *)(dst)); +#define CRYPT_AES_DECRYPT(src, dst, cryptstate) mbedtls_aes_crypt_ecb(&(cryptstate)->decrypt_key, MBEDTLS_AES_DECRYPT, (unsigned char *)(src), (unsigned char *)(dst)); + #elif defined(USE_GNUTLS) #include diff --git a/src/ssl.h b/src/ssl.h index 4efa24b..2bb80e2 100644 --- a/src/ssl.h +++ b/src/ssl.h @@ -88,6 +88,39 @@ int urandom_bytes(void *ctx, unsigned char *dest, size_t len); typedef ssl_context SSL_handle_t; +#elif defined(USE_MBEDTLS) +#include +#include +#include + +#if defined(MBEDTLS_VERSION_MAJOR) +#if (MBEDTLS_VERSION_MAJOR < 2) +#error mbedTLS version 2.0.0 or greater is required! +#endif +#else +#error mbedTLS version 2.0.0 or greater is required! +#endif + +#if defined(USE_MBEDTLS_HAVEGE) +#include + #define HAVEGE_RAND (havege_random) + #define RAND_bytes(_dst_, _size_) do { \ + mbedtls_havege_random(&hs, _dst_, _size_); \ + } while (0) +#else +#define RAND_bytes(_dst_, _size_) do { urandom_bytes(NULL, _dst_, _size_); } while (0) +int urandom_bytes(void *ctx, unsigned char *dest, size_t len); +#endif + +#define SSLI_ERROR_WANT_READ -0x0F300 /* mbedTLS v0.x.x uses -0x0f00 -> --0x0f90, v1.x.x uses -0x7080 -> -0x7e80 */ +#define SSLI_ERROR_WANT_WRITE -0x0F310 + +#define SSLI_ERROR_ZERO_RETURN 0 +#define SSLI_ERROR_CONNRESET MBEDTLS_ERR_NET_CONN_RESET +#define SSLI_ERROR_SYSCALL MBEDTLS_ERR_NET_RECV_FAILED + +typedef mbedtls_ssl_context SSL_handle_t; + #elif defined(USE_GNUTLS) #include diff --git a/src/ssli_mbedtls.c b/src/ssli_mbedtls.c new file mode 100644 index 0000000..3381e8b --- /dev/null +++ b/src/ssli_mbedtls.c @@ -0,0 +1,340 @@ +/* Copyright (C) 2009-2015, Martin Johansson + Copyright (C) 2005-2015, Thorvald Natvig + Copyright (C) 2015-2015, Szymon Pusz + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Developers nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#include "conf.h" +#include "log.h" +#include "ssl.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +const int ciphers[] = +{ + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, + 0 +}; + +static mbedtls_x509_crt certificate; +static inline int x509parse_keyfile(mbedtls_pk_context *pk, const char *path, + const char *pwd) +{ + int ret; + + mbedtls_pk_init(pk); + ret = mbedtls_pk_parse_keyfile(pk, path, pwd); + if (ret == 0 && !mbedtls_pk_can_do(pk, MBEDTLS_PK_RSA)) + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + + return ret; +} + +static mbedtls_pk_context key; +bool_t builtInTestCertificate; + +#ifdef USE_MBEDTLS_HAVEGE +havege_state hs; +#else +int urandom_fd; +#endif + +/* DH prime */ +char *my_dhm_P = + "9CE85640903BF123906947FEDE767261" \ + "D9B4A973EB8F7D984A8C656E2BCC161C" \ + "183D4CA471BA78225F940F16D1D99CA3" \ + "E66152CC68EDCE1311A390F307741835" \ + "44FF6AB553EC7073AD0CB608F2A3B480" \ + "19E6C02BCED40BD30E91BB2469089670" \ + "DEF409C08E8AC24D1732A6128D2220DC53"; +char *my_dhm_G = "4"; + +#ifdef USE_MBEDTLS_TESTCERT +static void initTestCert() +{ + int rc; + builtInTestCertificate = true; + rc = mbedtls_x509_crt_parse_rsa(&certificate, (unsigned char *)test_srv_crt, + strlen(test_srv_crt)); + + if (rc != 0) + Log_fatal("Could not parse built-in test certificate"); +} + +static void initTestKey() +{ + int rc; + + rc = mbedtls_x509parse_key_rsa(&key, (unsigned char *)test_srv_key, + strlen(test_srv_key), NULL, 0); + if (rc != 0) + Log_fatal("Could not parse built-in test RSA key"); +} +#endif + +/* + * How to generate a self-signed cert with openssl: + * openssl genrsa 1024 > host.key + * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert + */ +static void initCert() +{ + int rc; + char *crtfile = (char *)getStrConf(CERTIFICATE); + + if (crtfile == NULL) { +#ifdef USE_MBEDTLS_TESTCERT + Log_warn("No certificate file specified. Falling back to test certificate."); + initTestCert(); +#else + Log_fatal("No certificate file specified"); +#endif + return; + } + + rc = mbedtls_x509_crt_parse_file(&certificate, crtfile); + + if (rc != 0) { +#ifdef USE_MBEDTLS_TESTCERT + Log_warn("Could not read certificate file '%s'. Falling back to test certificate.", crtfile); + initTestCert(); +#else + Log_fatal("Could not read certificate file '%s'", crtfile); +#endif + return; + } +} + +static void initKey() +{ + int rc; + char *keyfile = (char *)getStrConf(KEY); + + if (keyfile == NULL) + Log_fatal("No key file specified"); + rc = x509parse_keyfile(&key, keyfile, NULL); + if (rc != 0) + Log_fatal("Could not read RSA key file %s", keyfile); +} + +#ifndef USE_MBEDTLS_HAVEGE +int urandom_bytes(void *ctx, unsigned char *dest, size_t len) +{ + int cur; + + while (len) { + cur = read(urandom_fd, dest, len); + if (cur < 0) + continue; + len -= cur; + } + return 0; +} +#endif + +#define DEBUG_LEVEL 0 +static void pssl_debug(void *ctx, int level, const char *file, int line, const char *str) +{ + if (level <= DEBUG_LEVEL) + Log_info("mbedTLS [level %d]: %s", level, str); +} + +void SSLi_init(void) +{ + char verstring[12]; + + initCert(); +#ifdef USE_MBEDTLS_TESTCERT + if (builtInTestCertificate) { + Log_warn("*** Using built-in test certificate and RSA key ***"); + Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***"); + initTestKey(); + } + else + initKey(); +#else + initKey(); +#endif + + /* Initialize random number generator */ +#ifdef USE_MBEDTLS_HAVEGE + mbedtls_havege_init(&hs); +#else + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) + Log_fatal("Cannot open /dev/urandom"); +#endif + +#ifdef MBEDTLS_VERSION_FEATURES + mbedtls_version_get_string(verstring); + Log_info("mbedTLS library version %s initialized", verstring); +#else + Log_info("mbedTLS library initialized"); +#endif +} + +void SSLi_deinit(void) +{ + mbedtls_x509_crt_free(&certificate); + mbedtls_pk_free(&key); +} + +/* Create SHA1 of last certificate in the peer's chain. */ +bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash) +{ + mbedtls_x509_crt const *cert; + cert = mbedtls_ssl_get_peer_cert(ssl); + + if (!cert) { + return false; + } + mbedtls_sha1(cert->raw.p, cert->raw.len, hash); + return true; +} + +SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready) +{ + mbedtls_ssl_context *ssl; + mbedtls_ssl_session *ssn; + mbedtls_ssl_config *conf; + int rc; + + ssl = calloc(1, sizeof(mbedtls_ssl_context)); + ssn = calloc(1, sizeof(mbedtls_ssl_session)); + conf = calloc(1, sizeof(mbedtls_ssl_config)); + + if (!ssl || !ssn || !conf) + Log_fatal("Out of memory"); + + mbedtls_ssl_init(ssl); + mbedtls_ssl_config_init(conf); + + if((rc = mbedtls_ssl_config_defaults(conf, + MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT)) != 0) + Log_fatal("mbedtls_ssl_config_defaults returned %d", rc); + + mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL); +#ifdef USE_MBEDTLS_HAVEGE + mbedtls_ssl_conf_rng(conf, HAVEGE_RAND, &hs); +#else + mbedtls_ssl_conf_rng(conf, urandom_bytes, NULL); +#endif + mbedtls_ssl_conf_dbg(conf, pssl_debug, NULL); + mbedtls_ssl_set_bio(ssl, fd, mbedtls_net_send, mbedtls_net_recv, NULL); + mbedtls_ssl_conf_ciphersuites(conf, (const int*)&ciphers); + mbedtls_ssl_set_session(ssl, ssn); + mbedtls_ssl_conf_ca_chain(conf, &certificate, NULL); + + if((rc = mbedtls_ssl_conf_own_cert(conf, &certificate, &key)) != 0) + Log_fatal("mbedtls_ssl_conf_own_cert returned %d", rc); + + if((rc = mbedtls_ssl_conf_dh_param(conf, my_dhm_P, my_dhm_G)) != 0) + Log_fatal("mbedtls_ssl_conf_dh_param returned %d", rc); + + if((rc = mbedtls_ssl_setup(ssl, conf)) != 0) + Log_fatal("mbedtls_ssl_setup returned %d", rc); + + return ssl; +} + +int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready) +{ + int rc; + + rc = mbedtls_ssl_handshake(ssl); + if (rc != 0) { + if (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE) { + return 0; + } else if (rc == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */ + return 0; + } else { + Log_warn("SSL handshake failed: %d", rc); + return -1; + } + } + *SSLready = true; + return 0; +} + +int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len) +{ + int rc; + + rc = mbedtls_ssl_read(ssl, buf, len); + if (rc == MBEDTLS_ERR_SSL_WANT_READ) + return SSLI_ERROR_WANT_READ; + return rc; +} + +int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len) +{ + int rc; + + rc = mbedtls_ssl_write(ssl, buf, len); + if (rc == MBEDTLS_ERR_SSL_WANT_WRITE) + return SSLI_ERROR_WANT_WRITE; + return rc; +} + +int SSLi_get_error(SSL_handle_t *ssl, int code) +{ + return code; +} + +bool_t SSLi_data_pending(SSL_handle_t *ssl) +{ + return mbedtls_ssl_get_bytes_avail(ssl) > 0; +} + +void SSLi_shutdown(SSL_handle_t *ssl) +{ + mbedtls_ssl_close_notify(ssl); +} + +void SSLi_free(SSL_handle_t *ssl) +{ + Log_debug("SSLi_free"); + mbedtls_ssl_config_free((mbedtls_ssl_config*)ssl->conf); + mbedtls_ssl_free(ssl); + free((mbedtls_ssl_config*)ssl->conf); + free(ssl); +} + -- 2.30.2