mbedTLS 2.x support
authorSzymon Pusz <szymon@pusz.net>
Sat, 25 Jul 2015 20:07:56 +0000 (22:07 +0200)
committerSzymon Pusz <szymon@pusz.net>
Sat, 25 Jul 2015 20:07:56 +0000 (22:07 +0200)
CMakeLists.txt
cmake/Modules/FindmbedTLS.cmake [new file with mode: 0644]
configure.ac
src/CMakeLists.txt
src/Makefile.am
src/config.h.in
src/crypt.c
src/crypt.h
src/ssl.h
src/ssli_mbedtls.c [new file with mode: 0644]

index 2b666e320c002462df7372421c1b2983e3164bc7..42e0b3e55d9e4d37abb180a0f5b14b8667e7393c 100644 (file)
@@ -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 (file)
index 0000000..cc02c59
--- /dev/null
@@ -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)
index 245bccd951dd9d117bf243aefb2b66df50a1da0b..3a03f50b8f1ba855659e9ec8a772632b43f4de37 100644 (file)
@@ -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 <mbedtls/ssl.h>]],
+               [[#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],
        [
index 096ef45cc5d50ca65dcf93bf70e41fc7d946f2f8..15473d3c1aedf07196d964e937032a9c1bf96500 100644 (file)
@@ -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")
index d8f476f521ae40ebe79d0364b3ec03d7e2999091..3b37ba8523cbda695cddd950e28712e6ed54d8f8 100644 (file)
@@ -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
index c0e92836090ccff767f60c5c1045c8607b86404d..b8ee850abe78425a667f8e839532f2917f6e2c11 100644 (file)
@@ -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
 
index 0b82cad1d9e8b2fb25fd149cf6278e9095eb0985..4b1b4f4261af769c09cb7b741eb6c6b29ac5b64d 100644 (file)
@@ -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
 
index f3a885a1dcf6a0119705455b8218064be7dc6d67..631d6e6d63a299a3060474bbdeb09cd0e007889a 100644 (file)
 #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 <mbedtls/havege.h>
+#include <mbedtls/aes.h>
+
+#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 <nettle/aes.h>
index 4efa24beb586caccb17a01e2a43086f7e835bc29..2bb80e2a9b76ebe87b695a3fd6e209875c4a72b5 100644 (file)
--- 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 <mbedtls/ssl.h>
+#include <mbedtls/net.h>
+#include <mbedtls/version.h>
+
+#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 <mbedtls/havege.h>
+    #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 <gnutls/gnutls.h>
diff --git a/src/ssli_mbedtls.c b/src/ssli_mbedtls.c
new file mode 100644 (file)
index 0000000..3381e8b
--- /dev/null
@@ -0,0 +1,340 @@
+/* Copyright (C) 2009-2015, Martin Johansson <martin@fatbob.nu>
+   Copyright (C) 2005-2015, Thorvald Natvig <thorvald@natvig.com>
+   Copyright (C) 2015-2015, Szymon Pusz <szymon@pusz.net>
+
+   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 <stdlib.h>
+#include <fcntl.h>
+
+#include <mbedtls/config.h>
+#include <mbedtls/havege.h>
+#include <mbedtls/certs.h>
+#include <mbedtls/x509.h>
+#include <mbedtls/ssl.h>
+#include <mbedtls/net.h>
+
+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);
+}
+