From d890b236704122c4b285db4782e9d0cfce10f0fe Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Fri, 23 Aug 2024 23:06:14 +0200 Subject: [PATCH] Submit CSR to server --- esp32_device/main/http_client.c | 82 +++++++++++++++++++++++++++++++++ esp32_device/main/http_client.h | 16 +++++++ esp32_device/main/main.c | 3 ++ esp32_device/main/secure_api.c | 36 ++++++++++++--- 4 files changed, 130 insertions(+), 7 deletions(-) diff --git a/esp32_device/main/http_client.c b/esp32_device/main/http_client.c index 91cbd40..f2c94c4 100644 --- a/esp32_device/main/http_client.c +++ b/esp32_device/main/http_client.c @@ -128,6 +128,7 @@ char *http_client_exec(const http_request_opts *opts) .url = opts->url, .disable_auto_redirect = true, .cert_pem = opts->root_ca, + .method = opts->method == MethodPOST ? HTTP_METHOD_POST : HTTP_METHOD_GET, }; esp_http_client_handle_t client = esp_http_client_init(&config); @@ -138,6 +139,16 @@ char *http_client_exec(const http_request_opts *opts) return NULL; } + if (opts->content_type) + { + esp_http_client_set_header(client, "Content-Type", opts->content_type); + } + + if (opts->body) + { + esp_http_client_set_post_field(client, opts->body, strlen(opts->body)); + } + ESP_LOGD(TAG, "esp_http_client_perform start"); esp_err_t err = esp_http_client_perform(client); ESP_LOGD(TAG, "esp_http_client_perform end"); @@ -158,6 +169,12 @@ char *http_client_exec(const http_request_opts *opts) if (status < 200 || status > 299) { ESP_LOGE(TAG, "HTTP request failed with status %d!", status); + + if (status > 299) + { + ESP_LOGI(TAG, "HTTP Response Body = %s", local_response_buffer); + } + free(local_response_buffer); return NULL; } @@ -165,4 +182,69 @@ char *http_client_exec(const http_request_opts *opts) local_response_buffer[resp_len] = 0; return local_response_buffer; +} + +static uint32_t uri[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0xd000002d, /* 1101 0000 0000 0000 0000 0000 0010 1101 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ +}; + +static u_char hex[] = "0123456789ABCDEF"; + +size_t http_client_escape_uri(unsigned char *dst, const u_char *src, size_t size) +{ + size_t n; + + if (dst == NULL) + { + /* find the number of the characters to be escaped */ + n = 0; + + while (size) + { + if (uri[*src >> 5] & (1U << (*src & 0x1f))) + { + n++; + n++; + } + src++; + size--; + n++; + } + + return n + 1; + } + + while (size) + { + if (uri[*src >> 5] & (1U << (*src & 0x1f))) + { + *dst++ = '%'; + *dst++ = hex[*src >> 4]; + *dst++ = hex[*src & 0xf]; + src++; + } + else + { + *dst++ = *src++; + } + size--; + } + + *dst++ = '\0'; + + return 0; } \ No newline at end of file diff --git a/esp32_device/main/http_client.h b/esp32_device/main/http_client.h index ff4eeaf..6c30040 100644 --- a/esp32_device/main/http_client.h +++ b/esp32_device/main/http_client.h @@ -11,10 +11,19 @@ extern "C" { #endif + enum method + { + MethodGET = 0, + MethodPOST + }; + typedef struct { const char *url; char *root_ca; + const char *body; + const char *content_type; + enum method method; } http_request_opts; /** @@ -25,6 +34,13 @@ extern "C" */ char *http_client_exec(const http_request_opts *opts); + /** + * Escape URI string + * + * See protocol_example_utils.c of esp32-idf + */ + size_t http_client_escape_uri(unsigned char *dst, const unsigned char *src, size_t size); + #ifdef __cplusplus } #endif diff --git a/esp32_device/main/main.c b/esp32_device/main/main.c index 752db95..000e294 100755 --- a/esp32_device/main/main.c +++ b/esp32_device/main/main.c @@ -126,11 +126,14 @@ void app_main(void) // TODO : remove certificate if present + // Enroll device + ESP_LOGI(TAG, "Enroll device"); if (secure_api_enroll_device() != 0) { ESP_LOGE(TAG, "Failed to enroll device!"); reboot(); } + ESP_LOGI(TAG, "Requested device enrollment."); break; } diff --git a/esp32_device/main/secure_api.c b/esp32_device/main/secure_api.c index 600b915..9a25dff 100644 --- a/esp32_device/main/secure_api.c +++ b/esp32_device/main/secure_api.c @@ -3,11 +3,13 @@ #include #include "secure_api.h" -#include "storage.h" #include "http_client.h" #include "constants.h" #include "crypto.h" #include "cJSON.h" +#include "dev_name.h" +#include "storage.h" +#include "http_client.h" #include "esp_log.h" @@ -28,7 +30,10 @@ static char *process_secure_request(const char *uri, const char *body) http_request_opts opts = { .url = url, - .root_ca = root_cat}; + .root_ca = root_cat, + .body = body, + .method = body == NULL ? MethodGET : MethodPOST, + .content_type = body == NULL ? NULL : "application/json"}; char *res = http_client_exec(&opts); free(url); @@ -42,10 +47,18 @@ enum DevEnrollmentStatus secure_api_get_device_enrollment_status() ESP_LOGI(TAG, "Will check device enrollment status"); // Prepare URI + unsigned char *name = (unsigned char *)dev_name(); + assert(name); + size_t escaped_name_len = http_client_escape_uri(NULL, name, strlen((char *)name)); + unsigned char *escaped_name = calloc(1, escaped_name_len + 1); + assert(escaped_name); + http_client_escape_uri(escaped_name, name, strlen((char *)name)); + free(name); + char *uri = calloc(1, 255); assert(uri); - sprintf(uri, "/devices_api/mgmt/enrollment_status?id="); - assert(storage_get_dev_name(uri + strlen(uri)) > 0); + sprintf(uri, "/devices_api/mgmt/enrollment_status?id=%s", escaped_name); + free(escaped_name); char *res = process_secure_request(uri, NULL); @@ -119,25 +132,34 @@ int secure_api_enroll_device() if (!obj) { ESP_LOGE(TAG, "Failed allocate memory to store JSON object!"); + free(csr); return 1; } cJSON_AddItemToObject(obj, "info", genDevInfo()); cJSON_AddStringToObject(obj, "csr", csr); + free(csr); char *body = cJSON_PrintUnformatted(obj); if (!body) { ESP_LOGE(TAG, "Failed to generate JSON body!"); + cJSON_Delete(obj); return 1; } - // TODO : perform request - printf("res = %s\n", body); + char *res = process_secure_request("/devices_api/mgmt/enroll", body); cJSON_Delete(obj); free(body); - free(csr); + + if (res == NULL) + { + ESP_LOGE(TAG, "Request failed!"); + return 1; + } + + free(res); return 0; } \ No newline at end of file