From 0aeb1d79b0a89e47c9982224af62c4cf4a6bf9e7 Mon Sep 17 00:00:00 2001 From: "sanket.wadekar" Date: Wed, 17 May 2023 17:27:23 +0530 Subject: [PATCH] feature: add a configurable option to read node id from device certificate. --- components/esp_rainmaker/Kconfig.projbuild | 7 ++++ .../src/core/esp_rmaker_client_data.h | 1 + .../esp_rainmaker/src/core/esp_rmaker_core.c | 41 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/components/esp_rainmaker/Kconfig.projbuild b/components/esp_rainmaker/Kconfig.projbuild index 3d723ff..0296dc6 100644 --- a/components/esp_rainmaker/Kconfig.projbuild +++ b/components/esp_rainmaker/Kconfig.projbuild @@ -76,6 +76,13 @@ menu "ESP RainMaker Config" ESP_RMAKER_MQTT_HOST, independent of this config option. However, if this is set, even if an MQTT host value is found in NVS, it will be overriden with ESP_RMAKER_MQTT_HOST. + config ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN + bool "Read Node ID from Device Certificate" + default n + help + If enabled, the device will get its node id from the device certificate's CN field. If not enabled, + it will read the node id either from nvs factory partition or mac address, depending on the configuration. + config ESP_RMAKER_MQTT_HOST string "ESP RainMaker MQTT Host" depends on ESP_RMAKER_SELF_CLAIM || ESP_RMAKER_ASSISTED_CLAIM || ESP_RMAKER_READ_MQTT_HOST_FROM_CONFIG diff --git a/components/esp_rainmaker/src/core/esp_rmaker_client_data.h b/components/esp_rainmaker/src/core/esp_rmaker_client_data.h index bbfb0ed..f89d573 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_client_data.h +++ b/components/esp_rainmaker/src/core/esp_rmaker_client_data.h @@ -22,6 +22,7 @@ #define ESP_RMAKER_CLIENT_RANDOM_NVS_KEY "random" char *esp_rmaker_get_client_cert(); +size_t esp_rmaker_get_client_cert_len(); char *esp_rmaker_get_client_key(); size_t esp_rmaker_get_client_key_len(); char *esp_rmaker_get_client_csr(); diff --git a/components/esp_rainmaker/src/core/esp_rmaker_core.c b/components/esp_rainmaker/src/core/esp_rmaker_core.c index 503c76c..609460f 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_core.c +++ b/components/esp_rainmaker/src/core/esp_rmaker_core.c @@ -118,9 +118,50 @@ static void esp_rmaker_mqtt_event_handler(void* arg, esp_event_base_t event_base } } +#ifdef CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN + +#include "mbedtls/x509_crt.h" +#include "mbedtls/oid.h" + +static char* esp_rmaker_populate_node_id_from_cert() +{ + void *addr = NULL; + size_t len = 0; + addr = esp_rmaker_get_client_cert(); + if (addr) { + len = esp_rmaker_get_client_cert_len(); + } else { + ESP_LOGE(TAG, "Failed to get device certificate."); + return NULL; + } + mbedtls_x509_crt crt; + mbedtls_x509_crt_init(&crt); + char *node_id = NULL; + int ret = mbedtls_x509_crt_parse(&crt, addr, len); + if (ret != 0) { + ESP_LOGE(TAG, "Parsing of device certificate failed, returned %02X", ret); + } else { + mbedtls_asn1_named_data *cn_data; + cn_data = mbedtls_asn1_find_named_data(&crt.subject, MBEDTLS_OID_AT_CN, + MBEDTLS_OID_SIZE(MBEDTLS_OID_AT_CN)); + if (cn_data) { + node_id = MEM_CALLOC_EXTRAM(1, cn_data->val.len + 1); + memcpy(node_id, (const char *)cn_data->val.p, cn_data->val.len); + } + } + mbedtls_x509_crt_free(&crt); + return node_id; +} +#endif + static char *esp_rmaker_populate_node_id(bool use_claiming) { +#ifdef CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN + char *node_id = esp_rmaker_populate_node_id_from_cert(); +#else /* !CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN */ char *node_id = esp_rmaker_factory_get("node_id"); +#endif /* CONFIG_ESP_RMAKER_READ_NODE_ID_FROM_CERT_CN */ + #ifdef ESP_RMAKER_CLAIM_ENABLED if (!node_id && use_claiming) { uint8_t eth_mac[6];