mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
esp_https_server: Add support for esp-tls server APIs
This commit is contained in:
@@ -1,4 +1,10 @@
|
|||||||
idf_component_register(SRCS "src/https_server.c"
|
if (CONFIG_ESP_HTTPS_SERVER_ENABLE)
|
||||||
INCLUDE_DIRS "include"
|
set(src "src/https_server.c")
|
||||||
REQUIRES esp_http_server openssl
|
set(inc "include")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_component_register(SRCS ${src}
|
||||||
|
INCLUDE_DIRS ${inc}
|
||||||
|
REQUIRES esp_http_server esp-tls
|
||||||
PRIV_REQUIRES lwip)
|
PRIV_REQUIRES lwip)
|
||||||
|
|
||||||
|
9
components/esp_https_server/Kconfig
Normal file
9
components/esp_https_server/Kconfig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
menu "ESP HTTPS server"
|
||||||
|
|
||||||
|
config ESP_HTTPS_SERVER_ENABLE
|
||||||
|
bool "Enable ESP_HTTPS_SERVER component"
|
||||||
|
select ESP_TLS_SERVER
|
||||||
|
help
|
||||||
|
Enable ESP HTTPS server component
|
||||||
|
|
||||||
|
endmenu
|
@@ -1,2 +1,6 @@
|
|||||||
|
ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE
|
||||||
COMPONENT_SRCDIRS := src
|
COMPONENT_SRCDIRS := src
|
||||||
COMPONENT_ADD_INCLUDEDIRS := include
|
COMPONENT_ADD_INCLUDEDIRS := include
|
||||||
|
else
|
||||||
|
COMPONENT_CONFIG_ONLY := 1
|
||||||
|
endif
|
||||||
|
@@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "esp_https_server.h"
|
#include "esp_https_server.h"
|
||||||
#include "openssl/ssl.h"
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_tls.h"
|
||||||
|
|
||||||
const static char *TAG = "esp_https_server";
|
const static char *TAG = "esp_https_server";
|
||||||
|
|
||||||
@@ -28,8 +28,7 @@ const static char *TAG = "esp_https_server";
|
|||||||
static void httpd_ssl_close(void *ctx)
|
static void httpd_ssl_close(void *ctx)
|
||||||
{
|
{
|
||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
SSL_shutdown(ctx);
|
esp_tls_server_session_delete(ctx);
|
||||||
SSL_free(ctx);
|
|
||||||
ESP_LOGD(TAG, "Secure socket closed");
|
ESP_LOGD(TAG, "Secure socket closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,9 +41,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)
|
||||||
{
|
{
|
||||||
SSL *ssl = httpd_sess_get_transport_ctx(server, sockfd);
|
esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd);
|
||||||
assert(ssl != NULL);
|
assert(tls != NULL);
|
||||||
return SSL_pending(ssl);
|
return esp_tls_get_bytes_avail(tls);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,9 +58,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)
|
||||||
{
|
{
|
||||||
SSL *ssl = httpd_sess_get_transport_ctx(server, sockfd);
|
esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd);
|
||||||
assert(ssl != NULL);
|
assert(tls != NULL);
|
||||||
return SSL_read(ssl, buf, buf_len);
|
return esp_tls_conn_read(tls, buf, buf_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,9 +75,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)
|
||||||
{
|
{
|
||||||
SSL *ssl = httpd_sess_get_transport_ctx(server, sockfd);
|
esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd);
|
||||||
assert(ssl != NULL);
|
assert(tls != NULL);
|
||||||
return SSL_write(ssl, buf, buf_len);
|
return esp_tls_conn_write(tls, buf, buf_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,28 +93,22 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|||||||
assert(server != NULL);
|
assert(server != NULL);
|
||||||
|
|
||||||
// Retrieve the SSL context from the global context field (set in config)
|
// Retrieve the SSL context from the global context field (set in config)
|
||||||
SSL_CTX *global_ctx = httpd_get_global_transport_ctx(server);
|
esp_tls_cfg_server_t *global_ctx = httpd_get_global_transport_ctx(server);
|
||||||
assert(global_ctx != NULL);
|
assert(global_ctx != NULL);
|
||||||
|
|
||||||
SSL *ssl = SSL_new(global_ctx);
|
esp_tls_t *tls = (esp_tls_t *)calloc(1, sizeof(esp_tls_t));
|
||||||
if (NULL == ssl) {
|
if (!tls) {
|
||||||
ESP_LOGE(TAG, "SSL_new ret NULL (out of memory)");
|
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
ESP_LOGI(TAG, "performing session handshake");
|
||||||
if (1 != SSL_set_fd(ssl, sockfd)) {
|
int ret = esp_tls_server_session_create(global_ctx, sockfd, tls);
|
||||||
ESP_LOGE(TAG, "fail to set SSL fd");
|
if (ret != 0) {
|
||||||
goto teardown;
|
ESP_LOGE(TAG, "esp_tls_create_server_session failed");
|
||||||
}
|
goto fail;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "SSL accept");
|
|
||||||
if (1 != SSL_accept(ssl)) {
|
|
||||||
ESP_LOGW(TAG, "fail to SSL_accept - handshake error");
|
|
||||||
goto teardown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, ssl, httpd_ssl_close);
|
httpd_sess_set_transport_ctx(server, sockfd, tls, 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);
|
||||||
@@ -127,9 +120,8 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|||||||
ESP_LOGD(TAG, "Secure socket open");
|
ESP_LOGD(TAG, "Secure socket open");
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
fail:
|
||||||
teardown:
|
esp_tls_server_session_delete(tls);
|
||||||
SSL_free(ssl);
|
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,38 +133,41 @@ teardown:
|
|||||||
static void free_secure_context(void *ctx)
|
static void free_secure_context(void *ctx)
|
||||||
{
|
{
|
||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
|
esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)ctx;
|
||||||
ESP_LOGI(TAG, "Server shuts down, releasing SSL context");
|
ESP_LOGI(TAG, "Server shuts down, releasing SSL context");
|
||||||
SSL_CTX_free(ctx);
|
if (cfg->servercert_pem_buf) {
|
||||||
|
free((void *)cfg->servercert_pem_buf);
|
||||||
|
}
|
||||||
|
if (cfg->serverkey_pem_buf) {
|
||||||
|
free((void *)cfg->serverkey_pem_buf);
|
||||||
|
}
|
||||||
|
free(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static esp_tls_cfg_server_t *create_secure_context(const struct httpd_ssl_config *config)
|
||||||
* Create and perform basic init of a SSL_CTX, or return NULL on failure
|
|
||||||
*
|
|
||||||
* @return ctx or null
|
|
||||||
*/
|
|
||||||
static SSL_CTX *create_secure_context(const struct httpd_ssl_config *config)
|
|
||||||
{
|
{
|
||||||
SSL_CTX *ctx = NULL;
|
esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)calloc(1, sizeof(esp_tls_cfg_server_t));
|
||||||
|
if (!cfg) {
|
||||||
ESP_LOGD(TAG, "SSL server context create");
|
return NULL;
|
||||||
ctx = SSL_CTX_new(TLS_server_method());
|
|
||||||
if (NULL != ctx) {
|
|
||||||
//region SSL ctx alloc'd
|
|
||||||
ESP_LOGD(TAG, "SSL ctx set own cert");
|
|
||||||
if (SSL_CTX_use_certificate_ASN1(ctx, config->cacert_len, config->cacert_pem)
|
|
||||||
&& SSL_CTX_use_PrivateKey_ASN1(0, ctx, config->prvtkey_pem, (long) config->prvtkey_len)) {
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ESP_LOGE(TAG, "Failed to set certificate");
|
|
||||||
SSL_CTX_free(ctx);
|
|
||||||
ctx = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ESP_LOGE(TAG, "Failed to create SSL context");
|
|
||||||
}
|
}
|
||||||
return NULL;
|
cfg->servercert_pem_buf = (unsigned char *)malloc(config->cacert_len);
|
||||||
|
if (!cfg->servercert_pem_buf) {
|
||||||
|
free(cfg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy((char *)cfg->servercert_pem_buf, config->cacert_pem, config->cacert_len);
|
||||||
|
cfg->servercert_pem_bytes = config->cacert_len;
|
||||||
|
|
||||||
|
cfg->serverkey_pem_buf = (unsigned char *)malloc(config->prvtkey_len);
|
||||||
|
if (!cfg->serverkey_pem_buf) {
|
||||||
|
free((void *)cfg->servercert_pem_buf);
|
||||||
|
free(cfg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy((char *)cfg->serverkey_pem_buf, config->prvtkey_pem, config->prvtkey_len);
|
||||||
|
cfg->serverkey_pem_bytes = config->prvtkey_len;
|
||||||
|
|
||||||
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Start the server */
|
/** Start the server */
|
||||||
@@ -184,15 +179,16 @@ esp_err_t httpd_ssl_start(httpd_handle_t *pHandle, struct httpd_ssl_config *conf
|
|||||||
ESP_LOGI(TAG, "Starting server");
|
ESP_LOGI(TAG, "Starting server");
|
||||||
|
|
||||||
if (HTTPD_SSL_TRANSPORT_SECURE == config->transport_mode) {
|
if (HTTPD_SSL_TRANSPORT_SECURE == config->transport_mode) {
|
||||||
SSL_CTX *ctx = create_secure_context(config);
|
|
||||||
if (!ctx) {
|
esp_tls_cfg_server_t *esp_tls_cfg = create_secure_context(config);
|
||||||
return ESP_FAIL;
|
if (!esp_tls_cfg) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG, "SSL context ready");
|
ESP_LOGD(TAG, "SSL context ready");
|
||||||
|
|
||||||
// set SSL specific config
|
// set SSL specific config
|
||||||
config->httpd.global_transport_ctx = ctx;
|
config->httpd.global_transport_ctx = esp_tls_cfg;
|
||||||
config->httpd.global_transport_ctx_free_fn = free_secure_context;
|
config->httpd.global_transport_ctx_free_fn = free_secure_context;
|
||||||
config->httpd.open_fn = httpd_ssl_open; // the open function configures the created SSL sessions
|
config->httpd.open_fn = httpd_ssl_open; // the open function configures the created SSL sessions
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user