mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
https_server: Add provision for callback at session close
Closes https://github.com/espressif/esp-idf/issues/8288
This commit is contained in:
parent
f8dad892ff
commit
1d71fbae92
@ -21,10 +21,21 @@ typedef enum {
|
|||||||
HTTPD_SSL_TRANSPORT_INSECURE // SSL disabled
|
HTTPD_SSL_TRANSPORT_INSECURE // SSL disabled
|
||||||
} httpd_ssl_transport_mode_t;
|
} httpd_ssl_transport_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicates the state at which the user callback is executed,
|
||||||
|
* i.e at session creation or session close
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
HTTPD_SSL_USER_CB_SESS_CREATE,
|
||||||
|
HTTPD_SSL_USER_CB_SESS_CLOSE
|
||||||
|
} httpd_ssl_user_cb_state_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback data struct, contains the ESP-TLS connection handle
|
* @brief Callback data struct, contains the ESP-TLS connection handle
|
||||||
|
* and the connection state at which the callback is executed
|
||||||
*/
|
*/
|
||||||
typedef struct esp_https_server_user_cb_arg {
|
typedef struct esp_https_server_user_cb_arg {
|
||||||
|
httpd_ssl_user_cb_state_t user_cb_state;
|
||||||
const esp_tls_t *tls;
|
const esp_tls_t *tls;
|
||||||
} esp_https_server_user_cb_arg_t;
|
} esp_https_server_user_cb_arg_t;
|
||||||
|
|
||||||
|
@ -18,6 +18,11 @@ typedef struct httpd_ssl_ctx {
|
|||||||
esp_https_server_user_cb *user_cb;
|
esp_https_server_user_cb *user_cb;
|
||||||
} httpd_ssl_ctx_t;
|
} httpd_ssl_ctx_t;
|
||||||
|
|
||||||
|
typedef struct httpd_ssl_transport_ctx {
|
||||||
|
esp_tls_t *tls;
|
||||||
|
httpd_ssl_ctx_t *global_ctx;
|
||||||
|
} httpd_ssl_transport_ctx_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SSL socket close handler
|
* SSL socket close handler
|
||||||
*
|
*
|
||||||
@ -26,7 +31,20 @@ typedef struct httpd_ssl_ctx {
|
|||||||
static void httpd_ssl_close(void *ctx)
|
static void httpd_ssl_close(void *ctx)
|
||||||
{
|
{
|
||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
esp_tls_server_session_delete(ctx);
|
|
||||||
|
httpd_ssl_transport_ctx_t *transport_ctx = (httpd_ssl_transport_ctx_t *)ctx;
|
||||||
|
httpd_ssl_ctx_t *global_ctx = transport_ctx->global_ctx;
|
||||||
|
esp_tls_t *tls = transport_ctx->tls;
|
||||||
|
|
||||||
|
if (global_ctx->user_cb) {
|
||||||
|
esp_https_server_user_cb_arg_t user_cb_data = {0};
|
||||||
|
user_cb_data.user_cb_state = HTTPD_SSL_USER_CB_SESS_CLOSE;
|
||||||
|
user_cb_data.tls = tls;
|
||||||
|
(global_ctx->user_cb)((void *)&user_cb_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_tls_server_session_delete(tls);
|
||||||
|
free(ctx);
|
||||||
ESP_LOGD(TAG, "Secure socket closed");
|
ESP_LOGD(TAG, "Secure socket closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +57,9 @@ static void httpd_ssl_close(void *ctx)
|
|||||||
*/
|
*/
|
||||||
static int httpd_ssl_pending(httpd_handle_t server, int sockfd)
|
static int httpd_ssl_pending(httpd_handle_t server, int sockfd)
|
||||||
{
|
{
|
||||||
esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd);
|
httpd_ssl_transport_ctx_t *transport_ctx = httpd_sess_get_transport_ctx(server, sockfd);
|
||||||
|
assert(transport_ctx != NULL);
|
||||||
|
esp_tls_t *tls = transport_ctx->tls;
|
||||||
assert(tls != NULL);
|
assert(tls != NULL);
|
||||||
return esp_tls_get_bytes_avail(tls);
|
return esp_tls_get_bytes_avail(tls);
|
||||||
}
|
}
|
||||||
@ -56,7 +76,9 @@ static int httpd_ssl_pending(httpd_handle_t server, int sockfd)
|
|||||||
*/
|
*/
|
||||||
static int httpd_ssl_recv(httpd_handle_t server, int sockfd, char *buf, size_t buf_len, int flags)
|
static int httpd_ssl_recv(httpd_handle_t server, int sockfd, char *buf, size_t buf_len, int flags)
|
||||||
{
|
{
|
||||||
esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd);
|
httpd_ssl_transport_ctx_t *transport_ctx = httpd_sess_get_transport_ctx(server, sockfd);
|
||||||
|
assert(transport_ctx != NULL);
|
||||||
|
esp_tls_t *tls = transport_ctx->tls;
|
||||||
assert(tls != NULL);
|
assert(tls != NULL);
|
||||||
return esp_tls_conn_read(tls, buf, buf_len);
|
return esp_tls_conn_read(tls, buf, buf_len);
|
||||||
}
|
}
|
||||||
@ -73,7 +95,9 @@ static int httpd_ssl_recv(httpd_handle_t server, int sockfd, char *buf, size_t b
|
|||||||
*/
|
*/
|
||||||
static int httpd_ssl_send(httpd_handle_t server, int sockfd, const char *buf, size_t buf_len, int flags)
|
static int httpd_ssl_send(httpd_handle_t server, int sockfd, const char *buf, size_t buf_len, int flags)
|
||||||
{
|
{
|
||||||
esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd);
|
httpd_ssl_transport_ctx_t *transport_ctx = httpd_sess_get_transport_ctx(server, sockfd);
|
||||||
|
assert(transport_ctx != NULL);
|
||||||
|
esp_tls_t *tls = transport_ctx->tls;
|
||||||
assert(tls != NULL);
|
assert(tls != NULL);
|
||||||
return esp_tls_conn_write(tls, buf, buf_len);
|
return esp_tls_conn_write(tls, buf, buf_len);
|
||||||
}
|
}
|
||||||
@ -105,8 +129,18 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass a new structure containing the global context and the tls pointer to httpd_ssl_close
|
||||||
|
// Store it in the context field of the HTTPD session object
|
||||||
|
// NOTE: allocated memory will be freed by httpd_ssl_close
|
||||||
|
httpd_ssl_transport_ctx_t *transport_ctx = (httpd_ssl_transport_ctx_t *)calloc(1, sizeof(httpd_ssl_transport_ctx_t));
|
||||||
|
if (!transport_ctx) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
transport_ctx->tls = tls;
|
||||||
|
transport_ctx->global_ctx = global_ctx;
|
||||||
|
|
||||||
// Store the SSL session into the context field of the HTTPD session object
|
// Store the SSL session into the context field of the HTTPD session object
|
||||||
httpd_sess_set_transport_ctx(server, sockfd, tls, httpd_ssl_close);
|
httpd_sess_set_transport_ctx(server, sockfd, transport_ctx, httpd_ssl_close);
|
||||||
|
|
||||||
// Set rx/tx/pending override functions
|
// Set rx/tx/pending override functions
|
||||||
httpd_sess_set_send_override(server, sockfd, httpd_ssl_send);
|
httpd_sess_set_send_override(server, sockfd, httpd_ssl_send);
|
||||||
@ -114,7 +148,6 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|||||||
httpd_sess_set_pending_override(server, sockfd, httpd_ssl_pending);
|
httpd_sess_set_pending_override(server, sockfd, httpd_ssl_pending);
|
||||||
|
|
||||||
// all access should now go through SSL
|
// all access should now go through SSL
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Secure socket open");
|
ESP_LOGD(TAG, "Secure socket open");
|
||||||
|
|
||||||
if (global_ctx->open_fn) {
|
if (global_ctx->open_fn) {
|
||||||
@ -123,6 +156,7 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|||||||
|
|
||||||
if (global_ctx->user_cb) {
|
if (global_ctx->user_cb) {
|
||||||
esp_https_server_user_cb_arg_t user_cb_data = {0};
|
esp_https_server_user_cb_arg_t user_cb_data = {0};
|
||||||
|
user_cb_data.user_cb_state = HTTPD_SSL_USER_CB_SESS_CREATE;
|
||||||
user_cb_data.tls = tls;
|
user_cb_data.tls = tls;
|
||||||
(global_ctx->user_cb)((void *)&user_cb_data);
|
(global_ctx->user_cb)((void *)&user_cb_data);
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,32 @@ static esp_err_t root_get_handler(httpd_req_t *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
|
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
|
||||||
|
|
||||||
|
void print_peer_cert_info(const mbedtls_ssl_context *ssl)
|
||||||
|
{
|
||||||
|
const mbedtls_x509_crt *cert;
|
||||||
|
const size_t buf_size = 1024;
|
||||||
|
char *buf = calloc(buf_size, sizeof(char));
|
||||||
|
if (buf == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Out of memory - Callback execution failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logging the peer certificate info
|
||||||
|
cert = mbedtls_ssl_get_peer_cert(ssl);
|
||||||
|
if (cert != NULL) {
|
||||||
|
mbedtls_x509_crt_info((char *) buf, buf_size - 1, " ", cert);
|
||||||
|
ESP_LOGI(TAG, "Peer certificate info:\n%s", buf);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Could not obtain the peer certificate!");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example callback function to get the certificate of connected clients,
|
* Example callback function to get the certificate of connected clients,
|
||||||
* whenever a new SSL connection is created
|
* whenever a new SSL connection is created and closed
|
||||||
*
|
*
|
||||||
* Can also be used to other information like Socket FD, Connection state, etc.
|
* Can also be used to other information like Socket FD, Connection state, etc.
|
||||||
*
|
*
|
||||||
@ -51,30 +74,28 @@ static esp_err_t root_get_handler(httpd_req_t *req)
|
|||||||
*/
|
*/
|
||||||
void https_server_user_callback(esp_https_server_user_cb_arg_t *user_cb)
|
void https_server_user_callback(esp_https_server_user_cb_arg_t *user_cb)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Session Created!");
|
ESP_LOGI(TAG, "User callback invoked!");
|
||||||
|
|
||||||
|
switch(user_cb->user_cb_state) {
|
||||||
|
case HTTPD_SSL_USER_CB_SESS_CREATE:
|
||||||
|
ESP_LOGD(TAG, "At session creation");
|
||||||
|
|
||||||
|
// Logging the socket FD
|
||||||
ESP_LOGI(TAG, "Socket FD: %d", user_cb->tls->sockfd);
|
ESP_LOGI(TAG, "Socket FD: %d", user_cb->tls->sockfd);
|
||||||
|
|
||||||
const mbedtls_x509_crt *cert;
|
// Logging the current ciphersuite
|
||||||
const size_t buf_size = 1024;
|
ESP_LOGI(TAG, "Current Ciphersuite: %s", mbedtls_ssl_get_ciphersuite(&user_cb->tls->ssl));
|
||||||
char *buf = calloc(buf_size, sizeof(char));
|
break;
|
||||||
if (buf == NULL) {
|
case HTTPD_SSL_USER_CB_SESS_CLOSE:
|
||||||
ESP_LOGE(TAG, "Out of memory - Callback execution failed!");
|
ESP_LOGD(TAG, "At session close");
|
||||||
|
|
||||||
|
// Logging the peer certificate
|
||||||
|
print_peer_cert_info(&user_cb->tls->ssl);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGE(TAG, "Illegal state!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_x509_crt_info((char *) buf, buf_size - 1, " ", &user_cb->tls->servercert);
|
|
||||||
ESP_LOGI(TAG, "Server certificate info:\n%s", buf);
|
|
||||||
memset(buf, 0x00, buf_size);
|
|
||||||
|
|
||||||
cert = mbedtls_ssl_get_peer_cert(&user_cb->tls->ssl);
|
|
||||||
if (cert != NULL) {
|
|
||||||
mbedtls_x509_crt_info((char *) buf, buf_size - 1, " ", cert);
|
|
||||||
ESP_LOGI(TAG, "Peer certificate info:\n%s", buf);
|
|
||||||
} else {
|
|
||||||
ESP_LOGW(TAG, "Could not obtain the peer certificate!");
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buf);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user