diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index 386ecb0883..b7014026f0 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -14,6 +14,7 @@ #include #include "esp_tls.h" +#include "esp_tls_private.h" #include "esp_tls_error_capture_internal.h" #include static const char *TAG = "esp-tls"; @@ -89,6 +90,18 @@ static ssize_t tcp_write(esp_tls_t *tls, const char *data, size_t datalen) return send(tls->sockfd, data, datalen, 0); } +ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen) +{ + return tls->read(tls, (char *)data, datalen); + +} + +ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_t datalen) +{ + return tls->write(tls, (char *)data, datalen); + +} + /** * @brief Close the TLS connection and free any allocated resources. */ @@ -629,6 +642,16 @@ esp_err_t esp_tls_get_and_clear_last_error(esp_tls_error_handle_t h, int *esp_tl return last_err; } +esp_err_t esp_tls_get_error_handle(esp_tls_t *tls, esp_tls_error_handle_t *error_handle) +{ + if (tls == NULL) { + return ESP_ERR_INVALID_ARG; + } + + *error_handle = tls->error_handle; + return ESP_OK; +} + esp_err_t esp_tls_init_global_ca_store(void) { return _esp_tls_init_global_ca_store(); diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index a4bbf8e2f2..100ef7d7fd 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -11,6 +11,7 @@ #include #include "esp_err.h" #include "esp_tls_errors.h" +#include "sdkconfig.h" #ifdef CONFIG_ESP_TLS_USING_MBEDTLS #include "mbedtls/platform.h" #include "mbedtls/net_sockets.h" @@ -27,6 +28,7 @@ #include "wolfssl/ssl.h" #endif + #ifdef __cplusplus extern "C" { #endif @@ -290,66 +292,7 @@ esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg); void esp_tls_cfg_server_session_tickets_free(esp_tls_cfg_server_t *cfg); #endif /* ! CONFIG_ESP_TLS_SERVER */ -/** - * @brief ESP-TLS Connection Handle - */ -typedef struct esp_tls { -#ifdef CONFIG_ESP_TLS_USING_MBEDTLS - mbedtls_ssl_context ssl; /*!< TLS/SSL context */ - - mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */ - - mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure. - CTR_DRBG is deterministic random - bit generation based on AES-256 */ - - mbedtls_ssl_config conf; /*!< TLS/SSL configuration to be shared - between mbedtls_ssl_context - structures */ - - mbedtls_net_context server_fd; /*!< mbedTLS wrapper type for sockets */ - - mbedtls_x509_crt cacert; /*!< Container for the X.509 CA certificate */ - - mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */ - - mbedtls_x509_crt clientcert; /*!< Container for the X.509 client certificate */ - - mbedtls_pk_context clientkey; /*!< Container for the private key of the client - certificate */ -#ifdef CONFIG_ESP_TLS_SERVER - mbedtls_x509_crt servercert; /*!< Container for the X.509 server certificate */ - - mbedtls_pk_context serverkey; /*!< Container for the private key of the server - certificate */ -#endif -#elif CONFIG_ESP_TLS_USING_WOLFSSL - void *priv_ctx; - void *priv_ssl; -#endif - int sockfd; /*!< Underlying socket file descriptor. */ - - ssize_t (*read)(struct esp_tls *tls, char *data, size_t datalen); /*!< Callback function for reading data from TLS/SSL - connection. */ - - ssize_t (*write)(struct esp_tls *tls, const char *data, size_t datalen); /*!< Callback function for writing data to TLS/SSL - connection. */ - - esp_tls_conn_state_t conn_state; /*!< ESP-TLS Connection state */ - - fd_set rset; /*!< read file descriptors */ - - fd_set wset; /*!< write file descriptors */ - - bool is_tls; /*!< indicates connection type (TLS or NON-TLS) */ - - esp_tls_role_t role; /*!< esp-tls role - - ESP_TLS_CLIENT - - ESP_TLS_SERVER */ - - esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ - -} esp_tls_t; +typedef struct esp_tls esp_tls_t; /** * @brief Create TLS connection @@ -470,10 +413,7 @@ int esp_tls_conn_http_new_async(const char *url, const esp_tls_cfg_t *cfg, esp_t * if the handshake is incomplete and waiting for data to be available for reading. * In this case this functions needs to be called again when the underlying transport is ready for operation. */ -static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_t datalen) -{ - return tls->write(tls, (char *)data, datalen); -} +ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_t datalen); /** * @brief Read from specified tls connection into the buffer 'data'. @@ -490,10 +430,7 @@ static inline ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_ * - <0 if read operation was not successful, because either an * error occured or an action must be taken by the calling process. */ -static inline ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen) -{ - return tls->read(tls, (char *)data, datalen); -} +ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen); /** * @brief Close the TLS/SSL connection and free any allocated resources. @@ -607,6 +544,20 @@ esp_err_t esp_tls_get_and_clear_last_error(esp_tls_error_handle_t h, int *esp_tl */ esp_err_t esp_tls_get_and_clear_error_type(esp_tls_error_handle_t h, esp_tls_error_type_t err_type, int *error_code); +/** + * @brief Returns the ESP-TLS error_handle + * + * @param[in] tls handle to esp_tls context + * + * @param[out] error_handle pointer to the error handle. + * + * @return + * - ESP_OK on success and error_handle will be updated with the ESP-TLS error handle. + * + * - ESP_ERR_INVALID_ARG if (tls == NULL) + */ +esp_err_t esp_tls_get_error_handle(esp_tls_t *tls, esp_tls_error_handle_t *error_handle); + #if CONFIG_ESP_TLS_USING_MBEDTLS /** * @brief Get the pointer to the global CA store currently being used. diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 37a1ca8c48..7dccec4960 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -14,6 +14,7 @@ #include #include "esp_tls_mbedtls.h" +#include "esp_tls_private.h" #include "esp_tls_error_capture_internal.h" #include #include "esp_log.h" diff --git a/components/esp-tls/private_include/esp_tls_mbedtls.h b/components/esp-tls/private_include/esp_tls_mbedtls.h index c1c5d4f328..cb64083186 100644 --- a/components/esp-tls/private_include/esp_tls_mbedtls.h +++ b/components/esp-tls/private_include/esp_tls_mbedtls.h @@ -6,6 +6,7 @@ #pragma once #include "esp_tls.h" +#include "esp_tls_private.h" /** * Internal Callback API for mbedtls_ssl_read diff --git a/components/esp-tls/private_include/esp_tls_private.h b/components/esp-tls/private_include/esp_tls_private.h new file mode 100644 index 0000000000..f071c9b0ff --- /dev/null +++ b/components/esp-tls/private_include/esp_tls_private.h @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/** + * @brief ESP-TLS Connection Handle + */ + +#include +#include +#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" +#include "mbedtls/esp_debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS +#include "mbedtls/ssl_ticket.h" +#endif +#elif CONFIG_ESP_TLS_USING_WOLFSSL +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/ssl.h" +#endif + +struct esp_tls { +#ifdef CONFIG_ESP_TLS_USING_MBEDTLS + mbedtls_ssl_context ssl; /*!< TLS/SSL context */ + + mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */ + + mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure. + CTR_DRBG is deterministic random + bit generation based on AES-256 */ + + mbedtls_ssl_config conf; /*!< TLS/SSL configuration to be shared + between mbedtls_ssl_context + structures */ + + mbedtls_net_context server_fd; /*!< mbedTLS wrapper type for sockets */ + + mbedtls_x509_crt cacert; /*!< Container for the X.509 CA certificate */ + + mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */ + + mbedtls_x509_crt clientcert; /*!< Container for the X.509 client certificate */ + + mbedtls_pk_context clientkey; /*!< Container for the private key of the client + certificate */ +#ifdef CONFIG_ESP_TLS_SERVER + mbedtls_x509_crt servercert; /*!< Container for the X.509 server certificate */ + + mbedtls_pk_context serverkey; /*!< Container for the private key of the server + certificate */ +#endif +#elif CONFIG_ESP_TLS_USING_WOLFSSL + void *priv_ctx; + void *priv_ssl; +#endif + int sockfd; /*!< Underlying socket file descriptor. */ + + ssize_t (*read)(esp_tls_t *tls, char *data, size_t datalen); /*!< Callback function for reading data from TLS/SSL + connection. */ + + ssize_t (*write)(esp_tls_t *tls, const char *data, size_t datalen); /*!< Callback function for writing data to TLS/SSL + connection. */ + + esp_tls_conn_state_t conn_state; /*!< ESP-TLS Connection state */ + + fd_set rset; /*!< read file descriptors */ + + fd_set wset; /*!< write file descriptors */ + + bool is_tls; /*!< indicates connection type (TLS or NON-TLS) */ + + esp_tls_role_t role; /*!< esp-tls role + - ESP_TLS_CLIENT + - ESP_TLS_SERVER */ + + esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ + +}; diff --git a/components/esp-tls/private_include/esp_tls_wolfssl.h b/components/esp-tls/private_include/esp_tls_wolfssl.h index a0c86730b7..b9f5de3b13 100644 --- a/components/esp-tls/private_include/esp_tls_wolfssl.h +++ b/components/esp-tls/private_include/esp_tls_wolfssl.h @@ -6,6 +6,7 @@ #pragma once #include "esp_tls.h" +#include "esp_tls_private.h" /** * Internal Callback for creating ssl handle for wolfssl diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index 6fd7218c56..cf7562c2ab 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -118,7 +118,7 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd) httpd_ssl_ctx_t *global_ctx = httpd_get_global_transport_ctx(server); assert(global_ctx != NULL); - esp_tls_t *tls = (esp_tls_t *)calloc(1, sizeof(esp_tls_t)); + esp_tls_t *tls = esp_tls_init(); if (!tls) { return ESP_ERR_NO_MEM; } diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index 8a8b2905bb..5794263b03 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -76,7 +76,11 @@ static int esp_tls_connect_async(esp_transport_handle_t t, const char *host, int if (ssl->conn_state == TRANS_SSL_CONNECTING) { int progress = esp_tls_conn_new_async(host, strlen(host), port, &ssl->cfg, ssl->tls); if (progress >= 0) { - ssl->sockfd = ssl->tls->sockfd; + if (esp_tls_get_conn_sockfd(ssl->tls, &ssl->sockfd) != ESP_OK) { + ESP_LOGE(TAG, "Error in obtaining socket fd for the session"); + esp_tls_conn_destroy(ssl->tls); + return -1; + } } return progress; @@ -110,14 +114,23 @@ static int ssl_connect(esp_transport_handle_t t, const char *host, int port, int } if (esp_tls_conn_new_sync(host, strlen(host), port, &ssl->cfg, ssl->tls) <= 0) { ESP_LOGE(TAG, "Failed to open a new connection"); - esp_transport_set_errors(t, ssl->tls->error_handle); + esp_tls_error_handle_t esp_tls_error_handle; + esp_tls_get_error_handle(ssl->tls, &esp_tls_error_handle); + esp_transport_set_errors(t, esp_tls_error_handle); + goto exit_failure; + } + + if (esp_tls_get_conn_sockfd(ssl->tls, &ssl->sockfd) != ESP_OK) { + ESP_LOGE(TAG, "Error in obtaining socket fd for the session"); + goto exit_failure; + } + return 0; + +exit_failure: esp_tls_conn_destroy(ssl->tls); ssl->tls = NULL; ssl->sockfd = INVALID_SOCKET; return -1; - } - ssl->sockfd = ssl->tls->sockfd; - return 0; } static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms) @@ -200,7 +213,12 @@ static int ssl_write(esp_transport_handle_t t, const char *buffer, int len, int int ret = esp_tls_conn_write(ssl->tls, (const unsigned char *) buffer, len); if (ret < 0) { ESP_LOGE(TAG, "esp_tls_conn_write error, errno=%s", strerror(errno)); - esp_transport_set_errors(t, ssl->tls->error_handle); + esp_tls_error_handle_t esp_tls_error_handle; + if (esp_tls_get_error_handle(ssl->tls, &esp_tls_error_handle) == ESP_OK) { + esp_transport_set_errors(t, esp_tls_error_handle); + } else { + ESP_LOGE(TAG, "Error in obtaining the error handle"); + } } return ret; } @@ -233,7 +251,12 @@ static int ssl_read(esp_transport_handle_t t, char *buffer, int len, int timeout int ret = esp_tls_conn_read(ssl->tls, (unsigned char *)buffer, len); if (ret < 0) { ESP_LOGE(TAG, "esp_tls_conn_read error, errno=%s", strerror(errno)); - esp_transport_set_errors(t, ssl->tls->error_handle); + esp_tls_error_handle_t esp_tls_error_handle; + if (esp_tls_get_error_handle(ssl->tls, &esp_tls_error_handle) == ESP_OK) { + esp_transport_set_errors(t, esp_tls_error_handle); + } else { + ESP_LOGE(TAG, "Error in obtaining the error handle"); + } } if (ret == 0) { if (poll > 0) { diff --git a/docs/en/migration-guides/protocols.rst b/docs/en/migration-guides/protocols.rst index b7e3359bed..ea290f1550 100644 --- a/docs/en/migration-guides/protocols.rst +++ b/docs/en/migration-guides/protocols.rst @@ -20,6 +20,7 @@ Most structure fields are now private - Appropriate accessor functions (getter/setter) must be used for the same. A temporary workaround would be to use ``MBEDTLS_PRIVATE`` macro (**not recommended**). - For more details, refer to the official guide `here `__. + SSL ^^^ - Removed support for TLS 1.0, 1.1 and DTLS 1.0 @@ -102,6 +103,19 @@ ESP-TLS Breaking Changes (Summary) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +esp_tls_t structure is now private +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :cpp:type:`esp_tls_t` has now been made completely private. You cannot access its internal structures directly. Any necessary data that needs to be obtained from the esp-tls handle can be done through respective getter/setter functions. If there is a requirement of a specific getter/setter function please raise an issue on ESP-IDF. + + +The list of newly added getter/setter function is as as follows: + +.. list:: + * :cpp:func:`esp_tls_get_ssl_context` - Obtain the ssl context of the underlying ssl stack from the esp-tls handle. + +Function deprecations and recommended alternatives +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Following table summarizes the deprecated functions removed and their alternatives to be used from ESP-IDF v5.0 onwards. +-----------------------------------+----------------------------------------+