[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openvpn-devel
Subject:    [Openvpn-devel] [L] Change in openvpn[release/2.6]: Backport mbed TLS 3 support to OpenVPN 2.6
From:       "MaxF (Code Review)" <gerrit () openvpn ! net>
Date:       2023-11-20 15:35:05
Message-ID: 23e0425453aae49e79eb5754cba15ab588dd1f72-HTML () gerrit ! openvpn ! net
[Download RAW message or body]

Attention is currently required from: flichtenheld, plaisthos.

Hello plaisthos, flichtenheld,

I'd like you to do a code review.
Please visit

    http://gerrit.openvpn.net/c/openvpn/+/404?usp=email

to review the following change.


Change subject: Backport mbed TLS 3 support to OpenVPN 2.6
......................................................................

Backport mbed TLS 3 support to OpenVPN 2.6

Based on commits
- ace7a4f1c271550bb8ad276663e045ab97a46f16
- f53f06316dbb804128fc5cbee1d8edb274ce81df
- efad93d049c318a3bd9ea5956c6ac8237b8d6d70
- b5faf1b2e90fd44c5137a2b8f3da98c7ae482fc1

Change-Id: Icb4ae73741dc84ef0ff7ef72721cc12b999f4d03
Signed-off-by: Max Fillinger <maximilian.fillinger@foxcrypto.com>
---
M README.mbedtls
M config.h.cmake.in
M configure.ac
M src/openvpn/Makefile.am
M src/openvpn/crypto_mbedtls.c
A src/openvpn/mbedtls_compat.h
M src/openvpn/options.c
M src/openvpn/ssl_mbedtls.c
M src/openvpn/ssl_verify_mbedtls.c
9 files changed, 422 insertions(+), 115 deletions(-)



  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/04/404/1

diff --git a/README.mbedtls b/README.mbedtls
index d3466fa..ed9d369 100644
--- a/README.mbedtls
+++ b/README.mbedtls
@@ -1,13 +1,13 @@
-This version of OpenVPN has mbed TLS support. To enable follow the following
-instructions:
+This version of OpenVPN has mbed TLS support. To enable, follow the
+instructions below:

-To Build and Install,
+To build and install,

 	./configure --with-crypto-library=mbedtls
 	make
 	make install

-This version depends on mbed TLS 2.0 (and requires at least 2.0.0).
+This version requires mbed TLS version >= 2.0.0 or >= 3.2.1.

 *************************************************************************

@@ -16,7 +16,8 @@
 As of mbed TLS 2.17, it can be licensed *only* under the Apache v2.0 license.
 That license is incompatible with OpenVPN's GPLv2.

-If you wish to distribute OpenVPN linked with mbed TLS, there are two options:
+We are currently in the process of resolving this problem, but for now, if you
+wish to distribute OpenVPN linked with mbed TLS, there are two options:

  * Ensure that your case falls under the system library exception in GPLv2, or

@@ -24,9 +25,6 @@
    that may be licensed under GPLv2. Unfortunately, this version is
    unsupported and won't receive any more updates.

-If nothing changes about the license situation, mbed TLS support may be
-deprecated in a future release of OpenVPN.
-
 *************************************************************************

 Due to limitations in the mbed TLS library, the following features are missing
@@ -42,3 +40,8 @@
  * X.509 subject line has a different format than the OpenSSL subject line
  * X.509 certificate export does not work
  * X.509 certificate tracking
+
+*************************************************************************
+
+Mbed TLS 3 has implemented (parts of) the TLS 1.3 protocol, but we have disabled
+support in OpenVPN because the TLS-Exporter function is not yet implemented.
diff --git a/config.h.cmake.in b/config.h.cmake.in
index 29006ce..e88cb77 100644
--- a/config.h.cmake.in
+++ b/config.h.cmake.in
@@ -387,7 +387,10 @@
 #undef HAVE_VSNPRINTF

 /* we always assume a recent mbed TLS version */
-#define HAVE_CTR_DRBG_UPDATE_RET 1
+#define HAVE_MBEDTLS_PSA_CRYPTO_H 1
+#define HAVE_MBEDTLS_SSL_TLS_PRF 1
+#define HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB 1
+#define HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET 1

 /* Path to ifconfig tool */
 #define IFCONFIG_PATH "@IFCONFIG_PATH@"
diff --git a/configure.ac b/configure.ac
index 052fe3f..749c857 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1019,13 +1019,19 @@
 #include <mbedtls/version.h>
 			]],
 			[[
-#if MBEDTLS_VERSION_NUMBER < 0x02000000 || MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER < 0x02000000 || (MBEDTLS_VERSION_NUMBER >= 0x03000000 && \
MBEDTLS_VERSION_NUMBER < 0x03020100)  #error invalid version
 #endif
 			]]
 		)],
 		[AC_MSG_RESULT([ok])],
-		[AC_MSG_ERROR([mbed TLS 2.y.z required])]
+		[AC_MSG_ERROR([mbed TLS version >= 2.0.0 or >= 3.2.1 required])]
+	)
+
+	AC_CHECK_HEADER(
+		psa/crypto.h,
+		[AC_DEFINE([HAVE_MBEDTLS_PSA_CRYPTO_H], [1], [yes])],
+		[AC_DEFINE([HAVE_MBEDTLS_PSA_CRYPTO_H], [0], [no])]
 	)

 	AC_CHECK_FUNCS(
@@ -1037,16 +1043,32 @@
 		[AC_MSG_ERROR([mbed TLS check for AEAD support failed])]
 	)

+	AC_CHECK_FUNC(
+		[mbedtls_ssl_tls_prf],
+		[AC_DEFINE([HAVE_MBEDTLS_SSL_TLS_PRF], [1], [yes])],
+		[AC_DEFINE([HAVE_MBEDTLS_SSL_TLS_PRF], [0], [no])]
+	)
+
 	have_export_keying_material="yes"
 	AC_CHECK_FUNC(
 		[mbedtls_ssl_conf_export_keys_ext_cb],
-		,
-		[have_export_keying_material="no"]
+		[AC_DEFINE([HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB], [1], [yes])],
+		[AC_DEFINE([HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB], [0], [no])]
 	)
