mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feat/http_client_session_ticket' into 'master'
feat(http_client): Restore TLS session and custom transport See merge request espressif/esp-idf!26059
This commit is contained in:
commit
096d1ce1bb
@ -21,4 +21,12 @@ menu "ESP HTTP client"
|
||||
This option will enable HTTP Digest Authentication. It is enabled by default, but use of this
|
||||
configuration is not recommended as the password can be derived from the exchange, so it introduces
|
||||
a vulnerability when not using TLS
|
||||
|
||||
config ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT
|
||||
bool "Enable custom transport"
|
||||
default n
|
||||
help
|
||||
This option will enable injection of a custom tcp_transport handle, so the http operation
|
||||
will be performed on top of the user defined transport abstraction (if configured)
|
||||
|
||||
endmenu
|
||||
|
@ -88,6 +88,13 @@ typedef enum {
|
||||
HTTP_STATE_RES_COMPLETE_DATA,
|
||||
HTTP_STATE_CLOSE
|
||||
} esp_http_state_t;
|
||||
|
||||
typedef enum {
|
||||
SESSION_TICKET_UNUSED = 0,
|
||||
SESSION_TICKET_NOT_SAVED,
|
||||
SESSION_TICKET_SAVED,
|
||||
} session_ticket_state_t;
|
||||
|
||||
/**
|
||||
* HTTP client class
|
||||
*/
|
||||
@ -127,6 +134,9 @@ struct esp_http_client {
|
||||
esp_transport_keep_alive_t keep_alive_cfg;
|
||||
struct ifreq *if_name;
|
||||
unsigned cache_data_in_fetch_hdr: 1;
|
||||
#ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
session_ticket_state_t session_ticket_state;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct esp_http_client esp_http_client_t;
|
||||
@ -742,6 +752,18 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
if (config->save_client_session) {
|
||||
client->session_ticket_state = SESSION_TICKET_NOT_SAVED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT
|
||||
if (config->transport) {
|
||||
client->transport = config->transport;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config->client_key_pem) {
|
||||
if (!config->client_key_len) {
|
||||
esp_transport_ssl_set_client_key_data(ssl, config->client_key_pem, strlen(config->client_key_pem));
|
||||
@ -1387,8 +1409,21 @@ static esp_err_t esp_http_client_connect(esp_http_client_handle_t client)
|
||||
}
|
||||
|
||||
if (client->state < HTTP_STATE_CONNECTED) {
|
||||
ESP_LOGD(TAG, "Begin connect to: %s://%s:%d", client->connection_info.scheme, client->connection_info.host, client->connection_info.port);
|
||||
client->transport = esp_transport_list_get_transport(client->transport_list, client->connection_info.scheme);
|
||||
#ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT
|
||||
// If the custom transport is enabled and defined, we skip the selection of appropriate transport from the list
|
||||
// based on the scheme, since we already have the transport
|
||||
if (!client->transport)
|
||||
#endif
|
||||
{
|
||||
ESP_LOGD(TAG, "Begin connect to: %s://%s:%d", client->connection_info.scheme, client->connection_info.host, client->connection_info.port);
|
||||
client->transport = esp_transport_list_get_transport(client->transport_list, client->connection_info.scheme);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
if (client->session_ticket_state == SESSION_TICKET_SAVED) {
|
||||
esp_transport_ssl_session_ticket_operation(client->transport, ESP_TRANSPORT_SESSION_TICKET_USE);
|
||||
}
|
||||
#endif
|
||||
if (client->transport == NULL) {
|
||||
ESP_LOGE(TAG, "No transport found");
|
||||
#ifndef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS
|
||||
@ -1420,6 +1455,13 @@ static esp_err_t esp_http_client_connect(esp_http_client_handle_t client)
|
||||
client->state = HTTP_STATE_CONNECTED;
|
||||
http_dispatch_event(client, HTTP_EVENT_ON_CONNECTED, NULL, 0);
|
||||
http_dispatch_event_to_event_loop(HTTP_EVENT_ON_CONNECTED, &client, sizeof(esp_http_client_handle_t));
|
||||
#ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
if (client->session_ticket_state != SESSION_TICKET_UNUSED) {
|
||||
esp_transport_ssl_session_ticket_operation(client->transport, ESP_TRANSPORT_SESSION_TICKET_SAVE);
|
||||
client->session_ticket_state = SESSION_TICKET_SAVED;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -24,6 +24,11 @@ ESP_EVENT_DECLARE_BASE(ESP_HTTP_CLIENT_EVENT);
|
||||
typedef struct esp_http_client *esp_http_client_handle_t;
|
||||
typedef struct esp_http_client_event *esp_http_client_event_handle_t;
|
||||
|
||||
#if CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT
|
||||
// Forward declares transport handle item to keep the dependency private (even if ENABLE_CUSTOM_TRANSPORT=y)
|
||||
struct esp_transport_item_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HTTP Client events id
|
||||
*/
|
||||
@ -178,6 +183,12 @@ typedef struct {
|
||||
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
void *ds_data; /*!< Pointer for digital signature peripheral context, see ESP-TLS Documentation for more details */
|
||||
#endif
|
||||
#if CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
bool save_client_session;
|
||||
#endif
|
||||
#if CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT
|
||||
struct esp_transport_item_t *transport;
|
||||
#endif
|
||||
} esp_http_client_config_t;
|
||||
|
||||
/**
|
||||
|
@ -211,6 +211,28 @@ void esp_transport_ssl_set_keep_alive(esp_transport_handle_t t, esp_transport_ke
|
||||
*/
|
||||
void esp_transport_ssl_set_interface_name(esp_transport_handle_t t, struct ifreq *if_name);
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
/**
|
||||
* @brief Session ticket operation
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_TRANSPORT_SESSION_TICKET_INIT, /*!< Allocate and initialize a TLS session */
|
||||
ESP_TRANSPORT_SESSION_TICKET_SAVE, /*!< Save TLS session so it can be restored for the next handshake */
|
||||
ESP_TRANSPORT_SESSION_TICKET_USE, /*!< Use already saved session to reconnect faster */
|
||||
ESP_TRANSPORT_SESSION_TICKET_FREE /*!< Deallocate and deinit the TLS session */
|
||||
} esp_transport_session_ticket_operation_t;
|
||||
|
||||
/**
|
||||
* @brief Perform desired session ticket operation (init, save, use)
|
||||
*
|
||||
* @param[in] t The transport handle
|
||||
* @param[in] operation Operation to perform with TLS session
|
||||
*
|
||||
* @note This operation is only available if CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS=y
|
||||
*/
|
||||
esp_err_t esp_transport_ssl_session_ticket_operation(esp_transport_handle_t t, esp_transport_session_ticket_operation_t operation);
|
||||
#endif // CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -38,6 +38,9 @@ typedef struct transport_esp_tls {
|
||||
bool ssl_initialized;
|
||||
transport_ssl_conn_state_t conn_state;
|
||||
int sockfd;
|
||||
#ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
esp_tls_client_session_t *session_ticket;
|
||||
#endif
|
||||
} transport_esp_tls_t;
|
||||
|
||||
/**
|
||||
@ -523,6 +526,9 @@ esp_transport_handle_t esp_transport_ssl_init(void)
|
||||
|
||||
void esp_transport_esp_tls_destroy(struct transport_esp_tls *transport_esp_tls)
|
||||
{
|
||||
#ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
esp_tls_free_client_session(transport_esp_tls->session_ticket);
|
||||
#endif
|
||||
free(transport_esp_tls);
|
||||
}
|
||||
|
||||
@ -548,3 +554,32 @@ void esp_transport_tcp_set_interface_name(esp_transport_handle_t t, struct ifreq
|
||||
{
|
||||
return esp_transport_ssl_set_interface_name(t, if_name);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
esp_err_t esp_transport_ssl_session_ticket_operation(esp_transport_handle_t t, esp_transport_session_ticket_operation_t operation)
|
||||
{
|
||||
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
||||
if (!ssl) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
switch (operation) {
|
||||
case ESP_TRANSPORT_SESSION_TICKET_INIT:
|
||||
break;
|
||||
case ESP_TRANSPORT_SESSION_TICKET_SAVE:
|
||||
esp_tls_free_client_session(ssl->session_ticket);
|
||||
ssl->session_ticket = esp_tls_get_client_session(ssl->tls);
|
||||
break;
|
||||
case ESP_TRANSPORT_SESSION_TICKET_USE:
|
||||
if (ssl->session_ticket == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ssl->cfg.client_session = ssl->session_ticket;
|
||||
break;
|
||||
case ESP_TRANSPORT_SESSION_TICKET_FREE:
|
||||
esp_tls_free_client_session(ssl->session_ticket);
|
||||
ssl->session_ticket = NULL;
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
|
||||
|
@ -7,3 +7,5 @@
|
||||
- ignore_arg
|
||||
- callback
|
||||
:when_ptr: :compare_ptr
|
||||
:strippables:
|
||||
- '(?:esp_transport_ssl_session_ticket_operation\s*\(+.*?\)+)'
|
||||
|
Loading…
Reference in New Issue
Block a user