2018-10-31 18:17:00 -04:00
|
|
|
/* Simple HTTP + SSL Server Example
|
|
|
|
|
|
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <esp_wifi.h>
|
2019-07-05 04:58:04 -04:00
|
|
|
#include <esp_event.h>
|
2018-10-31 18:17:00 -04:00
|
|
|
#include <esp_log.h>
|
|
|
|
#include <esp_system.h>
|
|
|
|
#include <nvs_flash.h>
|
|
|
|
#include <sys/param.h>
|
2019-08-31 10:19:21 -04:00
|
|
|
#include "esp_netif.h"
|
2018-11-20 11:42:37 -05:00
|
|
|
#include "esp_eth.h"
|
|
|
|
#include "protocol_examples_common.h"
|
2018-10-31 18:17:00 -04:00
|
|
|
|
|
|
|
#include <esp_https_server.h>
|
2021-10-08 04:49:57 -04:00
|
|
|
#include "esp_tls.h"
|
2022-05-10 04:23:50 -04:00
|
|
|
#include "sdkconfig.h"
|
2018-10-31 18:17:00 -04:00
|
|
|
|
|
|
|
/* A simple example that demonstrates how to create GET and POST
|
2018-11-20 11:42:37 -05:00
|
|
|
* handlers and start an HTTPS server.
|
2018-10-31 18:17:00 -04:00
|
|
|
*/
|
|
|
|
|
2018-11-20 11:42:37 -05:00
|
|
|
static const char *TAG = "example";
|
2018-10-31 18:17:00 -04:00
|
|
|
|
2024-02-13 06:40:57 -05:00
|
|
|
/* Event handler for catching system events */
|
|
|
|
static void event_handler(void* arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void* event_data)
|
|
|
|
{
|
|
|
|
if (event_base == ESP_HTTPS_SERVER_EVENT) {
|
|
|
|
if (event_id == HTTPS_SERVER_EVENT_ERROR) {
|
|
|
|
esp_https_server_last_error_t *last_error = (esp_tls_last_error_t *) event_data;
|
|
|
|
ESP_LOGE(TAG, "Error event triggered: last_error = %s, last_tls_err = %d, tls_flag = %d", esp_err_to_name(last_error->last_error), last_error->esp_tls_error_code, last_error->esp_tls_flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-31 18:17:00 -04:00
|
|
|
/* An HTTP GET handler */
|
2018-11-20 11:42:37 -05:00
|
|
|
static esp_err_t root_get_handler(httpd_req_t *req)
|
2018-10-31 18:17:00 -04:00
|
|
|
{
|
|
|
|
httpd_resp_set_type(req, "text/html");
|
2020-05-11 04:34:24 -04:00
|
|
|
httpd_resp_send(req, "<h1>Hello Secure World!</h1>", HTTPD_RESP_USE_STRLEN);
|
2018-10-31 18:17:00 -04:00
|
|
|
|
|
|
|
return ESP_OK;
|
|
|
|
}
|
|
|
|
|
2021-10-08 04:49:57 -04:00
|
|
|
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
|
2022-04-20 02:00:56 -04:00
|
|
|
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
|
2022-03-30 09:16:07 -04:00
|
|
|
static void print_peer_cert_info(const mbedtls_ssl_context *ssl)
|
2022-03-29 02:08:34 -04:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2022-04-20 02:00:56 -04:00
|
|
|
#endif
|
2021-10-08 04:49:57 -04:00
|
|
|
/**
|
|
|
|
* Example callback function to get the certificate of connected clients,
|
2022-03-29 02:08:34 -04:00
|
|
|
* whenever a new SSL connection is created and closed
|
2021-10-08 04:49:57 -04:00
|
|
|
*
|
|
|
|
* Can also be used to other information like Socket FD, Connection state, etc.
|
2022-03-28 08:04:38 -04:00
|
|
|
*
|
|
|
|
* NOTE: This callback will not be able to obtain the client certificate if the
|
|
|
|
* following config `Set minimum Certificate Verification mode to Optional` is
|
|
|
|
* not enabled (enabled by default in this example).
|
|
|
|
*
|
|
|
|
* The config option is found here - Component config → ESP-TLS
|
|
|
|
*
|
2021-10-08 04:49:57 -04:00
|
|
|
*/
|
2022-03-30 09:16:07 -04:00
|
|
|
static void https_server_user_callback(esp_https_server_user_cb_arg_t *user_cb)
|
2021-10-08 04:49:57 -04:00
|
|
|
{
|
2022-03-29 02:08:34 -04:00
|
|
|
ESP_LOGI(TAG, "User callback invoked!");
|
2022-04-20 02:00:56 -04:00
|
|
|
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
|
|
|
|
mbedtls_ssl_context *ssl_ctx = NULL;
|
|
|
|
#endif
|
2022-03-29 02:08:34 -04:00
|
|
|
switch(user_cb->user_cb_state) {
|
|
|
|
case HTTPD_SSL_USER_CB_SESS_CREATE:
|
|
|
|
ESP_LOGD(TAG, "At session creation");
|
2021-10-08 04:49:57 -04:00
|
|
|
|
2022-03-29 02:08:34 -04:00
|
|
|
// Logging the socket FD
|
2022-04-20 02:00:56 -04:00
|
|
|
int sockfd = -1;
|
|
|
|
esp_err_t esp_ret;
|
|
|
|
esp_ret = esp_tls_get_conn_sockfd(user_cb->tls, &sockfd);
|
|
|
|
if (esp_ret != ESP_OK) {
|
|
|
|
ESP_LOGE(TAG, "Error in obtaining the sockfd from tls context");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Socket FD: %d", sockfd);
|
|
|
|
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
|
|
|
|
ssl_ctx = (mbedtls_ssl_context *) esp_tls_get_ssl_context(user_cb->tls);
|
|
|
|
if (ssl_ctx == NULL) {
|
|
|
|
ESP_LOGE(TAG, "Error in obtaining ssl context");
|
|
|
|
break;
|
|
|
|
}
|
2022-03-29 02:08:34 -04:00
|
|
|
// Logging the current ciphersuite
|
2022-04-20 02:00:56 -04:00
|
|
|
ESP_LOGI(TAG, "Current Ciphersuite: %s", mbedtls_ssl_get_ciphersuite(ssl_ctx));
|
|
|
|
#endif
|
2022-03-29 02:08:34 -04:00
|
|
|
break;
|
2022-04-20 02:00:56 -04:00
|
|
|
|
2022-03-29 02:08:34 -04:00
|
|
|
case HTTPD_SSL_USER_CB_SESS_CLOSE:
|
|
|
|
ESP_LOGD(TAG, "At session close");
|
2022-04-20 02:00:56 -04:00
|
|
|
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
|
2022-03-29 02:08:34 -04:00
|
|
|
// Logging the peer certificate
|
2022-04-20 02:00:56 -04:00
|
|
|
ssl_ctx = (mbedtls_ssl_context *) esp_tls_get_ssl_context(user_cb->tls);
|
|
|
|
if (ssl_ctx == NULL) {
|
|
|
|
ESP_LOGE(TAG, "Error in obtaining ssl context");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
print_peer_cert_info(ssl_ctx);
|
|
|
|
#endif
|
2022-03-29 02:08:34 -04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ESP_LOGE(TAG, "Illegal state!");
|
|
|
|
return;
|
|
|
|
}
|
2021-10-08 04:49:57 -04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-11-20 11:42:37 -05:00
|
|
|
static const httpd_uri_t root = {
|
2018-10-31 18:17:00 -04:00
|
|
|
.uri = "/",
|
|
|
|
.method = HTTP_GET,
|
|
|
|
.handler = root_get_handler
|
|
|
|
};
|
|
|
|
|
2018-11-20 11:42:37 -05:00
|
|
|
static httpd_handle_t start_webserver(void)
|
2018-10-31 18:17:00 -04:00
|
|
|
{
|
|
|
|
httpd_handle_t server = NULL;
|
|
|
|
|
|
|
|
// Start the httpd server
|
|
|
|
ESP_LOGI(TAG, "Starting server");
|
|
|
|
|
|
|
|
httpd_ssl_config_t conf = HTTPD_SSL_CONFIG_DEFAULT();
|
|
|
|
|
2022-01-24 23:33:31 -05:00
|
|
|
extern const unsigned char servercert_start[] asm("_binary_servercert_pem_start");
|
|
|
|
extern const unsigned char servercert_end[] asm("_binary_servercert_pem_end");
|
|
|
|
conf.servercert = servercert_start;
|
|
|
|
conf.servercert_len = servercert_end - servercert_start;
|
2018-10-31 18:17:00 -04:00
|
|
|
|
|
|
|
extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
|
|
|
|
extern const unsigned char prvtkey_pem_end[] asm("_binary_prvtkey_pem_end");
|
|
|
|
conf.prvtkey_pem = prvtkey_pem_start;
|
|
|
|
conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
|
|
|
|
|
2022-03-28 08:04:38 -04:00
|
|
|
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
|
2021-10-08 04:49:57 -04:00
|
|
|
conf.user_cb = https_server_user_callback;
|
2022-03-28 08:04:38 -04:00
|
|
|
#endif
|
2018-10-31 18:17:00 -04:00
|
|
|
esp_err_t ret = httpd_ssl_start(&server, &conf);
|
|
|
|
if (ESP_OK != ret) {
|
|
|
|
ESP_LOGI(TAG, "Error starting server!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set URI handlers
|
|
|
|
ESP_LOGI(TAG, "Registering URI handlers");
|
|
|
|
httpd_register_uri_handler(server, &root);
|
|
|
|
return server;
|
|
|
|
}
|
|
|
|
|
2022-04-22 06:19:27 -04:00
|
|
|
static esp_err_t stop_webserver(httpd_handle_t server)
|
2018-10-31 18:17:00 -04:00
|
|
|
{
|
|
|
|
// Stop the httpd server
|
2022-04-22 06:19:27 -04:00
|
|
|
return httpd_ssl_stop(server);
|
2018-10-31 18:17:00 -04:00
|
|
|
}
|
|
|
|
|
2020-05-11 04:34:24 -04:00
|
|
|
static void disconnect_handler(void* arg, esp_event_base_t event_base,
|
2018-11-20 11:42:37 -05:00
|
|
|
int32_t event_id, void* event_data)
|
2018-10-31 18:17:00 -04:00
|
|
|
{
|
2018-11-20 11:42:37 -05:00
|
|
|
httpd_handle_t* server = (httpd_handle_t*) arg;
|
|
|
|
if (*server) {
|
2022-05-09 05:27:51 -04:00
|
|
|
if (stop_webserver(*server) == ESP_OK) {
|
2022-04-22 06:19:27 -04:00
|
|
|
*server = NULL;
|
2022-05-09 05:27:51 -04:00
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "Failed to stop https server");
|
|
|
|
}
|
2018-10-31 18:17:00 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-11 04:34:24 -04:00
|
|
|
static void connect_handler(void* arg, esp_event_base_t event_base,
|
2018-11-20 11:42:37 -05:00
|
|
|
int32_t event_id, void* event_data)
|
2018-10-31 18:17:00 -04:00
|
|
|
{
|
2018-11-20 11:42:37 -05:00
|
|
|
httpd_handle_t* server = (httpd_handle_t*) arg;
|
|
|
|
if (*server == NULL) {
|
|
|
|
*server = start_webserver();
|
|
|
|
}
|
2018-10-31 18:17:00 -04:00
|
|
|
}
|
|
|
|
|
2019-07-16 05:33:30 -04:00
|
|
|
void app_main(void)
|
2018-10-31 18:17:00 -04:00
|
|
|
{
|
|
|
|
static httpd_handle_t server = NULL;
|
2018-11-20 11:42:37 -05:00
|
|
|
|
2018-10-31 18:17:00 -04:00
|
|
|
ESP_ERROR_CHECK(nvs_flash_init());
|
2019-11-29 04:54:02 -05:00
|
|
|
ESP_ERROR_CHECK(esp_netif_init());
|
2018-11-20 11:42:37 -05:00
|
|
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
|
|
|
|
|
|
/* Register event handlers to start server when Wi-Fi or Ethernet is connected,
|
|
|
|
* and stop server when disconnection happens.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
|
|
|
|
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
|
|
|
|
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
|
|
|
|
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
|
2024-02-13 06:40:57 -05:00
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_SERVER_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
2018-11-20 11:42:37 -05:00
|
|
|
|
|
|
|
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
|
|
|
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
|
|
|
* examples/protocols/README.md for more information about this function.
|
|
|
|
*/
|
|
|
|
ESP_ERROR_CHECK(example_connect());
|
2018-10-31 18:17:00 -04:00
|
|
|
}
|