+	if test "x$ac_cv_func_mbedtls_ssl_conf_export_keys_ext_cb" != xyes; then
+		AC_CHECK_FUNC(
+			[mbedtls_ssl_set_export_keys_cb],
+			[AC_DEFINE([HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB], [1], [yes])],
+			[AC_DEFINE([HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB], [0], [no])]
+		)
+		if test "x$ac_cv_func_mbedtls_ssl_set_export_keys_cb" != xyes; then
+			have_export_keying_material="no"
+		fi
+	fi

 	AC_CHECK_FUNC(
 		[mbedtls_ctr_drbg_update_ret],
-		AC_DEFINE([HAVE_CTR_DRBG_UPDATE_RET], [1],
+		AC_DEFINE([HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET], [1],
 			  [Use mbedtls_ctr_drbg_update_ret from mbed TLS]),
 	)

diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index 52deef8..b953961 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -82,6 +82,7 @@
 	ovpn_dco_win.h \
 	platform.c platform.h \
 	console.c console.h console_builtin.c console_systemd.c \
+	mbedtls_compat.h \
 	mroute.c mroute.h \
 	mss.c mss.h \
 	mstats.c mstats.h \
diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c
index 98cac60..ad3439c 100644
--- a/src/openvpn/crypto_mbedtls.c
+++ b/src/openvpn/crypto_mbedtls.c
@@ -41,6 +41,7 @@
 #include "integer.h"
 #include "crypto_backend.h"
 #include "otime.h"
+#include "mbedtls_compat.h"
 #include "misc.h"

 #include <mbedtls/base64.h>
@@ -170,10 +171,11 @@
     while (*ciphers != 0)
     {
         const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
-        if (info && !cipher_kt_insecure(info->name)
-            && (cipher_kt_mode_aead(info->name) || cipher_kt_mode_cbc(info->name)))
+        const char *name = mbedtls_cipher_info_get_name(info);
+        if (info && name && !cipher_kt_insecure(name)
+            && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
         {
-            print_cipher(info->name);
+            print_cipher(name);
         }
         ciphers++;
     }
@@ -184,10 +186,11 @@
     while (*ciphers != 0)
     {
         const mbedtls_cipher_info_t *info = mbedtls_cipher_info_from_type(*ciphers);
-        if (info && cipher_kt_insecure(info->name)
-            && (cipher_kt_mode_aead(info->name) || cipher_kt_mode_cbc(info->name)))
+        const char *name = mbedtls_cipher_info_get_name(info);
+        if (info && name && cipher_kt_insecure(name)
+            && (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))
         {
-            print_cipher(info->name);
+            print_cipher(name);
         }
         ciphers++;
     }
@@ -295,7 +298,9 @@
     mbedtls_pem_context ctx = { 0 };
     bool ret = mbed_ok(mbedtls_pem_read_buffer(&ctx, header, footer, BPTR(&input),
                                                NULL, 0, &use_len));
-    if (ret && !buf_write(dst, ctx.buf, ctx.buflen))
+    size_t buf_size = 0;
+    const unsigned char *buf = mbedtls_pem_get_buffer(&ctx, &buf_size);
+    if (ret && !buf_write(dst, buf, buf_size))
     {
         ret = false;
         msg(M_WARN, "PEM decode error: destination buffer too small");
@@ -416,11 +421,12 @@
         return false;
     }

-    if (cipher->key_bitlen/8 > MAX_CIPHER_KEY_LENGTH)
+    const size_t key_bytelen = mbedtls_cipher_info_get_key_bitlen(cipher)/8;
+    if (key_bytelen > MAX_CIPHER_KEY_LENGTH)
     {
-        msg(D_LOW, "Cipher algorithm '%s' uses a default key size (%d bytes) "
+        msg(D_LOW, "Cipher algorithm '%s' uses a default key size (%zu bytes) "
             "which is larger than " PACKAGE_NAME "'s current maximum key size "
-            "(%d bytes)", ciphername, cipher->key_bitlen/8, MAX_CIPHER_KEY_LENGTH);
+            "(%d bytes)", ciphername, key_bytelen, MAX_CIPHER_KEY_LENGTH);
         *reason = "disabled due to key size too large";
         return false;
     }
@@ -438,7 +444,7 @@
         return "[null-cipher]";
     }

-    return translate_cipher_name_to_openvpn(cipher_kt->name);
+    return translate_cipher_name_to_openvpn(mbedtls_cipher_info_get_name(cipher_kt));
  }

 int
@@ -451,7 +457,7 @@
         return 0;
     }

-    return cipher_kt->key_bitlen/8;
+    return (int)mbedtls_cipher_info_get_key_bitlen(cipher_kt)/8;
 }

 int
@@ -463,7 +469,7 @@
     {
         return 0;
     }
-    return cipher_kt->iv_size;
+    return (int)mbedtls_cipher_info_get_iv_size(cipher_kt);
 }

 int
@@ -474,7 +480,7 @@
     {
         return 0;
     }
-    return cipher_kt->block_size;
+    return (int)mbedtls_cipher_info_get_block_size(cipher_kt);
 }

 int
@@ -498,16 +504,16 @@

     return !(cipher_kt_block_size(ciphername) >= 128 / 8
 #ifdef MBEDTLS_CHACHAPOLY_C
-             || cipher_kt->type == MBEDTLS_CIPHER_CHACHA20_POLY1305
+             || mbedtls_cipher_info_get_type(cipher_kt) == \
MBEDTLS_CIPHER_CHACHA20_POLY1305  #endif
              );
 }

-static int
+static mbedtls_cipher_mode_t
 cipher_kt_mode(const mbedtls_cipher_info_t *cipher_kt)
 {
     ASSERT(NULL != cipher_kt);
-    return cipher_kt->mode;
+    return mbedtls_cipher_info_get_mode(cipher_kt);
 }

 bool
@@ -566,22 +572,29 @@
     CLEAR(*ctx);

     const mbedtls_cipher_info_t *kt = cipher_get(ciphername);
-    int key_len = kt->key_bitlen/8;
-
     ASSERT(kt);
+    size_t key_bitlen = mbedtls_cipher_info_get_key_bitlen(kt);

     if (!mbed_ok(mbedtls_cipher_setup(ctx, kt)))
     {
         msg(M_FATAL, "mbed TLS cipher context init #1");
     }

-    if (!mbed_ok(mbedtls_cipher_setkey(ctx, key, key_len*8, operation)))
+    if (!mbed_ok(mbedtls_cipher_setkey(ctx, key, (int)key_bitlen, operation)))
     {
         msg(M_FATAL, "mbed TLS cipher set key");
     }

+    if (mbedtls_cipher_info_get_mode(kt) == MBEDTLS_MODE_CBC)
+    {
+        if (!mbed_ok(mbedtls_cipher_set_padding_mode(ctx, MBEDTLS_PADDING_PKCS7)))
+        {
+            msg(M_FATAL, "mbed TLS cipher set padding mode");
+        }
+    }
+
     /* make sure we used a big enough key */
-    ASSERT(ctx->key_bitlen <= key_len*8);
+    ASSERT(mbedtls_cipher_get_key_bitlen(ctx) <= key_bitlen);
 }

 int
@@ -609,7 +622,7 @@
 int
 cipher_ctx_block_size(const mbedtls_cipher_context_t *ctx)
 {
-    return mbedtls_cipher_get_block_size(ctx);
+    return (int)mbedtls_cipher_get_block_size(ctx);
 }

 int
@@ -617,7 +630,7 @@
 {
     ASSERT(NULL != ctx);

-    return cipher_kt_mode(ctx->cipher_info);
+    return mbedtls_cipher_get_cipher_mode(ctx);
 }

 bool
@@ -652,7 +665,7 @@
         return 0;
     }

-    if (!mbed_ok(mbedtls_cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size)))
+    if (!mbed_ok(mbedtls_cipher_set_iv(ctx, iv_buf, \
(size_t)mbedtls_cipher_get_iv_size(ctx))))  {
         return 0;
     }
@@ -714,7 +727,7 @@
 {
     size_t olen = 0;

-    if (MBEDTLS_DECRYPT != ctx->operation)
+    if (MBEDTLS_DECRYPT != mbedtls_cipher_get_operation(ctx))
     {
         return 0;
     }
@@ -866,7 +879,7 @@
     {
         return 0;
     }
-    return mbedtls_md_get_size(ctx->md_info);
+    return (int)mbedtls_md_get_size(mbedtls_md_info_from_ctx(ctx));
 }

 void
@@ -936,7 +949,7 @@
     {
         return 0;
     }
-    return mbedtls_md_get_size(ctx->md_info);
+    return mbedtls_md_get_size(mbedtls_md_info_from_ctx(ctx));
 }

 void
@@ -976,8 +989,9 @@

     return diff;
 }
-/* mbedtls-2.18.0 or newer */
-#ifdef HAVE_MBEDTLS_SSL_TLS_PRF
+/* mbedtls-2.18.0 or newer implements tls_prf, but prf_tls1 is removed
+ * from recent versions, so we use our own implementation if necessary. */
+#if HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1)
 bool
 ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret,
              int secret_len, uint8_t *output, int output_len)
