diff --git a/.gitignore b/.gitignore index f70980b703f2..6a29ce1d0f5b 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,44 @@ XUNIT_RESULT*.xml # Vale .vale/styles/* + +# Visual Studio and VisualGDB +**/.vs + +# VisualGDB +**/.visualgdb + +# Visual Studio Code Workspace Files +*.vscode +*.userprefs +*.exe +*.dll +Backup +UpgradeLog.htm +*.aps +*.VC.db +*.filters + +# Local backup files +*.bak + +# Espressif sdk config default should be saved in sdkconfig.defaults +# we won't track the actual working sdkconfig files +/IDE/Espressif/**/sdkconfig +/IDE/Espressif/**/sdkconfig.old + +# ESP8266 RTOS SDK has a slightly different sdkconfig filename to exclude: +/IDE/Espressif/**/sdkconfig.debug +/IDE/Espressif/**/sdkconfig.release + +# Always include Espressif makefiles (typically only used for ESP8266) +!/IDE/Espressif/**/Makefile +!/IDE/Espressif/**/component.mk + +# PlatformIO +/**/.pio +/**/.vscode/.browse.c_cpp.db* +/**/.vscode/c_cpp_properties.json +/**/.vscode/launch.json +/**/.vscode/ipch +/**/sdkconfig.esp32dev diff --git a/components/esp-tls/CMakeLists.txt b/components/esp-tls/CMakeLists.txt index 3809b6473b69..e259eaa9f116 100644 --- a/components/esp-tls/CMakeLists.txt +++ b/components/esp-tls/CMakeLists.txt @@ -5,8 +5,12 @@ if(CONFIG_ESP_TLS_USING_MBEDTLS) endif() if(CONFIG_ESP_TLS_USING_WOLFSSL) + message(STATUS "esp-tls configured for wolfssl") list(APPEND srcs "esp_tls_wolfssl.c") + set(wolfssl_esp_tls_lib "wolfssl") +else() + unset(wolfssl_esp_tls_lib) endif() set(priv_req http_parser esp_timer) @@ -14,17 +18,100 @@ if(NOT ${IDF_TARGET} STREQUAL "linux") list(APPEND priv_req lwip) endif() +message(STATUS "idf_component_register wolfssl_esp_tls_lib: ${wolfssl_esp_tls_lib}") + idf_component_register(SRCS "${srcs}" INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} esp-tls-crypto PRIV_INCLUDE_DIRS "private_include" # mbedtls is public requirements because esp_tls.h # includes mbedtls header files. - REQUIRES mbedtls + REQUIRES mbedtls ${wolfssl_esp_tls_lib} PRIV_REQUIRES ${priv_req}) +# When using wolfSSL for the ESP-TLS (see menuconfig), +# There are two options: +# 1) A specified source directory, typically a wolfssl git clone +# 2) The esp-wolfssl +# TODO this is duplicate code. See components/wap_supplicant +message(STATUS "esp-tls config begin") if(CONFIG_ESP_TLS_USING_WOLFSSL) - idf_component_get_property(wolfssl esp-wolfssl COMPONENT_LIB) - target_link_libraries(${COMPONENT_LIB} PUBLIC ${wolfssl}) + message(STATUS "found CONFIG_ESP_TLS_USING_WOLFSSL") + # See https://github.com/wolfSSL/wolfssl/ + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_ESPIDF") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS") + + # The published wolfSSL 5.7.0 user_settings.h does not include some features that + # might be enabled in Kconfig, so enable them here: + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_ALPN") + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_SNI") + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DOPENSSL_EXTRA_X509_SMALL") + # this only works for VisualGDB, not idf.py from command-line + + message(STATUS "CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}") + message(STATUS "CMAKE_PARENT_LIST_FILE = ${CMAKE_PARENT_LIST_FILE}") + message(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}") + message(STATUS "COMPONENT_DIR = ${CMAKE_HOME_DIRECTORY}") + message(STATUS "COMPONENT_LIB = ${COMPONENT_LIB}") + message(STATUS "FOUND_WOLFSSL = ${FOUND_WOLFSSL}") + message(STATUS "PROJECT_DIR = ${PROJECT_DIR}") + message(STATUS "WOLFSSL_PROJECT_DIR = ${WOLFSSL_PROJECT_DIR}") + message(STATUS "CMAKE_HOME_DIRECTORY = ${CMAKE_HOME_DIRECTORY}") + message(STATUS "WOLFSSL_ROOT = ${WOLFSSL_ROOT}") + + if(CONFIG_ESP_TLS_USING_WOLFSSL_SPECIFIED) + get_filename_component(CUSTOM_SETTING_WOLFSSL_ROOT_PATH "${CUSTOM_SETTING_WOLFSSL_ROOT}" ABSOLUTE) + if(EXISTS "${CUSTOM_SETTING_WOLFSSL_ROOT_PATH}/wolfcrypt/src") + message(STATUS "ESP-TLS using wolfSSL in: ${CUSTOM_SETTING_WOLFSSL_ROOT_PATH}") + else() + message(STATUS "ESP-TLS specified directory does not contain wolfSSL: ${CUSTOM_SETTING_WOLFSSL_ROOT_PATH}") + endif() + idf_component_get_property(wolfssl wolfssl COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC ${wolfssl}) + else() + # Is wolfSSL installed in the local project as a Managed Component? + set(WOLFSSL_COMPONENT_SEARCH "${PROJECT_DIR}/managed_components/wolfssl__wolfssl") + message(STATUS "Searching for wolfSSL in ${WOLFSSL_COMPONENT_SEARCH}") + if(EXISTS "${WOLFSSL_COMPONENT_SEARCH}") + message(STATUS "Configuring ESP-IDF to use wolfssl in Managed Component: ${WOLFSSL_COMPONENT_SEARCH}") + idf_component_get_property(wolfssl wolfssl__wolfssl COMPONENT_LIB) + else() + # Is wolfSSL installed in the local project as a Managed Component + # converted to regular project component? + set(WOLFSSL_COMPONENT_SEARCH "${PROJECT_DIR}/components/wolfssl__wolfssl") + message(STATUS "Searching for wolfSSL in ${WOLFSSL_COMPONENT_SEARCH}") + if(EXISTS "${WOLFSSL_COMPONENT_SEARCH}") + message(STATUS + "Configuring ESP-IDF to use wolfssl in Converted Managed Component: ${WOLFSSL_COMPONENT_SEARCH}") + idf_component_get_property(wolfssl wolfssl__wolfssl COMPONENT_LIB) + else() + # Is wolfSSL installed in the local project as a non-maged, regular component? + set(WOLFSSL_COMPONENT_SEARCH "${PROJECT_DIR}/components/wolfssl") + message(STATUS "Searching for wolfSSL in ${WOLFSSL_COMPONENT_SEARCH}") + if(EXISTS "${WOLFSSL_COMPONENT_SEARCH}") + message(STATUS "Configuring ESP-IDF to use wolfssl in Component: ${WOLFSSL_COMPONENT_SEARCH}") + idf_component_get_property(wolfssl wolfssl COMPONENT_LIB) + else() + set(WOLFSSL_COMPONENT_SEARCH "${THIS_IDF_PATH}/components/esp-wolfssl") + message(STATUS "Searching for wolfSSL in ${WOLFSSL_COMPONENT_SEARCH}") + if(EXISTS "${WOLFSSL_COMPONENT_SEARCH}") + message(STATUS "Configuring ESP-IDF to use wolfssl from: ${WOLFSSL_COMPONENT_SEARCH}") + message(STATUS "Warning: Using legacy esp-wolfssl. Consider using a Managed Component") + # See https://github.com/espressif/esp-idf + message(STATUS "Configuring ESP-TLS to use esp-wolfssl") + idf_component_get_property(wolfssl esp-wolfssl COMPONENT_LIB) + else() + message(STATUS "Consider installing wolfSSL from " + "https://components.espressif.com/components/wolfssl/wolfssl") + message(FATAL_ERROR "Component ${component} not found") + endif() # esp-wolfssl + endif() # project wolfssl + endif() # project converted wolfssl__wolfssl + endif() # project managed component wolfssl__wolfssl + # idf_component_get_property(wolfssl wolfssl__wolfssl COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC ${wolfssl}) + endif() +else() + message(STATUS "ESP-TLS is not configured to use wolfSSL.") endif() if(NOT ${IDF_TARGET} STREQUAL "linux") diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index 297a357b6df4..afc882fa9398 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -6,11 +6,17 @@ menu "ESP-TLS" The ESP-TLS APIs support multiple backend TLS libraries. Currently mbedTLS and WolfSSL are supported. Different TLS libraries may support different features and have different resource usage. Consult the ESP-TLS documentation in ESP-IDF Programming guide for more details. + config ESP_TLS_USING_MBEDTLS bool "mbedTLS" + config ESP_TLS_USING_WOLFSSL - depends on TLS_STACK_WOLFSSL bool "wolfSSL (License info in wolfSSL directory README)" + select TLS_STACK_WOLFSSL + help + This option enables wolfSSL for ESP-TLS. + Note: Ensure TLS_STACK_WOLFSSL is enabled to use this option. + endchoice config ESP_TLS_USE_SECURE_ELEMENT diff --git a/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c b/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c index c3a9a1b4fba7..ab7e7e44d44e 100644 --- a/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c +++ b/components/esp-tls/esp-tls-crypto/esp_tls_crypto.c @@ -14,10 +14,13 @@ static const char *TAG = "esp_crypto"; #define _esp_crypto_sha1 esp_crypto_sha1_mbedtls #define _esp_crypto_base64_encode esp_crypto_bas64_encode_mbedtls #elif CONFIG_ESP_TLS_USING_WOLFSSL -#include "wolfssl/ssl.h" /* SHA functions are listed in wolfssl/ssl.h */ -#include "wolfssl/wolfcrypt/coding.h" -#define _esp_crypto_sha1 esp_crypto_sha1_wolfSSL -#define _esp_crypto_base64_encode esp_crypto_base64_encode_woflSSL + #define OPENSSL_EXTRA + #include "wolfssl/wolfcrypt/settings.h" + #include "wolfssl/ssl.h" /* some SHA functions are listed in wolfssl/ssl.h */ + #include "wolfssl/openssl/sha.h" /* old SHA functions only available with OpenSSL */ + #include "wolfssl/wolfcrypt/coding.h" + #define _esp_crypto_sha1 esp_crypto_sha1_wolfSSL + #define _esp_crypto_base64_encode esp_crypto_base64_encode_woflSSL #endif #ifdef CONFIG_ESP_TLS_USING_MBEDTLS diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index a23eb27e8e83..f9cd263cb3a8 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -112,7 +112,12 @@ static const char *TAG = "esp-tls"; static esp_err_t create_ssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) { +/* TODO is the version wolfSSL or ESP-IDF ? */ +#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)) return _esp_create_ssl_handle(hostname, hostlen, cfg, tls, NULL); +#else + return _esp_create_ssl_handle(hostname, hostlen, cfg, tls); +#endif } static esp_err_t esp_tls_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) @@ -442,7 +447,10 @@ static inline esp_err_t tcp_connect(const char *host, int hostlen, int port, con static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_t *tls) { - + if (!tls) { + ESP_LOGE(TAG, "empty esp_tls parameter"); + return -1; + } esp_err_t esp_ret; /* These states are used to keep a tab on connection progress in case of non-blocking connect, and in case of blocking connect these cases will get executed one after the other */ @@ -497,6 +505,7 @@ static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, c } } /* By now, the connection has been established */ + ESP_LOGI(TAG, "\ncreate_ssl_handle for host: %s:%d\n", hostname, port); esp_ret = create_ssl_handle(hostname, hostlen, cfg, tls); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "create_ssl_handle failed"); @@ -706,7 +715,7 @@ int esp_tls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls /** * @brief Close the server side TLS/SSL connection and free any allocated resources. */ -void esp_tls_server_session_delete(esp_tls_t *tls) +int esp_tls_server_session_delete(esp_tls_t *tls) { return _esp_tls_server_session_delete(tls); } diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index b4a90b8f4c5e..3326c27b023d 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -711,7 +711,7 @@ int esp_tls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls * * @param[in] tls pointer to esp_tls_t */ -void esp_tls_server_session_delete(esp_tls_t *tls); +int esp_tls_server_session_delete(esp_tls_t *tls); /** * @brief Creates a plain TCP connection, returning a valid socket fd on success or an error handle diff --git a/components/esp-tls/esp_tls_wolfssl.c b/components/esp-tls/esp_tls_wolfssl.c index 733b097429da..55cf7207b224 100644 --- a/components/esp-tls/esp_tls_wolfssl.c +++ b/components/esp-tls/esp_tls_wolfssl.c @@ -1,17 +1,42 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "esp_tls_wolfssl.h" + +#if defined(CONFIG_ESP_TLS_USING_MBEDTLS) || (CONFIG_ESP_TLS_USING_MBEDTLS != 0) + #error "mbedTLS enabled for wolfSSL file" +#endif + +#ifdef CONFIG_ESP_TLS_USING_WOLFSSL -#include -#include -#include -#include +#include +#ifndef WOLFSSL_ESPIDF + #warning "WOLFSSL_ESPIDF not defined! Check build system." +#endif +#include +#include +#include +#ifdef LIBWOLFSSL_VERSION_HEX + #if LIBWOLFSSL_VERSION_HEX < 0x05007002 + #warning "wolfSSL 5.7.2 or newer is recommended." + #warning "Managed Components recommended. See: https://components.espressif.com/components/wolfssl/wolfssl" + #endif +#else + #warning "Unknown wolfSSL version. Check build system." +#endif -#include -#include -#include +#ifdef CONFIG_WOLFSSL_CERTIFICATE_BUNDLE + /* Note these are also set in wolfcrypt/src/port/Espressif/esp_crt_bundle.c + * to avoid conflicts with other cert bundles. + * Ensure they exactly match here: */ + #define BUNDLE_HEADER_OFFSET 2 + #define CRT_HEADER_OFFSET 2 + + #include + #include +#endif #include #include "esp_tls_wolfssl.h" @@ -19,12 +44,73 @@ #include #include "esp_log.h" +#if defined(CONFIG_WOLFSSL_CERTIFICATE_BUNDLE) && \ + defined(CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE) && \ + (CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE == 0) + +/* Only define the extern cert bundle data when using a bundle + * other than the "none" selection. + * + * NOTICE: These wolfSSL certs are loaded from + * [WOLFSSL_ROOT]/wolfcrypt/src/port/Espressif/esp_crt_bundle + * and *NOT* + * [ESP-IDF root]/components/mbedtls/esp_crt_bundle */ + +extern const uint8_t x509_crt_imported_bundle_wolfssl_bin_start[] + asm("_binary_x509_crt_bundle_wolfssl_start"); + +extern const uint8_t x509_crt_imported_bundle_wolfssl_bin_end[] + asm("_binary_x509_crt_bundle_wolfssl_end"); +#endif + +/* Bundle debug may come from user_settings.h and/or sdkconfig.h */ +#if defined(CONFIG_WOLFSSL_DEBUG_CERT_BUNDLE) || \ + defined( WOLFSSL_DEBUG_CERT_BUNDLE) + /* Only display certificate bundle debugging messages when enabled: */ + #define ESP_LOGCBI ESP_LOGI + #define ESP_LOGCBW ESP_LOGW +#else + /* Only display certificate bundle messages for most verbosee setting. + * Note that the delays will likely cause TLS connection failures. */ + #define ESP_LOGCBI ESP_LOGV + #define ESP_LOGCBW ESP_LOGV + #define ESP_LOGCBV ESP_LOGV +#endif +#if defined(WOLFSSL_EXAMPLE_VERBOSITY) + #define ESP_LOGXI ESP_LOGI + #define ESP_LOGXW ESP_LOGW + #define ESP_LOGXV ESP_LOGW +#else + #define ESP_LOGXI ESP_LOGV + #define ESP_LOGXI ESP_LOGV + #define ESP_LOGXI ESP_LOGV +#endif + +/* WOLFSSL_NO_CONF_COMPATIBILITY is not defined; + * assumes compatibility with existing Espressif "conf" parameters. */ + +static const char *TAG = "esp-tls-wolfssl"; + static unsigned char *global_cacert = NULL; static unsigned int global_cacert_pem_bytes = 0; -static const char *TAG = "esp-tls-wolfssl"; + +inline void esp_wolfssl_net_init(esp_tls_t *tls) +{ + ESP_LOGV(TAG, "esp_wolfssl_net_init"); + if ((tls == NULL) || (tls->priv_ssl == NULL)){ + /* nothing to do */ + } + else { + if (wolfSSL_set_fd((WOLFSSL*)&tls->priv_ssl, -1) != SSL_SUCCESS) { + ESP_LOGE(TAG, "Failed to initialize socket file descriptor"); + } + } +} + /* Prototypes for the static functions */ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls); +static int ShowCiphers(WOLFSSL* ssl); #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION) #include "freertos/semphr.h" @@ -44,15 +130,21 @@ static uint8_t psk_key_array[PSK_MAX_KEY_LEN]; static uint8_t psk_key_max_len = 0; #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ +#ifdef CONFIG_ESP_TLS_SERVER static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); +#endif /* CONFIG_ESP_TLS_SERVER */ /* This function shall return the error message when appropriate log level has been set otherwise this function shall do nothing */ static void wolfssl_print_error_msg(int error) { -#if (CONFIG_LOG_DEFAULT_LEVEL_DEBUG || CONFIG_LOG_DEFAULT_LEVEL_VERBOSE) +#if defined(DEBUG_WOLFSSL) || (CONFIG_LOG_DEFAULT_LEVEL_DEBUG || CONFIG_LOG_DEFAULT_LEVEL_VERBOSE) static char error_buf[100]; +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) ESP_LOGE(TAG, "(%d) : %s", error, ERR_error_string(error, error_buf)); +#else + ESP_LOGE(TAG, "Error: (%d)", error); +#endif #endif } @@ -97,7 +189,7 @@ static esp_err_t esp_load_wolfssl_verify_buffer(esp_tls_t *tls, const unsigned c wolf_fileformat = WOLFSSL_FILETYPE_ASN1; } if (type == FILE_TYPE_SELF_CERT) { - if ((*err_ret = wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) { + if ((*err_ret = wolfSSL_CTX_use_certificate_chain_buffer_format( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) { return ESP_OK; } return ESP_FAIL; @@ -122,7 +214,14 @@ void *esp_wolfssl_get_ssl_context(esp_tls_t *tls) return (void*)tls->priv_ssl; } -esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params) +static int _is_wolfssl_init = 0; + +/* ESP-IDF v5.3 introduced a new parameter: server_params */ +#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)) + esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params) +#else + esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) +#endif { #ifdef CONFIG_ESP_DEBUG_WOLFSSL wolfSSL_Debugging_ON(); @@ -132,9 +231,18 @@ esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const assert(tls != NULL); esp_err_t esp_ret = ESP_FAIL; - int ret; + int ret = WOLFSSL_SUCCESS; + + + if (_is_wolfssl_init == 0) { + ESP_LOGXI(TAG, "wolfSSL_Init"); + ret = wolfSSL_Init(); + // _is_wolfssl_init = 1; + } + else { + ESP_LOGXI(TAG, "skipping wolfSSL_Init"); + } - ret = wolfSSL_Init(); if (ret != WOLFSSL_SUCCESS) { ESP_LOGE(TAG, "Init wolfSSL failed: 0x%04X", ret); wolfssl_print_error_msg(ret); @@ -144,17 +252,24 @@ esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const } if (tls->role == ESP_TLS_CLIENT) { + ESP_LOGXI(TAG, "Set set_client_config"); esp_ret = set_client_config(hostname, hostlen, (esp_tls_cfg_t *)cfg, tls); + ESP_LOGXI(TAG, "Set set_client_config done!"); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to set client configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } } else if (tls->role == ESP_TLS_SERVER) { +#ifdef CONFIG_ESP_TLS_SERVER esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to set server configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } +#else + ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in menuconfig"); + goto exit; +#endif } else { ESP_LOGE(TAG, "tls->role is not valid"); @@ -163,40 +278,118 @@ esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const return ESP_OK; exit: + ESP_LOGE(TAG, "Error exit"); esp_wolfssl_cleanup(tls); return esp_ret; } +int my_verify_callback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) { + // You can add custom verification logic here + // For now, just return the result passed to the callback + ESP_LOGW(TAG, "my_verify_callback"); + return preverify_ok; +} + +#ifndef WOLFSSL_NO_CONF_COMPATIBILITY +/* Some functions such as those used in esp-tls Certificate Bundles + * expect a `conf` property of the tls. Keep them in sync with the + * actual values (tls->priv_ctx) and (tls->priv_ssl): + * + * example: + * tls->sync((void*)&tls); + * + * In all cases, it is preferred to use the non-conf-prefixed values. + * + * Once all instances of compatibility have been updated, this feature + * will likely be permanently removed. */ +static void sync_tls_conf_values(struct esp_tls *tls) { + if (tls) { + tls->conf.priv_ctx = tls->priv_ctx; + tls->conf.priv_ssl = tls->priv_ssl; + } +} +#endif + static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls) { int ret = WOLFSSL_FAILURE; -#ifdef WOLFSSL_TLS13 + assert(cfg != NULL); + assert(tls != NULL); + +#if defined(CONFIG_WOLFSSL_ALLOW_TLS13) && defined(CONFIG_WOLFSSL_ALLOW_TLS12) + ESP_LOGXI(TAG, "Set Client Config for ANY TLS version"); + tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfSSLv23_client_method()); +#elif defined(CONFIG_WOLFSSL_ALLOW_TLS13) & defined(WOLFSSL_TLS13) + ESP_LOGXI(TAG, "Set Client Config for TLS1.3 Only"); tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_3_client_method()); -#else +#elif defined(CONFIG_WOLFSSL_ALLOW_TLS13) + #error "CONFIG_WOLFSSL_ALLOW_TLS13 configured without WOLFSSL_TLS13?" +#elif defined(CONFIG_WOLFSSL_ALLOW_TLS12) + ESP_LOGXI(TAG, "Set Client Config for TLS1.2 Only"); tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_client_method()); +#else + ESP_LOGW(TAG, "No TLS enabled!"); + #warning "No TLS enabled!" #endif +#if defined(CONFIG_WOLFSSL_ALLOW_TLS13) || defined(CONFIG_WOLFSSL_ALLOW_TLS12) + if (tls == NULL) { + ESP_LOGE(TAG, "Failed to create wolfSSL TLS Client Method"); + return ESP_ERR_INVALID_STATE; + } + else { + #ifndef WOLFSSL_NO_CONF_COMPATIBILITY + tls->conf.priv_ctx = tls->priv_ctx; + tls->conf.priv_ssl = tls->priv_ssl; + tls->sync = sync_tls_conf_values; + #endif + } + +#if defined(CONFIG_WOLFSSL_CERTIFICATE_BUNDLE) && \ + defined(CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE) && \ + (CONFIG_WOLFSSL_CERTIFICATE_BUNDLE_DEFAULT_NONE == 0) + esp_crt_bundle_init(x509_crt_imported_bundle_wolfssl_bin_start, + x509_crt_imported_bundle_wolfssl_bin_end - x509_crt_imported_bundle_wolfssl_bin_start, + tls); + ESP_LOGXI(TAG, "No Certificate Bundle Selected."); +#endif /* Some certificate bundle other than "none" */ +#endif /* CONFIG_WOLFSSL_ALLOW_[TLS12 or TLS13] */ + if (!tls->priv_ctx) { ESP_LOGE(TAG, "Set wolfSSL ctx failed"); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, ret); return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED; } + /* Optionally call crt_bundle_attach */ if (cfg->crt_bundle_attach != NULL) { - ESP_LOGE(TAG,"use_crt_bundle not supported in wolfssl"); - return ESP_FAIL; - } - - if (cfg->use_global_ca_store == true) { +#ifdef CONFIG_WOLFSSL_CERTIFICATE_BUNDLE + ESP_LOGD(TAG, "Use certificate bundle"); + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, my_verify_callback); + cfg->crt_bundle_attach(&tls->conf); /* callback is also set here */ + #ifndef WOLFSSL_NO_CONF_COMPATIBILITY + tls->conf.priv_ctx = tls->priv_ctx; + tls->conf.priv_ssl = tls->priv_ssl; + #endif + +#else /* CONFIG_WOLFSSL_CERTIFICATE_BUNDLE */ + ESP_LOGE(TAG, "use_crt_bundle configured but not enabled in menuconfig:" + "Please enable CONFIG_WOLFSSL_CERTIFICATE_BUNDLE option"); + return ESP_ERR_INVALID_STATE; +#endif + /* cfg->crt_bundle_attach != NULL */ + } else if (cfg->use_global_ca_store == true) { + WOLFSSL_MSG("Using Global CA Store in esp_tls_wolfssl"); if ((esp_load_wolfssl_verify_buffer(tls, global_cacert, global_cacert_pem_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) { int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret); ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err); wolfssl_print_error_msg(err); return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; - } + } /* esp_load_wolfssl_verify_buffer */ wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL); } else if (cfg->cacert_buf != NULL) { + WOLFSSL_MSG("set_client_config found cert_buf"); if ((esp_load_wolfssl_verify_buffer(tls, cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) { int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret); ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err); @@ -204,6 +397,7 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED; } wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL); + /* end (cfg->cacert_buf != NULL) */ } else if (cfg->psk_hint_key) { #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION) /*** PSK encryption mode is configured only if no certificate supplied and psk pointer not null ***/ @@ -216,7 +410,7 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls ESP_LOGE(TAG, "tls_conn_lock could not be obtained in specified time"); return -1; } - ESP_LOGI(TAG, "setting psk configurations"); + ESP_LOGXI(TAG, "setting psk configurations"); if((cfg->psk_hint_key->key_size > PSK_MAX_KEY_LEN) || (strlen(cfg->psk_hint_key->hint) > PSK_MAX_ID_LEN)) { ESP_LOGE(TAG, "psk key length should be <= %d and identity hint length should be <= %d", PSK_MAX_KEY_LEN, PSK_MAX_ID_LEN); return ESP_ERR_INVALID_ARG; @@ -235,12 +429,15 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls ESP_LOGE(TAG, "psk_hint_key configured but not enabled in menuconfig: Please enable ESP_TLS_PSK_VERIFICATION option"); return ESP_ERR_INVALID_STATE; #endif + /* end (cfg->psk_hint_key) */ } else { + /* Not using Global CA Store, the cfg->cacert_buf is NULL, no PSK Hint Key */ #ifdef CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY - wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL); + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL); /* */ #else - ESP_LOGE(TAG, "No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference"); - return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED; + wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL); + ESP_LOGW(TAG, "No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference"); + return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED; /* TODO: really? */ #endif } @@ -263,6 +460,7 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls } tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx); + tls->conf.priv_ssl = tls->priv_ssl; if (!tls->priv_ssl) { ESP_LOGE(TAG, "Create wolfSSL failed"); int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret); @@ -270,6 +468,7 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED; } + /* Reminder: name check occurs after wolfSSL priv_ctx and priv_ssl init. */ if (!cfg->skip_common_name) { char *use_host = NULL; if (cfg->common_name != NULL) { @@ -280,6 +479,9 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls if (use_host == NULL) { return ESP_ERR_NO_MEM; } + else { + ESP_LOGXI(TAG, "Using host for wolfSSL Check Domain: %s", use_host); + } /* Hostname set here should match CN in server certificate */ if ((ret = (wolfSSL_check_domain_name( (WOLFSSL *)tls->priv_ssl, use_host))) != WOLFSSL_SUCCESS) { int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret); @@ -288,11 +490,18 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls free(use_host); return ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED; } + /* Mimic the semantics of mbedtls_ssl_set_hostname() */ +#ifdef HAVE_SNI + if ((ret = wolfSSL_CTX_UseSNI(tls->priv_ctx, WOLFSSL_SNI_HOST_NAME, use_host, strlen(use_host))) != WOLFSSL_SUCCESS) { + ESP_LOGE(TAG, "wolfSSL_CTX_UseSNI failed, returned %d", ret); + return ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED; + } +#endif free(use_host); } if (cfg->alpn_protos) { -#ifdef CONFIG_WOLFSSL_HAVE_ALPN +#if defined(CONFIG_WOLFSSL_HAVE_ALPN) && defined(HAVE_ALPN) char **alpn_list = (char **)cfg->alpn_protos; for (; *alpn_list != NULL; alpn_list ++) { ESP_LOGD(TAG, "alpn protocol is %s", *alpn_list); @@ -310,20 +519,56 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls #endif /* CONFIG_WOLFSSL_HAVE_ALPN */ } - wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd); +#ifdef CONFIG_WOLFSSL_HAVE_OCSP + /* enable OCSP certificate status check for this TLS context */ + if ((ret = wolfSSL_CTX_EnableOCSP((WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_OCSP_CHECKALL)) != WOLFSSL_SUCCESS) { + ESP_LOGE(TAG, "wolfSSL_CTX_EnableOCSP failed, returned %d", ret); + return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED; + } + /* enable OCSP stapling for this TLS context */ + if ((ret = wolfSSL_CTX_EnableOCSPStapling((WOLFSSL_CTX *)tls->priv_ctx )) != WOLFSSL_SUCCESS) { + ESP_LOGE(TAG, "wolfSSL_CTX_EnableOCSPStapling failed, returned %d", ret); + return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED; + } + /* set option to use OCSP v1 stapling with nounce extension */ + if ((ret = wolfSSL_UseOCSPStapling((WOLFSSL *)tls->priv_ssl, WOLFSSL_CSR_OCSP, WOLFSSL_CSR_OCSP_USE_NONCE)) != WOLFSSL_SUCCESS) { + ESP_LOGE(TAG, "wolfSSL_UseOCSPStapling failed, returned %d", ret); + return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED; + } +#endif /* CONFIG_WOLFSSL_HAVE_OCSP */ + + ret = wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd); + if (ret == WOLFSSL_SUCCESS) { + ESP_LOGXI(TAG, "Attach wolfSSL to the socket success!"); + } + else { + ESP_LOGE(TAG, "ERROR: failed wolfSSL_set_fd. Error: %d\n", ret); + return ESP_FAIL; + } return ESP_OK; } +#ifdef CONFIG_ESP_TLS_SERVER static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) { int ret = WOLFSSL_FAILURE; -#ifdef WOLFSSL_TLS13 +#if defined(CONFIG_WOLFSSL_ALLOW_TLS13) && defined(CONFIG_WOLFSSL_ALLOW_TLS12) + WOLFSSL_MSG("Set Server Config for any TLS version"); + tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfSSLv23_server_method()); +#elif defined(CONFIG_WOLFSSL_ALLOW_TLS13) + WOLFSSL_MSG("Set Server Config for TLS1.3 Only"); tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_3_server_method()); -#else +#elif defined(CONFIG_WOLFSSL_ALLOW_TLS12) + WOLFSSL_MSG("Set Server Config for TLS1.2 Only"); tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_server_method()); -#endif +#else + #warning "No TLS enabled!" +#endif /* TLS Version */ +#ifndef WOLFSSL_NO_CONF_COMPATIBILITY + tls->sync((void*)&tls); +#endif if (!tls->priv_ctx) { ESP_LOGE(TAG, "Set wolfSSL ctx failed"); return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED; @@ -370,13 +615,51 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd); return ESP_OK; } +#endif +int ShowCiphers(WOLFSSL* ssl) +{ + #define CLIENT_TLS_MAX_CIPHER_LENGTH 4096 + char ciphers[CLIENT_TLS_MAX_CIPHER_LENGTH]; + const char* cipher_used; + int ret = 0; + + if (ssl == NULL) { + ESP_LOGXI(TAG, "WOLFSSL* ssl is NULL, so no cipher in use"); + ret = wolfSSL_get_ciphers(ciphers, (int)sizeof(ciphers)); + if (ret == WOLFSSL_SUCCESS) { + for (int i = 0; i < CLIENT_TLS_MAX_CIPHER_LENGTH; i++) { + if (ciphers[i] == ':') { + ciphers[i] = '\n'; + } + } + ESP_LOGXI(TAG, "Available Ciphers:\n%s\n", ciphers); + } + else { + ESP_LOGE(TAG, "Failed to call wolfSSL_get_ciphers. Error %d", ret); + } + } + else { + cipher_used = wolfSSL_get_cipher_name(ssl); + ESP_LOGXI(TAG, "WOLFSSL* ssl using %s", cipher_used); + } + return ret; +} int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) { int ret; + + #ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); + #endif + ESP_LOGCBI(TAG, "Begin esp-tls esp_wolfssl_handshake"); ret = wolfSSL_connect( (WOLFSSL *)tls->priv_ssl); +#ifndef WOLFSSL_NO_CONF_COMPATIBILITY + tls->conf.priv_ssl = tls->priv_ssl; +#endif if (ret == WOLFSSL_SUCCESS) { tls->conn_state = ESP_TLS_DONE; + ShowCiphers((WOLFSSL *)tls->priv_ssl); return 1; } else { int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret); @@ -437,11 +720,21 @@ ssize_t esp_wolfssl_write(esp_tls_t *tls, const char *data, size_t datalen) void esp_wolfssl_verify_certificate(esp_tls_t *tls) { int flags; - if ((flags = wolfSSL_get_verify_result( (WOLFSSL *)tls->priv_ssl)) != X509_V_OK) { + if ((flags = wolfSSL_get_verify_result( (WOLFSSL *)tls->priv_ssl)) != WOLFSSL_SUCCESS) { ESP_LOGE(TAG, "Failed to verify peer certificate , returned %d", flags); +#ifdef WOLFSSL_ALT_CERT_CHAINS + ESP_LOGW(TAG, "WOLFSSL_ALT_CERT_CHAINS is defined"); +#else + /* wolfSSL is considerably more strict with certificates by default. */ + #if defined(CONFIG_WOLFSSL_CERTIFICATE_BUNDLE) && CONFIG_WOLFSSL_CERTIFICATE_BUNDLE + ESP_LOGW(TAG, "Consider chaging the certificates loaded and/or defining WOLFSSL_ALT_CERT_CHAINS to relax certificate check. (1)"); + #else + ESP_LOGW(TAG, "Consider enabling CONFIG_WOLFSSL_CERTIFICATE_BUNDLE."); + #endif +#endif ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL_CERT_FLAGS, flags); } else { - ESP_LOGI(TAG, "Certificate verified."); + ESP_LOGXI(TAG, "Certificate verified."); } } @@ -456,6 +749,7 @@ ssize_t esp_wolfssl_get_bytes_avail(esp_tls_t *tls) void esp_wolfssl_conn_delete(esp_tls_t *tls) { + ESP_LOGCBW(TAG, "esp_wolfssl_conn_delete"); if (tls != NULL) { esp_wolfssl_cleanup(tls); } @@ -463,17 +757,35 @@ void esp_wolfssl_conn_delete(esp_tls_t *tls) void esp_wolfssl_cleanup(esp_tls_t *tls) { + ESP_LOGCBW(TAG, "esp_wolfssl_cleanup"); if (!tls) { return; } #ifdef CONFIG_ESP_TLS_PSK_VERIFICATION xSemaphoreGive(tls_conn_lock); #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ + +#ifndef WOLFSSL_NO_CONF_COMPATIBILITY + if ((tls->priv_ssl != tls->conf.priv_ssl) && (tls->conf.priv_ssl != NULL)) { + /* priv_ssl may have been already cleanup up when connection closed. */ + ESP_LOGE(TAG, "tls->priv_ssl != tls->conf.priv_ssl inconsistency!"); + } + if (tls->priv_ctx != tls->conf.priv_ctx) { + ESP_LOGE(TAG, "tls->priv_ctx != tls->conf.priv_ctx inconsistency!"); + } +#endif wolfSSL_shutdown( (WOLFSSL *)tls->priv_ssl); wolfSSL_free( (WOLFSSL *)tls->priv_ssl); tls->priv_ssl = NULL; wolfSSL_CTX_free( (WOLFSSL_CTX *)tls->priv_ctx); tls->priv_ctx = NULL; + +#ifndef WOLFSSL_NO_CONF_COMPATIBILITY + /* The same addresses, but for clarity: */ + tls->conf.priv_ssl = NULL; + tls->conf.priv_ctx = NULL; +#endif + wolfSSL_bundle_cleanup(); wolfSSL_Cleanup(); } @@ -488,8 +800,14 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp tls->role = ESP_TLS_SERVER; tls->sockfd = sockfd; esp_tls_server_params_t server_params = {}; - server_params.set_server_cfg = &set_server_config; + // server_params.set_server_cfg = &set_server_config; + // TODO + +#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)) esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls, &server_params); +#else + esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls); +#endif if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "create_ssl_handle failed, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret); @@ -515,23 +833,26 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp /** * @brief Close the server side TLS/SSL connection and free any allocated resources. */ -void esp_wolfssl_server_session_delete(esp_tls_t *tls) +int esp_wolfssl_server_session_delete(esp_tls_t *tls) { if (tls != NULL) { esp_wolfssl_cleanup(tls); esp_tls_internal_event_tracker_destroy(tls->error_handle); free(tls); } + return ESP_OK; } esp_err_t esp_wolfssl_init_global_ca_store(void) { - /* This function is just to provide consistancy between function calls of esp_tls.h and wolfssl */ + /* This function is just to provide consistency between function calls of esp_tls.h and wolfssl */ + ESP_LOGW(TAG, "NOT implemented: esp_wolfssl_init_global_ca_store"); return ESP_OK; } esp_err_t esp_wolfssl_set_global_ca_store(const unsigned char *cacert_pem_buf, const unsigned int cacert_pem_bytes) { + ESP_LOGXI(TAG, "Enter esp_wolfssl_set_global_ca_store"); if (cacert_pem_buf == NULL) { ESP_LOGE(TAG, "cacert_pem_buf is null"); return ESP_ERR_INVALID_ARG; @@ -613,3 +934,5 @@ static inline unsigned int esp_wolfssl_psk_client_cb(WOLFSSL* ssl, const char* h /* return length of key in octets or 0 or for error */ } #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ + +#endif /* CONFIG_ESP_TLS_USING_WOLFSSL */ diff --git a/components/esp-tls/private_include/esp_tls_private.h b/components/esp-tls/private_include/esp_tls_private.h index 4341557aaf9e..665543d0564e 100644 --- a/components/esp-tls/private_include/esp_tls_private.h +++ b/components/esp-tls/private_include/esp_tls_private.h @@ -15,6 +15,7 @@ #include #include "esp_err.h" #include "esp_tls_errors.h" + #ifdef CONFIG_ESP_TLS_USING_MBEDTLS #include "mbedtls/platform.h" #include "mbedtls/net_sockets.h" @@ -30,8 +31,11 @@ #include "psa/crypto.h" #endif #elif CONFIG_ESP_TLS_USING_WOLFSSL -#include "wolfssl/wolfcrypt/settings.h" -#include "wolfssl/ssl.h" + #include "wolfssl/wolfcrypt/settings.h" + #include "wolfssl/ssl.h" + #include "wolfssl/openssl/x509.h" /* TODO not wolfssl internal WOLFSSL_X509 ? */ + #include "wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h" + #include "private_include/esp_tls_wolfssl.h" #endif struct esp_tls { @@ -69,6 +73,11 @@ struct esp_tls { uint8_t ecdsa_efuse_blk; /*!< The efuse block number where the ECDSA key is stored. */ #endif #elif CONFIG_ESP_TLS_USING_WOLFSSL + #ifndef WOLFSSL_NO_CONF_COMPATIBILITY + wolfssl_ssl_config conf; + void (*sync)(struct esp_tls*); + #endif + void *priv_ctx; void *priv_ssl; #endif diff --git a/components/esp-tls/private_include/esp_tls_wolfssl.h b/components/esp-tls/private_include/esp_tls_wolfssl.h index 121c13477f2d..8196d96c2ca7 100644 --- a/components/esp-tls/private_include/esp_tls_wolfssl.h +++ b/components/esp-tls/private_include/esp_tls_wolfssl.h @@ -7,11 +7,22 @@ #pragma once #include "esp_tls.h" #include "esp_tls_private.h" +#ifdef CONFIG_ESP_TLS_USING_WOLFSSL + +/* wolfssl_ssl_config is ESP-IDF specific helper for Certificate Bundles */ +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/ssl.h" +#include "wolfssl/openssl/x509.h" + /** * Internal Callback for creating ssl handle for wolfssl */ -int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params); +#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)) + int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params); +#else + int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls); +#endif /** * Internal Callback for wolfssl_handshake @@ -72,10 +83,15 @@ void *esp_wolfssl_get_ssl_context(esp_tls_t *tls); /** * wolfSSL function for Initializing socket wrappers (no-operation for wolfSSL) */ -static inline void esp_wolfssl_net_init(esp_tls_t *tls) -{ -} +void esp_wolfssl_net_init(esp_tls_t *tls); +/* + * Initialize a context + */ +//void wolfssl_net_init(wolfsslctx *ctx) +//{ +// ctx->fd = -1; +//} /** * Function to Create ESP-TLS Server session with wolfssl Stack @@ -85,4 +101,7 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp /* * Delete Server Session */ -void esp_wolfssl_server_session_delete(esp_tls_t *tls); +int esp_wolfssl_server_session_delete(esp_tls_t *tls); + + +#endif /* CONFIG_ESP_TLS_USING_WOLFSSL */ diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 8ac63e8f8bdb..d66a0209ffcf 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -723,11 +723,17 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co ESP_GOTO_ON_FALSE(init_common_tcp_transport(client, config, ssl), ESP_FAIL, error, TAG, "Failed to set SSL config"); if (config->crt_bundle_attach != NULL) { -#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE +#if defined(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) || defined(CONFIG_WOLFSSL_CERTIFICATE_BUNDLE) esp_transport_ssl_crt_bundle_attach(ssl, config->crt_bundle_attach); -#else //CONFIG_MBEDTLS_CERTIFICATE_BUNDLE +#else /* CONFIG_[PROVIDER]_CERTIFICATE_BUNDLE */ + #if defined(CONFIG_ESP_TLS_USING_MBEDTLS) ESP_LOGE(TAG, "use_crt_bundle configured but not enabled in menuconfig: Please enable MBEDTLS_CERTIFICATE_BUNDLE option"); -#endif + #elif defined(CONFIG_ESP_TLS_USING_WOLFSSL) + ESP_LOGE(TAG, "use_crt_bundle configured but not enabled in menuconfig: Please enable WOLFSSL_CERTIFICATE_BUNDLE option"); + #else + ESP_LOGE(TAG, "use_crt_bundle configured but a cryptographic provider not enabled in menuconfig: Please enable CONFIG_ESP_TLS_USING_WOLFSSL or CONFIG_ESP_TLS_USING_MBEDTLS"); + #endif +#endif /* !CONFIG_[PROVIDER]_CERTIFICATE_BUNDLE */ } else if (config->use_global_ca_store == true) { esp_transport_ssl_enable_global_ca_store(ssl); } else if (config->cert_pem) { diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index 7f0a4d78f386..0692f125e577 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -447,7 +447,7 @@ void esp_transport_ssl_use_secure_element(esp_transport_handle_t t) } #endif -#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE +#if defined(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) || defined(CONFIG_WOLFSSL_CERTIFICATE_BUNDLE) void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*crt_bundle_attach)(void *conf))) { GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);