WIP enroll device
This commit is contained in:
		
							
								
								
									
										14
									
								
								esp32_device/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								esp32_device/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@@ -34,6 +34,18 @@
 | 
				
			|||||||
    "http_client.h": "c",
 | 
					    "http_client.h": "c",
 | 
				
			||||||
    "string.h": "c",
 | 
					    "string.h": "c",
 | 
				
			||||||
    "cjson.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"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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"
 | 
					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"
 | 
					                        "dev_name.c"
 | 
				
			||||||
                    INCLUDE_DIRS ".")
 | 
					                    INCLUDE_DIRS ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_compile_options(${COMPONENT_LIB} PRIVATE -Werror)
 | 
				
			||||||
@@ -1,5 +1,20 @@
 | 
				
			|||||||
#pragma once
 | 
					#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
 | 
					 * Backend unsecure API URL
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ extern "C"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    typedef struct
 | 
					    typedef struct
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        char *url;
 | 
					        const char *url;
 | 
				
			||||||
        char *root_ca;
 | 
					        char *root_ca;
 | 
				
			||||||
    } http_request_opts;
 | 
					    } http_request_opts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,11 +98,49 @@ void app_main(void)
 | 
				
			|||||||
    ESP_LOGI(TAG, "Current root CA:\n%s", root_ca);
 | 
					    ESP_LOGI(TAG, "Current root CA:\n%s", root_ca);
 | 
				
			||||||
    free(root_ca);
 | 
					    free(root_ca);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool validated = false;
 | 
				
			||||||
 | 
					    while (!validated)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        // Check current device enrollment status
 | 
					        // Check current device enrollment status
 | 
				
			||||||
        ESP_LOGI(TAG, "Check enrollment status");
 | 
					        ESP_LOGI(TAG, "Check enrollment status");
 | 
				
			||||||
    int status = secure_api_get_device_enrollment_status();
 | 
					        enum DevEnrollmentStatus status = secure_api_get_device_enrollment_status();
 | 
				
			||||||
        ESP_LOGI(TAG, "Current enrollment status: %d\n", 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);
 | 
					    system_sleep(120);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reboot();
 | 
					    reboot();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,13 +6,14 @@
 | 
				
			|||||||
#include "storage.h"
 | 
					#include "storage.h"
 | 
				
			||||||
#include "http_client.h"
 | 
					#include "http_client.h"
 | 
				
			||||||
#include "constants.h"
 | 
					#include "constants.h"
 | 
				
			||||||
 | 
					#include "crypto.h"
 | 
				
			||||||
#include "cJSON.h"
 | 
					#include "cJSON.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "esp_log.h"
 | 
					#include "esp_log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *TAG = "secure_api";
 | 
					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);
 | 
					    char *url = calloc(1, 255);
 | 
				
			||||||
    assert(url);
 | 
					    assert(url);
 | 
				
			||||||
@@ -46,7 +47,7 @@ enum DevEnrollmentStatus secure_api_get_device_enrollment_status()
 | 
				
			|||||||
    sprintf(uri, "/devices_api/mgmt/enrollment_status?id=");
 | 
					    sprintf(uri, "/devices_api/mgmt/enrollment_status?id=");
 | 
				
			||||||
    assert(storage_get_dev_name(uri + strlen(uri)) > 0);
 | 
					    assert(storage_get_dev_name(uri + strlen(uri)) > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char *res = process_secure_request(uri);
 | 
					    char *res = process_secure_request(uri, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    free(uri);
 | 
					    free(uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,3 +91,53 @@ fail:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return s;
 | 
					    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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -30,6 +30,11 @@ extern "C"
 | 
				
			|||||||
    enum DevEnrollmentStatus
 | 
					    enum DevEnrollmentStatus
 | 
				
			||||||
    secure_api_get_device_enrollment_status();
 | 
					    secure_api_get_device_enrollment_status();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Enroll device
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int secure_api_enroll_device();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,7 +66,7 @@ if status == "Unknown":
 | 
				
			|||||||
        csr = "".join(f.read())
 | 
					        csr = "".join(f.read())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    print("Enrolling device...")
 | 
					    print("Enrolling device...")
 | 
				
			||||||
    crt = api.enroll_device(csr)
 | 
					    api.enroll_device(csr)
 | 
				
			||||||
    print("Done. Please accept the device on central system web UI")
 | 
					    print("Done. Please accept the device on central system web UI")
 | 
				
			||||||
    exit(0)
 | 
					    exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user