#include <string.h>
#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";
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");
}
*/
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);
}
/**
*/
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);
}
/**
*/
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);
}
/**
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);
ESP_LOGD(TAG, "Secure socket open");
return ESP_OK;
-
-teardown:
- SSL_free(ssl);
+fail:
+ esp_tls_server_session_delete(tls);
return ESP_FAIL;
}
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;
+ }
+ cfg->servercert_pem_buf = (unsigned char *)malloc(config->cacert_len);
+ if (!cfg->servercert_pem_buf) {
+ free(cfg);
+ return NULL;
}
- 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 */
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