@@ -986,7 +1000,7 @@
                                        secret_len, "", seed, seed_len, output,
                                        output_len));
 }
-#else  /* ifdef HAVE_MBEDTLS_SSL_TLS_PRF */
+#else /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
 /*
  * Generate the hash required by for the \c tls1_PRF function.
  *
@@ -1115,5 +1129,5 @@
     gc_free(&gc);
     return true;
 }
-#endif /* ifdef HAVE_MBEDTLS_SSL_TLS_PRF */
+#endif /* HAVE_MBEDTLS_SSL_TLS_PRF && defined(MBEDTLS_SSL_TLS_PRF_TLS1) */
 #endif /* ENABLE_CRYPTO_MBEDTLS */
diff --git a/src/openvpn/mbedtls_compat.h b/src/openvpn/mbedtls_compat.h
new file mode 100644
index 0000000..610215b
--- /dev/null
+++ b/src/openvpn/mbedtls_compat.h
@@ -0,0 +1,189 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single TCP/UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2023 Fox Crypto B.V. <openvpn@foxcrypto.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file mbedtls compatibility stub
+ *
+ * This file provide compatibility stubs for the mbedtls libraries
+ * prior to version 3. This version made most fields in structs private
+ * and requires accessor functions to be used. For earlier versions, we
+ * implement the accessor functions here.
+ */
+
+#ifndef MBEDTLS_COMPAT_H_
+#define MBEDTLS_COMPAT_H_
+
+#include "syshead.h"
+
+#include "errlevel.h"
+
+#include <mbedtls/cipher.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/dhm.h>
+#include <mbedtls/md.h>
+#include <mbedtls/pem.h>
+#include <mbedtls/pk.h>
+#include <mbedtls/ssl.h>
+#include <mbedtls/version.h>
+#include <mbedtls/x509_crt.h>
+
+#if HAVE_MBEDTLS_PSA_CRYPTO_H
+    #include <psa/crypto.h>
+#endif
+
+static inline void
+mbedtls_compat_psa_crypto_init(void)
+{
+#if HAVE_MBEDTLS_PSA_CRYPTO_H && defined(MBEDTLS_PSA_CRYPTO_C)
+    if (psa_crypto_init() != PSA_SUCCESS)
+    {
+        msg(M_FATAL, "mbedtls: psa_crypto_init() failed");
+    }
+#else
+    return;
+#endif /* HAVE_MBEDTLS_PSA_CRYPTO_H && defined(MBEDTLS_PSA_CRYPTO_C) */
+}
+
+/*
+ * In older versions of mbedtls, mbedtls_ctr_drbg_update() did not return an
+ * error code, and it was deprecated in favor of mbedtls_ctr_drbg_update_ret()
+ * which does.
+ *
+ * In mbedtls 3, this function was removed and mbedtls_ctr_drbg_update() returns
+ * an error code.
+ */
+static inline int
+mbedtls_compat_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
+                               const unsigned char *additional,
+                               size_t add_len)
+{
+#if HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET
+    return mbedtls_ctr_drbg_update_ret(ctx, additional, add_len);
+#elif MBEDTLS_VERSION_NUMBER < 0x03020100
+    mbedtls_ctr_drbg_update(ctx, additional, add_len);
+    return 0;
+#else
+    return mbedtls_ctr_drbg_update(ctx, additional, add_len);
+#endif /* HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET */
+}
+
+static inline int
+mbedtls_compat_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context \
*prv, +                             int (*f_rng)(void *, unsigned char *, size_t), \
void *p_rng) +{
+#if MBEDTLS_VERSION_NUMBER < 0x03020100
+    return mbedtls_pk_check_pair(pub, prv);
+#else
+    return mbedtls_pk_check_pair(pub, prv, f_rng, p_rng);
+#endif /* MBEDTLS_VERSION_NUMBER < 0x03020100 */
+}
+
+static inline int
+mbedtls_compat_pk_parse_key(mbedtls_pk_context *ctx,
+                            const unsigned char *key, size_t keylen,
+                            const unsigned char *pwd, size_t pwdlen,
+                            int (*f_rng)(void *, unsigned char *, size_t), void \
*p_rng) +{
+#if MBEDTLS_VERSION_NUMBER < 0x03020100
+    return mbedtls_pk_parse_key(ctx, key, keylen, pwd, pwdlen);
+#else
+    return mbedtls_pk_parse_key(ctx, key, keylen, pwd, pwdlen, f_rng, p_rng);
+#endif
+}
+
+static inline int
+mbedtls_compat_pk_parse_keyfile(mbedtls_pk_context *ctx,
+                                const char *path, const char *password,
+                                int (*f_rng)(void *, unsigned char *, size_t), void \
*p_rng) +{
+#if MBEDTLS_VERSION_NUMBER < 0x03020100
+    return mbedtls_pk_parse_keyfile(ctx, path, password);
+#else
+    return mbedtls_pk_parse_keyfile(ctx, path, password, f_rng, p_rng);
+#endif
+}
+
+#if MBEDTLS_VERSION_NUMBER < 0x03020100
+static inline size_t
+mbedtls_cipher_info_get_block_size(const mbedtls_cipher_info_t *cipher)
+{
+    return (size_t)cipher->block_size;
+}
+
+static inline size_t
+mbedtls_cipher_info_get_iv_size(const mbedtls_cipher_info_t *cipher)
+{
+    return (size_t)cipher->iv_size;
+}
+
+static inline size_t
+mbedtls_cipher_info_get_key_bitlen(const mbedtls_cipher_info_t *cipher)
+{
+    return (size_t)cipher->key_bitlen;
+}
+
+static inline mbedtls_cipher_mode_t
+mbedtls_cipher_info_get_mode(const mbedtls_cipher_info_t *cipher)
+{
+    return cipher->mode;
+}
+
+static inline const char *
+mbedtls_cipher_info_get_name(const mbedtls_cipher_info_t *cipher)
+{
+    return cipher->name;
+}
+
+static inline mbedtls_cipher_type_t
+mbedtls_cipher_info_get_type(const mbedtls_cipher_info_t *cipher)
+{
+    return cipher->type;
+}
+
+static inline size_t
+mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx)
+{
+    return 8 * ctx->len;
+}
+
+static inline const mbedtls_md_info_t *
+mbedtls_md_info_from_ctx(const mbedtls_md_context_t *ctx)
+{
+    return ctx->md_info;
+}
+
+static inline const unsigned char *
+mbedtls_pem_get_buffer(const mbedtls_pem_context *ctx, size_t *buf_size)
+{
+    *buf_size = ctx->buflen;
+    return ctx->buf;
+}
+
+static inline int
+mbedtls_x509_crt_has_ext_type(const mbedtls_x509_crt *ctx, int ext_type)
+{
+    return ctx->ext_types & ext_type;
+}
+#endif /* MBEDTLS_VERSION_NUMBER < 0x03020100 */
+
+#endif /* MBEDTLS_COMPAT_H_ */
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 7ca77a8..ea09d06 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -653,8 +653,10 @@
     "--verify-x509-name name: Accept connections only from a host with X509 \
                subject\n"
     "                  DN name. The remote host must also pass all other tests\n"
     "                  of verification.\n"
+#ifndef ENABLE_CRYPTO_MBEDTLS
     "--ns-cert-type t: (DEPRECATED) Require that peer certificate was signed with \
                \n"
     "                  an explicit nsCertType designation t = 'client' | \
'server'.\n" +#endif
     "--x509-track x  : Save peer X509 attribute x in environment for use by\n"
     "                  plugins and management interface.\n"
 #ifdef HAVE_EXPORT_KEYING_MATERIAL
