WIP enroll device

This commit is contained in:
Pierre HUBERT 2024-08-23 21:00:18 +02:00
parent dd0a957a63
commit 3b7e2f9a0c
8 changed files with 132 additions and 9 deletions

View File

@ -34,6 +34,18 @@
"http_client.h": "c",
"string.h": "c",
"cjson.h": "c",
"stddef.h": "c"
"stddef.h": "c",
"array": "c",
"chrono": "c",
"deque": "c",
"list": "c",
"string": "c",
"unordered_map": "c",
"vector": "c",
"iterator": "c",
"string_view": "c",
"format": "c",
"span": "c",
"regex": "c"
}
}

View File

@ -1,3 +1,5 @@
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 ".")
target_compile_options(${COMPONENT_LIB} PRIVATE -Werror)

View File

@ -1,5 +1,20 @@
#pragma once
/**
* Device reference
*/
#define DEV_REFERENCE "Wt32-Eth01"
/**
* Device version
*/
#define DEV_VERSION "0.0.1"
/**
* Device max number of relays
*/
#define DEV_MAX_RELAYS 1
/**
* Backend unsecure API URL
*/

View File

@ -13,7 +13,7 @@ extern "C"
typedef struct
{
char *url;
const char *url;
char *root_ca;
} http_request_opts;

View File

@ -98,11 +98,49 @@ void app_main(void)
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();
ESP_LOGI(TAG, "Current enrollment status: %d\n", status);
bool validated = false;
while (!validated)
{
// Check current device enrollment status
ESP_LOGI(TAG, "Check enrollment status");
enum DevEnrollmentStatus status = secure_api_get_device_enrollment_status();
ESP_LOGI(TAG, "Current enrollment status: %d\n", status);
switch (status)
{
case DevEnrollError:
ESP_LOGE(TAG, "Failed to retrieve device enrollment status!");
break;
case DevEnrollPending:
ESP_LOGI(TAG, "Device enrolled, but not validated yet. Please accept device on central system web UI");
break;
case DevEnrollValidated:
ESP_LOGI(TAG, "Device enrolled and validated. Ready to operate!");
validated = true;
break;
case DevEnrollUnknown:
ESP_LOGI(TAG, "Device unknown, need to enroll!");
// TODO : remove certificate if present
if (secure_api_enroll_device() != 0)
{
ESP_LOGE(TAG, "Failed to enroll device!");
reboot();
}
break;
}
// Wait before next try
system_sleep(60);
};
// TODO : retrieve certificate if missing
ESP_LOGI(TAG, "Starting main loop");
system_sleep(120);
reboot();

View File

@ -6,13 +6,14 @@
#include "storage.h"
#include "http_client.h"
#include "constants.h"
#include "crypto.h"
#include "cJSON.h"
#include "esp_log.h"
static const char *TAG = "secure_api";
static char *process_secure_request(const char *uri)
static char *process_secure_request(const char *uri, const char *body)
{
char *url = calloc(1, 255);
assert(url);
@ -46,7 +47,7 @@ enum DevEnrollmentStatus secure_api_get_device_enrollment_status()
sprintf(uri, "/devices_api/mgmt/enrollment_status?id=");
assert(storage_get_dev_name(uri + strlen(uri)) > 0);
char *res = process_secure_request(uri);
char *res = process_secure_request(uri, NULL);
free(uri);
@ -89,4 +90,54 @@ fail:
free(res);
return s;
}
/**
* Generate device information. Pointer to be released by caller
*/
static cJSON *genDevInfo()
{
cJSON *json = cJSON_CreateObject();
if (!json)
return NULL;
cJSON_AddStringToObject(json, "reference", DEV_REFERENCE);
cJSON_AddStringToObject(json, "version", DEV_VERSION);
cJSON_AddNumberToObject(json, "max_relays", DEV_MAX_RELAYS);
return json;
}
int secure_api_enroll_device()
{
char *csr = crypto_get_csr();
if (!csr)
{
ESP_LOGE(TAG, "Failed to get CSR!");
return 1;
}
cJSON *obj = cJSON_CreateObject();
if (!obj)
{
ESP_LOGE(TAG, "Failed allocate memory to store JSON object!");
return 1;
}
cJSON_AddItemToObject(obj, "info", genDevInfo());
cJSON_AddStringToObject(obj, "csr", csr);
char *body = cJSON_PrintUnformatted(obj);
if (!body)
{
ESP_LOGE(TAG, "Failed to generate JSON body!");
return 1;
}
// TODO : perform request
printf("res = %s\n", body);
cJSON_Delete(obj);
free(body);
free(csr);
return 0;
}

View File

@ -30,6 +30,11 @@ extern "C"
enum DevEnrollmentStatus
secure_api_get_device_enrollment_status();
/**
* Enroll device
*/
int secure_api_enroll_device();
#ifdef __cplusplus
}
#endif

View File

@ -66,7 +66,7 @@ if status == "Unknown":
csr = "".join(f.read())
print("Enrolling device...")
crt = api.enroll_device(csr)
api.enroll_device(csr)
print("Done. Please accept the device on central system web UI")
exit(0)