diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index a846341bc2..c29039f9aa 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -307,6 +307,10 @@ typedef struct esp_tls_cfg_server { bool use_secure_element; /*!< Enable this option to use secure element or atecc608a chip */ + uint32_t tls_handshake_timeout_ms; /*!< TLS handshake timeout in milliseconds. + Note: If this value is not set, by default the timeout is + set to 10 seconds. If you wish that the session should wait + indefinitely then please use a larger value e.g., INT32_MAX */ #if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS) esp_tls_server_session_ticket_ctx_t * ticket_ctx; /*!< Session ticket generation context. diff --git a/components/esp-tls/esp_tls_errors.h b/components/esp-tls/esp_tls_errors.h index 6606562671..9f6ee286c7 100644 --- a/components/esp-tls/esp_tls_errors.h +++ b/components/esp-tls/esp_tls_errors.h @@ -32,7 +32,7 @@ extern "C" { #define ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT (ESP_ERR_ESP_TLS_BASE + 0x06) /*!< new connection in esp_tls_low_level_conn connection timeouted */ #define ESP_ERR_ESP_TLS_SE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x07) /*< esp-tls use Secure Element returned failed */ #define ESP_ERR_ESP_TLS_TCP_CLOSED_FIN (ESP_ERR_ESP_TLS_BASE + 0x08) /*< esp-tls's TPC transport connection has benn closed (in a clean way) */ - +#define ESP_ERR_ESP_TLS_SERVER_HANDSHAKE_TIMEOUT (ESP_ERR_ESP_TLS_BASE + 0x09) /*!< TLS handshake timeout */ /* mbedtls specific error codes */ #define ESP_ERR_MBEDTLS_CERT_PARTLY_OK (ESP_ERR_ESP_TLS_BASE + 0x10) /*!< mbedtls parse certificates was partly successful */ #define ESP_ERR_MBEDTLS_CTR_DRBG_SEED_FAILED (ESP_ERR_ESP_TLS_BASE + 0x11) /*!< mbedtls api returned error */ diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 40898314a1..bf6c530d16 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,7 @@ #include "esp_tls_mbedtls.h" #include "esp_tls_private.h" #include "esp_tls_error_capture_internal.h" +#include "esp_tls_platform_port.h" #include #include "esp_log.h" #include "esp_check.h" @@ -928,10 +929,24 @@ int esp_mbedtls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp if ((ret = esp_mbedtls_server_session_init(cfg, sockfd, tls)) != 0) { return ret; } + + uint64_t timeout_ms; + if (cfg->tls_handshake_timeout_ms == 0) { + timeout_ms = ESP_TLS_DEFAULT_SERVER_HANDSHAKE_TIMEOUT_MS; + } else { + timeout_ms = cfg->tls_handshake_timeout_ms; + } + uint64_t start_time = esp_tls_get_platform_time(); + while ((ret = esp_mbedtls_server_session_continue_async(tls)) != 0) { if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) { return ret; } + uint64_t elapsed_time_us = esp_tls_get_platform_time() - start_time; + if ((elapsed_time_us / 1000) > timeout_ms) { + ESP_LOGD(TAG, "Server handshake timed out"); + return ESP_ERR_ESP_TLS_SERVER_HANDSHAKE_TIMEOUT; + } } return ret; } diff --git a/components/esp-tls/private_include/esp_tls_private.h b/components/esp-tls/private_include/esp_tls_private.h index 4341557aaf..669e01aad6 100644 --- a/components/esp-tls/private_include/esp_tls_private.h +++ b/components/esp-tls/private_include/esp_tls_private.h @@ -103,3 +103,5 @@ typedef esp_err_t (*set_server_config_func_ptr) (esp_tls_cfg_server_t *cfg, esp_ typedef struct esp_tls_server_params { set_server_config_func_ptr set_server_cfg; } esp_tls_server_params_t; + +#define ESP_TLS_DEFAULT_SERVER_HANDSHAKE_TIMEOUT_MS (10000) /*!< Default handshake timeout in milliseconds */ diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index bf4c3b7d7e..1c342e6b2a 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -694,6 +694,9 @@ static const esp_err_msg_t esp_err_msg_table[] = { # ifdef ESP_ERR_ESP_TLS_TCP_CLOSED_FIN ERR_TBL_IT(ESP_ERR_ESP_TLS_TCP_CLOSED_FIN), /* 32776 0x8008 */ # endif +# ifdef ESP_ERR_ESP_TLS_SERVER_HANDSHAKE_TIMEOUT + ERR_TBL_IT(ESP_ERR_ESP_TLS_SERVER_HANDSHAKE_TIMEOUT), /* 32777 0x8009 TLS handshake timeout */ +# endif # ifdef ESP_ERR_MBEDTLS_CERT_PARTLY_OK ERR_TBL_IT(ESP_ERR_MBEDTLS_CERT_PARTLY_OK), /* 32784 0x8010 mbedtls parse certificates was partly successful */ # endif diff --git a/components/esp_https_server/include/esp_https_server.h b/components/esp_https_server/include/esp_https_server.h index d893fbbbf5..611118fc83 100644 --- a/components/esp_https_server/include/esp_https_server.h +++ b/components/esp_https_server/include/esp_https_server.h @@ -132,6 +132,9 @@ struct httpd_ssl_config { * Used for negotiating during the TLS handshake, first one the client supports is selected. * The data structure must live as long as the https server itself */ const char** alpn_protos; + + /** TLS handshake timeout in milliseconds, default timeout is 10 seconds if not set */ + uint32_t tls_handshake_timeout_ms; }; typedef struct httpd_ssl_config httpd_ssl_config_t; @@ -192,6 +195,7 @@ typedef struct httpd_ssl_config httpd_ssl_config_t; .ssl_userdata = NULL, \ .cert_select_cb = NULL, \ .alpn_protos = NULL, \ + .tls_handshake_timeout_ms = 0 \ } /** diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index ed3d432a94..b3d22e5346 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -277,6 +277,7 @@ static esp_err_t create_secure_context(const struct httpd_ssl_config *config, ht cfg->userdata = config->ssl_userdata; cfg->alpn_protos = config->alpn_protos; + cfg->tls_handshake_timeout_ms = config->tls_handshake_timeout_ms; #if defined(CONFIG_ESP_HTTPS_SERVER_CERT_SELECT_HOOK) cfg->cert_select_cb = config->cert_select_cb;