From 3b5d2abcc0d98f07c435aa418f9aa610a2516a6d Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sun, 18 Aug 2024 20:13:03 +0200 Subject: [PATCH] Manage to perfom secure request --- esp32_device/main/CMakeLists.txt | 2 +- esp32_device/main/http_client.c | 1 + esp32_device/main/http_client.h | 1 + esp32_device/main/main.c | 15 ++++++++ esp32_device/main/secure_api.c | 62 ++++++++++++++++++++++++++++++++ esp32_device/main/secure_api.h | 35 ++++++++++++++++++ 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 esp32_device/main/secure_api.c create mode 100644 esp32_device/main/secure_api.h diff --git a/esp32_device/main/CMakeLists.txt b/esp32_device/main/CMakeLists.txt index 5135053..e64f73e 100755 --- a/esp32_device/main/CMakeLists.txt +++ b/esp32_device/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "http_client.c" "ethernet.c" "unsecure_api.c" "system.c" "crypto.c" "random.c" "storage.c" "main.c" +idf_component_register(SRCS "secure_api.c" "http_client.c" "ethernet.c" "unsecure_api.c" "system.c" "crypto.c" "random.c" "storage.c" "main.c" "dev_name.c" INCLUDE_DIRS ".") diff --git a/esp32_device/main/http_client.c b/esp32_device/main/http_client.c index 3fe5554..91cbd40 100644 --- a/esp32_device/main/http_client.c +++ b/esp32_device/main/http_client.c @@ -127,6 +127,7 @@ char *http_client_exec(const http_request_opts *opts) .user_data = local_response_buffer, .url = opts->url, .disable_auto_redirect = true, + .cert_pem = opts->root_ca, }; esp_http_client_handle_t client = esp_http_client_init(&config); diff --git a/esp32_device/main/http_client.h b/esp32_device/main/http_client.h index e70dc33..c730da5 100644 --- a/esp32_device/main/http_client.h +++ b/esp32_device/main/http_client.h @@ -14,6 +14,7 @@ extern "C" typedef struct { char *url; + char *root_ca; } http_request_opts; /** diff --git a/esp32_device/main/main.c b/esp32_device/main/main.c index dc0b64f..b835397 100755 --- a/esp32_device/main/main.c +++ b/esp32_device/main/main.c @@ -7,6 +7,7 @@ #include "system.h" #include "crypto.h" #include "unsecure_api.h" +#include "secure_api.h" #include "ethernet.h" #include "constants.h" @@ -18,12 +19,14 @@ void app_main(void) ESP_LOGI(TAG, "SolarEnergy WT32-ETH01 device"); + // Initialize storage if (storage_init() == false) { ESP_LOGE(TAG, "Failed to init storage!\n"); reboot(); } + // Give a name to the device if (dev_generate_name()) { ESP_LOGI(TAG, "Generated a new device name\n"); @@ -33,6 +36,7 @@ void app_main(void) ESP_LOGI(TAG, "Dev name: %s\n", name); free(name); + // Generate private key, if needed if (crypto_gen_priv_key()) { ESP_LOGI(TAG, "Generated device private key!\n"); @@ -40,14 +44,17 @@ void app_main(void) ESP_LOGI(TAG, "Device private key:\n"); crypto_print_priv_key(); + // Show current private key char *csr = crypto_get_csr(); ESP_LOGI(TAG, "Current CSR:\n%s\n", csr); free(csr); + // Initialize network stack ESP_LOGI(TAG, "Initialize network\n"); ethernet_init(); ethernet_wait_for_network(); + // Get if secure origin endpoint is known ESP_LOGI(TAG, "Check secure origin\n"); if (storage_get_secure_origin(NULL) == 0) { @@ -61,12 +68,14 @@ void app_main(void) free(sec_ori); } + // Print secure origin endpoint for debugging purposes ESP_LOGI(TAG, "Get secure origin\n"); char *sec_ori = calloc(SEC_ORIG_LEN, 1); assert(storage_get_secure_origin(sec_ori) > 0); ESP_LOGI(TAG, "Current secure origin: %s", sec_ori); free(sec_ori); + // Check if root CA is available locally ESP_LOGI(TAG, "Check root CA"); if (storage_get_root_ca(NULL) == 0) { @@ -80,12 +89,18 @@ void app_main(void) free(root_ca); } + // Print root CA for debugging purposes ESP_LOGI(TAG, "Get root CA"); char *root_ca = calloc(ROOT_CA_MAX_BYTES, 1); assert(storage_get_root_ca(root_ca) > 0); ESP_LOGI(TAG, "Current root CA:\n%s", root_ca); free(root_ca); + // Check current device enrollment status + ESP_LOGI(TAG, "Check enrollment status"); + int status = secure_api_get_device_enrollment_status(); + printf("Current enrollment status: %d\n", status); + system_sleep(120); reboot(); diff --git a/esp32_device/main/secure_api.c b/esp32_device/main/secure_api.c new file mode 100644 index 0000000..d4b2b8a --- /dev/null +++ b/esp32_device/main/secure_api.c @@ -0,0 +1,62 @@ +#include +#include +#include + +#include "secure_api.h" +#include "storage.h" +#include "http_client.h" +#include "constants.h" + +#include "esp_log.h" + +static const char *TAG = "secure_api"; + +static char *process_secure_request(const char *uri) +{ + char *url = calloc(1, 255); + assert(url); + size_t orig_len = storage_get_secure_origin(url); + assert(orig_len > 0); + strcat(url + strlen(url), uri); + ESP_LOGI(TAG, "HTTP request on %s", url); + + char *root_cat = calloc(1, ROOT_CA_MAX_BYTES); + assert(root_cat); + assert(storage_get_root_ca(root_cat) > 0); + + http_request_opts opts = { + .url = url, + .root_ca = root_cat}; + char *res = http_client_exec(&opts); + + free(url); + free(root_cat); + + return res; +} + +enum DevEnrollmentStatus secure_api_get_device_enrollment_status() +{ + ESP_LOGI(TAG, "Will check device enrollment status"); + + // Prepare URI + char *uri = calloc(1, 255); + assert(uri); + sprintf(uri, "/devices_api/mgmt/enrollment_status?id="); + assert(storage_get_dev_name(uri + strlen(uri)) > 0); + + char *res = process_secure_request(uri); + free(uri); + + if (res == NULL) + { + ESP_LOGE(TAG, "Failed to query device enrollment status!"); + return DevEnrollError; + } + + // TODO : parse reponse + printf("response = %s\n", res); + free(res); + + return DevEnrollError; +} \ No newline at end of file diff --git a/esp32_device/main/secure_api.h b/esp32_device/main/secure_api.h new file mode 100644 index 0000000..849e9ad --- /dev/null +++ b/esp32_device/main/secure_api.h @@ -0,0 +1,35 @@ +/** + * Secure API functions + */ + +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Device enrollment status + */ + enum DevEnrollmentStatus + { + /** An error occurred while retrieving device status */ + DevEnrollError, + /** Device is unknown by the backend */ + DevEnrollUnknown, + /** Device hasn't been validated yet */ + DevEnrollPending, + /** Device has been validated by the backend */ + DevEnrollValidated, + }; + + /** + * Get current device enrollment status + */ + enum DevEnrollmentStatus + secure_api_get_device_enrollment_status(); + +#ifdef __cplusplus +} +#endif