diff --git a/15_ssl_webserver/CA/openssl.cnf b/15_ssl_webserver/CA/openssl.cnf new file mode 100644 index 0000000..2bb627a --- /dev/null +++ b/15_ssl_webserver/CA/openssl.cnf @@ -0,0 +1,90 @@ +# OpenSSL root CA configuration file. + +[ ca ] +default_ca = CA_default + +[ CA_default ] + +# default folders +dir = /home/dentellaluca/myCA +certs = $dir/certs +crl_dir = $dir/crl +new_certs_dir = $dir/newcerts +database = $dir/index.txt +serial = $dir/serial +RANDFILE = $dir/private/.rand + +# CA private key and certificate files +private_key = $dir/private/ca.key +certificate = $dir/certs/ca.cer + +# Certificate revocation list +crlnumber = $dir/crlnumber +crl = $dir/crl/ca.crl +crl_extensions = crl_ext +default_crl_days = 30 + +# Use SHA-2 +default_md = sha256 + +name_opt = ca_default +cert_opt = ca_default +default_days = 365 +preserve = no +policy = policy_default + +[ policy_default ] +commonName = supplied +organizationalUnitName = optional +organizationName = optional +localityName = optional +stateOrProvinceName = optional +countryName = optional +emailAddress = optional + +[ req ] +# Settings for new requests +default_bits = 2048 +distinguished_name = req_distinguished_name +default_md = sha256 +x509_extensions = ca_cert + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +stateOrProvinceName = State or Province Name +localityName = Locality Name +0.organizationName = Organization Name +organizationalUnitName = Organizational Unit Name +commonName = Common Name +emailAddress = Email Address + +[ ca_cert ] +# Extensions for CA certificates +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ usr_cert ] +# Extensions for client certificates +basicConstraints = CA:FALSE +nsCertType = client, email +nsComment = "OpenSSL Generated Client Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, emailProtection + +[ server_cert ] +# Extensions for server certificates +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + +[ crl_ext ] +# Extension for CRLs +authorityKeyIdentifier=keyid:always diff --git a/15_ssl_webserver/firmware/Makefile b/15_ssl_webserver/firmware/Makefile new file mode 100644 index 0000000..25b9b6f --- /dev/null +++ b/15_ssl_webserver/firmware/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := 16_ssl_webserver + +include $(IDF_PATH)/make/project.mk + diff --git a/15_ssl_webserver/firmware/main/Kconfig.projbuild b/15_ssl_webserver/firmware/main/Kconfig.projbuild new file mode 100644 index 0000000..0a64ac9 --- /dev/null +++ b/15_ssl_webserver/firmware/main/Kconfig.projbuild @@ -0,0 +1,20 @@ +menu "Example configuration" + + config AP_SSID + string "Wifi SSID" + default "esp32-ap" + help + SSID for the Access Point Wifi network (max 31 chars) + + config AP_PASSWORD + string "Wifi password" + help + Password for the Wifi network (if needed) + + config RELAY_PIN + int "Number of the PIN connected to the RELAY" + range 0 34 + default 0 + +endmenu + diff --git a/15_ssl_webserver/firmware/main/ca.cer b/15_ssl_webserver/firmware/main/ca.cer new file mode 100644 index 0000000..225712e --- /dev/null +++ b/15_ssl_webserver/firmware/main/ca.cer @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCjCCAfKgAwIBAgIJAKDlWtmPY783MA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV +BAMMB0x1Y2EtQ0EwHhcNMTcwNTMwMTQxMjU2WhcNMjcwNTI4MTQxMjU2WjASMRAw +DgYDVQQDDAdMdWNhLUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +xVGXeHpnKADvVvjltwbimVK1coZJpQ7NoLdnquArrtV2YjmAH8fQL747o5Zooqib +XsItDjMnU80IIFAfqfp+L7bMatLXhNjEokU72gCQOzY+fCH01tvcSgk9Y0xKxwMF +Lbyx3BR54/DInEW0kLu70BIFGjRh6Vafw7o3kP888lesJXmO2BzKqdP6NA7GVdzT +vmabvXWZdjUxjzU9THERuYrSLzzosaJsGJS5xtzsI0nNGp9blm7NIxMkakVXAcFc +KyMrStorriOQRqy9KvLsdfxdAcD0yKw8Zcm85uxiCv3nbc/VH0vgurBVHu1X8pbs +EvUocBJieze6Q6DFwx52SwIDAQABo2MwYTAdBgNVHQ4EFgQUmU6wPUEhYrdeqK6L +lrl6Eh0jqlcwHwYDVR0jBBgwFoAUmU6wPUEhYrdeqK6Llrl6Eh0jqlcwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggEBAL+p +Dg6d6AcZC6PKldFPCRhwdbXii26wGbr6q/7dB50+jBo72CPGXCJBNRQ/jVT5mvV7 +5jFprIHzi2GWfvHC6ItTnFGkYDqhM83dn4TObjRJ4n5jfPD/7L28M3NAefP3kKqh +SJUojkHU+btgw8Cl+1MrCUGmYjWb6Yd1Et9vYZvqkG/cYyfEWk3TmRilsCWSxFEJ +84NxH3Ug8Hhip0VgdW/AHICOJ0OgRomfEeXjzGy5BJKkUnsGqA5UP94M+xonq7hu +K78zSV6zZGriojFBJqDhWOXoAIWa5swJN4rDONnaKDWdGl/zdy2UylkWzGjeHYeN +m4WGJImdyqaY57sOB0s= +-----END CERTIFICATE----- diff --git a/15_ssl_webserver/firmware/main/component.mk b/15_ssl_webserver/firmware/main/component.mk new file mode 100644 index 0000000..813c48e --- /dev/null +++ b/15_ssl_webserver/firmware/main/component.mk @@ -0,0 +1,2 @@ +COMPONENT_EMBED_FILES := on.png off.png +COMPONENT_EMBED_TXTFILES := ca.cer espserver.cer espserver.key diff --git a/15_ssl_webserver/firmware/main/espserver.cer b/15_ssl_webserver/firmware/main/espserver.cer new file mode 100644 index 0000000..5b1ec34 --- /dev/null +++ b/15_ssl_webserver/firmware/main/espserver.cer @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgjCCAmqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHTHVj +YS1DQTAeFw0xNzA1MzAxNDIzMDlaFw0xODA1MzAxNDIzMDlaMBUxEzARBgNVBAMM +CmVzcC1zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA1zeb +PMEfp/pdqUm+KYz2zlVqJle6n9ndK8AMEvvmLcq0+SHUKTdw+m5buBWLtRc0/paj +Vzd8+35jQqrjaeylJ/Zsmpw2pIor3cUerkzGsQYfpmjrV8dQpOVe0/77GN79DRGU +mE1BSFyBLNqr/PUFyw/kKJ7c2STl/lL7jqJgGIwYK1vbqZB8YV4KqcqSbVqJpZCx +FXnlXTMxthXCBKYhjprZ44dT2npAULgRXOrk0YoXKE5yVv2sxNdMghElA3wakwy8 +V0JgXyfousNOlOmLcahOllMdVLgWDDpevAGfRaHB3Uyv4t8NbPzIlQoJGphc7pML +IwF9F2KH4TuVPwfxAgMBAAGjgd4wgdswCQYDVR0TBAIwADARBglghkgBhvhCAQEE +BAMCBkAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBD +ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlIPIkALRTqDITAj6szS9MkxhX9swQgYDVR0j +BDswOYAUmU6wPUEhYrdeqK6Llrl6Eh0jqlehFqQUMBIxEDAOBgNVBAMMB0x1Y2Et +Q0GCCQCg5VrZj2O/NzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwDQYJKoZIhvcNAQELBQADggEBADvSbKerPVAeFEn4DzHVF7hkK8AYu3unZ5eV +BeeNeT9suqg85h+BnvnQv1Y1fBffvJx8UON/rMwXCpoVeh3cc0YyoLu2iIOU4ohW +yFac8J9dz1h9eUkuUPYJMmze8aA6vebQYXrl7k7oQLTr/EhqtU3yBJAdbOgHjw52 +Wx0L2TYKCyDMGVfoT+regdXQu6ZmjK17cg3NP/mBMF/pLoHZxcwZs7QdP3vBkRj5 ++5RXCd4uLoqb3/hFh2iT6Vl055GffGXwBxU+Pg+IohbrwHdTBMt6u5oM4klVG4U9 +dnhiCnPD3KrlohNWY+QTkBWSa4sYLqqEfLzlyw/Gc01fgswF3FE= +-----END CERTIFICATE----- diff --git a/15_ssl_webserver/firmware/main/espserver.key b/15_ssl_webserver/firmware/main/espserver.key new file mode 100644 index 0000000..c71b0cd --- /dev/null +++ b/15_ssl_webserver/firmware/main/espserver.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAwNc3mzzBH6f6XalJvimM9s5VaiZXup/Z3SvADBL75i3KtPkh +1Ck3cPpuW7gVi7UXNP6Wo1c3fPt+Y0Kq42nspSf2bJqcNqSKK93FHq5MxrEGH6Zo +61fHUKTlXtP++xje/Q0RlJhNQUhcgSzaq/z1BcsP5Cie3Nkk5f5S+46iYBiMGCtb +26mQfGFeCqnKkm1aiaWQsRV55V0zMbYVwgSmIY6a2eOHU9p6QFC4EVzq5NGKFyhO +clb9rMTXTIIRJQN8GpMMvFdCYF8n6LrDTpTpi3GoTpZTHVS4Fgw6XrwBn0Whwd1M +r+LfDWz8yJUKCRqYXO6TCyMBfRdih+E7lT8H8QIDAQABAoIBAQCFTL+9aTO+JClm +0PyOnL46ZMqaQ8Lk2FaLEhEAx6akqAa1Lnl55LvUNuhOMmOCXT2bfli2tDVBCb+F +8bGa3b+dMpCe5gkRpI92XyhBWw7rUbb/7dIczGKUlkePU0+wVrLdjUkXxGeytshq +6oyF0qe0x3dGqeWWl+tvqGvIRAJuFZWX6mVoaZOtqUeeVb+fwqbs3gR2VVABR9q9 +KqKRN1ZikWeJyhQPzTmVpZ5ebqP4blMiJZgFo9TDUp0D6TpC6IQso8VegBSQDrOK +lhYUfU76xsknb6HftqkuZE6BiPWP07tpApH5okp3fO1jGblKgRMDE4Cg9p1UAnef +F6O+uDuZAoGBAPFVL4F1zvT3A9ruzb/sUqBFd7XD7vtNcp/DoxUr6SHSHHJ5J5M3 +BDhGav20on4n3oXXYzPcw/atVey7wH8HLzBhKwujJ/jbYOCyu6MXA0gv7i+EG0Mc +iY6yJ/SFlEDnqlVgzZmMH4CL299Z4c6W1SPfq2VCcIM8ADxxaSSFWheHAoGBAMyP +j2GKsVIv4iT0Yq6Ertutc4Yo8FhVQiG/2OOnfYps2tAgKx7ETTms9VX6axggM38e ++psxeVX1NWM16OxRAuYaIOR6+NzFhShcVberxHgpVZYeQemdOHgIzRCd+Fin6Yjc +5YyfH0mFCjuY3IEwdUa3NFo1j8trmR+AUNs6RtLHAoGBAKSdJZVZ5XwkjeWlZITY +TxfxqpE6f+W800X07WXAmPov1qWizILXUTKNnedGclw5F8kVvR4gJS861tRu0QQU +w3Rtoy4B8X8HLRK399NsHBn+T6rroqjpa08BaM2a3CBVpVMtf7CP6uEFBUpZhfQj +4Gji5YdhhVuO7t5LwZtetrA7AoGACti13pMvEc+OKy12KhDJAMbysDNtgxGKPyXg +BzozUuqws4ZxIuF/wsYkABoWIaJbeKsY2K/H4kHtQcRzBEzLXY4XHmZS2cnzZI94 +0BNgiIqQijQyhIOcoei9jtsBdxn4LRSha1Joo0pVn5FcZ9E89rHyKbJbXIrpBJ2W +K/msFbMCgYAwCdYb9dcZXgy6DVX1H9AHrJfNqqSJYID7e47EA/RVhtBKIx85EX5T +7WXOquT0Xi9AhfLTxRM3kThNmGzx/C2PbMmfYsukDcjORlE53jeFGKJcfvFP28BZ +YxulaKAUJrhTUCoSZTfr6PCcjvzsaHf52DSyryJ7X8niR+IkA3JUOQ== +-----END RSA PRIVATE KEY----- diff --git a/15_ssl_webserver/firmware/main/main.c b/15_ssl_webserver/firmware/main/main.c new file mode 100644 index 0000000..60ee9ba --- /dev/null +++ b/15_ssl_webserver/firmware/main/main.c @@ -0,0 +1,381 @@ +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "nvs_flash.h" +#include "esp_log.h" + +#include "driver/gpio.h" + +#include "mbedtls/platform.h" +#include "mbedtls/net.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/debug.h" +#include "mbedtls/error.h" + + +// mbedTLS error check macro +#define MBEDTLS_ERR(x) do { \ + int retval = (x); \ + char errdesc[100]; \ + if (retval != 0) { \ + mbedtls_strerror(retval, errdesc, 100); \ + fprintf(stderr, "mbedTLS error in %s:\n%s (%d) at line %d\n", #x, errdesc, retval, __LINE__); \ + while(1) vTaskDelay(1000 / portTICK_RATE_MS); \ + } \ +} while (0) + + +// HTTP headers and web pages +const static unsigned char http_html_hdr[] = "HTTP/1.1 200 OK\nContent-type: text/html\n\n"; +const static unsigned char http_png_hdr[] = "HTTP/1.1 200 OK\nContent-type: image/png\n\n"; +const static unsigned char http_off_hml[] = "

