mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-07 06:34:34 +02:00
Implement server session ticket support with mbedtls
Closes https://github.com/espressif/esp-idf/pull/7048 Signed-off-by: Aditya Patwardhan <aditya.patwardhan@espressif.com>
This commit is contained in:
committed by
Aditya Patwardhan
parent
8f283421da
commit
7e886ca9ed
@@ -41,6 +41,20 @@ menu "ESP-TLS"
|
||||
Enable support for creating server side SSL/TLS session, available for mbedTLS
|
||||
as well as wolfSSL TLS library.
|
||||
|
||||
config ESP_TLS_SERVER_SESSION_TICKETS
|
||||
bool "Enable session tickets"
|
||||
depends on ESP_TLS_SERVER && ESP_TLS_USING_MBEDTLS && MBEDTLS_SERVER_SSL_SESSION_TICKETS
|
||||
default n
|
||||
help
|
||||
Enable session ticket support as specified in RFC5077
|
||||
|
||||
config ESP_TLS_SERVER_SESSION_TICKET_TIMEOUT
|
||||
int "Server session ticket timeout in seconds"
|
||||
depends on ESP_TLS_SERVER_SESSION_TICKETS
|
||||
default 86400
|
||||
help
|
||||
Sets the session ticket timeout used in the tls server.
|
||||
|
||||
config ESP_TLS_PSK_VERIFICATION
|
||||
bool "Enable PSK verification"
|
||||
select MBEDTLS_PSK_MODES if ESP_TLS_USING_MBEDTLS
|
||||
|
@@ -41,6 +41,8 @@ static const char *TAG = "esp-tls";
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
#define _esp_tls_server_session_create esp_mbedtls_server_session_create
|
||||
#define _esp_tls_server_session_delete esp_mbedtls_server_session_delete
|
||||
#define _esp_tls_session_ticket_ctx_init esp_mbedtls_session_ticket_ctx_init
|
||||
#define _esp_tls_session_ticket_ctx_free esp_mbedtls_session_ticket_ctx_free
|
||||
#endif /* CONFIG_ESP_TLS_SERVER */
|
||||
#define _esp_tls_get_bytes_avail esp_mbedtls_get_bytes_avail
|
||||
#define _esp_tls_init_global_ca_store esp_mbedtls_init_global_ca_store
|
||||
@@ -569,6 +571,32 @@ mbedtls_x509_crt *esp_tls_get_global_ca_store(void)
|
||||
|
||||
#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
|
||||
esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg)
|
||||
{
|
||||
#if defined(CONFIG_ESP_TLS_USING_MBEDTLS) && defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS)
|
||||
if (!cfg || cfg->ticket_ctx) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
cfg->ticket_ctx = calloc(1, sizeof(esp_tls_session_ticket_ctx_t));
|
||||
if (!cfg->ticket_ctx) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
return _esp_tls_session_ticket_ctx_init(cfg->ticket_ctx);
|
||||
#else
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_tls_cfg_server_session_tickets_free(esp_tls_cfg_server_t *cfg)
|
||||
{
|
||||
#if defined(CONFIG_ESP_TLS_USING_MBEDTLS) && defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS)
|
||||
if (cfg && cfg->ticket_ctx) {
|
||||
_esp_tls_session_ticket_ctx_free(cfg->ticket_ctx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a server side TLS/SSL connection
|
||||
*/
|
||||
|
@@ -20,6 +20,9 @@
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/certs.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"
|
||||
@@ -171,6 +174,20 @@ typedef struct esp_tls_cfg {
|
||||
} esp_tls_cfg_t;
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
#if defined(CONFIG_ESP_TLS_USING_MBEDTLS) && defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS)
|
||||
/**
|
||||
* @brief Data structures necessary to support TLS session tickets according to RFC5077
|
||||
*/
|
||||
typedef struct esp_tls_session_ticket_ctx {
|
||||
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_ticket_context ticket_ctx; /*!< Session ticket generation context */
|
||||
} esp_tls_session_ticket_ctx_t;
|
||||
#endif
|
||||
|
||||
typedef struct esp_tls_cfg_server {
|
||||
const char **alpn_protos; /*!< Application protocols required for HTTP2.
|
||||
If HTTP2/ALPN support is required, a list
|
||||
@@ -222,7 +239,37 @@ typedef struct esp_tls_cfg_server {
|
||||
unsigned int serverkey_password_len; /*!< String length of the password pointed to by
|
||||
serverkey_password */
|
||||
|
||||
#if defined(CONFIG_ESP_TLS_USING_MBEDTLS) && defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS)
|
||||
esp_tls_session_ticket_ctx_t * ticket_ctx; /*!< Session ticket generation context.
|
||||
You have to call esp_tls_cfg_server_session_tickets_init
|
||||
to use it.
|
||||
Call esp_tls_cfg_server_session_tickets_free
|
||||
to free the data associated with this context. */
|
||||
#endif
|
||||
} esp_tls_cfg_server_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the server side TLS session ticket context
|
||||
*
|
||||
* This function initializes the server side tls session ticket context
|
||||
* which holds all necessary data structures to enable tls session tickets
|
||||
* according to RFC5077.
|
||||
* Use esp_tls_cfg_server_session_tickets_free to free the data.
|
||||
*
|
||||
* @param[in] cfg server configuration as esp_tls_cfg_server_t
|
||||
* @return
|
||||
* ESP_OK if setup succeeded
|
||||
* ESP_ERR_INVALID_ARG if context is already initialized
|
||||
* ESP_ERR_NO_MEM if memory allocation failed
|
||||
* ESP_ERR_NOT_SUPPORTED if session tickets are not available due to build configuration
|
||||
* ESP_FAIL if setup failed
|
||||
*/
|
||||
esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Free the server side TLS session ticket context
|
||||
*/
|
||||
void esp_tls_cfg_server_session_tickets_free(esp_tls_cfg_server_t *cfg);
|
||||
#endif /* ! CONFIG_ESP_TLS_SERVER */
|
||||
|
||||
/**
|
||||
|
@@ -31,18 +31,19 @@ extern "C" {
|
||||
#define ESP_ERR_MBEDTLS_PK_PARSE_KEY_FAILED (ESP_ERR_ESP_TLS_BASE + 0x0F) /*!< mbedtls api returned failed */
|
||||
#define ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x10) /*!< mbedtls api returned failed */
|
||||
#define ESP_ERR_MBEDTLS_SSL_CONF_PSK_FAILED (ESP_ERR_ESP_TLS_BASE + 0x11) /*!< mbedtls api returned failed */
|
||||
#define ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT (ESP_ERR_ESP_TLS_BASE + 0x12) /*!< new connection in esp_tls_low_level_conn connection timeouted */
|
||||
#define ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED (ESP_ERR_ESP_TLS_BASE + 0x13) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED (ESP_ERR_ESP_TLS_BASE + 0x14) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x15) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_KEY_VERIFY_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x16) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_SSL_HANDSHAKE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x17) /*!< wolfSSL api returned failed */
|
||||
#define ESP_ERR_WOLFSSL_CTX_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x18) /*!< wolfSSL api returned failed */
|
||||
#define ESP_ERR_WOLFSSL_SSL_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x19) /*!< wolfSSL api returned failed */
|
||||
#define ESP_ERR_WOLFSSL_SSL_WRITE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1A) /*!< wolfSSL api returned failed */
|
||||
#define ESP_ERR_MBEDTLS_SSL_SESSION_TICKET_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x12) /*!< mbedtls api returned failed */
|
||||
#define ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT (ESP_ERR_ESP_TLS_BASE + 0x13) /*!< new connection in esp_tls_low_level_conn connection timeouted */
|
||||
#define ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED (ESP_ERR_ESP_TLS_BASE + 0x14) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED (ESP_ERR_ESP_TLS_BASE + 0x15) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x16) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_KEY_VERIFY_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x17) /*!< wolfSSL api returned error */
|
||||
#define ESP_ERR_WOLFSSL_SSL_HANDSHAKE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x18) /*!< wolfSSL api returned failed */
|
||||
#define ESP_ERR_WOLFSSL_CTX_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x19) /*!< wolfSSL api returned failed */
|
||||
#define ESP_ERR_WOLFSSL_SSL_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1A) /*!< wolfSSL api returned failed */
|
||||
#define ESP_ERR_WOLFSSL_SSL_WRITE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1B) /*!< wolfSSL api returned failed */
|
||||
|
||||
#define ESP_ERR_ESP_TLS_SE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1B) /*< esp-tls use Secure Element returned failed */
|
||||
#define ESP_ERR_ESP_TLS_TCP_CLOSED_FIN (ESP_ERR_ESP_TLS_BASE + 0x1C) /*< esp-tls's TPC transport connection has benn closed (in a clean way) */
|
||||
#define ESP_ERR_ESP_TLS_SE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1C) /*< esp-tls use Secure Element returned failed */
|
||||
#define ESP_ERR_ESP_TLS_TCP_CLOSED_FIN (ESP_ERR_ESP_TLS_BASE + 0x1D) /*< esp-tls's TPC transport connection has benn closed (in a clean way) */
|
||||
|
||||
/**
|
||||
* Definition of errors reported from IO API (potentially non-blocking) in case of error:
|
||||
|
@@ -368,8 +368,70 @@ static esp_err_t set_global_ca_store(esp_tls_t *tls)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
#ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS
|
||||
int esp_mbedtls_session_ticket_write(void *p_ticket, const mbedtls_ssl_session *session, unsigned char *start, const unsigned char *end, size_t *tlen, uint32_t *lifetime)
|
||||
{
|
||||
int ret = mbedtls_ssl_ticket_write(p_ticket, session, start, end, tlen, lifetime);
|
||||
#ifndef NDEBUG
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Writing session ticket resulted in error code -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int esp_mbedtls_session_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, unsigned char *buf, size_t len)
|
||||
{
|
||||
int ret = mbedtls_ssl_ticket_parse(p_ticket, session, buf, len);
|
||||
#ifndef NDEBUG
|
||||
if (ret != 0) {
|
||||
ESP_LOGD(TAG, "Parsing session ticket resulted in error code -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_mbedtls_session_ticket_ctx_init(esp_tls_session_ticket_ctx_t *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mbedtls_ctr_drbg_init(&ctx->ctr_drbg);
|
||||
mbedtls_entropy_init(&ctx->entropy);
|
||||
mbedtls_ssl_ticket_init(&ctx->ticket_ctx);
|
||||
int ret;
|
||||
if ((ret = mbedtls_ctr_drbg_seed(&ctx->ctr_drbg,
|
||||
mbedtls_entropy_func, &ctx->entropy, NULL, 0)) != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
return ESP_ERR_MBEDTLS_CTR_DRBG_SEED_FAILED;
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_ssl_ticket_setup( &ctx->ticket_ctx,
|
||||
mbedtls_ctr_drbg_random, &ctx->ctr_drbg,
|
||||
MBEDTLS_CIPHER_AES_256_GCM,
|
||||
CONFIG_ESP_TLS_SERVER_SESSION_TICKET_TIMEOUT ) ) != 0 )
|
||||
{
|
||||
ESP_LOGE(TAG, "mbedtls_ssl_ticket_setup returned -0x%04X", -ret);
|
||||
mbedtls_print_error_msg(ret);
|
||||
return ESP_ERR_MBEDTLS_SSL_SESSION_TICKET_SETUP_FAILED;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_mbedtls_session_ticket_ctx_free(esp_tls_session_ticket_ctx_t *ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
mbedtls_ssl_ticket_free(&ctx->ticket_ctx);
|
||||
mbedtls_ctr_drbg_init(&ctx->ctr_drbg);
|
||||
mbedtls_entropy_free(&ctx->entropy);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
@@ -421,6 +483,18 @@ esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
|
||||
ESP_LOGE(TAG, "Missing server certificate and/or key");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS
|
||||
if (cfg->ticket_ctx) {
|
||||
ESP_LOGD(TAG, "Enabling server-side tls session ticket support");
|
||||
|
||||
mbedtls_ssl_conf_session_tickets_cb( &tls->conf,
|
||||
esp_mbedtls_session_ticket_write,
|
||||
esp_mbedtls_session_ticket_parse,
|
||||
&cfg->ticket_ctx->ticket_ctx );
|
||||
}
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif /* ! CONFIG_ESP_TLS_SERVER */
|
||||
|
@@ -76,6 +76,22 @@ int esp_mbedtls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp
|
||||
* /note :- The function can only be used with mbedtls ssl library
|
||||
*/
|
||||
void esp_mbedtls_server_session_delete(esp_tls_t *tls);
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS
|
||||
/**
|
||||
* Internal function to setup server side session ticket context
|
||||
*
|
||||
* /note :- The function can only be used with mbedtls ssl library
|
||||
*/
|
||||
esp_err_t esp_mbedtls_session_ticket_ctx_init(esp_tls_session_ticket_ctx_t *cfg);
|
||||
|
||||
/**
|
||||
* Internal function to free server side session ticket context
|
||||
*
|
||||
* /note :- The function can only be used with mbedtls ssl library
|
||||
*/
|
||||
void esp_mbedtls_session_ticket_ctx_free(esp_tls_session_ticket_ctx_t *cfg);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@@ -63,6 +63,9 @@ struct httpd_ssl_config {
|
||||
|
||||
/** Port used when transport mode is insecure (default 80) */
|
||||
uint16_t port_insecure;
|
||||
|
||||
/** Enable tls session tickets */
|
||||
bool session_tickets;
|
||||
};
|
||||
|
||||
typedef struct httpd_ssl_config httpd_ssl_config_t;
|
||||
@@ -109,6 +112,7 @@ typedef struct httpd_ssl_config httpd_ssl_config_t;
|
||||
.transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \
|
||||
.port_secure = 443, \
|
||||
.port_insecure = 80, \
|
||||
.session_tickets = false, \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -145,6 +145,7 @@ static void free_secure_context(void *ctx)
|
||||
if (cfg->serverkey_buf) {
|
||||
free((void *)cfg->serverkey_buf);
|
||||
}
|
||||
esp_tls_cfg_server_session_tickets_free(cfg);
|
||||
free(cfg);
|
||||
free(ssl_ctx);
|
||||
}
|
||||
@@ -160,6 +161,16 @@ static httpd_ssl_ctx_t *create_secure_context(const struct httpd_ssl_config *con
|
||||
free(ssl_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (config->session_tickets) {
|
||||
if ( esp_tls_cfg_server_session_tickets_init(cfg) != ESP_OK ) {
|
||||
ESP_LOGE(TAG, "Failed to init session ticket support");
|
||||
free(ssl_ctx);
|
||||
free(cfg);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ssl_ctx->tls_cfg = cfg;
|
||||
/* cacert = CA which signs client cert, or client cert itself , which is mapped to client_verify_cert_pem */
|
||||
if(config->client_verify_cert_pem != NULL) {
|
||||
|
Reference in New Issue
Block a user