From ad94cc950260ad972315265f5e3c70d61a05d767 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Mon, 7 Apr 2025 13:33:15 +0200 Subject: [PATCH] feat(asio): Add mbedtls specific APIs to use TLS stack specific features Use mbedtls specific API to configure hostname for verification --- .../ssl_client_server/main/asio_ssl_main.cpp | 8 +++++ .../include/asio/ssl/mbedtls_specific.hpp | 29 +++++++++++++++++++ .../port/mbedtls/include/mbedtls_context.hpp | 9 +++++- .../port/mbedtls/include/mbedtls_engine.hpp | 19 ++++++++++-- 4 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 components/asio/port/include/asio/ssl/mbedtls_specific.hpp diff --git a/components/asio/examples/ssl_client_server/main/asio_ssl_main.cpp b/components/asio/examples/ssl_client_server/main/asio_ssl_main.cpp index 8356dc716..2e5cfe0ab 100644 --- a/components/asio/examples/ssl_client_server/main/asio_ssl_main.cpp +++ b/components/asio/examples/ssl_client_server/main/asio_ssl_main.cpp @@ -17,6 +17,8 @@ #include "asio/ssl.hpp" #include "asio/buffer.hpp" #include "esp_pthread.h" +// allows for direct access to mbedtls specifics +#include "asio/ssl/mbedtls_specific.hpp" extern const unsigned char server_pem_start[] asm("_binary_srv_crt_start"); extern const unsigned char server_pem_end[] asm("_binary_srv_crt_end"); @@ -217,6 +219,7 @@ void ssl_server_thread() io_context.run(); } + void ssl_client_thread() { asio::io_context io_context; @@ -229,6 +232,11 @@ void ssl_client_thread() asio::ssl::context ctx(asio::ssl::context::tls_client); #if CONFIG_EXAMPLE_CLIENT_VERIFY_PEER ctx.add_certificate_authority(cert_chain); + // mbedtls (from 3.6.3) requires hostname to be set when performing TLS handshake with verify-peer option + // asio::ssl allows for name verification using verification callback, i.e. socket_.set_verify_callback(asio::ssl::host_name_verification()), + // - which is not supported in Espressif ASIO port yet. + // Therefore we provide a way to directly use mbedtls API and here we just configure the expected hostname to verify + asio::ssl::mbedtls::set_hostname(ctx.native_handle(), server_ip); #endif // CONFIG_EXAMPLE_CLIENT_VERIFY_PEER Client c(io_context, ctx, endpoints); diff --git a/components/asio/port/include/asio/ssl/mbedtls_specific.hpp b/components/asio/port/include/asio/ssl/mbedtls_specific.hpp new file mode 100644 index 000000000..b0c99a103 --- /dev/null +++ b/components/asio/port/include/asio/ssl/mbedtls_specific.hpp @@ -0,0 +1,29 @@ +// +// SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// + +#pragma once + +#include "asio/ssl/context_base.hpp" +#include "asio/ssl/context.hpp" +#include "asio/ssl/detail/openssl_types.hpp" + +namespace asio { +namespace ssl { +namespace mbedtls { + +/** + * @brief Configures specific hostname to be used in peer verification + * + * @param handle asio::ssl context handle type + * @param name hostname to be verified (std::string ownership will be moved to ssl::context) + * + * @return true on success + */ +bool set_hostname(asio::ssl::context::native_handle_type handle, std::string name); + +}; +}; +} // namespace asio::ssl::mbedtls diff --git a/components/asio/port/mbedtls/include/mbedtls_context.hpp b/components/asio/port/mbedtls/include/mbedtls_context.hpp index 41b1345f7..9ce79c55a 100644 --- a/components/asio/port/mbedtls/include/mbedtls_context.hpp +++ b/components/asio/port/mbedtls/include/mbedtls_context.hpp @@ -1,5 +1,5 @@ // -// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +// SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD // // SPDX-License-Identifier: BSL-1.0 // @@ -52,6 +52,12 @@ public: return nullptr; } + bool set_hostname(std::string hostname) + { + hostname_ = std::move(hostname); + return true; + } + std::size_t size(container c) const { switch (c) { @@ -70,6 +76,7 @@ public: const_buffer cert_chain_; const_buffer private_key_; const_buffer ca_cert_; + std::string hostname_; }; /** diff --git a/components/asio/port/mbedtls/include/mbedtls_engine.hpp b/components/asio/port/mbedtls/include/mbedtls_engine.hpp index 4d0258c35..8563accdb 100644 --- a/components/asio/port/mbedtls/include/mbedtls_engine.hpp +++ b/components/asio/port/mbedtls/include/mbedtls_engine.hpp @@ -1,5 +1,5 @@ // -// SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +// SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD // // SPDX-License-Identifier: BSL-1.0 // @@ -16,6 +16,11 @@ namespace asio { namespace ssl { namespace mbedtls { +bool set_hostname(asio::ssl::context::native_handle_type handle, std::string name) +{ + return handle->get()->set_hostname(std::move(name)); +} + const char *error_message(int error_code) { static char error_buf[100]; @@ -25,7 +30,7 @@ const char *error_message(int error_code) void throw_alloc_failure(const char *location) { - asio::error_code ec( MBEDTLS_ERR_SSL_ALLOC_FAILED, asio::error::get_mbedtls_category()); + asio::error_code ec(MBEDTLS_ERR_SSL_ALLOC_FAILED, asio::error::get_mbedtls_category()); asio::detail::throw_error(ec, location); } @@ -269,6 +274,16 @@ private: } else { mbedtls_ssl_conf_ca_chain(&conf_, nullptr, nullptr); } + + // Configure hostname before handshake if users pre-configured any + // use NULL if not set (to preserve the default behaviour of mbedtls < v3.6.3) + const char* hostname = !ctx->hostname_.empty() ? ctx->hostname_.c_str() : NULL; + ret = mbedtls_ssl_set_hostname(&ssl_, hostname); + if (ret < 0) { + print_error("mbedtls_ssl_set_hostname", ret); + return false; + } + ret = mbedtls_ssl_setup(&ssl_, &conf_); if (ret) { print_error("mbedtls_ssl_setup", ret);