瀏覽代碼

fix(esp-tls): Use TLS 1.2 and TLS 1.3 simultaneously

This commit fixes the issue with TLS 1.2 connection when TLS 1.3 is
enabled in config.
Harshit Malpani 2 年之前
父節點
當前提交
27681a5073

+ 11 - 0
components/esp-tls/esp_tls.h

@@ -81,6 +81,16 @@ typedef enum esp_tls_addr_family {
     ESP_TLS_AF_INET6,                     /**< IPv6 address family. */
 } esp_tls_addr_family_t;
 
+/*
+* @brief ESP-TLS TLS Protocol version
+*/
+typedef enum {
+   ESP_TLS_VER_ANY = 0,         /* No preference */
+   ESP_TLS_VER_TLS_1_2 = 0x1,   /* (D)TLS 1.2 */
+   ESP_TLS_VER_TLS_1_3 = 0x2,   /* (D)TLS 1.3 */
+   ESP_TLS_VER_TLS_MAX,         /* to indicate max */
+} esp_tls_proto_ver_t;
+
 /**
  * @brief      ESP-TLS configuration parameters
  *
@@ -200,6 +210,7 @@ typedef struct esp_tls_cfg {
     esp_tls_addr_family_t addr_family;      /*!< The address family to use when connecting to a host. */
     const int *ciphersuites_list;           /*!< Pointer to a zero-terminated array of IANA identifiers of TLS ciphersuites.
                                                 Please check the list validity by esp_tls_get_ciphersuites_list() API */
+    esp_tls_proto_ver_t tls_version;        /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */
 } esp_tls_cfg_t;
 
 #ifdef CONFIG_ESP_TLS_SERVER

+ 25 - 10
components/esp-tls/esp_tls_mbedtls.c

@@ -97,6 +97,24 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const
             ESP_LOGE(TAG, "Failed to set client configurations, returned [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret));
             goto exit;
         }
+        const esp_tls_proto_ver_t tls_ver = ((esp_tls_cfg_t *)cfg)->tls_version;
+        if (tls_ver == ESP_TLS_VER_TLS_1_3) {
+#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
+            ESP_LOGD(TAG, "Setting TLS version to 0x%4x", MBEDTLS_SSL_VERSION_TLS1_3);
+            mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3);
+            mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3);
+#else
+            ESP_LOGW(TAG, "TLS 1.3 is not enabled in config, continuing with default TLS protocol");
+#endif
+        } else if (tls_ver == ESP_TLS_VER_TLS_1_2) {
+            ESP_LOGD(TAG, "Setting TLS version to 0x%4x", MBEDTLS_SSL_VERSION_TLS1_2);
+            mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_2);
+            mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_2);
+        } else if (tls_ver != ESP_TLS_VER_ANY) {
+            ESP_LOGE(TAG, "Unsupported protocol version");
+            esp_ret = ESP_ERR_INVALID_ARG;
+            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);
@@ -125,11 +143,6 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const
     mbedtls_esp_enable_debug_log(&tls->conf, CONFIG_MBEDTLS_DEBUG_LEVEL);
 #endif
 
