#include #include #include #include "secure_api.h" #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, const char *body) { 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, NULL); free(uri); if (res == NULL) { ESP_LOGE(TAG, "Failed to query device enrollment status!"); return DevEnrollError; } enum DevEnrollmentStatus s = DevEnrollError; cJSON *root = cJSON_Parse(res); if (root == NULL) { ESP_LOGE(TAG, "Failed to decode JSON response from server!"); goto fail; } cJSON *status = cJSON_GetObjectItem(root, "status"); if (status == NULL) { ESP_LOGE(TAG, "Status missing in response from server!"); goto fail; } if (!strcmp(status->valuestring, "Unknown")) s = DevEnrollUnknown; else if (!strcmp(status->valuestring, "Pending")) s = DevEnrollPending; else if (!strcmp(status->valuestring, "Validated")) s = DevEnrollValidated; else { ESP_LOGE(TAG, "Unknown enrollment status: %s", status->valuestring); goto fail; } fail: cJSON_Delete(root); 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; }