diff --git a/inc/ctoken/ctoken_decode.h b/inc/ctoken/ctoken_decode.h index 3132c3a..0809afa 100644 --- a/inc/ctoken/ctoken_decode.h +++ b/inc/ctoken/ctoken_decode.h @@ -1157,6 +1157,18 @@ ctoken_decode_hw_version(struct ctoken_decode_ctx *context, struct q_useful_buf_c *version); +void +ctoken_decode_get_num_manifests(struct ctoken_decode_ctx *context, + uint32_t *num_manifests); + + +void +ctoken_decode_get_nth_manifest(struct ctoken_decode_ctx *context, + uint32_t index, + uint64_t *tag, + struct q_useful_buf_c *manifest); + + /** * \brief Decode next claim in token or submodule * diff --git a/inc/ctoken/ctoken_encode.h b/inc/ctoken/ctoken_encode.h index 9a71fdd..0473dc0 100644 --- a/inc/ctoken/ctoken_encode.h +++ b/inc/ctoken/ctoken_encode.h @@ -85,6 +85,7 @@ struct ctoken_encode_ctx { struct ctoken_submod_state_t submod_state; QCBOREncodeContext cbor_encode_context; struct t_cose_sign1_sign_ctx signer_ctx; + bool in_manifests; }; @@ -756,6 +757,21 @@ ctoken_encode_hw_version(struct ctoken_encode_ctx *context, struct q_useful_buf_c version); +void +ctoken_encode_start_manifests(struct ctoken_encode_ctx *context); + +void +ctoken_encode_cbor_manifest(struct ctoken_encode_ctx *context, + struct q_useful_buf_c cbor_manifest); + +void +ctoken_encode_non_cbor_manifest(struct ctoken_encode_ctx *context, + int64_t tag, + struct q_useful_buf_c cbor_manifest); + +void +ctoken_encode_end_manifests(struct ctoken_encode_ctx *context); + /** * \brief Start encoding EAT submodules. * diff --git a/src/ctoken_decode.c b/src/ctoken_decode.c index edae5f0..4236fb6 100644 --- a/src/ctoken_decode.c +++ b/src/ctoken_decode.c @@ -596,6 +596,84 @@ static bool is_submod_section(const QCBORItem *claim) return false; } + +static enum ctoken_err_t +ctoken_decode_to_nth_manifest(QCBORDecodeContext *decode_context, + uint32_t submod_index, + uint32_t *num_submods) +{ + /* Traverse submods map until nth one is found and stop */ + QCBORItem map_item; + uint32_t submod_count; + enum ctoken_err_t return_value; + + /* Must have entered into submods map before calling this */ + submod_count = 0; + return_value = CTOKEN_ERR_SUCCESS; + + while(submod_index > 0) { + QCBORDecode_VGetNextConsume(decode_context, &map_item); + return_value = ctoken_get_and_reset_cbor_error(decode_context); + if(return_value != CTOKEN_ERR_SUCCESS) { + break; + } + + submod_count++; + submod_index--; + } + + if(return_value == CTOKEN_ERR_NO_MORE_CLAIMS) { + return_value = CTOKEN_ERR_SUCCESS; + } + +Done: + *num_submods = submod_count; + return return_value; +} + + +void +ctoken_decode_get_num_manifests(struct ctoken_decode_ctx *me, + uint32_t *num_manifests) +{ + QCBORDecode_EnterArrayFromMapN(&(me->qcbor_decode_context), 88); // TODO: + ctoken_decode_to_nth_manifest(&(me->qcbor_decode_context), UINT32_MAX, num_manifests); + QCBORDecode_ExitArray(&(me->qcbor_decode_context)); +} + + +void +ctoken_decode_get_nth_manifest(struct ctoken_decode_ctx *me, + uint32_t index, + uint64_t *tag, + struct q_useful_buf_c *manifest) +{ + uint32_t n; + QCBORItem DecodedItem; + + QCBORDecode_EnterArrayFromMapN(&(me->qcbor_decode_context), 88); // TODO: + ctoken_decode_to_nth_manifest(&(me->qcbor_decode_context), index, &n); + QCBORDecode_PeekNext(&(me->qcbor_decode_context), &DecodedItem); + uint64_t t = QCBORDecode_GetNthTag(&(me->qcbor_decode_context), &DecodedItem, 0); + if(t == CBOR_TAG_INVALID64) { + // Format is CBOR and the tag is inside + QCBORDecode_EnterBstrWrapped(&(me->qcbor_decode_context), + QCBOR_TAG_REQUIREMENT_NOT_A_TAG, + manifest); + QCBORDecode_PeekNext(&(me->qcbor_decode_context), &DecodedItem); + uint64_t t = QCBORDecode_GetNthTag(&(me->qcbor_decode_context), &DecodedItem, 0); + *tag = t; + } else { + QCBORDecode_GetByteString(&(me->qcbor_decode_context), manifest); + *tag = t; + } + + QCBORDecode_ExitArray(&(me->qcbor_decode_context)); +} + + + + /* * Public function. See ctoken_eat_encode.h */ @@ -725,7 +803,7 @@ leave_submod_section(struct ctoken_decode_ctx *me) * CBOR thoroughly. Improvement: check for duplicate labels. */ static enum ctoken_err_t -ctoken_decode_to_nth_submod(struct ctoken_decode_ctx *me, +ctoken_decode_to_nth_submod(struct ctoken_decode_ctx *me, // TODO: make this CBORDecodeContext uint32_t submod_index, uint32_t *num_submods) { diff --git a/src/ctoken_encode.c b/src/ctoken_encode.c index 2877786..43ff967 100644 --- a/src/ctoken_encode.c +++ b/src/ctoken_encode.c @@ -390,6 +390,56 @@ ctoken_encode_location(struct ctoken_encode_ctx *me, QCBOREncode_CloseMap(encode_cxt); } +void +ctoken_encode_start_manifests(struct ctoken_encode_ctx *me) +{ + if(me->in_manifests) { + me->error = 99; // TODO: + return; + } + QCBOREncode_OpenArrayInMapN(&(me->cbor_encode_context), 88); // TODO: label + me->in_manifests = true; + +} + +void +ctoken_encode_cbor_manifest(struct ctoken_encode_ctx *me, + struct q_useful_buf_c cbor_manifest) +{ + if(!me->in_manifests) { + me->error = 99; // TODO: + return; + } + /* Byte-string wrap the cbor that presumably has a tag */ + QCBOREncode_AddBytes(&(me->cbor_encode_context), cbor_manifest); +} + +void +ctoken_encode_non_cbor_manifest(struct ctoken_encode_ctx *me, + int64_t tag, + struct q_useful_buf_c non_cbor_manifest) +{ + if(!me->in_manifests) { + me->error = 99; // TODO: + return; + } + /* Byte-string wrap the cbor that presumably has a tag */ + QCBOREncode_AddTag(&(me->cbor_encode_context), tag); + QCBOREncode_AddBytes(&(me->cbor_encode_context), non_cbor_manifest); +} + +void +ctoken_encode_end_manifests(struct ctoken_encode_ctx *me) +{ + if(!me->in_manifests) { + me->error = 99; // TODO: + return; + } + QCBOREncode_CloseArray(&(me->cbor_encode_context)); + me->in_manifests = false; +} + + /* * Public function. See ctoken_encode.h