From adba870534bdcdd11f0f344e66090be8e2cd9ae4 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 20 Jan 2023 01:51:35 +0100 Subject: [NET] Refactor TLS configuration. Use a TLSOptions configuration object which is created via static functions. - "TLSOptions.client": uses the standard CA and common name verification. - "TLSOptions.client_unsafe": uses optional CA verification (i.e. if specified) - "TLSOptions.server": is the standard server configuration (chain + key) This will allow us to expand the TLS configuration options to include e.g. mutual authentication without bloating the classes that uses StreamPeerTLS and PacketPeerDTLS as underlying peers. --- modules/mbedtls/dtls_server_mbedtls.cpp | 20 ++++++------- modules/mbedtls/dtls_server_mbedtls.h | 8 ++---- modules/mbedtls/packet_peer_mbed_dtls.cpp | 16 +++++------ modules/mbedtls/packet_peer_mbed_dtls.h | 4 +-- modules/mbedtls/stream_peer_mbedtls.cpp | 14 ++++----- modules/mbedtls/stream_peer_mbedtls.h | 4 +-- modules/mbedtls/tls_context_mbedtls.cpp | 47 ++++++++++++++++++++----------- modules/mbedtls/tls_context_mbedtls.h | 10 +++---- 8 files changed, 67 insertions(+), 56 deletions(-) (limited to 'modules/mbedtls') diff --git a/modules/mbedtls/dtls_server_mbedtls.cpp b/modules/mbedtls/dtls_server_mbedtls.cpp index c54ab8ef6e..62513929ea 100644 --- a/modules/mbedtls/dtls_server_mbedtls.cpp +++ b/modules/mbedtls/dtls_server_mbedtls.cpp @@ -31,25 +31,25 @@ #include "dtls_server_mbedtls.h" #include "packet_peer_mbed_dtls.h" -Error DTLSServerMbedTLS::setup(Ref p_key, Ref p_cert, Ref p_ca_chain) { - ERR_FAIL_COND_V(_cookies->setup() != OK, ERR_ALREADY_IN_USE); - _key = p_key; - _cert = p_cert; - _ca_chain = p_ca_chain; +Error DTLSServerMbedTLS::setup(Ref p_options) { + ERR_FAIL_COND_V(p_options.is_null() || !p_options->is_server(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(cookies->setup() != OK, ERR_ALREADY_IN_USE); + tls_options = p_options; return OK; } void DTLSServerMbedTLS::stop() { - _cookies->clear(); + cookies->clear(); } Ref DTLSServerMbedTLS::take_connection(Ref p_udp_peer) { Ref out; - out.instantiate(); - ERR_FAIL_COND_V(!out.is_valid(), out); + ERR_FAIL_COND_V(tls_options.is_null(), out); ERR_FAIL_COND_V(!p_udp_peer.is_valid(), out); - out->accept_peer(p_udp_peer, _key, _cert, _ca_chain, _cookies); + + out.instantiate(); + out->accept_peer(p_udp_peer, tls_options, cookies); return out; } @@ -68,7 +68,7 @@ void DTLSServerMbedTLS::finalize() { } DTLSServerMbedTLS::DTLSServerMbedTLS() { - _cookies.instantiate(); + cookies.instantiate(); } DTLSServerMbedTLS::~DTLSServerMbedTLS() { diff --git a/modules/mbedtls/dtls_server_mbedtls.h b/modules/mbedtls/dtls_server_mbedtls.h index e4612d01ef..d5841a45fa 100644 --- a/modules/mbedtls/dtls_server_mbedtls.h +++ b/modules/mbedtls/dtls_server_mbedtls.h @@ -37,16 +37,14 @@ class DTLSServerMbedTLS : public DTLSServer { private: static DTLSServer *_create_func(); - Ref _key; - Ref _cert; - Ref _ca_chain; - Ref _cookies; + Ref tls_options; + Ref cookies; public: static void initialize(); static void finalize(); - virtual Error setup(Ref p_key, Ref p_cert, Ref p_ca_chain = Ref()); + virtual Error setup(Ref p_options); virtual void stop(); virtual Ref take_connection(Ref p_peer); diff --git a/modules/mbedtls/packet_peer_mbed_dtls.cpp b/modules/mbedtls/packet_peer_mbed_dtls.cpp index 16450e151e..e8eb32f88d 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.cpp +++ b/modules/mbedtls/packet_peer_mbed_dtls.cpp @@ -114,16 +114,14 @@ Error PacketPeerMbedDTLS::_do_handshake() { return OK; } -Error PacketPeerMbedDTLS::connect_to_peer(Ref p_base, bool p_validate_certs, const String &p_for_hostname, Ref p_ca_certs) { +Error PacketPeerMbedDTLS::connect_to_peer(Ref p_base, const String &p_hostname, Ref p_options) { ERR_FAIL_COND_V(!p_base.is_valid() || !p_base->is_socket_connected(), ERR_INVALID_PARAMETER); - base = p_base; - int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE; - - Error err = tls_ctx->init_client(MBEDTLS_SSL_TRANSPORT_DATAGRAM, authmode, p_ca_certs); + Error err = tls_ctx->init_client(MBEDTLS_SSL_TRANSPORT_DATAGRAM, p_hostname, p_options.is_valid() ? p_options : TLSOptions::client()); ERR_FAIL_COND_V(err != OK, err); - mbedtls_ssl_set_hostname(tls_ctx->get_context(), p_for_hostname.utf8().get_data()); + base = p_base; + mbedtls_ssl_set_bio(tls_ctx->get_context(), this, bio_send, bio_recv, nullptr); mbedtls_ssl_set_timer_cb(tls_ctx->get_context(), &timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); @@ -137,8 +135,10 @@ Error PacketPeerMbedDTLS::connect_to_peer(Ref p_base, bool p_vali return OK; } -Error PacketPeerMbedDTLS::accept_peer(Ref p_base, Ref p_key, Ref p_cert, Ref p_ca_chain, Ref p_cookies) { - Error err = tls_ctx->init_server(MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_VERIFY_NONE, p_key, p_cert, p_cookies); +Error PacketPeerMbedDTLS::accept_peer(Ref p_base, Ref p_options, Ref p_cookies) { + ERR_FAIL_COND_V(!p_base.is_valid() || !p_base->is_socket_connected(), ERR_INVALID_PARAMETER); + + Error err = tls_ctx->init_server(MBEDTLS_SSL_TRANSPORT_DATAGRAM, p_options, p_cookies); ERR_FAIL_COND_V(err != OK, err); base = p_base; diff --git a/modules/mbedtls/packet_peer_mbed_dtls.h b/modules/mbedtls/packet_peer_mbed_dtls.h index 744ef81524..05decec783 100644 --- a/modules/mbedtls/packet_peer_mbed_dtls.h +++ b/modules/mbedtls/packet_peer_mbed_dtls.h @@ -64,8 +64,8 @@ protected: public: virtual void poll(); - virtual Error accept_peer(Ref p_base, Ref p_key, Ref p_cert = Ref(), Ref p_ca_chain = Ref(), Ref p_cookies = Ref()); - virtual Error connect_to_peer(Ref p_base, bool p_validate_certs = true, const String &p_for_hostname = String(), Ref p_ca_certs = Ref()); + virtual Error accept_peer(Ref p_base, Ref p_options, Ref p_cookies = Ref()); + virtual Error connect_to_peer(Ref p_base, const String &p_hostname, Ref p_options = Ref()); virtual Status get_status() const; virtual void disconnect_from_peer(); diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp index 1d17fb9441..0ea426c8b5 100644 --- a/modules/mbedtls/stream_peer_mbedtls.cpp +++ b/modules/mbedtls/stream_peer_mbedtls.cpp @@ -102,16 +102,13 @@ Error StreamPeerMbedTLS::_do_handshake() { return OK; } -Error StreamPeerMbedTLS::connect_to_stream(Ref p_base, bool p_validate_certs, const String &p_for_hostname, Ref p_ca_certs) { +Error StreamPeerMbedTLS::connect_to_stream(Ref p_base, const String &p_common_name, Ref p_options) { ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER); - base = p_base; - int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE; - - Error err = tls_ctx->init_client(MBEDTLS_SSL_TRANSPORT_STREAM, authmode, p_ca_certs); + Error err = tls_ctx->init_client(MBEDTLS_SSL_TRANSPORT_STREAM, p_common_name, p_options.is_valid() ? p_options : TLSOptions::client()); ERR_FAIL_COND_V(err != OK, err); - mbedtls_ssl_set_hostname(tls_ctx->get_context(), p_for_hostname.utf8().get_data()); + base = p_base; mbedtls_ssl_set_bio(tls_ctx->get_context(), this, bio_send, bio_recv, nullptr); status = STATUS_HANDSHAKING; @@ -124,10 +121,11 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref p_base, bool p_valida return OK; } -Error StreamPeerMbedTLS::accept_stream(Ref p_base, Ref p_key, Ref p_cert, Ref p_ca_chain) { +Error StreamPeerMbedTLS::accept_stream(Ref p_base, Ref p_options) { ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_options.is_null() || !p_options->is_server(), ERR_INVALID_PARAMETER); - Error err = tls_ctx->init_server(MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_VERIFY_NONE, p_key, p_cert); + Error err = tls_ctx->init_server(MBEDTLS_SSL_TRANSPORT_STREAM, p_options); ERR_FAIL_COND_V(err != OK, err); base = p_base; diff --git a/modules/mbedtls/stream_peer_mbedtls.h b/modules/mbedtls/stream_peer_mbedtls.h index 8a36a7ea9a..ec0446c380 100644 --- a/modules/mbedtls/stream_peer_mbedtls.h +++ b/modules/mbedtls/stream_peer_mbedtls.h @@ -54,8 +54,8 @@ protected: public: virtual void poll(); - virtual Error accept_stream(Ref p_base, Ref p_key, Ref p_cert, Ref p_ca_chain = Ref()); - virtual Error connect_to_stream(Ref p_base, bool p_validate_certs = false, const String &p_for_hostname = String(), Ref p_valid_cert = Ref()); + virtual Error accept_stream(Ref p_base, Ref p_options); + virtual Error connect_to_stream(Ref p_base, const String &p_common_name, Ref p_options); virtual Status get_status() const; virtual Ref get_stream() const; diff --git a/modules/mbedtls/tls_context_mbedtls.cpp b/modules/mbedtls/tls_context_mbedtls.cpp index a01137f262..aab082f488 100644 --- a/modules/mbedtls/tls_context_mbedtls.cpp +++ b/modules/mbedtls/tls_context_mbedtls.cpp @@ -110,22 +110,20 @@ Error TLSContextMbedTLS::_setup(int p_endpoint, int p_transport, int p_authmode) return OK; } -Error TLSContextMbedTLS::init_server(int p_transport, int p_authmode, Ref p_pkey, Ref p_cert, Ref p_cookies) { - ERR_FAIL_COND_V(!p_pkey.is_valid(), ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(!p_cert.is_valid(), ERR_INVALID_PARAMETER); +Error TLSContextMbedTLS::init_server(int p_transport, Ref p_options, Ref p_cookies) { + ERR_FAIL_COND_V(p_options.is_null() || !p_options->is_server(), ERR_INVALID_PARAMETER); - Error err = _setup(MBEDTLS_SSL_IS_SERVER, p_transport, p_authmode); + // Check key and certificate(s) + pkey = p_options->get_private_key(); + certs = p_options->get_own_certificate(); + ERR_FAIL_COND_V(pkey.is_null() || certs.is_null(), ERR_INVALID_PARAMETER); + + Error err = _setup(MBEDTLS_SSL_IS_SERVER, p_transport, MBEDTLS_SSL_VERIFY_NONE); // TODO client auth. ERR_FAIL_COND_V(err != OK, err); // Locking key and certificate(s) - pkey = p_pkey; - certs = p_cert; - if (pkey.is_valid()) { - pkey->lock(); - } - if (certs.is_valid()) { - certs->lock(); - } + pkey->lock(); + certs->lock(); // Adding key and certificate int ret = mbedtls_ssl_conf_own_cert(&conf, &(certs->cert), &(pkey->pkey)); @@ -150,15 +148,32 @@ Error TLSContextMbedTLS::init_server(int p_transport, int p_authmode, Ref p_valid_cas) { - Error err = _setup(MBEDTLS_SSL_IS_CLIENT, p_transport, p_authmode); +Error TLSContextMbedTLS::init_client(int p_transport, const String &p_hostname, Ref p_options) { + ERR_FAIL_COND_V(p_options.is_null() || p_options->is_server(), ERR_INVALID_PARAMETER); + + int authmode = MBEDTLS_SSL_VERIFY_REQUIRED; + if (p_options->get_verify_mode() == TLSOptions::TLS_VERIFY_NONE) { + authmode = MBEDTLS_SSL_VERIFY_NONE; + } + + Error err = _setup(MBEDTLS_SSL_IS_CLIENT, p_transport, authmode); ERR_FAIL_COND_V(err != OK, err); + if (p_options->get_verify_mode() == TLSOptions::TLS_VERIFY_FULL) { + String cn = p_options->get_common_name(); + if (cn.is_empty()) { + cn = p_hostname; + } + mbedtls_ssl_set_hostname(&tls, cn.utf8().get_data()); + } else { + mbedtls_ssl_set_hostname(&tls, nullptr); + } + X509CertificateMbedTLS *cas = nullptr; - if (p_valid_cas.is_valid()) { + if (p_options->get_trusted_ca_chain().is_valid()) { // Locking CA certificates - certs = p_valid_cas; + certs = p_options->get_trusted_ca_chain(); certs->lock(); cas = certs.ptr(); } else { diff --git a/modules/mbedtls/tls_context_mbedtls.h b/modules/mbedtls/tls_context_mbedtls.h index 574e80e199..f1bad6a40c 100644 --- a/modules/mbedtls/tls_context_mbedtls.h +++ b/modules/mbedtls/tls_context_mbedtls.h @@ -71,17 +71,17 @@ public: static void print_mbedtls_error(int p_ret); Ref certs; + Ref pkey; + Ref cookies; + mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context tls; mbedtls_ssl_config conf; - Ref cookies; - Ref pkey; - Error _setup(int p_endpoint, int p_transport, int p_authmode); - Error init_server(int p_transport, int p_authmode, Ref p_pkey, Ref p_cert, Ref p_cookies = Ref()); - Error init_client(int p_transport, int p_authmode, Ref p_valid_cas); + Error init_server(int p_transport, Ref p_options, Ref p_cookies = Ref()); + Error init_client(int p_transport, const String &p_hostname, Ref p_options); void clear(); mbedtls_ssl_context *get_context(); -- cgit v1.2.3