Submit CSR to server

This commit is contained in:
Pierre HUBERT 2024-08-23 23:06:14 +02:00
parent 3b7e2f9a0c
commit d890b23670
4 changed files with 130 additions and 7 deletions

View File

@ -128,6 +128,7 @@ char *http_client_exec(const http_request_opts *opts)
.url = opts->url, .url = opts->url,
.disable_auto_redirect = true, .disable_auto_redirect = true,
.cert_pem = opts->root_ca, .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); 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; 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_LOGD(TAG, "esp_http_client_perform start");
esp_err_t err = esp_http_client_perform(client); esp_err_t err = esp_http_client_perform(client);
ESP_LOGD(TAG, "esp_http_client_perform end"); 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) if (status < 200 || status > 299)
{ {
ESP_LOGE(TAG, "HTTP request failed with status %d!", status); 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); free(local_response_buffer);
return NULL; return NULL;
} }
@ -166,3 +183,68 @@ char *http_client_exec(const http_request_opts *opts)
return local_response_buffer; 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;
}

View File

@ -11,10 +11,19 @@ extern "C"
{ {
#endif #endif
enum method
{
MethodGET = 0,
MethodPOST
};
typedef struct typedef struct
{ {
const char *url; const char *url;
char *root_ca; char *root_ca;
const char *body;
const char *content_type;
enum method method;
} http_request_opts; } http_request_opts;
/** /**
@ -25,6 +34,13 @@ extern "C"
*/ */
char *http_client_exec(const http_request_opts *opts); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -126,11 +126,14 @@ void app_main(void)
// TODO : remove certificate if present // TODO : remove certificate if present
// Enroll device
ESP_LOGI(TAG, "Enroll device");
if (secure_api_enroll_device() != 0) if (secure_api_enroll_device() != 0)
{ {
ESP_LOGE(TAG, "Failed to enroll device!"); ESP_LOGE(TAG, "Failed to enroll device!");
reboot(); reboot();
} }
ESP_LOGI(TAG, "Requested device enrollment.");
break; break;
} }

View File

@ -3,11 +3,13 @@
#include <stdio.h> #include <stdio.h>
#include "secure_api.h" #include "secure_api.h"
#include "storage.h"
#include "http_client.h" #include "http_client.h"
#include "constants.h" #include "constants.h"
#include "crypto.h" #include "crypto.h"
#include "cJSON.h" #include "cJSON.h"
#include "dev_name.h"
#include "storage.h"
#include "http_client.h"
#include "esp_log.h" #include "esp_log.h"
@ -28,7 +30,10 @@ static char *process_secure_request(const char *uri, const char *body)
http_request_opts opts = { http_request_opts opts = {
.url = url, .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); char *res = http_client_exec(&opts);
free(url); free(url);
@ -42,10 +47,18 @@ enum DevEnrollmentStatus secure_api_get_device_enrollment_status()
ESP_LOGI(TAG, "Will check device enrollment status"); ESP_LOGI(TAG, "Will check device enrollment status");
// Prepare URI // 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); char *uri = calloc(1, 255);
assert(uri); assert(uri);
sprintf(uri, "/devices_api/mgmt/enrollment_status?id="); sprintf(uri, "/devices_api/mgmt/enrollment_status?id=%s", escaped_name);
assert(storage_get_dev_name(uri + strlen(uri)) > 0); free(escaped_name);
char *res = process_secure_request(uri, NULL); char *res = process_secure_request(uri, NULL);
@ -119,25 +132,34 @@ int secure_api_enroll_device()
if (!obj) if (!obj)
{ {
ESP_LOGE(TAG, "Failed allocate memory to store JSON object!"); ESP_LOGE(TAG, "Failed allocate memory to store JSON object!");
free(csr);
return 1; return 1;
} }
cJSON_AddItemToObject(obj, "info", genDevInfo()); cJSON_AddItemToObject(obj, "info", genDevInfo());
cJSON_AddStringToObject(obj, "csr", csr); cJSON_AddStringToObject(obj, "csr", csr);
free(csr);
char *body = cJSON_PrintUnformatted(obj); char *body = cJSON_PrintUnformatted(obj);
if (!body) if (!body)
{ {
ESP_LOGE(TAG, "Failed to generate JSON body!"); ESP_LOGE(TAG, "Failed to generate JSON body!");
cJSON_Delete(obj);
return 1; return 1;
} }
// TODO : perform request char *res = process_secure_request("/devices_api/mgmt/enroll", body);
printf("res = %s\n", body);
cJSON_Delete(obj); cJSON_Delete(obj);
free(body); free(body);
free(csr);
if (res == NULL)
{
ESP_LOGE(TAG, "Request failed!");
return 1;
}
free(res);
return 0; return 0;
} }