|
|
@@ -20,6 +20,11 @@
|
|
|
|
|
|
const static char *TAG = "esp_https_server";
|
|
|
|
|
|
+typedef struct httpd_ssl_ctx {
|
|
|
+ esp_tls_cfg_server_t *tls_cfg;
|
|
|
+ httpd_open_func_t open_fn;
|
|
|
+} httpd_ssl_ctx_t;
|
|
|
+
|
|
|
/**
|
|
|
* SSL socket close handler
|
|
|
*
|
|
|
@@ -93,7 +98,7 @@ 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)
|
|
|
- esp_tls_cfg_server_t *global_ctx = httpd_get_global_transport_ctx(server);
|
|
|
+ httpd_ssl_ctx_t *global_ctx = httpd_get_global_transport_ctx(server);
|
|
|
assert(global_ctx != NULL);
|
|
|
|
|
|
esp_tls_t *tls = (esp_tls_t *)calloc(1, sizeof(esp_tls_t));
|
|
|
@@ -101,7 +106,7 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|
|
return ESP_ERR_NO_MEM;
|
|
|
}
|
|
|
ESP_LOGI(TAG, "performing session handshake");
|
|
|
- int ret = esp_tls_server_session_create(global_ctx, sockfd, tls);
|
|
|
+ int ret = esp_tls_server_session_create(global_ctx->tls_cfg, sockfd, tls);
|
|
|
if (ret != 0) {
|
|
|
ESP_LOGE(TAG, "esp_tls_create_server_session failed");
|
|
|
goto fail;
|
|
|
@@ -119,6 +124,9 @@ static esp_err_t httpd_ssl_open(httpd_handle_t server, int sockfd)
|
|
|
|
|
|
ESP_LOGD(TAG, "Secure socket open");
|
|
|
|
|
|
+ if (global_ctx->open_fn) {
|
|
|
+ (global_ctx->open_fn)(server, sockfd);
|
|
|
+ }
|
|
|
return ESP_OK;
|
|
|
fail:
|
|
|
esp_tls_server_session_delete(tls);
|
|
|
@@ -133,7 +141,8 @@ fail:
|
|
|
static void free_secure_context(void *ctx)
|
|
|
{
|
|
|
assert(ctx != NULL);
|
|
|
- esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)ctx;
|
|
|
+ httpd_ssl_ctx_t *ssl_ctx = ctx;
|
|
|
+ esp_tls_cfg_server_t *cfg = ssl_ctx->tls_cfg;
|
|
|
ESP_LOGI(TAG, "Server shuts down, releasing SSL context");
|
|
|
if (cfg->cacert_buf) {
|
|
|
free((void *)cfg->cacert_buf);
|
|
|
@@ -145,14 +154,21 @@ static void free_secure_context(void *ctx)
|
|
|
free((void *)cfg->serverkey_buf);
|
|
|
}
|
|
|
free(cfg);
|
|
|
+ free(ssl_ctx);
|
|
|
}
|
|
|
|
|
|
-static esp_tls_cfg_server_t *create_secure_context(const struct httpd_ssl_config *config)
|
|
|
+static httpd_ssl_ctx_t *create_secure_context(const struct httpd_ssl_config *config)
|
|
|
{
|
|
|
+ httpd_ssl_ctx_t *ssl_ctx = calloc(1, sizeof(httpd_ssl_ctx_t));
|
|
|
+ if (!ssl_ctx) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
esp_tls_cfg_server_t *cfg = (esp_tls_cfg_server_t *)calloc(1, sizeof(esp_tls_cfg_server_t));
|
|
|
if (!cfg) {
|
|
|
+ free(ssl_ctx);
|
|
|
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) {
|
|
|
cfg->cacert_buf = (unsigned char *)malloc(config->client_verify_cert_len);
|
|
|
@@ -186,7 +202,7 @@ static esp_tls_cfg_server_t *create_secure_context(const struct httpd_ssl_config
|
|
|
memcpy((char *)cfg->serverkey_buf, config->prvtkey_pem, config->prvtkey_len);
|
|
|
cfg->serverkey_bytes = config->prvtkey_len;
|
|
|
|
|
|
- return cfg;
|
|
|
+ return ssl_ctx;
|
|
|
}
|
|
|
|
|
|
/** Start the server */
|
|
|
@@ -199,16 +215,21 @@ esp_err_t httpd_ssl_start(httpd_handle_t *pHandle, struct httpd_ssl_config *conf
|
|
|
|
|
|
if (HTTPD_SSL_TRANSPORT_SECURE == config->transport_mode) {
|
|
|
|
|
|
- esp_tls_cfg_server_t *esp_tls_cfg = create_secure_context(config);
|
|
|
- if (!esp_tls_cfg) {
|
|
|
+ httpd_ssl_ctx_t *ssl_ctx = create_secure_context(config);
|
|
|
+ if (!ssl_ctx) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
ESP_LOGD(TAG, "SSL context ready");
|
|
|
|
|
|
// set SSL specific config
|
|
|
- config->httpd.global_transport_ctx = esp_tls_cfg;
|
|
|
+ config->httpd.global_transport_ctx = ssl_ctx;
|
|
|
config->httpd.global_transport_ctx_free_fn = free_secure_context;
|
|
|
+ if (config->httpd.open_fn) {
|
|
|
+ // since the httpd's open_fn is used for opening the SSL session, we save the configured
|
|
|
+ // user pointer and call it upon opening the ssl socket
|
|
|
+ ssl_ctx->open_fn = config->httpd.open_fn;
|
|
|
+ }
|
|
|
config->httpd.open_fn = httpd_ssl_open; // the open function configures the created SSL sessions
|
|
|
|
|
|
config->httpd.server_port = config->port_secure;
|