Merge pull request #12562 from kaspar030/pr/suit_v4_nanocbor
sys/suit/v4: switch to nanocbor
This commit is contained in:
commit
afecb9aa7a
@ -937,7 +937,7 @@ ifneq (,$(filter suit_v4_%,$(USEMODULE)))
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter suit_v4,$(USEMODULE)))
|
ifneq (,$(filter suit_v4,$(USEMODULE)))
|
||||||
USEPKG += tinycbor
|
USEPKG += nanocbor
|
||||||
USEPKG += libcose
|
USEPKG += libcose
|
||||||
USEMODULE += libcose_crypt_c25519
|
USEMODULE += libcose_crypt_c25519
|
||||||
USEMODULE += suit_conditions
|
USEMODULE += suit_conditions
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "suit/v4/suit.h"
|
#include "suit/v4/suit.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "cbor.h"
|
#include "nanocbor/nanocbor.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -39,12 +39,12 @@ extern "C" {
|
|||||||
* @brief suit handler prototype
|
* @brief suit handler prototype
|
||||||
*
|
*
|
||||||
* @param manifest SUIT v4 manifest context
|
* @param manifest SUIT v4 manifest context
|
||||||
* @param it CborValue iterator to the content the handler must handle
|
* @param it nanocbor_value_t iterator to the content the handler must handle
|
||||||
*
|
*
|
||||||
* @return 1 on success
|
* @return 1 on success
|
||||||
* @return negative on error
|
* @return negative on error
|
||||||
*/
|
*/
|
||||||
typedef int (*suit_manifest_handler_t)(suit_v4_manifest_t *manifest, int key, CborValue *it);
|
typedef int (*suit_manifest_handler_t)(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get suit manifest handler for given integer key
|
* @brief Get suit manifest handler for given integer key
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "cose/sign.h"
|
#include "cose/sign.h"
|
||||||
#include "cbor.h"
|
#include "nanocbor/nanocbor.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "riotboot/flashwrite.h"
|
#include "riotboot/flashwrite.h"
|
||||||
|
|
||||||
@ -73,11 +73,6 @@ typedef enum {
|
|||||||
SUIT_ERR_SIGNATURE = -6, /**< Unable to verify signature */
|
SUIT_ERR_SIGNATURE = -6, /**< Unable to verify signature */
|
||||||
} suit_v4_error_t;
|
} suit_v4_error_t;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TinyCBOR validation mode to use
|
|
||||||
*/
|
|
||||||
#define SUIT_TINYCBOR_VALIDATION_MODE CborValidateStrictMode
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SUIT payload digest algorithms
|
* @brief SUIT payload digest algorithms
|
||||||
*
|
*
|
||||||
@ -121,9 +116,9 @@ enum {
|
|||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t size; /**< Size */
|
uint32_t size; /**< Size */
|
||||||
CborValue identifier; /**< Identifier*/
|
nanocbor_value_t identifier; /**< Identifier*/
|
||||||
CborValue url; /**< Url */
|
nanocbor_value_t url; /**< Url */
|
||||||
CborValue digest; /**< Digest */
|
nanocbor_value_t digest; /**< Digest */
|
||||||
} suit_v4_component_t;
|
} suit_v4_component_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +134,7 @@ typedef struct {
|
|||||||
/** List of components in the manifest */
|
/** List of components in the manifest */
|
||||||
suit_v4_component_t components[SUIT_V4_COMPONENT_MAX];
|
suit_v4_component_t components[SUIT_V4_COMPONENT_MAX];
|
||||||
unsigned components_len; /**< Current number of components */
|
unsigned components_len; /**< Current number of components */
|
||||||
int component_current; /**< Current component index */
|
int32_t component_current; /**< Current component index */
|
||||||
riotboot_flashwrite_t *writer; /**< Pointer to the riotboot flash writer */
|
riotboot_flashwrite_t *writer; /**< Pointer to the riotboot flash writer */
|
||||||
/** Manifest validation buffer */
|
/** Manifest validation buffer */
|
||||||
uint8_t validation_buf[SUIT_COSE_BUF_SIZE];
|
uint8_t validation_buf[SUIT_COSE_BUF_SIZE];
|
||||||
@ -191,7 +186,7 @@ int suit_v4_policy_check(suit_v4_manifest_t *manifest);
|
|||||||
* @return SUIT_OK when initialization is successful
|
* @return SUIT_OK when initialization is successful
|
||||||
* @return SUIT_ERR_INVALID_MANIFEST if the manifest is not a cbor container
|
* @return SUIT_ERR_INVALID_MANIFEST if the manifest is not a cbor container
|
||||||
*/
|
*/
|
||||||
int suit_cbor_map_iterate_init(CborValue *map, CborValue *it);
|
int suit_cbor_map_iterate_init(nanocbor_value_t *map, nanocbor_value_t *it);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Iterate over a cbor map container
|
* @brief Iterate over a cbor map container
|
||||||
@ -203,10 +198,10 @@ int suit_cbor_map_iterate_init(CborValue *map, CborValue *it);
|
|||||||
* @return 0 when the iterator is already at the end of the container
|
* @return 0 when the iterator is already at the end of the container
|
||||||
* @return the number of returned (key, value) pair, e.g. 1
|
* @return the number of returned (key, value) pair, e.g. 1
|
||||||
*/
|
*/
|
||||||
int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value);
|
int suit_cbor_map_iterate(nanocbor_value_t *it, nanocbor_value_t *key, nanocbor_value_t *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get cbor value as int
|
* @brief Get cbor value as int32_t
|
||||||
*
|
*
|
||||||
* @param[in] it cbor container iterator
|
* @param[in] it cbor container iterator
|
||||||
* @param[out] out address of the returned integer
|
* @param[out] out address of the returned integer
|
||||||
@ -214,7 +209,7 @@ int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value);
|
|||||||
* @return SUIT_OK on success
|
* @return SUIT_OK on success
|
||||||
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit in an int
|
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit in an int
|
||||||
*/
|
*/
|
||||||
int suit_cbor_get_int(const CborValue *it, int *out);
|
int suit_cbor_get_int32(nanocbor_value_t *it, int32_t *out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get cbor value as unsigned
|
* @brief Get cbor value as unsigned
|
||||||
@ -226,7 +221,7 @@ int suit_cbor_get_int(const CborValue *it, int *out);
|
|||||||
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot
|
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot
|
||||||
* be converted to unsigned
|
* be converted to unsigned
|
||||||
*/
|
*/
|
||||||
int suit_cbor_get_uint(const CborValue *it, unsigned *out);
|
int suit_cbor_get_uint(nanocbor_value_t *it, unsigned *out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get cbor value as unsigned long
|
* @brief Get cbor value as unsigned long
|
||||||
@ -238,7 +233,7 @@ int suit_cbor_get_uint(const CborValue *it, unsigned *out);
|
|||||||
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot
|
* @return SUIT_ERR_INVALID_MANIFEST if value doesn't fit or cannot
|
||||||
* be converted to unsigned long
|
* be converted to unsigned long
|
||||||
*/
|
*/
|
||||||
int suit_cbor_get_uint32(const CborValue *it, uint32_t *out);
|
int suit_cbor_get_uint32(nanocbor_value_t *it, uint32_t *out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get cbor value as string
|
* @brief Get cbor value as string
|
||||||
@ -250,20 +245,19 @@ int suit_cbor_get_uint32(const CborValue *it, uint32_t *out);
|
|||||||
* @return SUIT_OK on success
|
* @return SUIT_OK on success
|
||||||
* @return SUIT_ERR_INVALID_MANIFEST if value is not a valid string
|
* @return SUIT_ERR_INVALID_MANIFEST if value is not a valid string
|
||||||
*/
|
*/
|
||||||
int suit_cbor_get_string(const CborValue *it, const uint8_t **buf, size_t *len);
|
int suit_cbor_get_string(nanocbor_value_t *it, const uint8_t **buf, size_t *len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parser a cbor subsequence
|
* @brief Parser a cbor subsequence
|
||||||
*
|
*
|
||||||
* @param[in] parser ptr to cbor subparser
|
* @param[in] bseq subsequence value
|
||||||
* @param[out] bseq subsequence value
|
|
||||||
* @param[out] it cbor iterator
|
* @param[out] it cbor iterator
|
||||||
*
|
*
|
||||||
* @return 0 on success
|
* @return 0 on success
|
||||||
* @return -1 if bseq is not a cbor string
|
* @return -1 if bseq is not a cbor string
|
||||||
* @return CborError code on other cbor parser errors
|
* @return CborError code on other cbor parser errors
|
||||||
*/
|
*/
|
||||||
int suit_cbor_subparse(CborParser *parser, CborValue *bseq, CborValue *it);
|
int suit_cbor_subparse(nanocbor_value_t *bseq, nanocbor_value_t *it);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper function for writing bytes on flash a specified offset
|
* @brief Helper function for writing bytes on flash a specified offset
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
#include "suit/v4/handlers.h"
|
#include "suit/v4/handlers.h"
|
||||||
#include "suit/v4/suit.h"
|
#include "suit/v4/suit.h"
|
||||||
#include "suit/v4/policy.h"
|
#include "suit/v4/policy.h"
|
||||||
#include "cbor.h"
|
#include "nanocbor/nanocbor.h"
|
||||||
#include "cose/sign.h"
|
#include "cose/sign.h"
|
||||||
|
|
||||||
#include "public_key.h"
|
#include "public_key.h"
|
||||||
@ -40,135 +40,116 @@
|
|||||||
static suit_manifest_handler_t _manifest_get_auth_wrapper_handler(int key);
|
static suit_manifest_handler_t _manifest_get_auth_wrapper_handler(int key);
|
||||||
typedef suit_manifest_handler_t (*suit_manifest_handler_getter_t)(int key);
|
typedef suit_manifest_handler_t (*suit_manifest_handler_getter_t)(int key);
|
||||||
|
|
||||||
int suit_cbor_map_iterate_init(CborValue *map, CborValue *it)
|
int suit_cbor_map_iterate_init(nanocbor_value_t *map, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
if (!cbor_value_is_map(map)) {
|
if (nanocbor_get_type(map) != NANOCBOR_TYPE_MAP) {
|
||||||
LOG_INFO("suit_v4_parse(): manifest not a map\n)");
|
LOG_INFO("suit_v4_parse(): manifest not a map\n)");
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbor_value_enter_container(map, it);
|
nanocbor_enter_map(map, it);
|
||||||
|
|
||||||
return SUIT_OK;
|
return SUIT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int suit_cbor_map_iterate(CborValue *it, CborValue *key, CborValue *value)
|
int suit_cbor_map_iterate(nanocbor_value_t *it, nanocbor_value_t *key,
|
||||||
|
nanocbor_value_t *value)
|
||||||
{
|
{
|
||||||
if (cbor_value_at_end(it)) {
|
if (nanocbor_at_end(it)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*key = *it;
|
*key = *it;
|
||||||
cbor_value_advance(it);
|
nanocbor_skip(it);
|
||||||
|
|
||||||
*value = *it;
|
*value = *it;
|
||||||
cbor_value_advance(it);
|
nanocbor_skip(it);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int suit_cbor_get_int(const CborValue *it, int *out)
|
int suit_cbor_get_int32(nanocbor_value_t *it, int32_t *out)
|
||||||
{
|
{
|
||||||
if (!cbor_value_is_integer(it)) {
|
int res = nanocbor_get_int32(it, out);
|
||||||
LOG_DEBUG("expected integer type, got %u\n", cbor_value_get_type(it));
|
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This check tests whether the integer fits into "int", thus the check
|
if (res < NANOCBOR_OK) {
|
||||||
* is platform dependent. This is for lack of specification of actually
|
LOG_DEBUG("suit_cbor_get_int32() error %u\n", res);
|
||||||
* allowed values, to be made explicit at some point. */
|
|
||||||
if (cbor_value_get_int_checked(it, out) == CborErrorDataTooLarge) {
|
|
||||||
LOG_DEBUG("integer doesn't fit into int type\n");
|
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUIT_OK;
|
return SUIT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int suit_cbor_get_string(const CborValue *it, const uint8_t **buf, size_t *len)
|
int suit_cbor_get_string(nanocbor_value_t *it, const uint8_t **buf, size_t *len)
|
||||||
{
|
{
|
||||||
if (!(cbor_value_is_text_string(it) || cbor_value_is_byte_string(it) || cbor_value_is_length_known(it))) {
|
if (nanocbor_get_type(it) == NANOCBOR_TYPE_TSTR) {
|
||||||
|
if (nanocbor_get_tstr(it, buf, len) < 0) {
|
||||||
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
|
}
|
||||||
|
return SUIT_OK;
|
||||||
|
}
|
||||||
|
else if (nanocbor_get_type(it) == NANOCBOR_TYPE_BSTR) {
|
||||||
|
if (nanocbor_get_bstr(it, buf, len) < 0) {
|
||||||
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
|
}
|
||||||
|
return SUIT_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_DEBUG("suit_cbor_get_string(): unexpected type: %i\n",
|
||||||
|
nanocbor_get_type(it));
|
||||||
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int suit_cbor_get_uint32(nanocbor_value_t *it, uint32_t *out)
|
||||||
|
{
|
||||||
|
if (nanocbor_get_uint32(it, out) < 0) {
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
CborValue next = *it;
|
|
||||||
cbor_value_get_string_length(it, len);
|
|
||||||
cbor_value_advance(&next);
|
|
||||||
*buf = next.ptr - *len;
|
|
||||||
return SUIT_OK;
|
return SUIT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int suit_cbor_get_uint32(const CborValue *it, uint32_t *out)
|
int suit_cbor_get_uint(nanocbor_value_t *it, unsigned *out)
|
||||||
{
|
|
||||||
int res;
|
|
||||||
int64_t val;
|
|
||||||
if (!cbor_value_is_unsigned_integer(it)) {
|
|
||||||
return CborErrorIllegalType;
|
|
||||||
}
|
|
||||||
if ((res = cbor_value_get_int64_checked(it, &val))) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
if (val > 0xFFFFFFFF) {
|
|
||||||
return CborErrorDataTooLarge;
|
|
||||||
}
|
|
||||||
*out = (val & 0xFFFFFFFF);
|
|
||||||
|
|
||||||
return CborNoError;
|
|
||||||
}
|
|
||||||
|
|
||||||
int suit_cbor_get_uint(const CborValue *it, unsigned *out)
|
|
||||||
{
|
{
|
||||||
return suit_cbor_get_uint32(it, (uint32_t *)out);
|
return suit_cbor_get_uint32(it, (uint32_t *)out);
|
||||||
}
|
}
|
||||||
|
|
||||||
int suit_cbor_subparse(CborParser *parser, CborValue *bseq, CborValue *it)
|
int suit_cbor_subparse(nanocbor_value_t *bseq, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
const uint8_t *bytes;
|
const uint8_t *bytes;
|
||||||
size_t bytes_len = 0;
|
size_t bytes_len = 0;
|
||||||
|
int res = suit_cbor_get_string(bseq, &bytes, &bytes_len);
|
||||||
if (!cbor_value_is_byte_string(bseq)) {
|
if (res != SUIT_OK) {
|
||||||
LOG_DEBUG("suit_cbor_subparse(): bseq not a byte string\n");
|
return res;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
nanocbor_decoder_init(it, bytes, bytes_len);
|
||||||
suit_cbor_get_string(bseq, &bytes, &bytes_len);
|
return SUIT_OK;
|
||||||
|
|
||||||
return cbor_parser_init(bytes, bytes_len, SUIT_TINYCBOR_VALIDATION_MODE, parser,
|
|
||||||
it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf,
|
static int _v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf,
|
||||||
size_t len, suit_manifest_handler_getter_t getter)
|
size_t len, suit_manifest_handler_getter_t getter)
|
||||||
{
|
{
|
||||||
|
nanocbor_value_t it, map, key, value;
|
||||||
|
|
||||||
CborParser parser;
|
nanocbor_decoder_init(&it, buf, len);
|
||||||
CborValue it, map, key, value;
|
|
||||||
CborError err = cbor_parser_init(buf, len, SUIT_TINYCBOR_VALIDATION_MODE,
|
|
||||||
&parser, &it);
|
|
||||||
|
|
||||||
if (err != 0) {
|
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
map = it;
|
map = it;
|
||||||
|
|
||||||
if (suit_cbor_map_iterate_init(&map, &it) != SUIT_OK) {
|
if (suit_cbor_map_iterate_init(&map, &it) != SUIT_OK) {
|
||||||
LOG_DEBUG("manifest not a map!\n");
|
LOG_DEBUG("suit _v4_parse(): manifest not a map!\n");
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("jumping into map\n)");
|
|
||||||
|
|
||||||
while (suit_cbor_map_iterate(&it, &key, &value)) {
|
while (suit_cbor_map_iterate(&it, &key, &value)) {
|
||||||
int integer_key;
|
int32_t integer_key;
|
||||||
if (suit_cbor_get_int(&key, &integer_key) != SUIT_OK){
|
if (suit_cbor_get_int32(&key, &integer_key) != SUIT_OK) {
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("got key val=%i\n", integer_key);
|
LOG_DEBUG("got key val=%" PRIi32 "\n", integer_key);
|
||||||
suit_manifest_handler_t handler = getter(integer_key);
|
suit_manifest_handler_t handler = getter(integer_key);
|
||||||
|
|
||||||
if (handler) {
|
if (handler) {
|
||||||
int res = handler(manifest, integer_key, &value);
|
int res = handler(manifest, integer_key, &value);
|
||||||
LOG_DEBUG("handler res=%i\n", res);
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
LOG_INFO("handler returned <0\n)");
|
LOG_INFO("handler returned <0\n)");
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
@ -179,7 +160,7 @@ static int _v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cbor_value_leave_container(&map, &it);
|
nanocbor_leave_container(&map, &it);
|
||||||
|
|
||||||
return SUIT_OK;
|
return SUIT_OK;
|
||||||
}
|
}
|
||||||
@ -192,7 +173,8 @@ int suit_v4_parse(suit_v4_manifest_t *manifest, const uint8_t *buf,
|
|||||||
return _v4_parse(manifest, buf, len, _manifest_get_auth_wrapper_handler);
|
return _v4_parse(manifest, buf, len, _manifest_get_auth_wrapper_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _auth_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _auth_handler(suit_v4_manifest_t *manifest, int key,
|
||||||
|
nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
const uint8_t *cose_buf;
|
const uint8_t *cose_buf;
|
||||||
@ -211,7 +193,8 @@ static int _auth_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _manifest_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _manifest_handler(suit_v4_manifest_t *manifest, int key,
|
||||||
|
nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
const uint8_t *manifest_buf;
|
const uint8_t *manifest_buf;
|
||||||
@ -238,7 +221,8 @@ static int _manifest_handler(suit_v4_manifest_t *manifest, int key, CborValue *i
|
|||||||
|
|
||||||
LOG_INFO("suit: verifying manifest signature...\n");
|
LOG_INFO("suit: verifying manifest signature...\n");
|
||||||
int verification = cose_sign_verify(&manifest->verify, &signature,
|
int verification = cose_sign_verify(&manifest->verify, &signature,
|
||||||
&pkey, manifest->validation_buf, SUIT_COSE_BUF_SIZE);
|
&pkey, manifest->validation_buf,
|
||||||
|
SUIT_COSE_BUF_SIZE);
|
||||||
if (verification != 0) {
|
if (verification != 0) {
|
||||||
LOG_INFO("Unable to validate signature\n");
|
LOG_INFO("Unable to validate signature\n");
|
||||||
return SUIT_ERR_SIGNATURE;
|
return SUIT_ERR_SIGNATURE;
|
||||||
|
|||||||
@ -27,50 +27,52 @@
|
|||||||
#include "suit/v4/suit.h"
|
#include "suit/v4/suit.h"
|
||||||
#include "riotboot/hdr.h"
|
#include "riotboot/hdr.h"
|
||||||
#include "riotboot/slot.h"
|
#include "riotboot/slot.h"
|
||||||
#include "cbor.h"
|
#include <nanocbor/nanocbor.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#define HELLO_HANDLER_MAX_STRLEN 32
|
#define HELLO_HANDLER_MAX_STRLEN 32
|
||||||
|
|
||||||
static int _handle_command_sequence(suit_v4_manifest_t *manifest, CborValue *it,
|
static int _handle_command_sequence(suit_v4_manifest_t *manifest, nanocbor_value_t *it,
|
||||||
suit_manifest_handler_t handler);
|
suit_manifest_handler_t handler);
|
||||||
static int _common_handler(suit_v4_manifest_t *manifest, int key, CborValue *it);
|
static int _common_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it);
|
||||||
static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, CborValue *it);
|
static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it);
|
||||||
|
|
||||||
static int _hello_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _hello_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)manifest;
|
(void)manifest;
|
||||||
(void)key;
|
(void)key;
|
||||||
|
|
||||||
if (cbor_value_is_text_string(it)) {
|
if (nanocbor_get_type(it) == NANOCBOR_TYPE_TSTR) {
|
||||||
size_t len = HELLO_HANDLER_MAX_STRLEN;
|
size_t len = HELLO_HANDLER_MAX_STRLEN;
|
||||||
char buf[HELLO_HANDLER_MAX_STRLEN];
|
char buf[HELLO_HANDLER_MAX_STRLEN];
|
||||||
cbor_value_copy_text_string(it, buf, &len, NULL);
|
nanocbor_get_tstr(it, ((const uint8_t **) &buf), &len);
|
||||||
return SUIT_OK;
|
return SUIT_OK;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_DEBUG("_hello_handler(): unexpected value type: %u\n", cbor_value_get_type(
|
LOG_DEBUG("_hello_handler(): unexpected value type: %u\n", nanocbor_get_type(it));
|
||||||
it));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _validate_uuid(suit_v4_manifest_t *manifest, CborValue *it, uuid_t *uuid)
|
static int _validate_uuid(suit_v4_manifest_t *manifest, nanocbor_value_t *it, uuid_t *uuid)
|
||||||
{
|
{
|
||||||
(void)manifest;
|
(void)manifest;
|
||||||
uuid_t uuid_manifest;
|
const uint8_t *uuid_manifest_ptr;
|
||||||
|
size_t len = sizeof(uuid_t);
|
||||||
char uuid_str[UUID_STR_LEN + 1];
|
char uuid_str[UUID_STR_LEN + 1];
|
||||||
char uuid_str2[UUID_STR_LEN + 1];
|
char uuid_str2[UUID_STR_LEN + 1];
|
||||||
size_t len = sizeof(uuid_t);
|
if (suit_cbor_get_string(it, &uuid_manifest_ptr, &len) != SUIT_OK) {
|
||||||
cbor_value_copy_byte_string(it, (uint8_t*)&uuid_manifest, &len, NULL);
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
uuid_to_string(&uuid_manifest, uuid_str);
|
|
||||||
uuid_to_string(uuid, uuid_str2);
|
|
||||||
LOG_INFO("Comparing %s to %s from manifest\n", uuid_str2, uuid_str);
|
|
||||||
return uuid_equal(uuid, &uuid_manifest) ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cond_vendor_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
uuid_to_string((uuid_t *)uuid_manifest_ptr, uuid_str);
|
||||||
|
uuid_to_string(uuid, uuid_str2);
|
||||||
|
LOG_INFO("Comparing %s to %s from manifest\n", uuid_str2, uuid_str);
|
||||||
|
return uuid_equal(uuid, (uuid_t *)uuid_manifest_ptr) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _cond_vendor_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
LOG_INFO("validating vendor ID\n");
|
LOG_INFO("validating vendor ID\n");
|
||||||
@ -82,7 +84,7 @@ static int _cond_vendor_handler(suit_v4_manifest_t *manifest, int key, CborValue
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cond_class_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _cond_class_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
LOG_INFO("validating class id\n");
|
LOG_INFO("validating class id\n");
|
||||||
@ -94,7 +96,7 @@ static int _cond_class_handler(suit_v4_manifest_t *manifest, int key, CborValue
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _cond_comp_offset(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _cond_comp_offset(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)manifest;
|
(void)manifest;
|
||||||
(void)key;
|
(void)key;
|
||||||
@ -107,21 +109,22 @@ static int _cond_comp_offset(suit_v4_manifest_t *manifest, int key, CborValue *i
|
|||||||
return other_offset == offset ? 0 : -1;
|
return other_offset == offset ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dtv_set_comp_idx(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _dtv_set_comp_idx(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
if (cbor_value_is_boolean(it)) {
|
if (nanocbor_get_type(it) == NANOCBOR_TYPE_FLOAT) {
|
||||||
LOG_DEBUG("_dtv_set_comp_idx() ignoring boolean\n)");
|
LOG_DEBUG("_dtv_set_comp_idx() ignoring boolean and floats\n)");
|
||||||
|
nanocbor_skip(it);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int res = suit_cbor_get_int(it, &manifest->component_current);
|
int res = suit_cbor_get_int32(it, &manifest->component_current);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
LOG_DEBUG("Setting component index to %d\n", manifest->component_current);
|
LOG_DEBUG("Setting component index to %d\n", (int)manifest->component_current);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dtv_run_seq_cond(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _dtv_run_seq_cond(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
LOG_DEBUG("Starting conditional sequence handler\n");
|
LOG_DEBUG("Starting conditional sequence handler\n");
|
||||||
@ -129,20 +132,20 @@ static int _dtv_run_seq_cond(suit_v4_manifest_t *manifest, int key, CborValue *i
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _param_get_uri_list(suit_v4_manifest_t *manifest, CborValue *it)
|
static int _param_get_uri_list(suit_v4_manifest_t *manifest, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("got url list\n");
|
LOG_DEBUG("got url list\n");
|
||||||
manifest->components[manifest->component_current].url = *it;
|
manifest->components[manifest->component_current].url = *it;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int _param_get_digest(suit_v4_manifest_t *manifest, CborValue *it)
|
static int _param_get_digest(suit_v4_manifest_t *manifest, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("got digest\n");
|
LOG_DEBUG("got digest\n");
|
||||||
manifest->components[manifest->component_current].digest = *it;
|
manifest->components[manifest->component_current].digest = *it;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _param_get_img_size(suit_v4_manifest_t *manifest, CborValue *it)
|
static int _param_get_img_size(suit_v4_manifest_t *manifest, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
int res = suit_cbor_get_uint32(it, &manifest->components[0].size);
|
int res = suit_cbor_get_uint32(it, &manifest->components[0].size);
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -152,21 +155,20 @@ static int _param_get_img_size(suit_v4_manifest_t *manifest, CborValue *it)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
/* `it` points to the entry of the map containing the type and value */
|
/* `it` points to the entry of the map containing the type and value */
|
||||||
CborValue map;
|
nanocbor_value_t map;
|
||||||
|
|
||||||
cbor_value_enter_container(it, &map);
|
nanocbor_enter_map(it, &map);
|
||||||
|
|
||||||
while (!cbor_value_at_end(&map)) {
|
while (!nanocbor_at_end(&map)) {
|
||||||
/* map points to the key of the param */
|
/* map points to the key of the param */
|
||||||
int param_key;
|
int32_t param_key;
|
||||||
suit_cbor_get_int(&map, ¶m_key);
|
suit_cbor_get_int32(&map, ¶m_key);
|
||||||
cbor_value_advance(&map);
|
LOG_DEBUG("Setting component index to %" PRIi32 "\n", manifest->component_current);
|
||||||
LOG_DEBUG("Setting component index to %d\n", manifest->component_current);
|
LOG_DEBUG("param_key=%" PRIi32 "\n", param_key);
|
||||||
LOG_DEBUG("param_key=%i\n", param_key);
|
|
||||||
int res;
|
int res;
|
||||||
switch (param_key) {
|
switch (param_key) {
|
||||||
case 6: /* SUIT URI LIST */
|
case 6: /* SUIT URI LIST */
|
||||||
@ -182,7 +184,7 @@ static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
|||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbor_value_advance(&map);
|
nanocbor_skip(&map);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
return res;
|
return res;
|
||||||
@ -191,7 +193,7 @@ static int _dtv_set_param(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
|||||||
return SUIT_OK;
|
return SUIT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it)
|
static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *_it)
|
||||||
{
|
{
|
||||||
(void)key; (void)_it; (void)manifest;
|
(void)key; (void)_it; (void)manifest;
|
||||||
LOG_DEBUG("_dtv_fetch() key=%i\n", key);
|
LOG_DEBUG("_dtv_fetch() key=%i\n", key);
|
||||||
@ -205,39 +207,40 @@ static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it)
|
|||||||
* (priority, url) tuples (represented as array with length two)
|
* (priority, url) tuples (represented as array with length two)
|
||||||
* */
|
* */
|
||||||
|
|
||||||
CborParser parser;
|
nanocbor_value_t it;
|
||||||
CborValue it;
|
|
||||||
|
|
||||||
/* open sequence with cbor parser */
|
/* open sequence with cbor parser */
|
||||||
int err = suit_cbor_subparse(&parser, &manifest->components[0].url, &it);
|
int err = suit_cbor_subparse(&manifest->components[0].url, &it);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
LOG_DEBUG("subparse failed\n)");
|
LOG_DEBUG("subparse failed\n)");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* confirm the document contains an array */
|
/* confirm the document contains an array */
|
||||||
if (!cbor_value_is_array(&it)) {
|
if (nanocbor_get_type(&it) != NANOCBOR_TYPE_ARR) {
|
||||||
LOG_DEBUG("url list no array\n)");
|
LOG_DEBUG("url list no array\n)");
|
||||||
LOG_DEBUG("type: %u\n", cbor_value_get_type(&it));
|
LOG_DEBUG("type: %u\n", nanocbor_get_type(&it));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enter container, confirm it is an array, too */
|
/* enter container, confirm it is an array, too */
|
||||||
CborValue url_it;
|
nanocbor_value_t url_it;
|
||||||
cbor_value_enter_container(&it, &url_it);
|
nanocbor_enter_array(&it, &url_it);
|
||||||
if (!cbor_value_is_array(&url_it)) {
|
if (nanocbor_get_type(&url_it) != NANOCBOR_TYPE_ARR) {
|
||||||
LOG_DEBUG("url entry no array\n)");
|
LOG_DEBUG("url entry no array\n)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expect two entries: priority as int, url as byte string. bail out if not. */
|
/* expect two entries: priority as int, url as byte string. bail out if not. */
|
||||||
CborValue url_value_it;
|
nanocbor_value_t url_value_it;
|
||||||
cbor_value_enter_container(&url_it, &url_value_it);
|
nanocbor_enter_array(&url_it, &url_value_it);
|
||||||
|
|
||||||
/* check that first array entry is an int (the priority of the url) */
|
/* check that first array entry is an int (the priotity of the url) */
|
||||||
if (cbor_value_get_type(&url_value_it) != CborIntegerType) {
|
if (nanocbor_get_type(&url_value_it) != NANOCBOR_TYPE_UINT) {
|
||||||
|
LOG_DEBUG("expected URL priority (int), got %d\n", nanocbor_get_type(&url_value_it));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbor_value_advance(&url_value_it);
|
/* skip URL priority (currently unused) */
|
||||||
|
nanocbor_skip(&url_value_it);
|
||||||
|
|
||||||
int res = suit_cbor_get_string(&url_value_it, &url, &url_len);
|
int res = suit_cbor_get_string(&url_value_it, &url, &url_len);
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -251,8 +254,8 @@ static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it)
|
|||||||
memcpy(manifest->urlbuf, url, url_len);
|
memcpy(manifest->urlbuf, url, url_len);
|
||||||
manifest->urlbuf[url_len] = '\0';
|
manifest->urlbuf[url_len] = '\0';
|
||||||
|
|
||||||
cbor_value_leave_container(&url_it, &url_value_it);
|
nanocbor_leave_container(&url_it, &url_value_it);
|
||||||
cbor_value_leave_container(&it, &url_it);
|
nanocbor_leave_container(&it, &url_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("_dtv_fetch() fetching \"%s\" (url_len=%u)\n", manifest->urlbuf, (unsigned)url_len);
|
LOG_DEBUG("_dtv_fetch() fetching \"%s\" (url_len=%u)\n", manifest->urlbuf, (unsigned)url_len);
|
||||||
@ -291,14 +294,14 @@ static int _dtv_fetch(suit_v4_manifest_t *manifest, int key, CborValue *_it)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _version_handler(suit_v4_manifest_t *manifest, int key,
|
static int _version_handler(suit_v4_manifest_t *manifest, int key,
|
||||||
CborValue *it)
|
nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)manifest;
|
(void)manifest;
|
||||||
(void)key;
|
(void)key;
|
||||||
/* Validate manifest version */
|
/* Validate manifest version */
|
||||||
int version = -1;
|
int32_t version = -1;
|
||||||
if (cbor_value_is_integer(it) &&
|
if ((nanocbor_get_type(it) == NANOCBOR_TYPE_UINT) &&
|
||||||
(cbor_value_get_int(it, &version) == CborNoError)) {
|
(nanocbor_get_int32(it, &version) >= 0)) {
|
||||||
if (version == SUIT_VERSION) {
|
if (version == SUIT_VERSION) {
|
||||||
manifest->validated |= SUIT_VALIDATED_VERSION;
|
manifest->validated |= SUIT_VALIDATED_VERSION;
|
||||||
LOG_INFO("suit: validated manifest version\n)");
|
LOG_INFO("suit: validated manifest version\n)");
|
||||||
@ -311,32 +314,31 @@ static int _version_handler(suit_v4_manifest_t *manifest, int key,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _seq_no_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _seq_no_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)manifest;
|
(void)manifest;
|
||||||
(void)key;
|
(void)key;
|
||||||
(void)it;
|
(void)it;
|
||||||
|
|
||||||
int64_t seq_nr;
|
int32_t seq_nr;
|
||||||
if (cbor_value_is_unsigned_integer(it) &&
|
|
||||||
(cbor_value_get_int64_checked(it, &seq_nr) == CborNoError)) {
|
|
||||||
|
|
||||||
|
if ((nanocbor_get_type(it) == NANOCBOR_TYPE_UINT)) {
|
||||||
|
nanocbor_get_int32(it, &seq_nr);
|
||||||
const riotboot_hdr_t *hdr = riotboot_slot_get_hdr(riotboot_slot_current());
|
const riotboot_hdr_t *hdr = riotboot_slot_get_hdr(riotboot_slot_current());
|
||||||
if (seq_nr <= (int64_t)hdr->version) {
|
if (seq_nr <= (int32_t)hdr->version) {
|
||||||
LOG_INFO("%"PRIu64" <= %"PRIu32"\n", seq_nr, hdr->version);
|
LOG_INFO("%"PRId32" <= %"PRId32"\n", seq_nr, hdr->version);
|
||||||
LOG_INFO("seq_nr <= running image\n)");
|
LOG_INFO("seq_nr <= running image\n)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = riotboot_slot_get_hdr(riotboot_slot_other());
|
hdr = riotboot_slot_get_hdr(riotboot_slot_other());
|
||||||
if (riotboot_hdr_validate(hdr) == 0) {
|
if (riotboot_hdr_validate(hdr) == 0) {
|
||||||
if (seq_nr <= (int64_t)hdr->version) {
|
if (seq_nr<= (int32_t)hdr->version) {
|
||||||
LOG_INFO("%"PRIu64" <= %"PRIu32"\n", seq_nr, hdr->version);
|
LOG_INFO("%"PRIu32" <= %"PRIu32"\n", seq_nr, hdr->version);
|
||||||
LOG_INFO("seq_nr <= other image\n)");
|
LOG_INFO("seq_nr <= other image\n)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("suit: validated sequence number\n)");
|
LOG_INFO("suit: validated sequence number\n)");
|
||||||
manifest->validated |= SUIT_VALIDATED_SEQ_NR;
|
manifest->validated |= SUIT_VALIDATED_SEQ_NR;
|
||||||
return 0;
|
return 0;
|
||||||
@ -346,7 +348,7 @@ static int _seq_no_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _dependencies_handler(suit_v4_manifest_t *manifest, int key,
|
static int _dependencies_handler(suit_v4_manifest_t *manifest, int key,
|
||||||
CborValue *it)
|
nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)manifest;
|
(void)manifest;
|
||||||
(void)key;
|
(void)key;
|
||||||
@ -356,23 +358,23 @@ static int _dependencies_handler(suit_v4_manifest_t *manifest, int key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _component_handler(suit_v4_manifest_t *manifest, int key,
|
static int _component_handler(suit_v4_manifest_t *manifest, int key,
|
||||||
CborValue *it)
|
nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)manifest;
|
(void)manifest;
|
||||||
(void)key;
|
(void)key;
|
||||||
|
|
||||||
CborValue arr;
|
nanocbor_value_t arr;
|
||||||
|
|
||||||
LOG_DEBUG("storing components\n)");
|
LOG_DEBUG("storing components\n)");
|
||||||
if (!cbor_value_is_array(it)) {
|
if (nanocbor_get_type(it) != NANOCBOR_TYPE_ARR) {
|
||||||
LOG_DEBUG("components field not an array\n");
|
LOG_DEBUG("components field not an array\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cbor_value_enter_container(it, &arr);
|
nanocbor_enter_array(it, &arr);
|
||||||
|
|
||||||
unsigned n = 0;
|
unsigned n = 0;
|
||||||
while (!cbor_value_at_end(&arr)) {
|
while (!nanocbor_at_end(&arr)) {
|
||||||
CborValue map, key, value;
|
nanocbor_value_t map, key, value;
|
||||||
if (n < SUIT_V4_COMPONENT_MAX) {
|
if (n < SUIT_V4_COMPONENT_MAX) {
|
||||||
manifest->components_len += 1;
|
manifest->components_len += 1;
|
||||||
}
|
}
|
||||||
@ -387,8 +389,8 @@ static int _component_handler(suit_v4_manifest_t *manifest, int key,
|
|||||||
|
|
||||||
while (suit_cbor_map_iterate(&map, &key, &value)) {
|
while (suit_cbor_map_iterate(&map, &key, &value)) {
|
||||||
/* handle key, value */
|
/* handle key, value */
|
||||||
int integer_key;
|
int32_t integer_key;
|
||||||
if (suit_cbor_get_int(&key, &integer_key)) {
|
if (suit_cbor_get_int32(&key, &integer_key)) {
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,20 +405,21 @@ static int _component_handler(suit_v4_manifest_t *manifest, int key,
|
|||||||
current->digest = value;
|
current->digest = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_DEBUG("ignoring unexpected component data (nr. %i)\n", integer_key);
|
LOG_DEBUG("ignoring unexpected component data (nr. %" PRIi32 ")\n", integer_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("component %u parsed\n", n);
|
LOG_DEBUG("component %u parsed\n", n);
|
||||||
}
|
}
|
||||||
|
nanocbor_leave_container(&arr, &map);
|
||||||
cbor_value_advance(&arr);
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
manifest->state |= SUIT_MANIFEST_HAVE_COMPONENTS;
|
manifest->state |= SUIT_MANIFEST_HAVE_COMPONENTS;
|
||||||
cbor_value_leave_container(it, &arr);
|
|
||||||
|
nanocbor_leave_container(it, &arr);
|
||||||
|
|
||||||
LOG_DEBUG("storing components done\n)");
|
LOG_DEBUG("storing components done\n)");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,7 +473,7 @@ suit_manifest_handler_t suit_manifest_get_manifest_handler(int key)
|
|||||||
global_handlers_len);
|
global_handlers_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
|
|
||||||
suit_manifest_handler_t handler = _suit_manifest_get_handler(key, _sequence_handlers, _sequence_handlers_len);
|
suit_manifest_handler_t handler = _suit_manifest_get_handler(key, _sequence_handlers, _sequence_handlers_len);
|
||||||
@ -484,52 +487,47 @@ static int _common_sequence_handler(suit_v4_manifest_t *manifest, int key, CborV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _common_handler(suit_v4_manifest_t *manifest, int key, CborValue *it)
|
static int _common_handler(suit_v4_manifest_t *manifest, int key, nanocbor_value_t *it)
|
||||||
{
|
{
|
||||||
(void)key;
|
(void)key;
|
||||||
return _handle_command_sequence(manifest, it, _common_sequence_handler);
|
return _handle_command_sequence(manifest, it, _common_sequence_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _handle_command_sequence(suit_v4_manifest_t *manifest, CborValue *bseq,
|
int _handle_command_sequence(suit_v4_manifest_t *manifest, nanocbor_value_t *bseq,
|
||||||
suit_manifest_handler_t handler)
|
suit_manifest_handler_t handler)
|
||||||
{
|
{
|
||||||
|
|
||||||
LOG_DEBUG("Handling command sequence\n");
|
LOG_DEBUG("Handling command sequence\n");
|
||||||
CborParser parser;
|
nanocbor_value_t it, arr;
|
||||||
CborValue it, arr;
|
|
||||||
|
|
||||||
int err = suit_cbor_subparse(&parser, bseq, &it);
|
int err = suit_cbor_subparse(bseq, &it);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cbor_value_is_array(&it)) {
|
if (nanocbor_get_type(&it) != NANOCBOR_TYPE_ARR) {
|
||||||
LOG_DEBUG("Not a byte array\n");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cbor_value_enter_container(&it, &arr);
|
nanocbor_enter_array(&it, &arr);
|
||||||
|
|
||||||
while (!cbor_value_at_end(&arr)) {
|
while (!nanocbor_at_end(&arr)) {
|
||||||
CborValue map;
|
nanocbor_value_t map;
|
||||||
if (!cbor_value_is_map(&arr)) {
|
if (nanocbor_get_type(&arr) != NANOCBOR_TYPE_MAP) {
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
cbor_value_enter_container(&arr, &map);
|
nanocbor_enter_map(&arr, &map);
|
||||||
int integer_key;
|
int32_t integer_key;
|
||||||
if (suit_cbor_get_int(&map, &integer_key)) {
|
if (suit_cbor_get_int32(&map, &integer_key)) {
|
||||||
return SUIT_ERR_INVALID_MANIFEST;
|
return SUIT_ERR_INVALID_MANIFEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbor_value_advance(&map);
|
|
||||||
int res = handler(manifest, integer_key, &map);
|
int res = handler(manifest, integer_key, &map);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
LOG_DEBUG("Sequence handler error\n");
|
LOG_DEBUG("Sequence handler error\n");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
cbor_value_advance(&map);
|
nanocbor_leave_container(&arr, &map);
|
||||||
cbor_value_leave_container(&arr, &map);
|
|
||||||
}
|
}
|
||||||
cbor_value_leave_container(&it, &arr);
|
nanocbor_leave_container(&it, &arr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user