From d823106aa6b24b8bdcc30373513c8688c61438c4 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 14 Oct 2021 10:17:24 +0200 Subject: [PATCH] asio: Use internal ssl context and engine impl Implement asio-ssl layer with three classes in asio::ssl::mbedtls: * context -- replaces SSL_CTX, used mainly as a container to options, certs, keys * engine -- replaces SSL, implements the actual mbedtls operations * bio -- implements openssl BIO specifically tailered to mbedtls and its asio usage Further updates: * asio: Used shared_ptr<> for bio pairs * asio: Add error checks to mbedtls-bio * asio: Address potential ssl-context ownership issue * asio: Address potential bio-engine ownership issue --- components/asio/CMakeLists.txt | 11 +- components/asio/Kconfig | 9 + .../asio/port/include/esp_asio_config.h | 8 +- components/asio/port/include/esp_exception.h | 1 - components/asio/port/include/openssl/conf.h | 18 -- components/asio/port/include/openssl/dh.h | 15 - .../include/openssl/esp_asio_openssl_stubs.h | 201 ------------ components/asio/port/include/openssl/rsa.h | 15 - components/asio/port/include/openssl/x509v3.h | 15 - components/asio/port/include/openssl_stub.hpp | 46 +++ .../asio/port/mbedtls/include/mbedtls_bio.hpp | 113 +++++++ .../port/mbedtls/include/mbedtls_context.hpp | 105 +++++++ .../port/mbedtls/include/mbedtls_engine.hpp | 294 ++++++++++++++++++ .../port/mbedtls/include/mbedtls_error.hpp | 55 ++++ .../asio/port/mbedtls/include/openssl/conf.h | 6 + .../asio/port/mbedtls/include/openssl/dh.h | 6 + .../asio/port/mbedtls/include/openssl/err.h | 6 + .../asio/port/mbedtls/include/openssl/rsa.h | 6 + .../asio/port/mbedtls/include/openssl/ssl.h | 8 + .../port/mbedtls/include/openssl/x509v3.h | 6 + .../asio/port/mbedtls/src/mbedtls_context.cpp | 115 +++++++ .../asio/port/mbedtls/src/mbedtls_engine.cpp | 208 +++++++++++++ components/asio/port/src/asio_ssl_impl.cpp | 20 ++ .../asio/port/src/esp_asio_openssl_stubs.c | 47 --- .../asio/ssl_client_server/CMakeLists.txt | 1 + 25 files changed, 1014 insertions(+), 321 deletions(-) delete mode 100644 components/asio/port/include/openssl/conf.h delete mode 100644 components/asio/port/include/openssl/dh.h delete mode 100644 components/asio/port/include/openssl/esp_asio_openssl_stubs.h delete mode 100644 components/asio/port/include/openssl/rsa.h delete mode 100644 components/asio/port/include/openssl/x509v3.h create mode 100644 components/asio/port/include/openssl_stub.hpp create mode 100644 components/asio/port/mbedtls/include/mbedtls_bio.hpp create mode 100644 components/asio/port/mbedtls/include/mbedtls_context.hpp create mode 100644 components/asio/port/mbedtls/include/mbedtls_engine.hpp create mode 100644 components/asio/port/mbedtls/include/mbedtls_error.hpp create mode 100644 components/asio/port/mbedtls/include/openssl/conf.h create mode 100644 components/asio/port/mbedtls/include/openssl/dh.h create mode 100644 components/asio/port/mbedtls/include/openssl/err.h create mode 100644 components/asio/port/mbedtls/include/openssl/rsa.h create mode 100644 components/asio/port/mbedtls/include/openssl/ssl.h create mode 100644 components/asio/port/mbedtls/include/openssl/x509v3.h create mode 100644 components/asio/port/mbedtls/src/mbedtls_context.cpp create mode 100644 components/asio/port/mbedtls/src/mbedtls_engine.cpp create mode 100644 components/asio/port/src/asio_ssl_impl.cpp delete mode 100644 components/asio/port/src/esp_asio_openssl_stubs.c diff --git a/components/asio/CMakeLists.txt b/components/asio/CMakeLists.txt index e2421fead4..3366545970 100644 --- a/components/asio/CMakeLists.txt +++ b/components/asio/CMakeLists.txt @@ -11,8 +11,10 @@ set(asio_sources "asio/asio/src/asio.cpp") if(CONFIG_ASIO_SSL_SUPPORT) if(CONFIG_ASIO_USE_ESP_OPENSSL) list(APPEND asio_sources - "asio/asio/src/asio_ssl.cpp" - "port/src/esp_asio_openssl_stubs.c") + "port/src/asio_ssl_impl.cpp" + "port/mbedtls/src/mbedtls_context.cpp" + "port/mbedtls/src/mbedtls_engine.cpp") + set(asio_priv_includes "port/mbedtls/include") endif() if(CONFIG_ASIO_USE_ESP_WOLFSSL) @@ -23,6 +25,7 @@ endif() idf_component_register(SRCS ${asio_sources} INCLUDE_DIRS "asio/asio/include" "port/include" + PRIV_INCLUDE_DIRS ${asio_priv_includes} REQUIRES lwip) if(CONFIG_ASIO_SSL_SUPPORT) @@ -35,7 +38,7 @@ if(CONFIG_ASIO_SSL_SUPPORT) endif() if(CONFIG_ASIO_USE_ESP_OPENSSL) - idf_component_get_property(esp_openssl openssl COMPONENT_LIB) - target_link_libraries(${COMPONENT_LIB} PUBLIC ${esp_openssl}) + idf_component_get_property(mbedtls mbedtls COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC ${mbedtls}) endif() endif() diff --git a/components/asio/Kconfig b/components/asio/Kconfig index 3b488a0c3b..6754e1aa2f 100644 --- a/components/asio/Kconfig +++ b/components/asio/Kconfig @@ -24,4 +24,13 @@ menu "ESP-ASIO" bool "wolfSSL (License info in wolfSSL directory README)" endchoice + config ASIO_SSL_BIO_SIZE + int "Size of BIO object" + default 1024 + depends on ASIO_SSL_SUPPORT + help + Size in bytes of SSL-BIO implementation. + Reducing the BIO size saves more RAM, but may slow down input output operations due to + fragmentation. + endmenu diff --git a/components/asio/port/include/esp_asio_config.h b/components/asio/port/include/esp_asio_config.h index 3f3a9b03ed..53215ca16e 100644 --- a/components/asio/port/include/esp_asio_config.h +++ b/components/asio/port/include/esp_asio_config.h @@ -18,11 +18,6 @@ # define ASIO_NO_TYPEID # endif // CONFIG_COMPILER_RTTI -// -// Supress OpenSSL deprecation warning, when building ASIO -// -#define ESP_OPENSSL_SUPPRESS_LEGACY_WARNING - // // LWIP compatibility inet and address macros/functions // @@ -40,6 +35,9 @@ # ifdef CONFIG_ASIO_USE_ESP_OPENSSL # define ASIO_USE_ESP_OPENSSL # define OPENSSL_NO_ENGINE +# define ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP +# include "openssl_stub.hpp" + # elif CONFIG_ASIO_USE_ESP_WOLFSSL # define ASIO_USE_WOLFSSL # endif // CONFIG_ASIO_USE_ESP_OPENSSL diff --git a/components/asio/port/include/esp_exception.h b/components/asio/port/include/esp_exception.h index 6f88866a4e..15cada7a7d 100644 --- a/components/asio/port/include/esp_exception.h +++ b/components/asio/port/include/esp_exception.h @@ -1,4 +1,3 @@ - /* * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD * diff --git a/components/asio/port/include/openssl/conf.h b/components/asio/port/include/openssl/conf.h deleted file mode 100644 index 1ed025d93c..0000000000 --- a/components/asio/port/include/openssl/conf.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _ESP_ASIO_OPENSSL_CONF_H -#define _ESP_ASIO_OPENSSL_CONF_H -#include "esp_asio_config.h" -#include "openssl/esp_asio_openssl_stubs.h" - -#if defined(ASIO_USE_WOLFSSL) -// SSLv3 Methods not present in current wolfSSL library -#define OPENSSL_NO_SSL3 -#include_next "openssl/conf.h" -#endif // ASIO_USE_WOLFSSL - -#endif // _ESP_ASIO_OPENSSL_CONF_H diff --git a/components/asio/port/include/openssl/dh.h b/components/asio/port/include/openssl/dh.h deleted file mode 100644 index af72e083aa..0000000000 --- a/components/asio/port/include/openssl/dh.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _ESP_ASIO_OPENSSL_DH_STUB_H -#define _ESP_ASIO_OPENSSL_DH_STUB_H -// Dummy header needed for ASIO compilation with esp-openssl - -#if defined(ASIO_USE_WOLFSSL) -#include_next "openssl/dh.h" -#endif // ASIO_USE_WOLFSSL - -#endif // _ESP_ASIO_OPENSSL_DH_STUB_H diff --git a/components/asio/port/include/openssl/esp_asio_openssl_stubs.h b/components/asio/port/include/openssl/esp_asio_openssl_stubs.h deleted file mode 100644 index 5062774107..0000000000 --- a/components/asio/port/include/openssl/esp_asio_openssl_stubs.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _ESP_ASIO_OPENSSL_STUBS_H -#define _ESP_ASIO_OPENSSL_STUBS_H - -/** - * @note This header contains openssl API which are NOT implemented, and are only provided - * as stubs or no-operations to get the ASIO library compiled and working with most - * practical use cases as an embedded application on ESP platform - */ - -#if defined(ASIO_USE_WOLFSSL) - -#include "wolfssl/ssl.h" -// esp-wolfssl disables filesystem by default, but the ssl filesystem functions are needed for the ASIO to compile -// - so we could either configure wolfSSL to use filesystem -// - or use the default wolfSSL and declare the filesystem functions -- preferred option, as whenever -// the filesystem functions are used from app code (potential security impact if private keys in a filesystem) -// compilation fails with linking errors. - -#if defined(NO_FILESYSTEM) -// WolfSSL methods that are not included in standard esp-wolfssl config, must be defined here -// as function stubs, so ASIO compiles, but would get link errors, if these functions were used. - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct WOLFSSL_CTX WOLFSSL_CTX; - -void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth); -int SSL_CTX_load_verify_locations(WOLFSSL_CTX*, const char*, const char*); -int SSL_CTX_use_certificate_file(WOLFSSL_CTX*, const char*, int); -int SSL_CTX_use_certificate_chain_file(WOLFSSL_CTX*, const char*); -int SSL_CTX_use_PrivateKey_file(WOLFSSL_CTX*, const char*, int); -int SSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX*, const char*, int); - -#if defined(__cplusplus) -} /* extern C */ -#endif - -#endif // NO_FILESYSTEM - -#elif defined(ASIO_USE_ESP_OPENSSL) - -#include "internal/ssl_x509.h" -#include "internal/ssl_pkey.h" -#include "mbedtls/pem.h" -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -// The most applicable OpenSSL version wrtt ASIO usage -#define OPENSSL_VERSION_NUMBER 0x10100001L -// SSLv2 methods not supported -// OpenSSL port supports: TLS_ANY, TLS_1, TLS_1_1, TLS_1_2, SSL_3 -#define OPENSSL_NO_SSL2 -#define SSL2_VERSION 0x0002 - -#define SSL_R_SHORT_READ 219 -#define SSL_OP_ALL 0 -#define SSL_OP_SINGLE_DH_USE 0 -#define SSL_OP_NO_COMPRESSION 0 -// Translates mbedTLS PEM parse error, used by ASIO -#define PEM_R_NO_START_LINE -MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT - -#define SSL_OP_NO_SSLv2 0x01000000L -#define SSL_OP_NO_SSLv3 0x02000000L -#define SSL_OP_NO_TLSv1 0x04000000L - -#define X509_FILETYPE_PEM 1 -#define X509_FILETYPE_ASN1 2 -#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 -#define SSL_FILETYPE_PEM X509_FILETYPE_PEM - -#define NID_subject_alt_name 85 - - -#define GEN_DNS 2 -#define GEN_IPADD 7 -#define V_ASN1_OCTET_STRING 4 -#define V_ASN1_IA5STRING 22 -#define NID_commonName 13 - -#define SSL_CTX_get_app_data(ctx) ((void*)SSL_CTX_get_ex_data(ctx, 0)) - -/** -* @brief Frees DH object -- not implemented -* -* Current implementation calls SSL_ASSERT -* -* @param r DH object -*/ -void DH_free(DH *r); - -/** - * @brief Frees GENERAL_NAMES -- not implemented - * - * Current implementation calls SSL_ASSERT - * - * @param r GENERAL_NAMES object - */ -void GENERAL_NAMES_free(GENERAL_NAMES * gens); - -/** - * @brief Returns subject name from X509 -- not implemented - * - * Current implementation calls SSL_ASSERT - * - * @param r X509 object - */ -X509_NAME *X509_get_subject_name(X509 *a); - -/** - * @brief API provaded as declaration only - * - */ -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); - -/** - * @brief API provaded as declaration only - * - */ -int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); - -/** - * @brief API provaded as declaration only - * - */ -X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); - -/** - * @brief API provaded as declaration only - * - */ -ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); - -/** - * @brief API provaded as declaration only - * - */ -void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); - -/** - * @brief API provaded as declaration only - * - */ -X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); - -/** - * @brief Reads DH params from a bio object -- not implemented - * - * Current implementation calls SSL_ASSERT - */ -DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u); - -/** - * @brief API provaded as declaration only - * - */ -void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); - -/** - * @brief Sets DH params to ssl ctx -- not implemented - * - * Current implementation calls SSL_ASSERT - */ -int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh); - -/** - * @brief API provaded as declaration only - * - */ -void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data); - -/** - * @brief API provaded as declaration only - * - */ -void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); - -/** - * @brief Clears any existing chain associated with the current certificate of ctx. - * - */ -int SSL_CTX_clear_chain_certs(SSL_CTX *ctx); - -#if defined(__cplusplus) -} /* extern C */ -#endif - -#endif /* ASIO_USE_ESP_OPENSSL, ASIO_USE_WOLFSSL */ -#endif /* _ESP_ASIO_OPENSSL_STUBS_H */ diff --git a/components/asio/port/include/openssl/rsa.h b/components/asio/port/include/openssl/rsa.h deleted file mode 100644 index 53018a33a8..0000000000 --- a/components/asio/port/include/openssl/rsa.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _ESP_ASIO_OPENSSL_RSA_STUB_H -#define _ESP_ASIO_OPENSSL_RSA_STUB_H -// Dummy header needed for ASIO compilation with esp-openssl - -#if defined(ASIO_USE_WOLFSSL) -#include_next "openssl/rsa.h" -#endif // ASIO_USE_WOLFSSL - -#endif // _ESP_ASIO_OPENSSL_RSA_STUB_H diff --git a/components/asio/port/include/openssl/x509v3.h b/components/asio/port/include/openssl/x509v3.h deleted file mode 100644 index dad7475424..0000000000 --- a/components/asio/port/include/openssl/x509v3.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _ESP_ASIO_OPENSSL_X509V3_STUB_H -#define _ESP_ASIO_OPENSSL_X509V3_STUB_H -// Dummy header needed for ASIO compilation with esp-openssl - -#if defined(ASIO_USE_WOLFSSL) -#include_next "openssl/x509v3.h" -#endif // ASIO_USE_WOLFSSL - -#endif // _ESP_ASIO_OPENSSL_X509V3_STUB_H diff --git a/components/asio/port/include/openssl_stub.hpp b/components/asio/port/include/openssl_stub.hpp new file mode 100644 index 0000000000..1758795423 --- /dev/null +++ b/components/asio/port/include/openssl_stub.hpp @@ -0,0 +1,46 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// + +#pragma once + +// +// Supply OpenSSL macros and flags for asio-ssl header files +// +#define OPENSSL_VERSION_NUMBER 0x10100001L + +#define SSL_R_SHORT_READ 219 +#define SSL_OP_ALL 0 +#define SSL_OP_SINGLE_DH_USE 0 +#define SSL_OP_NO_COMPRESSION 0 + +#define SSL_OP_NO_SSLv2 0x01000000L +#define SSL_OP_NO_SSLv3 0x02000000L +#define SSL_OP_NO_TLSv1 0x04000000L + +#define SSL_VERIFY_NONE 0x00 +#define SSL_VERIFY_PEER 0x01 +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +#define SSL_VERIFY_CLIENT_ONCE 0x04 + +// +// Implement asio-ssl layer with these three classes in asio::ssl::mbedtls +// +namespace asio { +namespace ssl { +namespace mbedtls { + +class engine; +class bio; +class shared_ctx; +} } } // namespace asio::ssl::mbedtls + +// +// Supply OpenSSL types as aliases to mbedtls classes +// +using X509_STORE_CTX=void; +using BIO=asio::ssl::mbedtls::bio; +using SSL_CTX=asio::ssl::mbedtls::shared_ctx; +using SSL=asio::ssl::mbedtls::engine; diff --git a/components/asio/port/mbedtls/include/mbedtls_bio.hpp b/components/asio/port/mbedtls/include/mbedtls_bio.hpp new file mode 100644 index 0000000000..d5348a0520 --- /dev/null +++ b/components/asio/port/mbedtls/include/mbedtls_bio.hpp @@ -0,0 +1,113 @@ +// +// SPDX-FileCopyrightText: 2021 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 "sdkconfig.h" + +namespace asio { +namespace ssl { +namespace mbedtls { + +class bio { + static constexpr int BIO_SIZE = CONFIG_ASIO_SSL_BIO_SIZE; + static constexpr int BIO_FLAGS_READ = 1; + static constexpr int BIO_FLAGS_WRITE = 2; + +public: + int write(const void *buf, int len) + { + if (buf == nullptr || len <= 0) { + // not an error, just empty operation (as in openssl/bio) + return 0; + } + int remaining = size_ - offset_; + if (remaining <= 0) { + flags_ |= BIO_FLAGS_WRITE; + return -1; + } + int len_to_write = len > remaining ? remaining : len; + std::memcpy(&data_[offset_], buf, len_to_write); + offset_ += len_to_write; + dlen_ = offset_; + if (len_to_write == len) { + flags_ &= ~BIO_FLAGS_WRITE; + } + return len_to_write; + } + + int read(void *buf, int len) + { + if (buf == nullptr || len <= 0) { + // not an error, just empty operation (as in openssl/bio) + return 0; + } + int remaining = peer_->dlen_ - peer_->roffset_; + if (remaining <= 0) { + flags_ |= BIO_FLAGS_READ; + return -1; + } + int len_to_read = remaining > len ? len : remaining; + std::memcpy(buf, &peer_->data_[peer_->roffset_], len_to_read); + peer_->roffset_ += len_to_read; + if (len_to_read == len) { + flags_ &= ~BIO_FLAGS_READ; + } + if (peer_->offset_) { + // shift data back to the beginning of the buffer + std::memmove(&peer_->data_[0], &peer_->data_[peer_->roffset_], peer_->offset_ - peer_->roffset_); + peer_->offset_ -= peer_->roffset_; + peer_->roffset_ = 0; + peer_->dlen_ = peer_->offset_; + } + return len_to_read; + } + + size_t wpending() const + { + return dlen_ - roffset_; + } + + size_t ctrl_pending() + { + return peer_->dlen_ - peer_->roffset_; + } + + bool should_write() const + { + return flags_ & BIO_FLAGS_WRITE; + } + + bool should_read() const + { + return flags_ & BIO_FLAGS_READ; + } + + static std::pair, std::shared_ptr> new_pair(const char* error_location) + { + auto b1 = std::shared_ptr(new (std::nothrow) bio); + auto b2 = std::shared_ptr(new (std::nothrow) bio); + if (b1 == nullptr || b2 == nullptr) { + throw_alloc_failure(error_location); + } else { + b1->peer_ = b2; + b2->peer_ = b1; + } + return std::make_pair(b1, b2); + } + +private: + std::array data_ {}; + size_t size_ {BIO_SIZE}; + std::shared_ptr peer_ {nullptr}; + int dlen_ {0}; + size_t offset_ {0}; + size_t roffset_ {0}; + size_t flags_ {0}; +}; + +} } } // namespace asio::ssl::mbedtls diff --git a/components/asio/port/mbedtls/include/mbedtls_context.hpp b/components/asio/port/mbedtls/include/mbedtls_context.hpp new file mode 100644 index 0000000000..27d135b5dd --- /dev/null +++ b/components/asio/port/mbedtls/include/mbedtls_context.hpp @@ -0,0 +1,105 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once + +#include "asio/ssl/context_base.hpp" +#include "asio/ssl/context.hpp" + +namespace asio { +namespace error { + +const asio::error_category& get_mbedtls_category(); +} // namespace error + +namespace ssl { +namespace mbedtls { + +void throw_alloc_failure(const char* location); + +const char *error_message(int error_code); + +enum class container { + CERT, CA_CERT, PRIVKEY +}; + +template +inline T* create(const char * location, Args &&... args) +{ + T* t = new (std::nothrow) T(std::forward(args)...); + if (t == nullptr) + { + throw_alloc_failure(location); + } + return t; +} + +class context { +public: + explicit context(context_base::method m): method_(m), options_(0) {} + + const unsigned char *data(container c) const + { + switch (c) { + case container::CERT: + return static_cast(cert_chain_.data()); + case container::CA_CERT: + return static_cast(ca_cert_.data()); + case container::PRIVKEY: + return static_cast(private_key_.data()); + } + return nullptr; + } + + std::size_t size(container c) const + { + switch (c) { + case container::CERT: + return cert_chain_.size(); + case container::CA_CERT: + return ca_cert_.size(); + case container::PRIVKEY: + return private_key_.size(); + } + return 0; + } + + context_base::method method_; + asio::ssl::context::options options_; + const_buffer cert_chain_; + const_buffer private_key_; + const_buffer ca_cert_; +}; + +/** + * @brief Wrapper class around SSL_CTX so we can easily create + * a shared pointer to the context without throwing the default exception. + * This is useful, as we can use asio::detail::throw_error for allocation errors. + */ +class shared_ctx { +public: + static SSL_CTX *create(const char* location, context_base::method m) + { + auto wrapped = asio::ssl::mbedtls::create(location, m); + if (wrapped->ctx_ == nullptr) + { + throw_alloc_failure(location); + } + return wrapped; + } + + std::shared_ptr get() const + { + return ctx_; + } + + explicit shared_ctx(context_base::method m) + :ctx_(std::shared_ptr(new (std::nothrow) context(m))) { } + +private: + std::shared_ptr ctx_; +}; + +} } } // namespace asio::ssl::mbedtls diff --git a/components/asio/port/mbedtls/include/mbedtls_engine.hpp b/components/asio/port/mbedtls/include/mbedtls_engine.hpp new file mode 100644 index 0000000000..9e77acbc3a --- /dev/null +++ b/components/asio/port/mbedtls/include/mbedtls_engine.hpp @@ -0,0 +1,294 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once + +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" +#include "mbedtls/esp_debug.h" +#include "esp_log.h" + +namespace asio { +namespace ssl { +namespace mbedtls { + +const char *error_message(int error_code) +{ + static char error_buf[100]; + mbedtls_strerror(error_code, error_buf, sizeof(error_buf)); + return error_buf; +} + +void throw_alloc_failure(const char* location) +{ + asio::error_code ec( MBEDTLS_ERR_SSL_ALLOC_FAILED, asio::error::get_mbedtls_category()); + asio::detail::throw_error(ec, location); +} + +namespace error_codes { + +bool is_error(int ret) +{ + return ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE; +} + +static bool want_write(int ret) +{ + return ret == MBEDTLS_ERR_SSL_WANT_WRITE; +} + +static bool want_read(int ret) +{ + return ret == MBEDTLS_ERR_SSL_WANT_READ; +} + +} // namespace error_codes + +enum rw_state { + IDLE, READING, WRITING, CLOSED +}; + +class engine { +public: + explicit engine(std::shared_ptr ctx): ctx_(std::move(ctx)), + bio_(bio::new_pair("mbedtls-engine")), state_(IDLE), verify_mode_(0) {} + + void set_verify_mode(asio::ssl::verify_mode mode) + { + verify_mode_ = mode; + } + + bio* ext_bio() const + { + return bio_.second.get(); + } + + rw_state get_state() const + { + return state_; + } + + int shutdown() + { + int ret = mbedtls_ssl_close_notify(&impl_.ssl_); + if (ret) { + impl::print_error("mbedtls_ssl_close_notify", ret); + } + state_ = CLOSED; + return ret; + } + + int connect() + { + return handshake(true); + } + + int accept() + { + return handshake(false); + } + + int write(const void *buffer, int len) + { + int ret = impl_.write(buffer, len); + state_ = ret == len ? IDLE: WRITING; + return ret; + } + + int read(void *buffer, int len) + { + int ret = impl_.read(buffer, len); + state_ = ret == len ? IDLE: READING; + return ret; + } + +private: + int handshake(bool is_client_not_server) + { + if (impl_.before_handshake()) { + impl_.configure(ctx_.get(), is_client_not_server, impl_verify_mode(is_client_not_server)); + } + return do_handshake(); + } + + static int bio_read(void *ctx, unsigned char *buf, size_t len) + { + auto bio = static_cast(ctx); + int read = bio->read(buf, len); + if (read <= 0 && bio->should_read()) { + return MBEDTLS_ERR_SSL_WANT_READ; + } + return read; + } + + static int bio_write(void *ctx, const unsigned char *buf, size_t len) + { + auto bio = static_cast(ctx); + int written = bio->write(buf, len); + if (written <= 0 && bio->should_write()) { + return MBEDTLS_ERR_SSL_WANT_WRITE; + } + return written; + } + + int do_handshake() + { + int ret = 0; + mbedtls_ssl_set_bio(&impl_.ssl_, bio_.first.get(), bio_write, bio_read, nullptr); + + while (impl_.ssl_.state != MBEDTLS_SSL_HANDSHAKE_OVER) { + ret = mbedtls_ssl_handshake_step(&impl_.ssl_); + + if (ret != 0) { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + impl::print_error("mbedtls_ssl_handshake_step", ret); + } + if (ret == MBEDTLS_ERR_SSL_WANT_READ) { + state_ = READING; + } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + state_ = WRITING; + } + break; + } + } + return ret; + } + + // Converts OpenSSL verification mode to mbedtls enum + int impl_verify_mode(bool is_client_not_server) const + { + int mode = MBEDTLS_SSL_VERIFY_UNSET; + if (is_client_not_server) { + if (verify_mode_ & SSL_VERIFY_PEER) + mode = MBEDTLS_SSL_VERIFY_REQUIRED; + else if (verify_mode_ == SSL_VERIFY_NONE) + mode = MBEDTLS_SSL_VERIFY_NONE; + } else { + if (verify_mode_ & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) + mode = MBEDTLS_SSL_VERIFY_REQUIRED; + else if (verify_mode_ & SSL_VERIFY_PEER) + mode = MBEDTLS_SSL_VERIFY_OPTIONAL; + else if (verify_mode_ == SSL_VERIFY_NONE) + mode = MBEDTLS_SSL_VERIFY_NONE; + } + return mode; + } + + struct impl { + static void print_error(const char* function, int error_code) + { + constexpr const char *TAG="mbedtls-engine-impl"; + ESP_LOGE(TAG, "%s() returned -0x%04X", function, -error_code); + ESP_LOGI(TAG, "-0x%04X: %s", -error_code, error_message(error_code)); + } + + bool before_handshake() const + { + return ssl_.state == 0; + } + + int write(const void *buffer, int len) + { + int ret = mbedtls_ssl_write(&ssl_, static_cast(buffer), len); + if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + print_error("mbedtls_ssl_write", ret); + } + return ret; + } + + int read(void *buffer, int len) + { + int ret = mbedtls_ssl_read(&ssl_, static_cast(buffer), len); + if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ) { + print_error("mbedtls_ssl_read", ret); + } + return ret; + } + + impl() + { + const unsigned char pers[] = "asio ssl"; + mbedtls_ssl_init(&ssl_); + mbedtls_ssl_config_init(&conf_); + mbedtls_ctr_drbg_init(&ctr_drbg_); +#ifdef CONFIG_MBEDTLS_DEBUG + mbedtls_esp_enable_debug_log(&conf_, CONFIG_MBEDTLS_DEBUG_LEVEL); +#endif + mbedtls_entropy_init(&entropy_); + mbedtls_ctr_drbg_seed(&ctr_drbg_, mbedtls_entropy_func, &entropy_, pers, sizeof(pers)); + mbedtls_x509_crt_init(&public_cert_); + mbedtls_pk_init(&pk_key_); + mbedtls_x509_crt_init(&ca_cert_); + } + + bool configure(context *ctx, bool is_client_not_server, int mbedtls_verify_mode) + { + mbedtls_x509_crt_init(&public_cert_); + mbedtls_pk_init(&pk_key_); + mbedtls_x509_crt_init(&ca_cert_); + int ret = mbedtls_ssl_config_defaults(&conf_, is_client_not_server ? MBEDTLS_SSL_IS_CLIENT: MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret) { + print_error("mbedtls_ssl_config_defaults", ret); + return false; + } + mbedtls_ssl_conf_rng(&conf_, mbedtls_ctr_drbg_random, &ctr_drbg_); + mbedtls_ssl_conf_authmode(&conf_, mbedtls_verify_mode); + if (ctx->cert_chain_.size() > 0 && ctx->private_key_.size() > 0) { + ret = mbedtls_x509_crt_parse(&public_cert_, ctx->data(container::CERT), ctx->size(container::CERT)); + if (ret < 0) { + print_error("mbedtls_x509_crt_parse", ret); + return false; + } + ret = mbedtls_pk_parse_key(&pk_key_, ctx->data(container::PRIVKEY), ctx->size(container::PRIVKEY), + nullptr, 0); + if (ret < 0) { + print_error("mbedtls_pk_parse_keyfile", ret); + return false; + } + ret = mbedtls_ssl_conf_own_cert(&conf_, &public_cert_, &pk_key_); + if (ret) { + print_error("mbedtls_ssl_conf_own_cert", ret); + return false; + } + } + + if (ctx->ca_cert_.size() > 0) { + ret = mbedtls_x509_crt_parse(&ca_cert_, ctx->data(container::CA_CERT), ctx->size(container::CA_CERT)); + if (ret < 0) { + print_error("mbedtls_x509_crt_parse", ret); + return false; + } + mbedtls_ssl_conf_ca_chain(&conf_, &ca_cert_, nullptr); + } else { + mbedtls_ssl_conf_ca_chain(&conf_, nullptr, nullptr); + } + ret = mbedtls_ssl_setup(&ssl_, &conf_); + if (ret) { + print_error("mbedtls_ssl_setup", ret); + return false; + } + return true; + } + mbedtls_ssl_context ssl_{}; + mbedtls_entropy_context entropy_{}; + mbedtls_ctr_drbg_context ctr_drbg_{}; + mbedtls_ssl_config conf_{}; + mbedtls_x509_crt public_cert_{}; + mbedtls_pk_context pk_key_{}; + mbedtls_x509_crt ca_cert_{}; + }; + + impl impl_{}; + std::shared_ptr ctx_; + std::pair, std::shared_ptr> bio_; + enum rw_state state_; + asio::ssl::verify_mode verify_mode_; +}; + +} } } // namespace asio::ssl::mbedtls diff --git a/components/asio/port/mbedtls/include/mbedtls_error.hpp b/components/asio/port/mbedtls/include/mbedtls_error.hpp new file mode 100644 index 0000000000..083cf6c886 --- /dev/null +++ b/components/asio/port/mbedtls/include/mbedtls_error.hpp @@ -0,0 +1,55 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once + +#include "asio/detail/config.hpp" +#include "asio/ssl/error.hpp" +#include "asio/ssl/detail/openssl_init.hpp" +#include "mbedtls_context.hpp" + +namespace asio { +namespace error { +namespace detail { + +class mbedtls_category : public asio::error_category +{ +public: + const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT + { + return "asio.ssl"; + } + + std::string message(int value) const + { + const char* s = asio::ssl::mbedtls::error_message(value); + return s ? s : "asio.mbedtls error"; + } +}; + +} // namespace detail + +const asio::error_category& get_mbedtls_category() +{ + static detail::mbedtls_category instance; + return instance; +} + +const asio::error_category& get_ssl_category() +{ + return asio::error::get_mbedtls_category(); +} + +} // namespace error + +namespace ssl { +namespace error { + +const asio::error_category& get_stream_category() +{ + return asio::error::get_mbedtls_category(); +} + +} } } // namespace asio::ssl::error diff --git a/components/asio/port/mbedtls/include/openssl/conf.h b/components/asio/port/mbedtls/include/openssl/conf.h new file mode 100644 index 0000000000..dc024544e7 --- /dev/null +++ b/components/asio/port/mbedtls/include/openssl/conf.h @@ -0,0 +1,6 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once diff --git a/components/asio/port/mbedtls/include/openssl/dh.h b/components/asio/port/mbedtls/include/openssl/dh.h new file mode 100644 index 0000000000..dc024544e7 --- /dev/null +++ b/components/asio/port/mbedtls/include/openssl/dh.h @@ -0,0 +1,6 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once diff --git a/components/asio/port/mbedtls/include/openssl/err.h b/components/asio/port/mbedtls/include/openssl/err.h new file mode 100644 index 0000000000..dc024544e7 --- /dev/null +++ b/components/asio/port/mbedtls/include/openssl/err.h @@ -0,0 +1,6 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once diff --git a/components/asio/port/mbedtls/include/openssl/rsa.h b/components/asio/port/mbedtls/include/openssl/rsa.h new file mode 100644 index 0000000000..dc024544e7 --- /dev/null +++ b/components/asio/port/mbedtls/include/openssl/rsa.h @@ -0,0 +1,6 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once diff --git a/components/asio/port/mbedtls/include/openssl/ssl.h b/components/asio/port/mbedtls/include/openssl/ssl.h new file mode 100644 index 0000000000..be147bc008 --- /dev/null +++ b/components/asio/port/mbedtls/include/openssl/ssl.h @@ -0,0 +1,8 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once + +#include "openssl_stub.hpp" diff --git a/components/asio/port/mbedtls/include/openssl/x509v3.h b/components/asio/port/mbedtls/include/openssl/x509v3.h new file mode 100644 index 0000000000..dc024544e7 --- /dev/null +++ b/components/asio/port/mbedtls/include/openssl/x509v3.h @@ -0,0 +1,6 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: BSL-1.0 +// +#pragma once diff --git a/components/asio/port/mbedtls/src/mbedtls_context.cpp b/components/asio/port/mbedtls/src/mbedtls_context.cpp new file mode 100644 index 0000000000..36ba700ddf --- /dev/null +++ b/components/asio/port/mbedtls/src/mbedtls_context.cpp @@ -0,0 +1,115 @@ +// +// SPDX-FileCopyrightText: 2005 Voipster / Indrek dot Juhani at voipster dot com +// SPDX-FileCopyrightText: 2005-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// SPDX-License-Identifier: BSL-1.0 +// +// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD +// + +#include "asio/detail/config.hpp" +#include "openssl_stub.hpp" +#include +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/ssl/context.hpp" +#include "asio/ssl/error.hpp" +#include "mbedtls_context.hpp" + + +namespace asio { +namespace ssl { + + +context::context(context::method m) + : handle_(0) +{ + handle_ = mbedtls::shared_ctx::create("mbedtls-context", m); + set_options(no_compression); +} + +context::context(context&& other) +{ + handle_ = other.handle_; + other.handle_ = 0; +} + +context& context::operator=(context&& other) +{ + context tmp(ASIO_MOVE_CAST(context)(*this)); + handle_ = other.handle_; + other.handle_ = 0; + return *this; +} + +context::~context() +{ + delete handle_; +} + +context::native_handle_type context::native_handle() +{ + return handle_; +} + +void context::set_options(context::options o) +{ + asio::error_code ec; + set_options(o, ec); + asio::detail::throw_error(ec, "set_options"); +} + +ASIO_SYNC_OP_VOID context::set_options( + context::options o, asio::error_code& ec) +{ + handle_->get()->options_ = o; + ec = asio::error_code(); + ASIO_SYNC_OP_VOID_RETURN(ec); +} + +void context::add_certificate_authority(const const_buffer& ca) +{ + asio::error_code ec; + add_certificate_authority(ca, ec); + asio::detail::throw_error(ec, "add_certificate_authority"); +} + +ASIO_SYNC_OP_VOID context::add_certificate_authority( + const const_buffer& ca, asio::error_code& ec) +{ + handle_->get()->ca_cert_ = ca; + ASIO_SYNC_OP_VOID_RETURN(asio::error_code()); +} + +void context::use_certificate_chain(const const_buffer& chain) +{ + asio::error_code ec; + use_certificate_chain(chain, ec); + asio::detail::throw_error(ec, "use_certificate_chain"); +} + +ASIO_SYNC_OP_VOID context::use_certificate_chain( + const const_buffer& chain, asio::error_code& ec) +{ + handle_->get()->cert_chain_ = chain; + ASIO_SYNC_OP_VOID_RETURN(asio::error_code()); +} + +void context::use_private_key( + const const_buffer& private_key, context::file_format format) +{ + asio::error_code ec; + use_private_key(private_key, format, ec); + asio::detail::throw_error(ec, "use_private_key"); +} + +ASIO_SYNC_OP_VOID context::use_private_key( + const const_buffer& private_key, context::file_format format, + asio::error_code& ec) +{ + handle_->get()->private_key_ = private_key; + ASIO_SYNC_OP_VOID_RETURN(asio::error_code()); +} + +} // namespace ssl +} // namespace asio diff --git a/components/asio/port/mbedtls/src/mbedtls_engine.cpp b/components/asio/port/mbedtls/src/mbedtls_engine.cpp new file mode 100644 index 0000000000..c3ff91842c --- /dev/null +++ b/components/asio/port/mbedtls/src/mbedtls_engine.cpp @@ -0,0 +1,208 @@ +// +// SPDX-FileCopyrightText: 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// SPDX-License-Identifier: BSL-1.0 +// +// SPDX-FileContributor: 2021 Espressif Systems (Shanghai) CO LTD +// + +#include "asio/detail/config.hpp" +#include "openssl_stub.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/ssl/detail/engine.hpp" +#include "asio/ssl/error.hpp" +#include "asio/ssl/verify_context.hpp" +#include "mbedtls_context.hpp" +#include "mbedtls_bio.hpp" +#include "mbedtls_error.hpp" +#include "mbedtls_engine.hpp" + + +namespace asio { +namespace ssl { +namespace detail { + + +engine::engine(SSL_CTX* context) + : ssl_(nullptr) +{ + ssl_ = mbedtls::create("mbedtls-engine", context->get()); +} + +engine::~engine() +{ + delete ssl_; +} + +SSL* engine::native_handle() +{ + return ssl_; +} + +asio::error_code engine::set_verify_mode( + verify_mode v, asio::error_code& ec) +{ + ssl_->set_verify_mode(v); + return {}; +} + +engine::want engine::handshake( + stream_base::handshake_type type, asio::error_code& ec) +{ + return perform((type == asio::ssl::stream_base::client) + ? &engine::do_connect : &engine::do_accept, 0, 0, ec, 0); +} + +engine::want engine::shutdown(asio::error_code& ec) +{ + return perform(&engine::do_shutdown, 0, 0, ec, 0); +} + +engine::want engine::write(const asio::const_buffer& data, + asio::error_code& ec, std::size_t& bytes_transferred) +{ + if (data.size() == 0) + { + ec = asio::error_code(); + return engine::want_nothing; + } + + return perform(&engine::do_write, + const_cast(data.data()), + data.size(), ec, &bytes_transferred); +} + +engine::want engine::read(const asio::mutable_buffer& data, + asio::error_code& ec, std::size_t& bytes_transferred) +{ + if (data.size() == 0) + { + ec = asio::error_code(); + return engine::want_nothing; + } + + return perform(&engine::do_read, data.data(), + data.size(), ec, &bytes_transferred); +} + +asio::mutable_buffer engine::get_output( + const asio::mutable_buffer& data) +{ + int length = ssl_->ext_bio()->read(data.data(), static_cast(data.size())); + + return asio::buffer(data, + length > 0 ? static_cast(length) : 0); +} + +asio::const_buffer engine::put_input( + const asio::const_buffer& data) +{ + int length = ssl_->ext_bio()->write(data.data(), static_cast(data.size())); + + return asio::buffer(data + + (length > 0 ? static_cast(length) : 0)); +} + +const asio::error_code& engine::map_error_code( + asio::error_code& ec) const +{ + // We only want to map the error::eof code. + if (ec != asio::error::eof) + return ec; + + // If there's data yet to be read, it's an error. + if (ssl_->ext_bio()->wpending()) + { + ec = asio::ssl::error::stream_truncated; + return ec; + } + + // Otherwise, the peer should have negotiated a proper shutdown. + if (ssl_->shutdown() != 0) + { + ec = asio::ssl::error::stream_truncated; + } + + return ec; +} + +// This is a simplified implementation of a generic ssl io operation +// original implementation using openssl's SSL object is in asio/include/asio/ssl/detail/impl/engine.ipp +engine::want engine::perform(int (engine::* op)(void*, std::size_t), + void* data, std::size_t length, asio::error_code& ec, + std::size_t* bytes_transferred) +{ + std::size_t pending_output_before = ssl_->ext_bio()->ctrl_pending(); + int result = (this->*op)(data, length); + + std::size_t pending_output_after = ssl_->ext_bio()->ctrl_pending(); + + if (mbedtls::error_codes::is_error(result)) + { + ec = asio::error_code(result, asio::error::get_mbedtls_category()); + return pending_output_after > pending_output_before ? want_output : want_nothing; + } + + if (result == 0) + { + return pending_output_after > pending_output_before + ? want_output : want_nothing; + } + + if (result > 0 && bytes_transferred) + *bytes_transferred = static_cast(result); + + if (mbedtls::error_codes::want_write(result)) + { + ec = asio::error_code(); + return want_output_and_retry; + } + else if (pending_output_after > pending_output_before) + { + ec = asio::error_code(); + return result > 0 ? want_output : want_output_and_retry; + } + else if (mbedtls::error_codes::want_read(result)) + { + ec = asio::error_code(); + return want_input_and_retry; + } + else if (ssl_->get_state() == mbedtls::CLOSED) + { + ec = asio::error::eof; + return want_nothing; + } + + ec = asio::error_code(); + return want_nothing; +} + +int engine::do_accept(void*, std::size_t) +{ + return ssl_->accept(); +} + +int engine::do_connect(void*, std::size_t) +{ + return ssl_->connect(); +} + +int engine::do_shutdown(void*, std::size_t) +{ + return ssl_->shutdown(); +} + +int engine::do_read(void* data, std::size_t length) +{ + return ssl_->read(data, length < INT_MAX ? static_cast(length) : INT_MAX); +} + +int engine::do_write(void* data, std::size_t length) +{ + return ssl_->write(data, length < INT_MAX ? static_cast(length) : INT_MAX); +} + +} // namespace detail +} // namespace ssl +} // namespace asio diff --git a/components/asio/port/src/asio_ssl_impl.cpp b/components/asio/port/src/asio_ssl_impl.cpp new file mode 100644 index 0000000000..8f387dd7b8 --- /dev/null +++ b/components/asio/port/src/asio_ssl_impl.cpp @@ -0,0 +1,20 @@ +// +// SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD +// +// SPDX-License-Identifier: Apache-2.0 +// + +#include "asio/detail/config.hpp" +#include "asio/ssl/detail/openssl_init.hpp" + +namespace asio { +namespace ssl { +namespace detail { + +// No OpenSSL in this implementation, instance is nullptr +asio::detail::shared_ptr openssl_init_base::instance() +{ + return nullptr; +} + +} } } // namespace asio::ssl::detail diff --git a/components/asio/port/src/esp_asio_openssl_stubs.c b/components/asio/port/src/esp_asio_openssl_stubs.c deleted file mode 100644 index c766fb0d72..0000000000 --- a/components/asio/port/src/esp_asio_openssl_stubs.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -// - -#include "esp_asio_config.h" -#include "internal/ssl_dbg.h" -#include "openssl/esp_asio_openssl_stubs.h" - -// Unsupported features as macros to make the assertions more readable -#define ESP_OPENSSL_DH_IS_SUPPORTED 0 -#define ESP_OPENSSL_GENERAL_NAMES_IS_SUPPORTED 0 - -void DH_free (DH *r) -{ - SSL_ASSERT3(ESP_OPENSSL_DH_IS_SUPPORTED); -} - -DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) -{ - SSL_ASSERT2(ESP_OPENSSL_DH_IS_SUPPORTED); - return NULL; -} - -int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) -{ - SSL_ASSERT1(ESP_OPENSSL_DH_IS_SUPPORTED); - return -1; -} - -void GENERAL_NAMES_free(GENERAL_NAMES * gens) -{ - SSL_ASSERT3(ESP_OPENSSL_GENERAL_NAMES_IS_SUPPORTED); -} - -X509_NAME *X509_get_subject_name(X509 *a) -{ - SSL_ASSERT2(ESP_OPENSSL_GENERAL_NAMES_IS_SUPPORTED); - return NULL; -} - -int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) -{ - return 1; -} diff --git a/examples/protocols/asio/ssl_client_server/CMakeLists.txt b/examples/protocols/asio/ssl_client_server/CMakeLists.txt index fcdac14880..804b8428ba 100644 --- a/examples/protocols/asio/ssl_client_server/CMakeLists.txt +++ b/examples/protocols/asio/ssl_client_server/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 3.5) # (Not part of the boilerplate) # This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) +set(EXCLUDE_COMPONENTS openssl) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(asio_ssl_client_server)