Browse Source

Merge branch 'kbf-41' of kraxor/kbf into develop

Bence Balint 2 years ago
parent
commit
cefc4cce2a

+ 21 - 0
include/kbf/http/client.h

@@ -82,6 +82,27 @@ namespace kbf::http {
          */
         [[nodiscard]] bool isRunning() const { return running; }
 
+        /**
+         * @brief Closes the connection if it was persistent (i.e. keep-alive or HTTP/1.1).
+         */
+        void disconnect();
+
+        /**
+         * @brief Adds a certificate to the global CA store.
+         *
+         * @param start
+         * @param end
+         */
+        static void addCert(const unsigned char *start, const unsigned char *const end);
+
+        /**
+         * @brief Frees the global CA store.
+         *
+         * @warning Calling this will result in heap corruption when disconnecting if there are any open connections.
+         * Make sure to disconnect() all clients before calling this.
+         */
+        static void clearCerts();
+
         /** @brief Request timeout in milliseconds. */
         const int timeoutMs;
 

+ 7 - 1
include/kbf/http/server.h

@@ -89,10 +89,16 @@ namespace kbf::http {
         /**
          * @brief Starts the server in SSL (HTTPS) mode.
          *
+         * @param cert_start start of the certificate
+         * @param cert_end end of the certificate
+         * @param key_start start of the private key
+         * @param key_end end of the private key
          * @param port TCP port, default is 443
          * @return *this (to enable builder-like syntax)
          */
-        Server &startSSL(int port = 443);
+        Server &startSSL(const unsigned char *cert_start, const unsigned char *cert_end,
+                         const unsigned char *key_start, const unsigned char *key_end,
+                         int port = 443);
 
         /**
          * @brief Stops the HTTP server.

+ 18 - 6
include/kbf/web_service.h

@@ -18,15 +18,13 @@ namespace kbf {
 
         /**
          * @brief Constructor.
-         *
-         * @param port web server port; default is 80
          */
-        explicit WebService(int port = 80);
+        WebService();
 
         /**
          * @brief Destructor.
          *
-         * Will call stop() if #running.
+         * Will call stop() if running.
          */
         ~WebService();
 
@@ -34,8 +32,23 @@ namespace kbf {
          * @brief Starts the service.
          *
          * @note All Controllers must be attached before calling start().
+         *
+         * @param port web server port; default is 80
+         */
+        void start(int port = 80);
+
+        /**
+         * @brief Starts the service in SSL (HTTPS) mode.
+         *
+         * @param cert_start start of the certificate
+         * @param cert_end end of the certificate
+         * @param key_start start of the private key
+         * @param key_end end of the private key
+         * @param port TCP port, default is 443
          */
-        void start();
+        void startSSL(const unsigned char *cert_start, const unsigned char *cert_end,
+                      const unsigned char *key_start, const unsigned char *key_end,
+                      int port = 443);
 
         /**
          * @brief Stops the service.
@@ -168,7 +181,6 @@ namespace kbf {
         http::Server server;
 
         bool running = false;
-        int  port;
 
         struct HandlerArg {
             WebService &webService;

+ 28 - 8
src/http/client.cpp

@@ -2,6 +2,9 @@
 
 #include <freertos/task.h>
 #include <esp_log.h>
+#include <esp_tls.h>
+
+#include <memory>
 
 #include "kbf/exception.h"
 #include "kbf/http/exception.h"
@@ -16,12 +19,12 @@ using std::nullopt;
 using std::map;
 
 http::Client::Client(int timeoutMs, bool async) : timeoutMs(timeoutMs), async(async), buffer() {
-    ESP_LOGD(TAG, "Client()");
+    ESP_LOGD(TAG, "%s()", __func__);
     init();
 }
 
 void http::Client::init() {
-    ESP_LOGD(TAG, "init()");
+    ESP_LOGD(TAG, "%s()", __func__);
     esp_http_client_config_t config{};
     config.event_handler         = handleHttpEvent;
     config.user_data             = this;
@@ -31,18 +34,19 @@ void http::Client::init() {
     config.max_redirection_count = 0;
     config.timeout_ms            = timeoutMs;
     config.is_async              = async;
+    config.use_global_ca_store   = true;
     handle = esp_http_client_init(&config);
 }
 
 http::Client::~Client() {
-    ESP_LOGD(TAG, "~Client()");
+    ESP_LOGD(TAG, "%s()", __func__);
     CHECK_ABORT(esp_http_client_cleanup(handle));
 }
 
 std::shared_ptr<kbf::http::Response>
 http::Client::performRequest(const kbf::http::Method method, const std::string &url, const nlohmann::json *postData,
                              const optional<const map<string, string>> &headers) {
-    ESP_LOGD(TAG, "performRequest(); method: %d, url: %s", method, url.c_str());
+    ESP_LOGD(TAG, "%s(); method: %d, url: %s", __func__, method, url.c_str());
 
     if (running) {
         ESP_LOGE(TAG, "request already in progress");
@@ -50,7 +54,7 @@ http::Client::performRequest(const kbf::http::Method method, const std::string &
     }
     running = true;
 
-    response = shared_ptr<Response>(new Response()); // TODO why doesn't make_shared work here? :/
+    response = std::make_shared<Response>();
     buffer.clear();
     string body;
 
@@ -159,7 +163,7 @@ esp_err_t http::Client::handleHttpEvent(esp_http_client_event_t *event) {
             updateResponse(*client);
             break;
         case HTTP_EVENT_DISCONNECTED:
-            ESP_LOGW(TAG, "disconnected");
+            ESP_LOGI(TAG, "disconnected");
             client->running = false;
             break;
     }
@@ -182,13 +186,29 @@ void http::Client::updateResponse(http::Client &client) {
 
 shared_ptr<http::Response>
 http::Client::get(const string &url, const optional<const map<string, string>> &headers) {
-    ESP_LOGD(TAG, "get(%s)", url.c_str());
+    ESP_LOGD(TAG, "%s(%s)", __func__, url.c_str());
     return performRequest(GET, url, nullptr, headers);
 }
 
 shared_ptr<http::Response>
 http::Client::post(const string &url, const nlohmann::json &data, const optional<const map<string, string>> &headers) {
-    ESP_LOGD(TAG, "post(%s)", url.c_str());
+    ESP_LOGD(TAG, "%s(%s)", __func__, url.c_str());
     return performRequest(POST, url, &data, headers);
 }
 
+void http::Client::addCert(const unsigned char *const start, const unsigned char *const end) {
+    ESP_LOGI(TAG, "%s()", __func__);
+    ESP_LOGD(TAG, "certificate:\n%s", start);
+
+    CHECK(esp_tls_set_global_ca_store(start, end - start));
+}
+
+void http::Client::clearCerts() {
+    ESP_LOGI(TAG, "%s()", __func__);
+    esp_tls_free_global_ca_store();
+}
+
+void http::Client::disconnect() {
+    ESP_LOGD(TAG, "%s()", __func__);
+    CHECK(esp_http_client_close(handle));
+}

+ 13 - 14
src/http/server.cpp

@@ -24,7 +24,7 @@ http::Server &http::Server::start(int port) {
     handle = nullptr;
     httpd_config_t config = HTTPD_DEFAULT_CONFIG();
     config.server_port = port;
-    config.stack_size  = 16384;
+    config.stack_size  = 16384; // TODO use Kconfig
     CHECK(httpd_start(&handle, &config));
 
     registerUriHandlers();
@@ -33,8 +33,10 @@ http::Server &http::Server::start(int port) {
     return *this;
 }
 
-http::Server &http::Server::startSSL(int port) {
-    ESP_LOGI(TAG, "startSSL(%d)", port);
+http::Server &http::Server::startSSL(const unsigned char *cert_start, const unsigned char *cert_end,
+                                     const unsigned char *key_start, const unsigned char *key_end,
+                                     int port) {
+    ESP_LOGI(TAG, "%s(%d)", __func__, port);
     if (running) {
         ESP_LOGE(TAG, "server already running");
         ABORT("fix me");
@@ -42,16 +44,12 @@ http::Server &http::Server::startSSL(int port) {
 
     handle = nullptr;
     httpd_ssl_config_t conf = HTTPD_SSL_CONFIG_DEFAULT();
+    conf.cacert_pem  = cert_start;
+    conf.cacert_len  = cert_end - cert_start;
+    conf.prvtkey_pem = key_start;
+    conf.prvtkey_len = key_end - key_start;
 
-    extern const unsigned char cacert_pem_start[] asm("_binary_cacert_pem_start");
-    extern const unsigned char cacert_pem_end[]   asm("_binary_cacert_pem_end");
-    conf.cacert_pem = cacert_pem_start;
-    conf.cacert_len = cacert_pem_end - cacert_pem_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;
+    conf.httpd.stack_size  = 16384; // TODO use Kconfig
 
     CHECK(httpd_ssl_start(&handle, &conf));
 
@@ -62,7 +60,7 @@ http::Server &http::Server::startSSL(int port) {
 }
 
 void http::Server::registerUriHandlers() {
-    ESP_LOGI(TAG, "registering URI handlers");
+    ESP_LOGD(TAG, "%s()", __func__);
     for (auto &route : routes) {
         ESP_LOGI(TAG, "  method: %d; uri: %s", static_cast<int>(route.method), route.uri.c_str());
         httpd_uri_t uriHandler = {
@@ -76,6 +74,7 @@ void http::Server::registerUriHandlers() {
 }
 
 void http::Server::stop() {
+    ESP_LOGI(TAG, "%s()", __func__);
     CHECK(httpd_stop(handle));
     running = false;
 }
@@ -91,7 +90,7 @@ static string getDefaultStatusText(int status) {
 
 esp_err_t http::Server::handleHttpRequest(httpd_req_t *httpdRequest) {
     auto route = static_cast<Route *>(httpdRequest->user_ctx);
-    ESP_LOGD(TAG, "handleHttpRequest; method: %d, path: \"%s\"", httpdRequest->method, route->uri.c_str());
+    ESP_LOGD(TAG, "%s; method: %d, path: \"%s\"", __func__, httpdRequest->method, route->uri.c_str());
 
     auto request  = Request(httpdRequest);
     auto response = route->handler(request, route->data);

+ 18 - 4
src/web_service.cpp

@@ -8,8 +8,8 @@ using namespace kbf;
 using http::Request;
 using http::Response;
 
-WebService::WebService(int port) : server(), port(port) {
-    ESP_LOGI(TAG, "%s(%d)", __func__, this->port);
+WebService::WebService() : server() {
+    ESP_LOGI(TAG, "%s()", __func__);
 }
 
 WebService::~WebService() {
@@ -19,8 +19,8 @@ WebService::~WebService() {
     }
 }
 
-void WebService::start() {
-    ESP_LOGI(TAG, "%s()", __func__);
+void WebService::start(int port) {
+    ESP_LOGI(TAG, "%s(%d)", __func__, port);
 
     if (running) {
         ABORT("WebService already running");
@@ -30,6 +30,20 @@ void WebService::start() {
     server.start(port);
 }
 
+void WebService::startSSL(const unsigned char *const cert_start, const unsigned char *const cert_end,
+                          const unsigned char *const key_start, const unsigned char *const key_end,
+                          int port) {
+
+    ESP_LOGI(TAG, "%s(%d)", __func__, port);
+
+    if (running) {
+        ABORT("WebService already running");
+    }
+
+    running = true;
+    server.startSSL(cert_start, cert_end, key_start, key_end, port);
+}
+
 void WebService::stop() {
     ESP_LOGI(TAG, "%s()", __func__);
 

+ 48 - 6
test/test_https.cpp

@@ -4,6 +4,7 @@
 #include "kbf/wifi_legacy.h"
 #include "kbf/http/server.h"
 #include "kbf/http/client.h"
+#include "kbf/http/exception.h"
 #include "kbf/rtos.h"
 
 #include <unity.h>
@@ -12,6 +13,30 @@ using namespace kbf;
 using namespace std;
 using nlohmann::json;
 
+extern const unsigned char cert_pem_start[] asm("_binary_cert_pem_start");
+extern const unsigned char cert_pem_end[]   asm("_binary_cert_pem_end");
+extern const unsigned char cert_wrong_pem_start[] asm("_binary_wrong_cert_pem_start");
+extern const unsigned char cert_wrong_pem_end[]   asm("_binary_wrong_cert_pem_end");
+extern const unsigned char key_pem_start[] asm("_binary_key_pem_start");
+extern const unsigned char key_pem_end[]   asm("_binary_key_pem_end");
+
+static void assert_fail(http::Client &client, const string &message) {
+    bool caught = false;
+    try {
+        auto response = client.get("https://localhost/get-me");
+        ESP_LOGI("assert", "gonna fail, got %d", response->status);
+    } catch (http::exception::ConnectionError &e) {
+        caught = true;
+    }
+    TEST_ASSERT_TRUE_MESSAGE(caught, message.c_str());
+}
+
+static void assert_ok(http::Client &client, const string &message) {
+    auto response = client.get("https://localhost/get-me");
+    TEST_ASSERT_EQUAL_MESSAGE(200, response->status, message.c_str());
+    TEST_ASSERT_EQUAL_STRING("OK", response->body.c_str());
+}
+
 TEST_CASE("HTTPS GET", "[kbf_http]") {
     wifi_legacy::start();
     auto server = http::Server();
@@ -22,13 +47,30 @@ TEST_CASE("HTTPS GET", "[kbf_http]") {
         return http::Response("OK");
     }};
     server.route({http::GET, "/get-me", handleGet, nullptr});
-    server.startSSL();
+    server.startSSL(cert_pem_start, cert_pem_end, key_pem_start, key_pem_end);
     TEST_ASSERT_TRUE(server.isRunning())
 
-    auto client   = http::Client();
-    auto response = client.get("https://localhost/get-me");
-    TEST_ASSERT_EQUAL(200, response->status);
-    TEST_ASSERT_EQUAL_STRING("OK", response->body.c_str());
+    auto client = http::Client();
+    assert_fail(client, "no certs");
+
+    http::Client::addCert(cert_pem_start, cert_pem_end);
+    assert_ok(client, "right cert");
+
+    client.disconnect();
+    http::Client::clearCerts();
+    assert_fail(client, "certs cleared");
+
+    http::Client::addCert(cert_wrong_pem_start, cert_wrong_pem_end);
+    assert_fail(client, "wrong cert");
+
+    http::Client::addCert(cert_pem_start, cert_pem_end);
+    assert_ok(client, "wrong + right cert");
+
+    client.disconnect();
+    http::Client::clearCerts();
+    http::Client::addCert(cert_pem_start, cert_pem_end);
+    http::Client::addCert(cert_wrong_pem_start, cert_wrong_pem_end);
+    assert_ok(client, "right + wrong cert");
 
     server.stop();
     wifi_legacy::stop();
@@ -46,7 +88,7 @@ TEST_CASE("HTTPS async", "[broken]") {
     }};
     auto server = http::Server()
             .route({http::GET, "/", handleRequest, nullptr})
-            .startSSL();
+            .startSSL(cert_pem_start, cert_pem_end, key_pem_start, key_pem_end);
 
     auto client = http::Client(true);
     client.onSuccess = {[](http::Client &client, const http::Response &response) {

+ 12 - 6
test/test_web_service.cpp

@@ -6,6 +6,11 @@
 
 using namespace kbf;
 
+extern const unsigned char cert_pem_start[] asm("_binary_cert_pem_start");
+extern const unsigned char cert_pem_end[]   asm("_binary_cert_pem_end");
+extern const unsigned char key_pem_start[] asm("_binary_key_pem_start");
+extern const unsigned char key_pem_end[]   asm("_binary_key_pem_end");
+
 class CounterController : public WebService::Controller {
 public:
     CounterController() : Controller("/counter") {}
@@ -42,26 +47,27 @@ TEST_CASE("WebService", "[kbf_web_service]") {
     auto webService = WebService();
     webService.controller<CounterController>();
     webService.controller<EchoController>();
-    webService.start();
+    webService.startSSL(cert_pem_start, cert_pem_end, key_pem_start, key_pem_end);
 
+    http::Client::addCert(cert_pem_start, cert_pem_end);
     auto client = http::Client();
 
-    auto response = client.get("http://localhost/counter");
+    auto response = client.get("https://localhost/counter");
     TEST_ASSERT_EQUAL(200, response->status);
     TEST_ASSERT_EQUAL_STRING("0", response->body.c_str());
 
-    response = client.get("http://localhost/counter");
+    response = client.get("https://localhost/counter");
     TEST_ASSERT_EQUAL_STRING("1", response->body.c_str());
 
-    response = client.post("http://localhost/counter", {{"str", "notallowed"}});
+    response = client.post("https://localhost/counter", {{"str", "notallowed"}});
     TEST_ASSERT_EQUAL(405, response->status);
     TEST_ASSERT_EQUAL_STRING("method not allowed", response->body.c_str());
 
-    response = client.get("http://localhost/echo?str=foo");
+    response = client.get("https://localhost/echo?str=foo");
     TEST_ASSERT_EQUAL(200, response->status);
     TEST_ASSERT_EQUAL_STRING("foo", response->body.c_str());
 
-    response = client.post("http://localhost/echo", {{"str", "bar"}});
+    response = client.post("https://localhost/echo", {{"str", "bar"}});
     TEST_ASSERT_EQUAL(200, response->status);
     TEST_ASSERT_EQUAL_STRING("bar", response->body.c_str());
 

+ 7 - 5
test_app/main/CMakeLists.txt

@@ -1,10 +1,12 @@
 idf_component_register(
-  SRCS "main_test.c"
-  INCLUDE_DIRS "."
+        SRCS "main_test.c"
+        INCLUDE_DIRS "."
 
-  EMBED_TXTFILES
-  "certs/cacert.pem"
-  "certs/prvtkey.pem"
+        EMBED_TXTFILES
+        "certs/cert.pem"
+        "certs/key.pem"
+        "certs/wrong_cert.pem"
+        "certs/wrong_key.pem"
 )
 
 spiffs_create_partition_image("storage" "spiffs" FLASH_IN_PROJECT)

+ 0 - 19
test_app/main/certs/cacert.pem

@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDDzCCAfegAwIBAgIUDdzYo6ANlTi9J0HbGea7tpGXnacwDQYJKoZIhvcNAQEL
-BQAwFzEVMBMGA1UEAwwMS0JGIFNTTCB0ZXN0MB4XDTIxMDQyNzA4NTE1NFoXDTMx
-MDQyNTA4NTE1NFowFzEVMBMGA1UEAwwMS0JGIFNTTCB0ZXN0MIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzLHIG2k+Y7mZ/Uq9hR1eDkCv8dS7ceuK0X/S
-R3Dkq8PAGIEm+xH3MRcxT3CyhA06P0RhZMke9NZqA7E51qpT0e7REENto5LrYUuX
-HtU5jAGE9da6kwDa4ZbeJQeib4ppTZICjkiTzMZMy7xNL/xF6jWjMbwXSJaRcutB
-OusQ3pQOnCfXDLsas+zY+j6uydPl6AMCP6ZIXpr7Vt//H6CkJNENUdNnPgFIV1rm
-belvuw/YaIcOTdpm9YnIoeTvwoTb4hSfl8dDVjGrd3bzbvEzxwBypx2UgN3JvxpP
-/DQLbUGiDnvFUhrs4p2nGkyYK14H0hbdUmtRgDNCDofVL948KQIDAQABo1MwUTAd
-BgNVHQ4EFgQUwvXLD/DTPrgU6VjoAnpgTPRmjbEwHwYDVR0jBBgwFoAUwvXLD/DT
-PrgU6VjoAnpgTPRmjbEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
-AQEAhMOsfKWVKrs1uZt6AjM4PVW23TN0qb0/80lnkLIPKTz5eJmI8ZJJPZaSfNfj
-lDrdvx1wGzp5QpHt0utYw6pqm+TOqCjUB9fejHGbdZ/jVBFwDX/UHAsi8bG56znw
-OSXd/80vf+tuS1m5aLaG838L3RCjUxGcJF8FDk8eiYAfWvHiX7u3wcvRjgI22tIl
-b04XeqIuBMqHvW++PTrHVIPkjO3lmAYMF1dSnZw0RyB2rSCDXXMzrhEHiDiDvzgC
-uH9jWM5VbuQk6CQjSmYhbOT9mAZ84zeigzFE/ZldskMzyxJ5dmRO51lz1mzcWS4f
-YVG3Yq1mWyBCfKe6TBap0e3i+g==
------END CERTIFICATE-----

+ 29 - 0
test_app/main/certs/cert.pem

@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIFCTCCAvGgAwIBAgIUG42CacY6oMbcaF35SZz+9EODpckwDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIxMDgxOTEwMTEwNloXDTIxMDkx
+ODEwMTEwNlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA58kJMq2Q5mb9+zt4lfSjSefzvOl0Ps4WWqMOahe7CYnB
+N607YyzVnHPThS6Pyzej/Tfvdd8687MHsQ5N1FhaLq22k0SFBAt2mDiGDzQWSTs7
+4ks6weWN2S6PR67Z3iqvhOMw7pbAwZRWwDtLzpqHgClMyh2L0YRr1empg2ukGzMa
+fTuA+gKTlu9Dj05sRGlYNd7237pwW/PlFknHDApHs29dfQQAS9bTEHpuywNcxH5E
+6dGs7chIbcPZYDJHSpY6bmOzwVCPbmED0GkAIMwHqEzaP+chSPygCe4zdSTHAbtI
+AFKwe2wW2m2My858okquuHWli/qK9sGcPhE7dmK4VSIWq/ZCwJkPLLe+TY8oY2RR
+KLRGy9UbXzAUBjDI5Y8KW/REJT/DtKWbXPD7xkHPjLGbhS2Sm0e1AThhV8H7Kv4q
+wPwY5gT0ImenFnDl9jZ8DyBUtnomJFPnqdJo9NX/Xhw7E68IbecGgBwupnw8rXuT
+m2vpuOOJDppSyH8TlreFQgTG+igqeE7IyLsYUI0Vs4nEHsYPCX9qiNjZRWSimiaE
+0hqyNzqGeTp++XOZadZhqDOO5nfL5ps5026QsNvTEOLezUlt/DBi5BmTQtmWYZj2
+R0IvIW6t6Ln7aIThpjhofprmbk0zTXP3DeQ/63QdE76r4gYZuSCoi3vLyg+a+WcC
+AwEAAaNTMFEwHQYDVR0OBBYEFAnbj48xqB+iADXboUjVzYJz7Gg9MB8GA1UdIwQY
+MBaAFAnbj48xqB+iADXboUjVzYJz7Gg9MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggIBAHYawkqGMKbpKrdVKY27DOagpp77hT7FIlzErD7HLguJqALF
+0ls6+88nmkr7wKvptmAUikJsjGqj5bTQsT4viIJx89pgNjYd4ZvDIVnRa1FfxWdy
+rqSBNyEuJJet8VBpcmFI6mTFtuhGSNGYXaNUCmZ64Cm+G7v3h+BWCV3WbJfjvDtj
+dQzBnm7PjmSMm4thquZivU755MuYLeUSAywMJKyNr9nSIHo2vLlX/1ayXHyONdlp
+4KfsPMbNh8Yq4cZVqwKaQebIlGFmedczPb4QiqH8OA+ikpArxU0VHKN9woPeA+Xz
+5mdwWc8qgDe/v99m9kerPQwoyYxI2bd3aGuhV0HeVLxWsQAxpld0K8Kr70pdVXLf
+ZAVD1k+HyoEb0IMl7loBQyb/IF/AKHMMXgfHZD48H70WadBXSZYpHTEitKv2gn/r
+2IwrA0ZqbyjT0FUmsoSr+zyME3rOhCXavhnorVz+uKfZialqIstn1lIEkz/OyW+C
+F7nt20O8cIOSPBARjsE89jdaJsXyUWaLLNd7HA5lysuUCfgnhUKB89zSGCZ/y9ir
+LsFa+9h4QNQfcmM0NdoVgrf25CiA8hUtTs+/PdKKYsJ2Yi3Au90D5koKhuPmbmMo
+u/EFHgaLThJfwbDsX0JYnIIKBTL/+EvmpXRj078z7F6Sce7NNGw+1ttgjpSJ
+-----END CERTIFICATE-----

+ 52 - 0
test_app/main/certs/key.pem

@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+yp78LV5KcuoEmN5JI0juKmiN1yzw6zY=
+-----END PRIVATE KEY-----

+ 0 - 28
test_app/main/certs/prvtkey.pem

@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDMscgbaT5juZn9
-Sr2FHV4OQK/x1Ltx64rRf9JHcOSrw8AYgSb7EfcxFzFPcLKEDTo/RGFkyR701moD
-sTnWqlPR7tEQQ22jkuthS5ce1TmMAYT11rqTANrhlt4lB6JvimlNkgKOSJPMxkzL
-vE0v/EXqNaMxvBdIlpFy60E66xDelA6cJ9cMuxqz7Nj6Pq7J0+XoAwI/pkhemvtW
-3/8foKQk0Q1R02c+AUhXWuZt6W+7D9hohw5N2mb1icih5O/ChNviFJ+Xx0NWMat3
-dvNu8TPHAHKnHZSA3cm/Gk/8NAttQaIOe8VSGuzinacaTJgrXgfSFt1Sa1GAM0IO
-h9Uv3jwpAgMBAAECggEAeT3sSuAhhiwPG8pDSy9D4KlMDa91f1qGlORjBtHFgD+n
-7lvBXQEdK0STfnxAIJs9HvA/x9Sgs2C01o8ItS+aCkSsLDfkHvkM1kpRrn+ZYGYd
-/Qc854mgG/Kijchh3DNdgAa14NT4RlhGcH6OMZf5SWqPyQuhtusIJ8tUjbNiAJMe
-FuB97oL/lQDkFGUkosQtdZRP8kW3GFQuTi+y3uucTAao/7TYUdLRm6XKc4yhkPNE
-QgPgKePh4mfQjCNg/leAZgZqzzq1Ulcm3HntVXa64MO+nM7M+pDWOEcUgYoJML5e
-dgrCvfxZdl15e+oLRuRMnivkOaQg6kGnB0vAzoF3AQKBgQDyvvFWre7cLzedaUEa
-obmngYhVNiLEA4HyObqHGNvImtvf4QKh/fc+9QYy65kjznl4P9ytz1hqveLiky07
-8jUvhHRYCghl/g/BHKUMAnYKES/Ivu6LENouqYYcCqPDyT4fcTzEFlctPYDGQCfN
-4Si7iUV0idyQQoF9rZpQETZvWQKBgQDX3vaa3KX66F3bSS1spAcyPa9OYjQyr0DT
-LbMRLovNyMz0hkNZicaPxX7UIbRppLlfjo43MtZ69LPlwSLLtyRTrlDOQ1UGwNED
-xh0Iu15eEE5QPUZU1ZpR6dHmQHluLQ7l8Y9nhz4PlVhJNqjndZ5UzUrlxcxz7uvi
-ybcckBXpUQKBgQCsrK0KZsHB+QiLveKk6iQhhqAPVWoXmxMl1nDcRw+YvKfpsqrn
-xrvJGg0lzbfq46Y+ptb5AMS5cYfieqUzvlCdE5CbS8+7laVpTlINn/aNpLokB8Wy
-QPOjO839RohF7nJ1dVyvc+Dhep2O6PYnmqIZ/UTd6G9wYw6v8v0RNZ1OSQKBgQDM
-FDBlBTYxN14LwmmcLJHVEHXcD4EzbXVGcAy6sJtgp3YDsa6YRmUeZGJbn6WUvjK1
-wOp4CqqzwQUVrvn7Rx+jsMcZyJPod37iJ3gpWiGDoby3pMYJy4pB6GAUYl2qKBTO
-lAizoiqsxs6ZIICbmRlfKFmnUdDQxU3hsDtZWGoukQKBgQDGejnc+whsG7wO3F9r
-DTFJerOxR3r67IDF2UPMQFgfoN9qpEqXuMBcZIGtlouxI4ziZicrNFk+o5QB6ODr
-7wcEOhinSnMC1iRkCFDeCnIh1pJXlnNXglnqmbx2AC74K5Q7Ij8lyzDXNuLOpkg8
-QOc+7JvkDM65Vq7tTTzaV0QQYw==
------END PRIVATE KEY-----

+ 29 - 0
test_app/main/certs/wrong_cert.pem

@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIFCTCCAvGgAwIBAgIUIJAyKznyevWxSqjdRr9nlrLv65wwDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIxMDgxOTEwMTA1MVoXDTIxMDkx
+ODEwMTA1MVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEAuLDylZUnQXM65Sbps1Ku2gsIrQC4gnF95TceR3K4eOx+
+/6L1jP+uzQGSGlqge9hwekIDj5lDg6zrzk9GMTafwAgL6wH15z0stROMGggEBjO1
+q317l+7BOw5mmYsLAct36X76+or+san612faV80y0IhHxD4Uv2UCfvoUrNPrQkOf
+uZPFi7gCuWdgYNwJgkL99DY5f2dOb++DmqScsQ6rKIxz3rUeBNFNaolXuFuCKJp7
+2Jnp1fmhYf/baQZcZAQypHYlRlhs2k1Htu3nT5ByJjImnlsHhWcuXYwbYsis1Yyp
+pCkzBoQKTyIGotcadXxUE7k6fID8dvbbBx/P3QrEL7AhqT/sWP0WPPt+MHYXHHxF
+UfI5i8JYwVnnHExeNRXA8MDzsjO93yKt1Ou96+h8r/3Nx159eQFz9b3110jUS1M4
+W5jwcDC4+f2nNegqbzYXGt4MVklC0wmHNWPFS0q68DbURAsXVm+JYYaKM/1cJ4eb
+hUr8AEv9u4mzoTZtQsESy74BCn6UOJXCdtbEhlCag1luFq8KOt5PFNQkfZU4jKVp
+cQotYWexmlfwnXdq/tpxSpgeyASevk/oX89I9voN124XjT44WGdbwf0/KcBulQy4
+x/+uQrrCn0fxkm3YSNPe5j3dFeH/PUutZlVhUVBXniveh2fopPBulyNSTzlO0ScC
+AwEAAaNTMFEwHQYDVR0OBBYEFGsNKKbp0WbSumQr+2QaY3uhUc26MB8GA1UdIwQY
+MBaAFGsNKKbp0WbSumQr+2QaY3uhUc26MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggIBAJmeQ7bbgTV6p8cpSBz22euMKz8fygyo5tOZZLKfnV20WdlF
+kjqh7HM7R3jIaVvVlqY+MC9hRXOU6/olxDIsB1VKxhRTJwXfTsRETOZL2KkUecfS
+PTa884MLC9IzDdBB4g0ufX5Z07XPfPmtuq8XdURbJmr+5EryHmPSw3n2Kcmmz7dB
+pV+Q8WRqIDyEVG5Vl8JMLVmHubbPFRTXqeLoRF37i0HN5ct9DRROLCeKNFC4PGXF
+sgPVI8RWzluIVzRNoRtcUz6cioEACSE0z6ayRRRK+ROVutIy50/oeTQNBDJAags+
+ruuMYEvc9/Yyfb62A05jYVtwiHsZhfYcyrJrrnt39Q9kk2Zpy1I2HoeVZh+vMRE7
++hJ5syRVW01wZmj0iGy7L7a/ghFT8DYjAe0NNb4nRYXzRtCG8/e24h69baw2igUO
+cz9m37I87JgU3nPW975Y+Zwr52NRo1F+NDxWGA9T5j4kcUJmDckRBRkuzJxszsy6
+u3ZxDe4WV5RYZMFHUp+NenHkRG1/S/l5TWIQ2UjfRZ/QpnGeZHh/Zg4gcGxVOlMk
+Cwn7uUlCl6E2aqDrlFQy7q4NcFVrKYQ+Aa6eZH7UvDu78TEDs7xVknr1WSrwnpN+
+xBjUmB4ToLrs+NqvNL/y1wMU+uDZclVVxWcvuchhBvG+rLbDhuSy63Xlp1gb
+-----END CERTIFICATE-----

+ 52 - 0
test_app/main/certs/wrong_key.pem

@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+v4iHaLjQXlEPr2mOZdLe8isgLaX/
+-----END PRIVATE KEY-----

+ 32 - 20
test_app/sdkconfig

@@ -197,6 +197,7 @@ CONFIG_BT_CTRL_SLEEP_MODE_EFF=0
 CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0
 CONFIG_BT_CTRL_HCI_TL_EFF=1
 CONFIG_BT_RESERVE_DRAM=0
+CONFIG_BT_NIMBLE_USE_ESP_TIMER=y
 # end of Bluetooth
 
 #
@@ -232,6 +233,10 @@ CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
 # TWAI configuration
 #
 # CONFIG_TWAI_ISR_IN_IRAM is not set
+# CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC is not set
+# CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set
+# CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set
+# CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set
 # end of TWAI configuration
 
 #
@@ -272,7 +277,7 @@ CONFIG_ESP_TLS_USING_MBEDTLS=y
 CONFIG_ESP_TLS_SERVER=y
 # CONFIG_ESP_TLS_PSK_VERIFICATION is not set
 CONFIG_ESP_TLS_INSECURE=y
-CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y
+# CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY is not set
 # end of ESP-TLS
 
 #
@@ -325,6 +330,7 @@ CONFIG_ESP32_XTAL_FREQ=40
 # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set
 # CONFIG_ESP32_NO_BLOBS is not set
 # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
+# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set
 # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set
 CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5
 # end of ESP32-specific
@@ -362,7 +368,6 @@ CONFIG_ESP_INT_WDT_CHECK_CPU1=y
 CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y
 CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y
 CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y
-CONFIG_ESP_MAC_ADDR_UNIVERSE_BT_OFFSET=2
 CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y
 # end of Common ESP-related
 
@@ -488,10 +493,17 @@ CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
 # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set
 CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
-# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set
+# CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE is not set
+# CONFIG_WIFI_LOG_DEFAULT_LEVEL_ERROR is not set
+# CONFIG_WIFI_LOG_DEFAULT_LEVEL_WARN is not set
+CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y
+# CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set
+# CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set
 CONFIG_ESP32_WIFI_IRAM_OPT=y
 CONFIG_ESP32_WIFI_RX_IRAM_OPT=y
 CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y
+# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set
+# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set
 # end of Wi-Fi
 
 #
@@ -678,16 +690,19 @@ CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
 CONFIG_LWIP_GARP_TMR_INTERVAL=60
 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
+# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
 # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
 
 #
 # DHCP server
 #
+CONFIG_LWIP_DHCPS=y
 CONFIG_LWIP_DHCPS_LEASE_UNIT=60
 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
 # end of DHCP server
 
 # CONFIG_LWIP_AUTOIP is not set
+CONFIG_LWIP_IPV6=y
 # CONFIG_LWIP_IPV6_AUTOCONFIG is not set
 CONFIG_LWIP_NETIF_LOOPBACK=y
 CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
@@ -743,6 +758,7 @@ CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5
 #
 # ICMP
 #
+CONFIG_LWIP_ICMP=y
 # CONFIG_LWIP_MULTICAST_PING is not set
 # CONFIG_LWIP_BROADCAST_PING is not set
 # end of ICMP
@@ -776,22 +792,7 @@ CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y
 # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set
 # end of Hooks
 
-#
-# Debug
-#
-# CONFIG_LWIP_NETIF_DEBUG is not set
-# CONFIG_LWIP_PBUF_DEBUG is not set
-# CONFIG_LWIP_ETHARP_DEBUG is not set
-# CONFIG_LWIP_API_LIB_DEBUG is not set
-# CONFIG_LWIP_SOCKETS_DEBUG is not set
-# CONFIG_LWIP_IP_DEBUG is not set
-# CONFIG_LWIP_ICMP_DEBUG is not set
-# CONFIG_LWIP_DHCP_STATE_DEBUG is not set
-# CONFIG_LWIP_DHCP_DEBUG is not set
-# CONFIG_LWIP_IP6_DEBUG is not set
-# CONFIG_LWIP_ICMP6_DEBUG is not set
-# CONFIG_LWIP_TCP_DEBUG is not set
-# end of Debug
+# CONFIG_LWIP_DEBUG is not set
 # end of LWIP
 
 #
@@ -821,6 +822,7 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y
 CONFIG_MBEDTLS_HARDWARE_AES=y
 CONFIG_MBEDTLS_HARDWARE_MPI=y
 CONFIG_MBEDTLS_HARDWARE_SHA=y
+CONFIG_MBEDTLS_ROM_MD5=y
 # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set
 # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set
 CONFIG_MBEDTLS_HAVE_TIME=y
@@ -856,6 +858,8 @@ CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
 # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set
 CONFIG_MBEDTLS_SSL_ALPN=y
 CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y
+CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y
+CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y
 CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y
 
 #
@@ -871,6 +875,7 @@ CONFIG_MBEDTLS_RC4_DISABLED=y
 # CONFIG_MBEDTLS_XTEA_C is not set
 CONFIG_MBEDTLS_CCM_C=y
 CONFIG_MBEDTLS_GCM_C=y
+# CONFIG_MBEDTLS_NIST_KW_C is not set
 # end of Symmetric Ciphers
 
 # CONFIG_MBEDTLS_RIPEMD160_C is not set
@@ -920,6 +925,7 @@ CONFIG_MDNS_TASK_AFFINITY_CPU0=y
 # CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set
 CONFIG_MDNS_TASK_AFFINITY=0x0
 CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000
+# CONFIG_MDNS_STRICT_MODE is not set
 CONFIG_MDNS_TIMER_PERIOD_MS=100
 # end of mDNS
 
@@ -1047,7 +1053,13 @@ CONFIG_SPIFFS_USE_MTIME=y
 #
 # TCP Transport
 #
+
+#
+# Websocket
+#
+CONFIG_WS_TRANSPORT=y
 CONFIG_WS_BUFFER_SIZE=1024
+# end of Websocket
 # end of TCP Transport
 
 #
@@ -1105,7 +1117,7 @@ CONFIG_WPA_MBEDTLS_CRYPTO=y
 # CONFIG_WPA_WAPI_PSK is not set
 # CONFIG_WPA_DEBUG_PRINT is not set
 # CONFIG_WPA_TESTING_OPTIONS is not set
-# CONFIG_WPA_WPS_WARS is not set
+# CONFIG_WPA_WPS_STRICT is not set
 # CONFIG_WPA_11KV_SUPPORT is not set
 # end of Supplicant