@@ -9051,6 +9053,10 @@
     }
     else if (streq(p[0], "ns-cert-type") && p[1] && !p[2])
     {
+#ifdef ENABLE_CRYPTO_MBEDTLS
+        msg(msglevel, "--ns-cert-type is not available with mbedtls.");
+        goto err;
+#else
         VERIFY_PERMISSION(OPT_P_GENERAL);
         if (streq(p[1], "server"))
         {
@@ -9065,6 +9071,7 @@
             msg(msglevel, "--ns-cert-type must be 'client' or 'server'");
             goto err;
         }
+#endif /* ENABLE_CRYPTO_MBEDTLS */
     }
     else if (streq(p[0], "remote-cert-ku"))
     {
diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c
index 81dd906..9c9167d 100644
--- a/src/openvpn/ssl_mbedtls.c
+++ b/src/openvpn/ssl_mbedtls.c
@@ -41,6 +41,7 @@
 #include "buffer.h"
 #include "misc.h"
 #include "manage.h"
+#include "mbedtls_compat.h"
 #include "pkcs11_backend.h"
 #include "ssl_common.h"

@@ -58,25 +59,6 @@
 #include <mbedtls/oid.h>
 #include <mbedtls/pem.h>
 
-/**
- * Compatibility: mbedtls_ctr_drbg_update was deprecated in mbedtls 2.16 and
- * replaced with mbedtls_ctr_drbg_update_ret, which returns an error code.
- * For older versions, we call mbedtls_ctr_drbg_update and return 0 (success).
- *
- * Note: this change was backported to other mbedTLS branches, therefore we
- * rely on function detection at configure time.
- */
-#ifndef HAVE_CTR_DRBG_UPDATE_RET
-static int
-mbedtls_ctr_drbg_update_ret(mbedtls_ctr_drbg_context *ctx,
-                            const unsigned char *additional,
-                            size_t add_len)
-{
-    mbedtls_ctr_drbg_update(ctx, additional, add_len);
-    return 0;
-}
-#endif
-
 static const mbedtls_x509_crt_profile openvpn_x509_crt_profile_legacy =
 {
     /* Hashes from SHA-1 and above */
@@ -108,6 +90,7 @@
 void
 tls_init_lib(void)
 {
+    mbedtls_compat_psa_crypto_init();
 }

 void
@@ -190,6 +173,16 @@
 }

 #ifdef HAVE_EXPORT_KEYING_MATERIAL
+
+#if HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB
+/*
+ * Key export callback for older versions of mbed TLS, to be used with
+ * mbedtls_ssl_conf_export_keys_ext_cb(). It is called with the master
+ * secret, client random and server random, and the type of PRF function
+ * to use.
+ *
+ * Mbed TLS stores this callback in the mbedtls_ssl_config struct and it
+ * is used in the mbedtls_ssl_contexts set up from that config. */
 int
 mbedtls_ssl_export_keys_cb(void *p_expkey, const unsigned char *ms,
                            const unsigned char *kb, size_t maclen,
@@ -210,8 +203,55 @@
     memcpy(cache->master_secret, ms, sizeof(cache->master_secret));
     cache->tls_prf_type = tls_prf_type;

-    return true;
+    return 0;
 }
+#elif HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB
+/*
+ * Key export callback for newer versions of mbed TLS, to be used with
+ * mbedtls_ssl_set_export_keys_cb(). When used with TLS 1.2, the callback
+ * is called with the TLS 1.2 master secret, client random, server random
+ * and the type of PRF to use. With TLS 1.3, it is called with several
+ * different keys (indicated by type), but unfortunately not the exporter
+ * master secret.
+ *
+ * Unlike in older versions, the callback is not stored in the
+ * mbedtls_ssl_config. It is placed in the mbedtls_ssl_context after it
+ * has been set up. */
+void
+mbedtls_ssl_export_keys_cb(void *p_expkey,
+                           mbedtls_ssl_key_export_type type,
+                           const unsigned char *secret,
+                           size_t secret_len,
+                           const unsigned char client_random[32],
+                           const unsigned char server_random[32],
+                           mbedtls_tls_prf_types tls_prf_type)
+{
+    /* Since we can't get the TLS 1.3 exporter master secret, we ignore all key
+     * types except MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET. */
+    if (type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET)
+    {
+        return;
+    }
+
+    struct tls_session *session = p_expkey;
+    struct key_state_ssl *ks_ssl = &session->key[KS_PRIMARY].ks_ssl;
+    struct tls_key_cache *cache = &ks_ssl->tls_key_cache;
+
+    /* The TLS 1.2 master secret has a fixed size, so if secret_len has
+     * a different value, something is wrong with mbed TLS. */
+    if (secret_len != sizeof(cache->master_secret))
+    {
+        msg(M_FATAL,
+            "ERROR: Incorrect TLS 1.2 master secret length: Got %zu, expected %zu",
+            secret_len, sizeof(cache->master_secret));
+    }
+
+    memcpy(cache->client_server_random, client_random, 32);
+    memcpy(cache->client_server_random + 32, server_random, 32);
+    memcpy(cache->master_secret, secret, sizeof(cache->master_secret));
+    cache->tls_prf_type = tls_prf_type;
+}
+#endif /* HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB */

 bool
 key_state_export_keying_material(struct tls_session *session,
@@ -430,7 +470,7 @@
     }

     msg(D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with " counter_format " bit \
                key",
-        (counter_type) 8 * mbedtls_mpi_size(&ctx->dhm_ctx->P));
+        (counter_type) mbedtls_dhm_get_bitlen(ctx->dhm_ctx));
 }

 void
@@ -504,29 +544,40 @@

     if (priv_key_inline)
     {
-        status = mbedtls_pk_parse_key(ctx->priv_key,
-                                      (const unsigned char *) priv_key_file,
-                                      strlen(priv_key_file) + 1, NULL, 0);
+        status = mbedtls_compat_pk_parse_key(ctx->priv_key,
+                                             (const unsigned char *) priv_key_file,
+                                             strlen(priv_key_file) + 1, NULL, 0,
+                                             mbedtls_ctr_drbg_random,
+                                             rand_ctx_get());

         if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
         {
             char passbuf[512] = {0};
             pem_password_callback(passbuf, 512, 0, NULL);
-            status = mbedtls_pk_parse_key(ctx->priv_key,
-                                          (const unsigned char *) priv_key_file,
-                                          strlen(priv_key_file) + 1,
-                                          (unsigned char *) passbuf,
-                                          strlen(passbuf));
+            status = mbedtls_compat_pk_parse_key(ctx->priv_key,
+                                                 (const unsigned char *) \
priv_key_file, +                                                 \
strlen(priv_key_file) + 1, +                                                 \
(unsigned char *) passbuf, +                                                 \
strlen(passbuf), +                                                 \
mbedtls_ctr_drbg_random, +                                                 \
rand_ctx_get());  }
     }
     else
     {
-        status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL);
+        status = mbedtls_compat_pk_parse_keyfile(ctx->priv_key,
+                                                 priv_key_file,
+                                                 NULL,
+                                                 mbedtls_ctr_drbg_random,
+                                                 rand_ctx_get());
         if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
         {
             char passbuf[512] = {0};
             pem_password_callback(passbuf, 512, 0, NULL);
-            status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, \
passbuf); +            status = mbedtls_compat_pk_parse_keyfile(ctx->priv_key,
+                                                     priv_key_file, passbuf,
+                                                     mbedtls_ctr_drbg_random,
+                                                     rand_ctx_get());
         }
     }
     if (!mbed_ok(status))
