diff --git a/components/esp_https_server/CMakeLists.txt b/components/esp_https_server/CMakeLists.txt index c63549b0e2..0eb83865b5 100644 --- a/components/esp_https_server/CMakeLists.txt +++ b/components/esp_https_server/CMakeLists.txt @@ -1,4 +1,10 @@ -idf_component_register(SRCS "src/https_server.c" - INCLUDE_DIRS "include" - REQUIRES esp_http_server openssl +if (CONFIG_ESP_HTTPS_SERVER_ENABLE) + set(src "src/https_server.c") + set(inc "include") +endif() + +idf_component_register(SRCS ${src} + INCLUDE_DIRS ${inc} + REQUIRES esp_http_server esp-tls PRIV_REQUIRES lwip) + diff --git a/components/esp_https_server/Kconfig b/components/esp_https_server/Kconfig new file mode 100644 index 0000000000..e4085539bb --- /dev/null +++ b/components/esp_https_server/Kconfig @@ -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 diff --git a/components/esp_https_server/component.mk b/components/esp_https_server/component.mk index be1bffc586..c90f6ee255 100644 --- a/components/esp_https_server/component.mk +++ b/components/esp_https_server/component.mk @@ -1,2 +1,6 @@ +ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE COMPONENT_SRCDIRS := src COMPONENT_ADD_INCLUDEDIRS := include +else +COMPONENT_CONFIG_ONLY := 1 +endif diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index 4a0d21792f..f012ffec8e 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -14,9 +14,9 @@ #include #include "esp_https_server.h" -#include "openssl/ssl.h" #include "esp_log.h" #include "sdkconfig.h" +#include "esp_tls.h" 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) { assert(ctx != NULL); - SSL_shutdown(ctx); - SSL_free(ctx); + esp_tls_server_session_delete(ctx); 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) { - SSL *ssl = httpd_sess_get_transport_ctx(server, sockfd); - assert(ssl != NULL); - return SSL_pending(ssl); + esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd); + assert(tls != NULL); + 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) { - SSL *ssl = httpd_sess_get_transport_ctx(server, sockfd); - assert(ssl != NULL); - return SSL_read(ssl, buf, buf_len); + esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd); + assert(tls != NULL); + 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) { - SSL *ssl = httpd_sess_get_transport_ctx(server, sockfd); - assert(ssl != NULL); - return SSL_write(ssl, buf, buf_len); + esp_tls_t *tls = httpd_sess_get_transport_ctx(server, sockfd); + assert(tls != NULL); + 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); // 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); - SSL *ssl = SSL_new(global_ctx); - if (NULL == ssl) { - ESP_LOGE(TAG, "SSL_new ret NULL (out of memory)"); + esp_tls_t *tls = (esp_tls_t *)calloc(1, sizeof(esp_tls_t)); + if (!tls) { return ESP_ERR_NO_MEM; } - - if (1 != SSL_set_fd(ssl, sockfd)) { - ESP_LOGE(TAG, "fail to set SSL fd"); - goto teardown; - } - - ESP_LOGD(TAG, "SSL accept"); - if (1 != SSL_accept(ssl)) { - ESP_LOGW(TAG, "fail to SSL_accept - handshake error"); - goto teardown; + ESP_LOGI(TAG, "performing session handshake"); + int ret = esp_tls_server_session_create(global_ctx, sockfd, tls); + if (ret != 0) { + ESP_LOGE(TAG, "esp_tls_create_server_session failed"); + goto fail; } // 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 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"); return ESP_OK; - -teardown: - SSL_free(ssl); +fail: + esp_tls_server_session_delete(tls); return ESP_FAIL; } @@ -141,38 +133,41 @@ teardown: static void free_secure_context(void *ctx) { assert(ctx != NULL); - + esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)ctx; 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); } -/** -* 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) +static esp_tls_cfg_server_t *create_secure_context(const struct httpd_ssl_config *config) { - SSL_CTX *ctx = NULL; - - ESP_LOGD(TAG, "SSL server context create"); - 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"); + esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)calloc(1, sizeof(esp_tls_cfg_server_t)); + if (!cfg) { + return NULL; } - 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 */ @@ -184,15 +179,16 @@ esp_err_t httpd_ssl_start(httpd_handle_t *pHandle, struct httpd_ssl_config *conf ESP_LOGI(TAG, "Starting server"); if (HTTPD_SSL_TRANSPORT_SECURE == config->transport_mode) { - SSL_CTX *ctx = create_secure_context(config); - if (!ctx) { - return ESP_FAIL; + + esp_tls_cfg_server_t *esp_tls_cfg = create_secure_context(config); + if (!esp_tls_cfg) { + return -1; } ESP_LOGD(TAG, "SSL context ready"); // 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.open_fn = httpd_ssl_open; // the open function configures the created SSL sessions