Sfoglia il codice sorgente

KBF-41 implement SSL certificate checking in http::Client

Bence Balint 2 anni fa
parent
commit
52645ab94c

+ 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;
 

+ 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));
+}

+ 4 - 4
src/http/server.cpp

@@ -43,13 +43,13 @@ http::Server &http::Server::startSSL(int port) {
     handle = nullptr;
     httpd_ssl_config_t conf = HTTPD_SSL_CONFIG_DEFAULT();
 
-    extern const unsigned char cacert_pem_start[] asm("_binary_cacert_pem_start");
-    extern const unsigned char cacert_pem_end[]   asm("_binary_cacert_pem_end");
+    extern const unsigned char cacert_pem_start[] asm("_binary_cert_pem_start");
+    extern const unsigned char cacert_pem_end[]   asm("_binary_cert_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");
+    extern const unsigned char prvtkey_pem_start[] asm("_binary_key_pem_start");
+    extern const unsigned char prvtkey_pem_end[]   asm("_binary_key_pem_end");
     conf.prvtkey_pem = prvtkey_pem_start;
     conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
 

+ 44 - 4
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,28 @@ 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");
+
+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();
@@ -25,10 +48,27 @@ TEST_CASE("HTTPS GET", "[kbf_http]") {
     server.startSSL();
     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();

+ 9 - 5
test_app/main/CMakeLists.txt

@@ -1,10 +1,14 @@
 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/cacert.pem"
+        "certs/prvtkey.pem"
+        "certs/cert.pem"
+        "certs/key.pem"
+        "certs/wrong_cert.pem"
+        "certs/wrong_key.pem"
 )
 
 spiffs_create_partition_image("storage" "spiffs" FLASH_IN_PROJECT)

+ 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-----

+ 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-----

+ 1 - 1
test_app/sdkconfig

@@ -277,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
 
 #