@@ -542,7 +593,10 @@
         return 1;
     }

-    if (!mbed_ok(mbedtls_pk_check_pair(&ctx->crt_chain->pk, ctx->priv_key)))
+    if (!mbed_ok(mbedtls_compat_pk_check_pair(&ctx->crt_chain->pk,
+                                              ctx->priv_key,
+                                              mbedtls_ctr_drbg_random,
+                                              rand_ctx_get())))
     {
         msg(M_WARN, "Private key does not match the certificate");
         return 1;
@@ -558,7 +612,6 @@
  * @param ctx_voidptr   Management external key context.
  * @param f_rng         (Unused)
  * @param p_rng         (Unused)
- * @param mode          RSA mode (should be RSA_PRIVATE).
  * @param md_alg        Message digest ('hash') algorithm type.
  * @param hashlen       Length of hash (overridden by length specified by md_alg
  *                      if md_alg != MBEDTLS_MD_NONE).
@@ -572,7 +625,10 @@
  */
 static inline int
 external_pkcs1_sign( void *ctx_voidptr,
-                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int \
mode, +                     int (*f_rng)(void *, unsigned char *, size_t), void \
*p_rng, +#if MBEDTLS_VERSION_NUMBER < 0x03020100
+                     int mode,
+#endif
                      mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned \
char *hash,  unsigned char *sig )
 {
@@ -587,10 +643,12 @@
         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
     }

+#if MBEDTLS_VERSION_NUMBER < 0x03020100
     if (MBEDTLS_RSA_PRIVATE != mode)
     {
         return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
     }
+#endif

     /*
      * Support a wide range of hashes. TLSv1.1 and before only need SIG_RSA_RAW,
@@ -967,7 +1025,7 @@

         if (0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash)))
         {
-            if (!mbed_ok(mbedtls_ctr_drbg_update_ret(cd_ctx, sha256_hash, 32)))
+            if (!mbed_ok(mbedtls_compat_ctr_drbg_update(cd_ctx, sha256_hash, 32)))
             {
                 msg(M_WARN, "WARNING: failed to personalise random, could not update \
CTR_DRBG");  }
@@ -979,13 +1037,15 @@
 int
 tls_version_max(void)
 {
-#if defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_3)
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
     return TLS_VER_1_2;
-#elif defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_2)
+#elif defined(MBEDTLS_SSL_PROTO_TLS1_1)
     return TLS_VER_1_1;
-#else
+#elif defined(MBEDTLS_SSL_PROTO_TLS1)
     return TLS_VER_1_0;
-#endif
+#else /* defined(MBEDTLS_SSL_PROTO_TLS1_2) */
+    #error "mbedtls is compiled without support for TLS 1.0, 1.1 and 1.2."
+#endif /* defined(MBEDTLS_SSL_PROTO_TLS1_2) */
 }

 /**
@@ -1006,23 +1066,29 @@

     switch (tls_ver)
     {
+#if defined(MBEDTLS_SSL_PROTO_TLS1)
         case TLS_VER_1_0:
             *major = MBEDTLS_SSL_MAJOR_VERSION_3;
             *minor = MBEDTLS_SSL_MINOR_VERSION_1;
             break;
+#endif

+#if defined(MBEDTLS_SSL_PROTO_TLS1_1)
         case TLS_VER_1_1:
             *major = MBEDTLS_SSL_MAJOR_VERSION_3;
             *minor = MBEDTLS_SSL_MINOR_VERSION_2;
             break;
+#endif

+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
         case TLS_VER_1_2:
             *major = MBEDTLS_SSL_MAJOR_VERSION_3;
             *minor = MBEDTLS_SSL_MINOR_VERSION_3;
             break;
+#endif

         default:
-            msg(M_FATAL, "%s: invalid TLS version %d", __func__, tls_ver);
+            msg(M_FATAL, "%s: invalid or unsupported TLS version %d", __func__, \
tls_ver);  break;
     }
 }
@@ -1149,17 +1215,17 @@

     /* Initialize minimum TLS version */
     {
-        const int tls_version_min =
+        const int configured_tls_version_min =
             (session->opt->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT)
             &SSLF_TLS_VERSION_MIN_MASK;

-        /* default to TLS 1.0 */
+        /* default to TLS 1.2 */
         int major = MBEDTLS_SSL_MAJOR_VERSION_3;
-        int minor = MBEDTLS_SSL_MINOR_VERSION_1;
+        int minor = MBEDTLS_SSL_MINOR_VERSION_3;

-        if (tls_version_min > TLS_VER_UNSPEC)
+        if (configured_tls_version_min > TLS_VER_UNSPEC)
         {
-            tls_version_to_major_minor(tls_version_min, &major, &minor);
+            tls_version_to_major_minor(configured_tls_version_min, &major, &minor);
         }

         mbedtls_ssl_conf_min_version(ks_ssl->ssl_config, major, minor);
@@ -1167,20 +1233,28 @@

     /* Initialize maximum TLS version */
     {
-        const int tls_version_max =
+        const int configured_tls_version_max =
             (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT)
             &SSLF_TLS_VERSION_MAX_MASK;

-        if (tls_version_max > TLS_VER_UNSPEC)
+        int major = 0;
+        int minor = 0;
+
+        if (configured_tls_version_max > TLS_VER_UNSPEC)
         {
-            int major, minor;
-            tls_version_to_major_minor(tls_version_max, &major, &minor);
-            mbedtls_ssl_conf_max_version(ks_ssl->ssl_config, major, minor);
+            tls_version_to_major_minor(configured_tls_version_max, &major, &minor);
         }
+        else
+        {
+            /* Default to tls_version_max(). */
+            tls_version_to_major_minor(tls_version_max(), &major, &minor);
+        }
+
+        mbedtls_ssl_conf_max_version(ks_ssl->ssl_config, major, minor);
     }

-#ifdef HAVE_EXPORT_KEYING_MATERIAL
-    /* Initialize keying material exporter */
+#if HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB
+    /* Initialize keying material exporter, old style. */
     mbedtls_ssl_conf_export_keys_ext_cb(ks_ssl->ssl_config,
                                         mbedtls_ssl_export_keys_cb, session);
 #endif
@@ -1188,7 +1262,12 @@
     /* Initialise SSL context */
     ALLOC_OBJ_CLEAR(ks_ssl->ctx, mbedtls_ssl_context);
     mbedtls_ssl_init(ks_ssl->ctx);
-    mbedtls_ssl_setup(ks_ssl->ctx, ks_ssl->ssl_config);
+    mbed_ok(mbedtls_ssl_setup(ks_ssl->ctx, ks_ssl->ssl_config));
+
+#if HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB
+    /* Initialize keying material exporter, new style. */
+    mbedtls_ssl_set_export_keys_cb(ks_ssl->ctx, mbedtls_ssl_export_keys_cb, \
session); +#endif

     /* Initialise BIOs */
     ALLOC_OBJ_CLEAR(ks_ssl->bio_ctx, bio_ctx);
diff --git a/src/openvpn/ssl_verify_mbedtls.c b/src/openvpn/ssl_verify_mbedtls.c
index a1ddf8d..ce21324 100644
--- a/src/openvpn/ssl_verify_mbedtls.c
+++ b/src/openvpn/ssl_verify_mbedtls.c
@@ -35,6 +35,7 @@
 #if defined(ENABLE_CRYPTO_MBEDTLS)

 #include "crypto_mbedtls.h"
+#include "mbedtls_compat.h"
 #include "ssl_verify.h"
 #include <mbedtls/asn1.h>
 #include <mbedtls/error.h>
@@ -432,6 +433,8 @@
     }
 }

