mirror of
https://github.com/amnezia-vpn/openvpn3.git
synced 2026-05-17 00:16:12 +03:00
Add support for mbed TLS 3.0
This currently still depends on the mbed TLS compat API functionality. Signed-off-by: Arne Schwabe <arne@openvpn.net>
This commit is contained in:
committed by
Frank Lichtenheld
parent
ade5f80f8a
commit
c1bcf78d2e
@@ -51,7 +51,7 @@ function(add_core_dependencies target)
|
||||
-DASIO_STANDALONE
|
||||
-DUSE_ASIO
|
||||
-DHAVE_LZ4
|
||||
-DMBEDTLS_DEPRECATED_REMOVED
|
||||
#-DMBEDTLS_DEPRECATED_REMOVED # with mbed TLS 3.0 we currently still need the deprecated APIs
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
|
||||
@@ -310,6 +310,7 @@ class ParseClientConfig
|
||||
try
|
||||
{
|
||||
sslConfig.reset(new SSLLib::SSLAPI::Config());
|
||||
sslConfig->set_rng(new SSLLib::RandomAPI());
|
||||
sslConfig->load(options, lflags);
|
||||
}
|
||||
catch (...)
|
||||
|
||||
@@ -143,7 +143,7 @@ class CipherContext
|
||||
throw mbedtls_cipher_error("mbedtls_cipher_setup");
|
||||
|
||||
// set key and encrypt/decrypt mode
|
||||
if (mbedtls_cipher_setkey(&ctx, key, ci->key_bitlen, (mbedtls_operation_t)mode) < 0)
|
||||
if (mbedtls_cipher_setkey(&ctx, key, mbedtls_cipher_get_key_bitlen(&ctx), (mbedtls_operation_t)mode) < 0)
|
||||
throw mbedtls_cipher_error("mbedtls_cipher_setkey");
|
||||
|
||||
initialized = true;
|
||||
@@ -229,8 +229,11 @@ class CipherContext
|
||||
return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_CBC);
|
||||
case CryptoAlgs::DES_EDE3_CBC:
|
||||
return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_EDE3_CBC);
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
/* no longer supported in newer mbed TLS versions */
|
||||
case CryptoAlgs::BF_CBC:
|
||||
return mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_BLOWFISH_CBC);
|
||||
#endif
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/crypto/cryptoalgs.hpp>
|
||||
#include <openvpn/mbedtls/mbedtls_compat.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace MbedTLSCrypto {
|
||||
@@ -80,7 +81,6 @@ class DigestContext
|
||||
void init(const CryptoAlgs::Type alg)
|
||||
{
|
||||
erase();
|
||||
ctx.md_ctx = nullptr;
|
||||
|
||||
mbedtls_md_init(&ctx);
|
||||
if (mbedtls_md_setup(&ctx, digest_type(alg), 1) < 0)
|
||||
@@ -121,8 +121,10 @@ class DigestContext
|
||||
{
|
||||
switch (alg)
|
||||
{
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
case CryptoAlgs::MD4:
|
||||
return mbedtls_md_info_from_type(MBEDTLS_MD_MD4);
|
||||
#endif
|
||||
case CryptoAlgs::MD5:
|
||||
return mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
|
||||
case CryptoAlgs::SHA1:
|
||||
@@ -151,7 +153,7 @@ class DigestContext
|
||||
|
||||
size_t size_() const
|
||||
{
|
||||
return mbedtls_md_get_size(ctx.md_info);
|
||||
return mbedtls_md_get_size(mbedtls_md_info_from_ctx(&ctx));
|
||||
}
|
||||
|
||||
void check_initialized() const
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/mbedtls/crypto/digest.hpp>
|
||||
#include <openvpn/mbedtls/mbedtls_compat.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace MbedTLSCrypto {
|
||||
@@ -66,7 +67,6 @@ class HMACContext
|
||||
void init(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
|
||||
{
|
||||
erase();
|
||||
ctx.md_ctx = nullptr;
|
||||
|
||||
mbedtls_md_init(&ctx);
|
||||
if (mbedtls_md_setup(&ctx, DigestContext::digest_type(digest), 1) < 0)
|
||||
@@ -121,7 +121,7 @@ class HMACContext
|
||||
|
||||
size_t size_() const
|
||||
{
|
||||
return mbedtls_md_get_size(ctx.md_info);
|
||||
return mbedtls_md_get_size(mbedtls_md_info_from_ctx(&ctx));
|
||||
}
|
||||
|
||||
void check_initialized() const
|
||||
|
||||
61
openvpn/mbedtls/mbedtls_compat.hpp
Normal file
61
openvpn/mbedtls/mbedtls_compat.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2022 OpenVPN Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License Version 3
|
||||
// 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 Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/version.h>
|
||||
#include <mbedtls/pem.h>
|
||||
|
||||
#if not defined(MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION)
|
||||
#define MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION
|
||||
#endif
|
||||
|
||||
#if not defined(MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE)
|
||||
#define MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE MBEDTLS_X509_EXT_KEY_USAGE
|
||||
#endif
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
static inline const mbedtls_md_info_t *
|
||||
mbedtls_md_info_from_ctx(const mbedtls_md_context_t *ctx)
|
||||
{
|
||||
if (ctx == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return ctx->md_info;
|
||||
}
|
||||
|
||||
static inline int
|
||||
mbedtls_x509_crt_has_ext_type(const mbedtls_x509_crt *crt, int ext_type)
|
||||
{
|
||||
return crt->ext_types & ext_type;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/rc.hpp>
|
||||
#include <openvpn/mbedtls/util/error.hpp>
|
||||
#include <openvpn/mbedtls/util/rand.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace MbedTLSPKI {
|
||||
@@ -48,12 +49,12 @@ class PKContext : public RC<thread_unsafe_refcount>
|
||||
{
|
||||
}
|
||||
|
||||
PKContext(const std::string &key_txt, const std::string &title, const std::string &priv_key_pwd)
|
||||
PKContext(const std::string &key_txt, const std::string &title, const std::string &priv_key_pwd, MbedTLSRandom &rand)
|
||||
: ctx(nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
parse(key_txt, title, priv_key_pwd);
|
||||
parse(key_txt, title, priv_key_pwd, rand);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -92,7 +93,7 @@ class PKContext : public RC<thread_unsafe_refcount>
|
||||
return mbedtls_pk_get_bitlen(ctx);
|
||||
}
|
||||
|
||||
void parse(const std::string &key_txt, const std::string &title, const std::string &priv_key_pwd)
|
||||
void parse(const std::string &key_txt, const std::string &title, const std::string &priv_key_pwd, MbedTLSRandom &rand)
|
||||
{
|
||||
alloc();
|
||||
// key_txt.length() is increased by 1 as it does not include the NULL-terminator
|
||||
@@ -101,7 +102,13 @@ class PKContext : public RC<thread_unsafe_refcount>
|
||||
(const unsigned char *)key_txt.c_str(),
|
||||
key_txt.length() + 1,
|
||||
(const unsigned char *)priv_key_pwd.c_str(),
|
||||
priv_key_pwd.length());
|
||||
priv_key_pwd.length()
|
||||
#if MBEDTLS_VERSION_NUMBER > 0x03000000
|
||||
,
|
||||
mbedtls_ctr_drbg_random,
|
||||
rand.get_ctr_drbg_ctx()
|
||||
#endif
|
||||
);
|
||||
if (status < 0)
|
||||
throw MbedTLSException("error parsing " + title + " private key", status);
|
||||
}
|
||||
|
||||
@@ -69,12 +69,19 @@ namespace openvpn {
|
||||
|
||||
namespace mbedtls_ctx_private {
|
||||
namespace {
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
/*
|
||||
* This is a modified list from mbed TLS ssl_ciphersuites.c.
|
||||
* We removed some SHA1 methods near the top of the list to
|
||||
* avoid Chrome warnings about "obsolete cryptography".
|
||||
* We also removed ECDSA, CCM, PSK, and CAMELLIA algs.
|
||||
*
|
||||
* With mbed TLS 3 or newer we trust the default list of
|
||||
* algorithms in mbed TLS
|
||||
*/
|
||||
|
||||
|
||||
const int ciphersuites[] = // CONST GLOBAL
|
||||
{
|
||||
/* Selected AES-256 ephemeral suites */
|
||||
@@ -132,6 +139,7 @@ const int ciphersuites[] = // CONST GLOBAL
|
||||
MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
|
||||
|
||||
0};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* X509 cert profiles.
|
||||
@@ -301,7 +309,8 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
virtual void load_private_key(const std::string &key_txt)
|
||||
{
|
||||
MbedTLSPKI::PKContext::Ptr p = new MbedTLSPKI::PKContext();
|
||||
p->parse(key_txt, "config", priv_key_pwd);
|
||||
auto *mbedrng = get_mbed_random_class();
|
||||
p->parse(key_txt, "config", priv_key_pwd, *mbedrng);
|
||||
priv_key = p;
|
||||
}
|
||||
|
||||
@@ -464,7 +473,8 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
|
||||
virtual std::string validate_private_key(const std::string &key_txt) const
|
||||
{
|
||||
MbedTLSPKI::PKContext::Ptr pkey = new MbedTLSPKI::PKContext(key_txt, "validation", "");
|
||||
auto *mbedrng = get_mbed_random_class();
|
||||
MbedTLSPKI::PKContext::Ptr pkey = new MbedTLSPKI::PKContext(key_txt, "validation", "", *mbedrng);
|
||||
return key_txt; // fixme -- implement parse/re-render semantics
|
||||
}
|
||||
|
||||
@@ -597,6 +607,21 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
}
|
||||
|
||||
private:
|
||||
MbedTLSRandom *get_mbed_random_class() const
|
||||
{
|
||||
if (!rng)
|
||||
{
|
||||
throw MbedTLSException("RNG not initialised yet");
|
||||
}
|
||||
auto *mbedrng = dynamic_cast<MbedTLSRandom *>(rng.get());
|
||||
if (!mbedrng)
|
||||
{
|
||||
throw MbedTLSException("RNG needs to be MbedTLSRandom");
|
||||
}
|
||||
return mbedrng;
|
||||
}
|
||||
|
||||
|
||||
const mbedtls_x509_crt_profile *select_crt_profile() const
|
||||
{
|
||||
switch (TLSCertProfile::default_if_undef(tls_cert_profile))
|
||||
@@ -813,15 +838,31 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
mbedtls_ssl_init(ssl);
|
||||
|
||||
// set minimum TLS version
|
||||
#if MBEDTLS_VERSION_NUMBER > 0x03000000
|
||||
mbedtls_ssl_protocol_version version;
|
||||
switch (c.tls_version_min)
|
||||
{
|
||||
default:
|
||||
case TLSVersion::Type::V1_2:
|
||||
version = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
break;
|
||||
|
||||
case TLSVersion::Type::V1_3:
|
||||
version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
break;
|
||||
}
|
||||
mbedtls_ssl_conf_min_tls_version(sslconf, version);
|
||||
#else
|
||||
int major;
|
||||
int minor;
|
||||
switch (c.tls_version_min)
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_1)
|
||||
case TLSVersion::Type::V1_0:
|
||||
default:
|
||||
major = MBEDTLS_SSL_MAJOR_VERSION_3;
|
||||
minor = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_2)
|
||||
case TLSVersion::Type::V1_1:
|
||||
major = MBEDTLS_SSL_MAJOR_VERSION_3;
|
||||
@@ -829,6 +870,7 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
break;
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_3)
|
||||
default:
|
||||
case TLSVersion::Type::V1_2:
|
||||
major = MBEDTLS_SSL_MAJOR_VERSION_3;
|
||||
minor = MBEDTLS_SSL_MINOR_VERSION_3;
|
||||
@@ -836,9 +878,13 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
#endif
|
||||
}
|
||||
mbedtls_ssl_conf_min_version(sslconf, major, minor);
|
||||
#if 0 // force TLS 1.0 as maximum version (debugging only, disable in production)
|
||||
mbedtls_ssl_conf_max_version(sslconf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1);
|
||||
#if 0
|
||||
/* force TLS 1.2 as maximum version (debugging only, disable in production) */
|
||||
/* This is basically is the same as tls-version-max that OpenVPN 2.x has but hardcoded */
|
||||
mbedtls_ssl_conf_max_version(sslconf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
{
|
||||
// peer must present a valid certificate unless SSLConst::NO_VERIFY_PEER.
|
||||
@@ -875,7 +921,10 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
}
|
||||
else
|
||||
{
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
/* With newer versions we trust the default */
|
||||
mbedtls_ssl_conf_ciphersuites(sslconf, mbedtls_ctx_private::ciphersuites);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!c.tls_groups.empty())
|
||||
@@ -1218,11 +1267,13 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
|
||||
bool verify_ns_cert_type(const mbedtls_x509_crt *cert) const
|
||||
{
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
if (config->ns_cert_type == NSCert::SERVER)
|
||||
return bool(cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER);
|
||||
else if (config->ns_cert_type == NSCert::CLIENT)
|
||||
return bool(cert->ns_cert_type & MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT);
|
||||
else
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1235,12 +1286,11 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
|
||||
bool verify_x509_cert_ku(const mbedtls_x509_crt *cert)
|
||||
{
|
||||
if (cert->ext_types & MBEDTLS_X509_EXT_KEY_USAGE)
|
||||
if (mbedtls_x509_crt_has_ext_type(cert, MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE))
|
||||
{
|
||||
const unsigned int ku = cert->key_usage;
|
||||
for (std::vector<unsigned int>::const_iterator i = config->ku.begin(); i != config->ku.end(); ++i)
|
||||
{
|
||||
if (ku == *i)
|
||||
if (mbedtls_x509_crt_check_key_usage(cert, *i))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1256,7 +1306,7 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
|
||||
bool verify_x509_cert_eku(mbedtls_x509_crt *cert)
|
||||
{
|
||||
if (cert->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE)
|
||||
if (mbedtls_x509_crt_has_ext_type(cert, MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE))
|
||||
{
|
||||
mbedtls_x509_sequence *oid_seq = &cert->ext_key_usage;
|
||||
while (oid_seq != nullptr)
|
||||
@@ -1309,7 +1359,11 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
if (self->config->flags & SSLConst::LOG_VERIFY_STATUS)
|
||||
OPENVPN_LOG_SSL(status_string(cert, depth, flags));
|
||||
|
||||
// notify if connection is happening with an insecurely signed cert
|
||||
// notify if connection is happening with an insecurely signed cert.
|
||||
|
||||
// mbed TLS 3.0 does not allow the weaker signatures by default and also does not give a
|
||||
// proper accessor to these fields anymore
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
if (cert->sig_md == MBEDTLS_MD_MD5)
|
||||
{
|
||||
ssl->tls_warnings |= SSLAPI::TLS_WARN_SIG_MD5;
|
||||
@@ -1319,6 +1373,7 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
{
|
||||
ssl->tls_warnings |= SSLAPI::TLS_WARN_SIG_SHA1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// leaf-cert verification
|
||||
if (depth == 0)
|
||||
@@ -1466,21 +1521,25 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
}
|
||||
|
||||
static int epki_decrypt(void *arg,
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
int mode,
|
||||
#endif
|
||||
size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len)
|
||||
{
|
||||
OPENVPN_LOG_SSL("MbedTLSContext::epki_decrypt is unimplemented, mode=" << mode
|
||||
<< " output_max_len=" << output_max_len);
|
||||
OPENVPN_LOG_SSL("MbedTLSContext::epki_decrypt is unimplemented"
|
||||
<< " output_max_len=" << output_max_len);
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
static int epki_sign(void *arg,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
int mode,
|
||||
#endif
|
||||
mbedtls_md_type_t md_alg,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
@@ -1489,7 +1548,11 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
MbedTLSContext *self = (MbedTLSContext *)arg;
|
||||
try
|
||||
{
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
if (mode == MBEDTLS_RSA_PRIVATE)
|
||||
#else
|
||||
if (true)
|
||||
#endif
|
||||
{
|
||||
size_t digest_prefix_len = 0;
|
||||
const unsigned char *digest_prefix = nullptr;
|
||||
@@ -1499,10 +1562,6 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
{
|
||||
case MBEDTLS_MD_NONE:
|
||||
break;
|
||||
case MBEDTLS_MD_MD2:
|
||||
digest_prefix = PKCS1::DigestPrefix::MD2;
|
||||
digest_prefix_len = sizeof(PKCS1::DigestPrefix::MD2);
|
||||
break;
|
||||
case MBEDTLS_MD_MD5:
|
||||
digest_prefix = PKCS1::DigestPrefix::MD5;
|
||||
digest_prefix_len = sizeof(PKCS1::DigestPrefix::MD5);
|
||||
@@ -1524,8 +1583,11 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
digest_prefix_len = sizeof(PKCS1::DigestPrefix::SHA512);
|
||||
break;
|
||||
default:
|
||||
OPENVPN_LOG_SSL("MbedTLSContext::epki_sign unrecognized hash_id, mode=" << mode
|
||||
<< " md_alg=" << md_alg << " hashlen=" << hashlen);
|
||||
OPENVPN_LOG_SSL("MbedTLSContext::epki_sign unrecognized hash_id"
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
<< "mode=" << mode
|
||||
#endif
|
||||
<< " md_alg=" << md_alg << " hashlen=" << hashlen);
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
@@ -1558,8 +1620,11 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENVPN_LOG_SSL("MbedTLSContext::epki_sign unrecognized parameters, mode=" << mode
|
||||
<< " md_alg=" << md_alg << " hashlen=" << hashlen);
|
||||
OPENVPN_LOG_SSL("MbedTLSContext::epki_sign unrecognized parameters"
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
<< "mode=" << mode
|
||||
#endif
|
||||
<< " md_alg=" << md_alg << " hashlen=" << hashlen);
|
||||
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
}
|
||||
}
|
||||
@@ -1598,9 +1663,13 @@ class MbedTLSContext : public SSLFactoryAPI
|
||||
// We support for older mbed TLS versions
|
||||
// to be able to build on Debian 9 and Ubuntu 16.
|
||||
mbedtls_sha1(cert->raw.p, cert->raw.len, authcert->issuer_fp);
|
||||
#else
|
||||
#elif MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
if (mbedtls_sha1_ret(cert->raw.p, cert->raw.len, authcert.issuer_fp))
|
||||
return false;
|
||||
#else
|
||||
// mbedtls_sha1_ret is renamed to mbedtls_sha1 in 3.0
|
||||
if (mbedtls_sha1(cert->raw.p, cert->raw.len, authcert.issuer_fp))
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/error/error.hpp>
|
||||
#include <openvpn/error/excode.hpp>
|
||||
#include <openvpn/mbedtls/mbedtls_compat.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
@@ -79,7 +80,7 @@ class MbedTLSException : public ExceptionCode
|
||||
case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
|
||||
set_code(Error::PEM_PASSWORD_FAIL, true);
|
||||
break;
|
||||
case MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION:
|
||||
case MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION:
|
||||
set_code(Error::TLS_VERSION_MIN, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,11 @@ class MbedTLSPEM
|
||||
0,
|
||||
&out_len);
|
||||
if (ret == 0)
|
||||
dst.init(ctx.buf, ctx.buflen, BufferAllocated::DESTRUCT_ZERO);
|
||||
{
|
||||
size_t buflen = 0;
|
||||
const uint8_t *bufptr = mbedtls_pem_get_buffer(&ctx, &buflen);
|
||||
dst.init(bufptr, buflen, BufferAllocated::DESTRUCT_ZERO);
|
||||
}
|
||||
|
||||
mbedtls_pem_free(&ctx);
|
||||
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
namespace openvpn {
|
||||
namespace PKCS1 {
|
||||
namespace DigestPrefix {
|
||||
|
||||
class MbedTLSParse : public Parse<mbedtls_md_type_t>
|
||||
{
|
||||
public:
|
||||
MbedTLSParse()
|
||||
: Parse(MBEDTLS_MD_NONE,
|
||||
MBEDTLS_MD_MD2,
|
||||
MBEDTLS_MD_MD5,
|
||||
MBEDTLS_MD_SHA1,
|
||||
MBEDTLS_MD_SHA256,
|
||||
@@ -47,8 +47,6 @@ class MbedTLSParse : public Parse<mbedtls_md_type_t>
|
||||
{
|
||||
case MBEDTLS_MD_NONE:
|
||||
return "MBEDTLS_MD_NONE";
|
||||
case MBEDTLS_MD_MD2:
|
||||
return "MBEDTLS_MD_MD2";
|
||||
case MBEDTLS_MD_MD5:
|
||||
return "MBEDTLS_MD_MD5";
|
||||
case MBEDTLS_MD_SHA1:
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
#define OPENVPN_MBEDTLS_UTIL_RAND_H
|
||||
|
||||
#include <mbedtls/entropy.h>
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
#include <mbedtls/entropy_poll.h>
|
||||
#endif
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
|
||||
#include <openvpn/random/randapi.hpp>
|
||||
@@ -42,6 +44,7 @@ class MbedTLSRandom : public StrongRandomAPI
|
||||
|
||||
typedef RCPtr<MbedTLSRandom> Ptr;
|
||||
|
||||
|
||||
MbedTLSRandom(StrongRandomAPI::Ptr entropy_source)
|
||||
: entropy(std::move(entropy_source))
|
||||
{
|
||||
@@ -90,6 +93,17 @@ class MbedTLSRandom : public StrongRandomAPI
|
||||
return rndbytes(buf, size) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* function to get the mbedtls_ctr_drbg_context. This is needed for the pk_parse
|
||||
* methods in mbed TLS 3.0 that require a random number generator to avoid side
|
||||
* channel attacks when loading private keys. The returned context is tied
|
||||
* to the internal state of this random number generator.
|
||||
*/
|
||||
mbedtls_ctr_drbg_context *get_ctr_drbg_ctx()
|
||||
{
|
||||
return &ctx;
|
||||
}
|
||||
|
||||
private:
|
||||
int rndbytes(unsigned char *buf, size_t size)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
#include <sstream>
|
||||
|
||||
#include <mbedtls/bignum.h>
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
#include <mbedtls/config.h>
|
||||
#endif
|
||||
#include <mbedtls/cipher.h>
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/sha1.h>
|
||||
|
||||
@@ -68,6 +68,10 @@ const unsigned char SHA512[] = {
|
||||
// clang-format on
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* Class that parses an PKCS #1 header (RFC 3447) to identify the used digest type
|
||||
* @tparam T the type of the crypto library that used should be used for the digest algorithm identification
|
||||
*/
|
||||
template <typename T>
|
||||
class Parse
|
||||
{
|
||||
@@ -89,6 +93,23 @@ class Parse
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for TLS libraries that no longer support MD2 */
|
||||
Parse(const T none,
|
||||
const T md5,
|
||||
const T sha1,
|
||||
const T sha256,
|
||||
const T sha384,
|
||||
const T sha512)
|
||||
: none_(none),
|
||||
md2_(none),
|
||||
md5_(md5),
|
||||
sha1_(sha1),
|
||||
sha256_(sha256),
|
||||
sha384_(sha384),
|
||||
sha512_(sha512)
|
||||
{
|
||||
}
|
||||
|
||||
T alg_from_prefix(Buffer &buf) const
|
||||
{
|
||||
if (match(buf, MD2, sizeof(MD2)))
|
||||
|
||||
@@ -123,8 +123,10 @@ class MacGatewayInfoV4
|
||||
sockfd.reset(socket(PF_ROUTE, SOCK_RAW, 0));
|
||||
if (!sockfd.defined())
|
||||
throw route_gateway_error("GDG: socket #1 failed");
|
||||
if (::write(sockfd(), (char *)&m_rtmsg, l) < 0)
|
||||
throw route_gateway_error("GDG: problem writing to routing socket");
|
||||
auto ret = ::write(sockfd(), (char *)&m_rtmsg, l);
|
||||
if (ret < 0)
|
||||
throw route_gateway_error("GDG: problem writing to routing socket: " + std::to_string(ret)
|
||||
+ " errno: " + std::to_string(errno) + " msg: " + strerror(errno));
|
||||
do
|
||||
{
|
||||
l = ::read(sockfd(), (char *)&m_rtmsg, sizeof(m_rtmsg));
|
||||
|
||||
@@ -614,6 +614,9 @@ class Client : public ClientBase
|
||||
signdata.c_data(),
|
||||
signdata.size(),
|
||||
sig.data(),
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
sig.length(),
|
||||
#endif
|
||||
&sig_size,
|
||||
rng_callback,
|
||||
this);
|
||||
@@ -1391,7 +1394,9 @@ int openvpn_client(int argc, char *argv[], const std::string *profile_content)
|
||||
{
|
||||
const std::string epki_key_txt = read_text_utf8(epki_key_fn);
|
||||
#if defined(USE_MBEDTLS)
|
||||
client.epki_ctx.parse(epki_key_txt, "EPKI", privateKeyPassword);
|
||||
|
||||
auto mbedrng = std::make_unique<MbedTLSRandom>();
|
||||
client.epki_ctx.parse(epki_key_txt, "EPKI", privateKeyPassword, *mbedrng);
|
||||
#else
|
||||
client.epki_pkey.parse_pem(epki_key_txt, "epki private key", nullptr);
|
||||
#endif
|
||||
|
||||
@@ -904,6 +904,7 @@ int test(const int thread_num)
|
||||
ClientSSLAPI::Config::Ptr cc(new ClientSSLAPI::Config());
|
||||
cc->set_mode(Mode(Mode::CLIENT));
|
||||
cc->set_frame(frame);
|
||||
cc->set_rng(rng_cli);
|
||||
#ifdef USE_APPLE_SSL
|
||||
cc->load_identity("etest");
|
||||
#else
|
||||
@@ -915,7 +916,6 @@ int test(const int thread_num)
|
||||
#ifdef VERBOSE
|
||||
cc->set_debug_level(1);
|
||||
#endif
|
||||
cc->set_rng(rng_cli);
|
||||
|
||||
// stats
|
||||
MySessionStats::Ptr cli_stats(new MySessionStats);
|
||||
@@ -1001,12 +1001,12 @@ int test(const int thread_num)
|
||||
ClientSSLAPI::Config::Ptr sc(new ClientSSLAPI::Config());
|
||||
sc->set_mode(Mode(Mode::SERVER));
|
||||
sc->set_frame(frame);
|
||||
sc->set_rng(rng_serv);
|
||||
sc->load_ca(ca_crt, true);
|
||||
sc->load_cert(server_crt);
|
||||
sc->load_private_key(server_key);
|
||||
sc->load_dh(dh_pem);
|
||||
sc->set_tls_version_min(TLS_VER_MIN);
|
||||
sc->set_rng(rng_serv);
|
||||
#ifdef VERBOSE
|
||||
sc->set_debug_level(1);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user