feat(http_client): Add support for TLS session tickets

This commit is contained in:
David Cermak 2023-09-19 18:52:45 +02:00
parent 1d7132ce6b
commit 7e22a13afe
5 changed files with 92 additions and 1 deletions

View File

@ -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,12 @@ 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->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));
@ -1384,6 +1400,12 @@ 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_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
@ -1415,6 +1437,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;
}

View File

@ -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
*/
@ -178,6 +178,9 @@ 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
} esp_http_client_config_t;
/**

View File

@ -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

View File

@ -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

View File

@ -7,3 +7,5 @@
- ignore_arg
- callback
:when_ptr: :compare_ptr
:strippables:
- '(?:esp_transport_ssl_session_ticket_operation\s*\(+.*?\)+)'