Relay is OFF

"; +const static unsigned char http_on_hml[] = "

Relay is ON

"; + +// embedded binary data +extern const uint8_t ca_cer_start[] asm("_binary_ca_cer_start"); +extern const uint8_t ca_cer_end[] asm("_binary_ca_cer_end"); +extern const uint8_t espserver_cer_start[] asm("_binary_espserver_cer_start"); +extern const uint8_t espserver_cer_end[] asm("_binary_espserver_cer_end"); +extern const uint8_t espserver_key_start[] asm("_binary_espserver_key_start"); +extern const uint8_t espserver_key_end[] asm("_binary_espserver_key_end"); +extern const uint8_t on_png_start[] asm("_binary_on_png_start"); +extern const uint8_t on_png_end[] asm("_binary_on_png_end"); +extern const uint8_t off_png_start[] asm("_binary_off_png_start"); +extern const uint8_t off_png_end[] asm("_binary_off_png_end"); + + +// mbed TLS variables +mbedtls_ssl_config conf; +mbedtls_ssl_context ssl; +mbedtls_net_context listen_fd, client_fd; +mbedtls_entropy_context entropy; +mbedtls_ctr_drbg_context ctr_drbg; +mbedtls_x509_crt srvcert; +mbedtls_x509_crt cachain; +mbedtls_pk_context pkey; + +// Event group for inter-task communication +static EventGroupHandle_t event_group; +const int AP_STARTED = BIT0; + +// actual relay status +bool relay_status; + + +// mbedTLS debug function +void my_mbedtls_debug(void *ctx, int level, const char *file, int line, const char *st) { + + printf("mbedtls: %s\n", st); +} + +// mbedTLS write function with fragment and error management +int ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len) { + + int ret; + do { + + ret = mbedtls_ssl_write(ssl, buf, len); + + // an error occurred? + if(ret <= 0) { + + if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) continue; + else return -1; + } + + // did it send all the buffer? + if(ret == len) return 0; + + // if not, move the pointer at the end of the data already sent + else { + buf = buf + ret; + len = len - ret; + } + } while(1); +} + +// AP event handler +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + + case SYSTEM_EVENT_AP_START: + xEventGroupSetBits(event_group, AP_STARTED); + break; + + case SYSTEM_EVENT_AP_STACONNECTED: + printf("New station connected to the AP\n"); + break; + + case SYSTEM_EVENT_AP_STADISCONNECTED: + printf("A station disconnected from the AP\n"); + break; + + default: + break; + } + + return ESP_OK; +} + + +static void https_serve(mbedtls_net_context *client_fd) { + + // return variable + int ret; + + // initialize SSL context + mbedtls_ssl_init(&ssl); + MBEDTLS_ERR(mbedtls_ssl_setup(&ssl, &conf)); + //printf("SSL initialized\n"); + + // configure the input and output functions + mbedtls_ssl_set_bio(&ssl, client_fd, mbedtls_net_send, mbedtls_net_recv, NULL); + + // handshake + while((ret = mbedtls_ssl_handshake(&ssl)) != 0) + if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + char errdesc[100]; + mbedtls_strerror(ret, errdesc, 100); + goto serve_exit; + }; + //printf("Handshake performed\n"); + + // read the request from the client + unsigned char buf[1024]; + do { + int len = sizeof(buf) - 1; + memset(buf, 0, sizeof(buf)); + ret = mbedtls_ssl_read(&ssl, buf, len); + if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) continue; + if(ret <= 0) switch(ret) { + + case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: + printf("* peer closed connection gracefully\n"); + goto serve_exit; + + case MBEDTLS_ERR_NET_CONN_RESET: + printf("* connection reset by peer\n"); + goto serve_exit; + + default: + printf("* mbedtls_ssl_read returned -0x%04x\n", ret); + goto serve_exit; + } + + if(ret > 0) break; + } while(1); + + buf[ret] = '\0'; + + // extract the first line, with the request + char *first_line = strtok((char *)buf, "\n"); + + if(first_line) { + + // default page + if(strstr(first_line, "GET / ")) { + mbedtls_ssl_write(&ssl, http_html_hdr, sizeof(http_html_hdr) - 1); + if(relay_status) { + printf("* sending default page, relay is ON\n"); + mbedtls_ssl_write(&ssl, http_on_hml, sizeof(http_on_hml) - 1); + } + else { + printf("* sending default page, relay is OFF\n"); + mbedtls_ssl_write(&ssl, http_off_hml, sizeof(http_off_hml) - 1); + } + } + + // ON page + else if(strstr(first_line, "GET /on.html ")) { + + if(relay_status == false) { + printf("* turning relay ON\n"); + gpio_set_level(CONFIG_RELAY_PIN, 1); + relay_status = true; + } + + printf("* sending OFF page...\n"); + mbedtls_ssl_write(&ssl, http_html_hdr, sizeof(http_html_hdr) - 1); + mbedtls_ssl_write(&ssl, http_on_hml, sizeof(http_on_hml) - 1); + } + + // OFF page + else if(strstr(first_line, "GET /off.html ")) { + + if(relay_status == true) { + printf("* turning relay OFF\n"); + gpio_set_level(CONFIG_RELAY_PIN, 0); + relay_status = false; + } + + printf("* sending OFF page...\n"); + mbedtls_ssl_write(&ssl, http_html_hdr, sizeof(http_html_hdr) - 1); + mbedtls_ssl_write(&ssl, http_off_hml, sizeof(http_off_hml) - 1); + } + + // ON image + else if(strstr(first_line, "GET /on.png ")) { + printf("* sending ON image...\n"); + ssl_write(&ssl, http_png_hdr, sizeof(http_png_hdr) - 1); + ssl_write(&ssl, on_png_start, on_png_end - on_png_start); + } + + // OFF image + else if(strstr(first_line, "GET /off.png ")) { + printf("* sending OFF image...\n"); + ssl_write(&ssl, http_png_hdr, sizeof(http_png_hdr) - 1); + ssl_write(&ssl, off_png_start, off_png_end - off_png_start); + } + + else printf("* unkown request: %s\n", first_line); + } + else printf("* unknown request\n"); + + // close the connection and free the buffer + serve_exit: + mbedtls_ssl_close_notify(&ssl); + mbedtls_net_free(client_fd); + mbedtls_ssl_free(&ssl); + printf("\n"); +} + + +static void https_server(void *pvParameters) { + + // initialize mbedTLS components + mbedtls_net_init(&listen_fd); + mbedtls_net_init(&client_fd); + mbedtls_ssl_config_init(&conf); + mbedtls_ctr_drbg_init(&ctr_drbg); + mbedtls_entropy_init(&entropy); + mbedtls_x509_crt_init(&srvcert); + mbedtls_x509_crt_init(&cachain); + mbedtls_pk_init(&pkey); + + // load certificates and private key + MBEDTLS_ERR(mbedtls_x509_crt_parse(&cachain, ca_cer_start, ca_cer_end - ca_cer_start)); + MBEDTLS_ERR(mbedtls_x509_crt_parse(&srvcert, espserver_cer_start, espserver_cer_end - espserver_cer_start)); + MBEDTLS_ERR(mbedtls_pk_parse_key(&pkey, espserver_key_start, espserver_key_end - espserver_key_start, NULL, 0)); + + // seed the random number generator + MBEDTLS_ERR(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)); + + // prepare the configuration + MBEDTLS_ERR(mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)); + + // apply the configuration to the random engine and set the debug function + mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); + mbedtls_ssl_conf_dbg(&conf, my_mbedtls_debug, NULL); + + // configure CA chain and server certificate + mbedtls_ssl_conf_ca_chain(&conf, &cachain, NULL); + MBEDTLS_ERR(mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey)); + + // require client authentication + mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED); + + printf("- mbedTLS configured\n"); + + // bind to the default port (443) + MBEDTLS_ERR(mbedtls_net_bind(&listen_fd, NULL, "443", MBEDTLS_NET_PROTO_TCP)); + printf("- bind on port 443 completed\n\n"); + printf("HTTPS Server ready!\n\n"); + + // accept incoming connections + while(1) { + MBEDTLS_ERR(mbedtls_net_accept(&listen_fd, &client_fd, NULL, 0, NULL)); + printf("* new client connected\n"); + + // serve the connection + https_serve(&client_fd); + } +} + + +// setup and start SoftAP +void ap_setup() { + + event_group = xEventGroupCreate(); + + tcpip_adapter_init(); + + ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); + + tcpip_adapter_ip_info_t info; + memset(&info, 0, sizeof(info)); + IP4_ADDR(&info.ip, 192, 168, 10, 1); + IP4_ADDR(&info.gw, 192, 168, 10, 1); + IP4_ADDR(&info.netmask, 255, 255, 255, 0); + ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info)); + printf("- Wifi interface configured\n"); + + ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP)); + printf("- DHCP server started\n"); + + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); + + wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + + wifi_config_t ap_config = { + .ap = { + .ssid = CONFIG_AP_SSID, + .password = CONFIG_AP_PASSWORD, + .ssid_len = 0, + .channel = 1, + .authmode = WIFI_AUTH_WPA2_PSK, + .ssid_hidden = 0, + .max_connection = 4, + .beacon_interval = 100, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config)); + printf("- SoftAP mode configured\n"); + + ESP_ERROR_CHECK(esp_wifi_start()); +} + + +// configure the output PIN +void gpio_setup() { + + // configure the relay pin as GPIO, output + gpio_pad_select_gpio(CONFIG_RELAY_PIN); + gpio_set_direction(CONFIG_RELAY_PIN, GPIO_MODE_OUTPUT); + + // set initial status = OFF + gpio_set_level(CONFIG_RELAY_PIN, 0); + relay_status = false; +} + + +// Main application +void app_main() +{ + // disable the default wifi logging + esp_log_level_set("wifi", ESP_LOG_NONE); + + printf("HTTPS Server starting...\n\n"); + + // initialize the different components + nvs_flash_init(); + ap_setup(); + gpio_setup(); + + // wait for the AP to start + xEventGroupWaitBits(event_group, AP_STARTED, pdFALSE, pdTRUE, portMAX_DELAY); + printf("- Access point started\n\n"); + + // start the HTTPS Server task + xTaskCreate(&https_server, "https_server", 10000, NULL, 5, NULL); +} diff --git a/15_ssl_webserver/firmware/main/off.png b/15_ssl_webserver/firmware/main/off.png new file mode 100644 index 0000000..789d33c Binary files /dev/null and b/15_ssl_webserver/firmware/main/off.png differ diff --git a/15_ssl_webserver/firmware/main/on.png b/15_ssl_webserver/firmware/main/on.png new file mode 100644 index 0000000..6e4cd9f Binary files /dev/null and b/15_ssl_webserver/firmware/main/on.png differ