-#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3
-    mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3);
-    mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3);
-#endif
-
     if ((ret = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) {
         ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%04X", -ret);
         mbedtls_print_error_msg(ret);
@@ -233,15 +246,17 @@ ssize_t esp_mbedtls_read(esp_tls_t *tls, char *data, size_t datalen)
 {
 
     ssize_t ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen);
-#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 && CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS
+#if CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS
     // If a post-handshake message is received, connection state is changed to `MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET`
     // Call mbedtls_ssl_read() till state is `MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET` or return code is `MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET`
     // to process session tickets in TLS 1.3 connection
-    while (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET || tls->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET) {
-        ESP_LOGD(TAG, "got session ticket in TLS 1.3 connection, retry read");
-        ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen);
+    if (mbedtls_ssl_get_version_number(&tls->ssl) == MBEDTLS_SSL_VERSION_TLS1_3) {
+        while (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET || tls->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET) {
+            ESP_LOGD(TAG, "got session ticket in TLS 1.3 connection, retry read");
+            ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen);
+        }
     }
-#endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 && CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS
+#endif // CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS
 
     if (ret < 0) {
         if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {

+ 6 - 0
components/esp_http_client/esp_http_client.c

@@ -9,6 +9,7 @@
 #include <inttypes.h>
 
 #include "esp_log.h"
+#include "esp_assert.h"
 #include "esp_check.h"
 #include "http_parser.h"
 #include "http_header.h"
@@ -20,6 +21,7 @@
 #include "esp_http_client.h"
 #include "errno.h"
 #include "esp_random.h"
+#include "esp_tls.h"
 
 #ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS
 #include "esp_transport_ssl.h"
@@ -29,6 +31,9 @@ ESP_EVENT_DEFINE_BASE(ESP_HTTP_CLIENT_EVENT);
 
 static const char *TAG = "HTTP_CLIENT";
 
+ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_ANY == (int)ESP_TLS_VER_ANY, "Enum mismatch in esp_http_client and esp-tls");
+ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_MAX <= (int)ESP_TLS_VER_TLS_MAX, "HTTP client supported TLS is not supported in esp-tls");
+
 /**
  * HTTP Buffer
  */
@@ -723,6 +728,7 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
             esp_transport_ssl_set_client_cert_data_der(ssl, config->client_cert_pem, config->client_cert_len);
         }
     }
+    esp_transport_ssl_set_tls_version(ssl, config->tls_version);
 
 #if CONFIG_ESP_TLS_USE_SECURE_ELEMENT
     if (config->use_secure_element) {

+ 11 - 0
components/esp_http_client/include/esp_http_client.h

@@ -78,6 +78,16 @@ typedef enum {
     HTTP_TRANSPORT_OVER_SSL,        /*!< Transport over ssl */
 } esp_http_client_transport_t;
 
+/*
+* @brief TLS Protocol version
+*/
+typedef enum {
+   ESP_HTTP_CLIENT_TLS_VER_ANY = 0,         /* No preference */
+   ESP_HTTP_CLIENT_TLS_VER_TLS_1_2 = 0x1,   /* (D)TLS 1.2 */
+   ESP_HTTP_CLIENT_TLS_VER_TLS_1_3 = 0x2,   /* (D)TLS 1.3 */
+   ESP_HTTP_CLIENT_TLS_VER_MAX,             /* to indicate max */
+} esp_http_client_proto_ver_t;
+
 typedef esp_err_t (*http_event_handle_cb)(esp_http_client_event_t *evt);
 
 /**
@@ -133,6 +143,7 @@ typedef struct {
     size_t                      client_key_len;      /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */
     const char                  *client_key_password;      /*!< Client key decryption password string */
     size_t                      client_key_password_len;   /*!< String length of the password pointed to by client_key_password */
+    esp_http_client_proto_ver_t tls_version;         /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */
 #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
     bool                        use_ecdsa_peripheral;       /*!< Use ECDSA peripheral to use private key. */
     uint8_t                     ecdsa_key_efuse_blk;        /*!< The efuse block where ECDSA key is stored. */

+ 8 - 0
components/tcp_transport/include/esp_transport_ssl.h

@@ -61,6 +61,14 @@ void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*
  */
 void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t);
 
+/**
+ * @brief      Set TLS protocol version for ESP-TLS connection
+ *
+ * @param      t    ssl transport
+ * @param[in]  tls_version      TLS version
+ */
+void esp_transport_ssl_set_tls_version(esp_transport_handle_t t, esp_tls_proto_ver_t tls_version);
+
 /**
  * @brief      Set SSL client certificate data for mutual authentication (as PEM format).
  *             Note that, this function stores the pointer to data, rather than making a copy.

+ 6 - 0
components/tcp_transport/transport_ssl.c

@@ -341,6 +341,12 @@ void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t)
     ssl->cfg.use_global_ca_store = true;
 }
 
+void esp_transport_ssl_set_tls_version(esp_transport_handle_t t, esp_tls_proto_ver_t tls_version)
+{
+    GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
+    ssl->cfg.tls_version = tls_version;
+}
+
 #ifdef CONFIG_ESP_TLS_PSK_VERIFICATION
 void esp_transport_ssl_set_psk_key_hint(esp_transport_handle_t t, const psk_hint_key_t *psk_hint_key)
 {