1
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
27
28
29
30
31
32
41
42
43
50
51
52
53
54
55
56
57
58
62
63
64
65
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
106
107
108
115
116
117
118
130
133
134
135
136
137
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
170
171
172
173
174
175
176
177
182
183
184
195
196
197
204
205
206
207
208
209
210
211
212
213
216
217
218
220
221
222
224
225
226
227
231
232
/* ... */
#include <esp_wifi.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include "esp_netif.h"
#include "esp_eth.h"
#include "protocol_examples_common.h"
#include <esp_https_server.h>
#include "esp_tls.h"
#include "sdkconfig.h"12 includes
/* ... */
static const char *TAG = "example";
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);
}{...}
}{...}
}{ ... }
static esp_err_t root_get_handler(httpd_req_t *req)
{
httpd_resp_set_type(req, "text/html");
httpd_resp_send(req, "<h1>Hello Secure World!</h1>", HTTPD_RESP_USE_STRLEN);
return ESP_OK;
}{ ... }
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
static void print_peer_cert_info(const mbedtls_ssl_context *ssl)
{
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;
}{...}
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);
}{...}
/* ... */#endif
/* ... */
static void https_server_user_callback(esp_https_server_user_cb_arg_t *user_cb)
{
ESP_LOGI(TAG, "User callback invoked!");
#ifdef CONFIG_ESP_TLS_USING_MBEDTLS
mbedtls_ssl_context *ssl_ctx = NULL;
#endif
switch(user_cb->user_cb_state) {
case HTTPD_SSL_USER_CB_SESS_CREATE:
ESP_LOGD(TAG, "At session creation");
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;
}{...}
ESP_LOGI(TAG, "Current Ciphersuite: %s", mbedtls_ssl_get_ciphersuite(ssl_ctx));/* ... */
#endif
break;
...
case HTTPD_SSL_USER_CB_SESS_CLOSE:
ESP_LOGD(TAG, "At session close");
#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;
}{...}
print_peer_cert_info(ssl_ctx);/* ... */
#endif
break;...
default:
ESP_LOGE(TAG, "Illegal state!");
return;...
}{...}
}{...}
/* ... */#endif
static const httpd_uri_t root = {
.uri = "/",
.method = HTTP_GET,
.handler = root_get_handler
}{...};
static httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
ESP_LOGI(TAG, "Starting server");
httpd_ssl_config_t conf = HTTPD_SSL_CONFIG_DEFAULT();
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;
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;
#if CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK
conf.user_cb = https_server_user_callback;
#endif
esp_err_t ret = httpd_ssl_start(&server, &conf);
if (ESP_OK != ret) {
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}{...}
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &root);
return server;
}{ ... }
static esp_err_t stop_webserver(httpd_handle_t server)
{
return httpd_ssl_stop(server);
}{ ... }
static void disconnect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
if (stop_webserver(*server) == ESP_OK) {
*server = NULL;
}{...} else {
ESP_LOGE(TAG, "Failed to stop https server");
}{...}
}{...}
}{ ... }
static void connect_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
*server = start_webserver();
}{...}
}{ ... }
void app_main(void)
{
static httpd_handle_t server = NULL;
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* ... */
#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
#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
ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_SERVER_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
/* ... */
ESP_ERROR_CHECK(example_connect());
}{ ... }