+/* Dummy function because Netscape certificate types are not supported in OpenVPN \
with mbedtls. + * Returns SUCCESS if usage is NS_CERT_CHECK_NONE, FAILURE otherwise. \
*/  result_t
 x509_verify_ns_cert_type(mbedtls_x509_crt *cert, const int usage)
 {
@@ -439,18 +442,6 @@
     {
         return SUCCESS;
     }
-    if (usage == NS_CERT_CHECK_CLIENT)
-    {
-        return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE)
-                && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT)) ?
-               SUCCESS : FAILURE;
-    }
-    if (usage == NS_CERT_CHECK_SERVER)
-    {
-        return ((cert->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE)
-                && (cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER)) ?
-               SUCCESS : FAILURE;
-    }

     return FAILURE;
 }
@@ -461,7 +452,7 @@
 {
     msg(D_HANDSHAKE, "Validating certificate key usage");

-    if (!(cert->ext_types & MBEDTLS_X509_EXT_KEY_USAGE))
+    if (!mbedtls_x509_crt_has_ext_type(cert, MBEDTLS_X509_EXT_KEY_USAGE))
     {
         msg(D_TLS_ERRORS,
             "ERROR: Certificate does not have key usage extension");
@@ -486,9 +477,7 @@

     if (fFound != SUCCESS)
     {
-        msg(D_TLS_ERRORS,
-            "ERROR: Certificate has key usage %04x, expected one of:",
-            cert->key_usage);
+        msg(D_TLS_ERRORS, "ERROR: Certificate has invalid key usage, expected one \
of:");  for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
         {
             msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
@@ -503,7 +492,7 @@
 {
     result_t fFound = FAILURE;
 
-    if (!(cert->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE))
+    if (!mbedtls_x509_crt_has_ext_type(cert, MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE))
     {
         msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
     }

--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/404?usp=email
To unsubscribe, or for help writing mail filters, visit \
http://gerrit.openvpn.net/settings

Gerrit-Project: openvpn
Gerrit-Branch: release/2.6
Gerrit-Change-Id: Icb4ae73741dc84ef0ff7ef72721cc12b999f4d03
Gerrit-Change-Number: 404
Gerrit-PatchSet: 1
Gerrit-Owner: MaxF <max@max-fillinger.net>
Gerrit-Reviewer: flichtenheld <frank@lichtenheld.com>
Gerrit-Reviewer: plaisthos <arne-openvpn@rfc2549.org>
Gerrit-CC: openvpn-devel <openvpn-devel@lists.sourceforge.net>
Gerrit-Attention: plaisthos <arne-openvpn@rfc2549.org>
Gerrit-Attention: flichtenheld <frank@lichtenheld.com>
Gerrit-MessageType: newchange


[Attachment #3 (text/html)]

<p> Attention is currently required from: flichtenheld, plaisthos. </p>
<p>MaxF would like plaisthos and flichtenheld to <strong>review</strong> this change.
</p><p><a href="http://gerrit.openvpn.net/c/openvpn/+/404?usp=email">View \
Change</a></p><pre style="font-family: monospace,monospace; white-space: \
pre-wrap;">Backport mbed TLS 3 support to OpenVPN 2.6<br><br>Based on commits<br>- \
ace7a4f1c271550bb8ad276663e045ab97a46f16<br>- \
f53f06316dbb804128fc5cbee1d8edb274ce81df<br>- \
efad93d049c318a3bd9ea5956c6ac8237b8d6d70<br>- \
b5faf1b2e90fd44c5137a2b8f3da98c7ae482fc1<br><br>Change-Id: \
Icb4ae73741dc84ef0ff7ef72721cc12b999f4d03<br>Signed-off-by: Max Fillinger \
&lt;maximilian.fillinger@foxcrypto.com&gt;<br>---<br>M README.mbedtls<br>M \
config.h.cmake.in<br>M configure.ac<br>M src/openvpn/Makefile.am<br>M \
src/openvpn/crypto_mbedtls.c<br>A src/openvpn/mbedtls_compat.h<br>M \
src/openvpn/options.c<br>M src/openvpn/ssl_mbedtls.c<br>M \
src/openvpn/ssl_verify_mbedtls.c<br>9 files changed, 422 insertions(+), 115 \
deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: \
pre-wrap;">git pull ssh://gerrit.openvpn.net:29418/openvpn \
refs/changes/04/404/1</pre><pre style="font-family: monospace,monospace; white-space: \
pre-wrap;"><span>diff --git a/README.mbedtls b/README.mbedtls</span><br><span>index \
d3466fa..ed9d369 100644</span><br><span>--- a/README.mbedtls</span><br><span>+++ \
b/README.mbedtls</span><br><span>@@ -1,13 +1,13 @@</span><br><span style="color: \
hsl(0, 100%, 40%);">-This version of OpenVPN has mbed TLS support. To enable follow \
the following</span><br><span style="color: hsl(0, 100%, \
40%);">-instructions:</span><br><span style="color: hsl(120, 100%, 40%);">+This \
version of OpenVPN has mbed TLS support. To enable, follow the</span><br><span \
style="color: hsl(120, 100%, 40%);">+instructions below:</span><br><span> \
</span><br><span style="color: hsl(0, 100%, 40%);">-To Build and \
Install,</span><br><span style="color: hsl(120, 100%, 40%);">+To build and \
install,</span><br><span> </span><br><span> 	./configure \
--with-crypto-library=mbedtls</span><br><span> 	make</span><br><span> 	make \
install</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-This \
version depends on mbed TLS 2.0 (and requires at least 2.0.0).</span><br><span \
style="color: hsl(120, 100%, 40%);">+This version requires mbed TLS version &gt;= \
2.0.0 or &gt;= 3.2.1.</span><br><span> </span><br><span> \
*************************************************************************</span><br><span> \
</span><br><span>@@ -16,7 +16,8 @@</span><br><span> As of mbed TLS 2.17, it can be \
licensed *only* under the Apache v2.0 license.</span><br><span> That license is \
incompatible with OpenVPN&#39;s GPLv2.</span><br><span> </span><br><span \
style="color: hsl(0, 100%, 40%);">-If you wish to distribute OpenVPN linked with mbed \
TLS, there are two options:</span><br><span style="color: hsl(120, 100%, 40%);">+We \
are currently in the process of resolving this problem, but for now, if \
you</span><br><span style="color: hsl(120, 100%, 40%);">+wish to distribute OpenVPN \
linked with mbed TLS, there are two options:</span><br><span> </span><br><span>  * \
Ensure that your case falls under the system library exception in GPLv2, \
or</span><br><span> </span><br><span>@@ -24,9 +25,6 @@</span><br><span>    that may \
be licensed under GPLv2. Unfortunately, this version is</span><br><span>    \
unsupported and won&#39;t receive any more updates.</span><br><span> </span><br><span \
style="color: hsl(0, 100%, 40%);">-If nothing changes about the license situation, \
mbed TLS support may be</span><br><span style="color: hsl(0, 100%, 40%);">-deprecated \
in a future release of OpenVPN.</span><br><span style="color: hsl(0, 100%, \
40%);">-</span><br><span> \
*************************************************************************</span><br><span> \
</span><br><span> Due to limitations in the mbed TLS library, the following features \
are missing</span><br><span>@@ -42,3 +40,8 @@</span><br><span>  * X.509 subject line \
has a different format than the OpenSSL subject line</span><br><span>  * X.509 \
certificate export does not work</span><br><span>  * X.509 certificate \
tracking</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span \
style="color: hsl(120, 100%, \
40%);">+*************************************************************************</span><br><span \
style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, \
40%);">+Mbed TLS 3 has implemented (parts of) the TLS 1.3 protocol, but we have \
disabled</span><br><span style="color: hsl(120, 100%, 40%);">+support in OpenVPN \
because the TLS-Exporter function is not yet implemented.</span><br><span>diff --git \
a/config.h.cmake.in b/config.h.cmake.in</span><br><span>index 29006ce..e88cb77 \
100644</span><br><span>--- a/config.h.cmake.in</span><br><span>+++ \
b/config.h.cmake.in</span><br><span>@@ -387,7 +387,10 @@</span><br><span> #undef \
HAVE_VSNPRINTF</span><br><span> </span><br><span> /* we always assume a recent mbed \
TLS version */</span><br><span style="color: hsl(0, 100%, 40%);">-#define \
HAVE_CTR_DRBG_UPDATE_RET 1</span><br><span style="color: hsl(120, 100%, \
40%);">+#define HAVE_MBEDTLS_PSA_CRYPTO_H 1</span><br><span style="color: hsl(120, \
100%, 40%);">+#define HAVE_MBEDTLS_SSL_TLS_PRF 1</span><br><span style="color: \
hsl(120, 100%, 40%);">+#define HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB 1</span><br><span \
style="color: hsl(120, 100%, 40%);">+#define HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET \
1</span><br><span> </span><br><span> /* Path to ifconfig tool */</span><br><span> \
#define IFCONFIG_PATH &quot;@IFCONFIG_PATH@&quot;</span><br><span>diff --git \
a/configure.ac b/configure.ac</span><br><span>index 052fe3f..749c857 \
100644</span><br><span>--- a/configure.ac</span><br><span>+++ \
b/configure.ac</span><br><span>@@ -1019,13 +1019,19 @@</span><br><span> #include \
&lt;mbedtls/version.h&gt;</span><br><span> 			]],</span><br><span> \
[[</span><br><span style="color: hsl(0, 100%, 40%);">-#if MBEDTLS_VERSION_NUMBER &lt; \
0x02000000 || MBEDTLS_VERSION_NUMBER &gt;= 0x03000000</span><br><span style="color: \
hsl(120, 100%, 40%);">+#if MBEDTLS_VERSION_NUMBER &lt; 0x02000000 || \
(MBEDTLS_VERSION_NUMBER &gt;= 0x03000000 &amp;&amp; MBEDTLS_VERSION_NUMBER &lt; \
0x03020100)</span><br><span> #error invalid version</span><br><span> \
#endif</span><br><span> 			]]</span><br><span> 		)],</span><br><span> \
[AC_MSG_RESULT([ok])],</span><br><span style="color: hsl(0, 100%, \
40%);">-		[AC_MSG_ERROR([mbed TLS 2.y.z required])]</span><br><span style="color: \
hsl(120, 100%, 40%);">+		[AC_MSG_ERROR([mbed TLS version &gt;= 2.0.0 or &gt;= 3.2.1 \
required])]</span><br><span style="color: hsl(120, 100%, 40%);">+	)</span><br><span \
style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, \
40%);">+	AC_CHECK_HEADER(</span><br><span style="color: hsl(120, 100%, \
40%);">+		psa/crypto.h,</span><br><span style="color: hsl(120, 100%, \
40%);">+		[AC_DEFINE([HAVE_MBEDTLS_PSA_CRYPTO_H], [1], [yes])],</span><br><span \
style="color: hsl(120, 100%, 40%);">+		[AC_DEFINE([HAVE_MBEDTLS_PSA_CRYPTO_H], [0], \
[no])]</span><br><span> 	)</span><br><span> </span><br><span> \
AC_CHECK_FUNCS(</span><br><span>@@ -1037,16 +1043,32 @@</span><br><span> \
[AC_MSG_ERROR([mbed TLS check for AEAD support failed])]</span><br><span> \
)</span><br><span> </span><br><span style="color: hsl(120, 100%, \
40%);">+	AC_CHECK_FUNC(</span><br><span style="color: hsl(120, 100%, \
40%);">+		[mbedtls_ssl_tls_prf],</span><br><span style="color: hsl(120, 100%, \
40%);">+		[AC_DEFINE([HAVE_MBEDTLS_SSL_TLS_PRF], [1], [yes])],</span><br><span \
style="color: hsl(120, 100%, 40%);">+		[AC_DEFINE([HAVE_MBEDTLS_SSL_TLS_PRF], [0], \
[no])]</span><br><span style="color: hsl(120, 100%, 40%);">+	)</span><br><span \
style="color: hsl(120, 100%, 40%);">+</span><br><span> \
have_export_keying_material=&quot;yes&quot;</span><br><span> \
AC_CHECK_FUNC(</span><br><span> \
[mbedtls_ssl_conf_export_keys_ext_cb],</span><br><span style="color: hsl(0, 100%, \
40%);">-		,</span><br><span style="color: hsl(0, 100%, \
40%);">-		[have_export_keying_material=&quot;no&quot;]</span><br><span style="color: \
hsl(120, 100%, 40%);">+		[AC_DEFINE([HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB], [1], \
[yes])],</span><br><span style="color: hsl(120, 100%, \
40%);">+		[AC_DEFINE([HAVE_MBEDTLS_SSL_CONF_EXPORT_KEYS_EXT_CB], [0], \
[no])]</span><br><span> 	)</span><br><span style="color: hsl(120, 100%, 40%);">+	if \
test &quot;x$ac_cv_func_mbedtls_ssl_conf_export_keys_ext_cb&quot; != xyes; \
then</span><br><span style="color: hsl(120, 100%, \
40%);">+		AC_CHECK_FUNC(</span><br><span style="color: hsl(120, 100%, \
40%);">+			[mbedtls_ssl_set_export_keys_cb],</span><br><span style="color: hsl(120, \
100%, 40%);">+			[AC_DEFINE([HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB], [1], \
[yes])],</span><br><span style="color: hsl(120, 100%, \
40%);">+			[AC_DEFINE([HAVE_MBEDTLS_SSL_SET_EXPORT_KEYS_CB], [0], \
[no])]</span><br><span style="color: hsl(120, 100%, 40%);">+		)</span><br><span \
style="color: hsl(120, 100%, 40%);">+		if test \
&quot;x$ac_cv_func_mbedtls_ssl_set_export_keys_cb&quot; != xyes; then</span><br><span \
style="color: hsl(120, 100%, \
40%);">+			have_export_keying_material=&quot;no&quot;</span><br><span style="color: \
hsl(120, 100%, 40%);">+		fi</span><br><span style="color: hsl(120, 100%, \
40%);">+	fi</span><br><span> </span><br><span> 	AC_CHECK_FUNC(</span><br><span> \
[mbedtls_ctr_drbg_update_ret],</span><br><span style="color: hsl(0, 100%, \
40%);">-		AC_DEFINE([HAVE_CTR_DRBG_UPDATE_RET], [1],</span><br><span style="color: \
hsl(120, 100%, 40%);">+		AC_DEFINE([HAVE_MBEDTLS_CTR_DRBG_UPDATE_RET], \
[1],</span><br><span> 			  [Use mbedtls_ctr_drbg_update_ret from mbed \
TLS]),</span><br><span> 	)</span><br><span> </span><br><span>diff --git \
a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am</span><br><span>index \
52deef8..b953961 100644</span><br><span>--- \
a/src/openvpn/Makefile.am</span><br><span>+++ \
b/src/openvpn/Makefile.am</span><br><span>@@ -82,6 +82,7 @@</span><br><span> \
ovpn_dco_win.h \</span><br><span> 	platform.c platform.h \</span><br><span> \
console.c console.h console_builtin.c console_systemd.c \</span><br><span \
style="color: hsl(120, 100%, 40%);">+	mbedtls_compat.h \</span><br><span> 	mroute.c \
mroute.h \</span><br><span> 	mss.c mss.h \</span><br><span> 	mstats.c mstats.h \
\</span><br><span>diff --git a/src/openvpn/crypto_mbedtls.c \
b/src/openvpn/crypto_mbedtls.c</span><br><span>index 98cac60..ad3439c \
100644</span><br><span>--- a/src/openvpn/crypto_mbedtls.c</span><br><span>+++ \
b/src/openvpn/crypto_mbedtls.c</span><br><span>@@ -41,6 +41,7 @@</span><br><span> \
#include &quot;integer.h&quot;</span><br><span> #include \
&quot;crypto_backend.h&quot;</span><br><span> #include \
&quot;otime.h&quot;</span><br><span style="color: hsl(120, 100%, 40%);">+#include \
&quot;mbedtls_compat.h&quot;</span><br><span> #include \
&quot;misc.h&quot;</span><br><span> </span><br><span> #include \
&lt;mbedtls/base64.h&gt;</span><br><span>@@ -170,10 +171,11 @@</span><br><span>     \
while (*ciphers != 0)</span><br><span>     {</span><br><span>         const \
mbedtls_cipher_info_t *info = \
mbedtls_cipher_info_from_type(*ciphers);</span><br><span style="color: hsl(0, 100%, \
40%);">-        if (info &amp;&amp; \
!cipher_kt_insecure(info-&gt;name)</span><br><span style="color: hsl(0, 100%, \
40%);">-            &amp;&amp; (cipher_kt_mode_aead(info-&gt;name) || \
cipher_kt_mode_cbc(info-&gt;name)))</span><br><span style="color: hsl(120, 100%, \
40%);">+        const char *name = \
mbedtls_cipher_info_get_name(info);</span><br><span style="color: hsl(120, 100%, \
40%);">+        if (info &amp;&amp; name &amp;&amp; \
!cipher_kt_insecure(name)</span><br><span style="color: hsl(120, 100%, 40%);">+       \
&amp;&amp; (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))</span><br><span>  \
{</span><br><span style="color: hsl(0, 100%, 40%);">-            \
print_cipher(info-&gt;name);</span><br><span style="color: hsl(120, 100%, 40%);">+    \
print_cipher(name);</span><br><span>         }</span><br><span>         \
ciphers++;</span><br><span>     }</span><br><span>@@ -184,10 +186,11 \
@@</span><br><span>     while (*ciphers != 0)</span><br><span>     {</span><br><span> \
const mbedtls_cipher_info_t *info = \
mbedtls_cipher_info_from_type(*ciphers);</span><br><span style="color: hsl(0, 100%, \
40%);">-        if (info &amp;&amp; cipher_kt_insecure(info-&gt;name)</span><br><span \
style="color: hsl(0, 100%, 40%);">-            &amp;&amp; \
(cipher_kt_mode_aead(info-&gt;name) || \
cipher_kt_mode_cbc(info-&gt;name)))</span><br><span style="color: hsl(120, 100%, \
40%);">+        const char *name = \
mbedtls_cipher_info_get_name(info);</span><br><span style="color: hsl(120, 100%, \
40%);">+        if (info &amp;&amp; name &amp;&amp; \
cipher_kt_insecure(name)</span><br><span style="color: hsl(120, 100%, 40%);">+        \
&amp;&amp; (cipher_kt_mode_aead(name) || cipher_kt_mode_cbc(name)))</span><br><span>  \
{</span><br><span style="color: hsl(0, 100%, 40%);">-            \
print_cipher(info-&gt;name);</span><br><span style="color: hsl(120, 100%, 40%);">+    \
print_cipher(name);</span><br><span>         }</span><br><span>         \
ciphers++;</span><br><span>     }</span><br><span>@@ -295,7 +298,9 \
@@</span><br><span>     mbedtls_pem_context ctx = { 0 };</span><br><span>     bool \
ret = mbed_ok(mbedtls_pem_read_buffer(&amp;ctx, header, footer, \
BPTR(&amp;input),</span><br><span>                                                \
NULL, 0, &amp;use_len));</span><br><span style="color: hsl(0, 100%, 40%);">-    if \
(ret &amp;&amp; !buf_write(dst, ctx.buf, ctx.buflen))</span><br><span style="color: \
hsl(120, 100%, 40%);">+    size_t buf_size = 0;</span><br><span style="color: \
hsl(120, 100%, 40%);">+    const unsigned char *buf = \
mbedtls_pem_get_buffer(&amp;ctx, &amp;buf_size);</span><br><span style="color: \
hsl(120, 100%, 40%);">+    if (ret &amp;&amp; !buf_write(dst, buf, \
buf_size))</span><br><span>     {</span><br><span>         ret = \
false;</span><br><span>         msg(M_WARN, &quot;PEM decode error: destination \
buffer too small&quot;);</span><br><span>@@ -416,11 +421,12 @@</span><br><span>       \
return false;</span><br><span>     }</span><br><span> </span><br><span style="color: \
hsl(0, 100%, 40%);">-    if (cipher-&gt;key_bitlen/8 &gt; \
MAX_CIPHER_KEY_LENGTH)</span><br><span style="color: hsl(120, 100%, 40%);">+    const \
size_t key_bytelen = mbedtls_cipher_info_get_key_bitlen(cipher)/8;</span><br><span \
style="color: hsl(120, 100%, 40%);">+    if (key_bytelen &gt; \
MAX_CIPHER_KEY_LENGTH)</span><br><span>     {</span><br><span style="color: hsl(0, \
100%, 40%);">-        msg(D_LOW, &quot;Cipher algorithm &#39;%s&#39; uses a default \
key size (%d bytes) &quot;</span><br><span style="color: hsl(120, 100%, 40%);">+      \
msg(D_LOW, &quot;Cipher algorithm &#39;%s&#39; uses a default key size (%zu bytes) \
&quot;</span><br><span>             &quot;which is larger than &quot; PACKAGE_NAME \

<div style="display:none"> Gerrit-Project: openvpn </div>
<div style="display:none"> Gerrit-Branch: release/2.6 </div>
<div style="display:none"> Gerrit-Change-Id: \
Icb4ae73741dc84ef0ff7ef72721cc12b999f4d03 </div> <div style="display:none"> \
Gerrit-Change-Number: 404 </div> <div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: MaxF &lt;max@max-fillinger.net&gt; </div>
<div style="display:none"> Gerrit-Reviewer: flichtenheld \
&lt;frank@lichtenheld.com&gt; </div> <div style="display:none"> Gerrit-Reviewer: \
plaisthos &lt;arne-openvpn@rfc2549.org&gt; </div> <div style="display:none"> \
Gerrit-CC: openvpn-devel &lt;openvpn-devel@lists.sourceforge.net&gt; </div> <div \
style="display:none"> Gerrit-Attention: plaisthos &lt;arne-openvpn@rfc2549.org&gt; \
</div> <div style="display:none"> Gerrit-Attention: flichtenheld \
&lt;frank@lichtenheld.com&gt; </div> <div style="display:none"> Gerrit-MessageType: \
newchange </div>


[Attachment #4 (--===============5805029615913005394==)]


_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic