43#include "status_words.h"
44#include "tlv_library.h"
55#if defined(HAVE_ADDRESS_BOOK)
58#define STRUCT_VERSION 0x01
62 edit_identifier_t *edit;
63 TLV_reception_t received_tags;
64 uint8_t hmac_proof[CX_SHA256_SIZE];
65 uint8_t hmac_rest[CX_SHA256_SIZE];
66 uint8_t group_handle[GROUP_HANDLE_SIZE];
70#define EDIT_IDENTIFIER_TAGS(X) \
71 X(0x01, TAG_STRUCTURE_TYPE, handle_struct_type, ENFORCE_UNIQUE_TAG) \
72 X(0x02, TAG_STRUCTURE_VERSION, handle_struct_version, ENFORCE_UNIQUE_TAG) \
73 X(0xf0, TAG_CONTACT_NAME, handle_contact_name, ENFORCE_UNIQUE_TAG) \
74 X(0xf1, TAG_SCOPE, handle_scope, ENFORCE_UNIQUE_TAG) \
75 X(0xf2, TAG_ACCOUNT_IDENTIFIER, handle_identifier, ENFORCE_UNIQUE_TAG) \
76 X(0xf4, TAG_PREVIOUS_IDENTIFIER, handle_previous_identifier, ENFORCE_UNIQUE_TAG) \
77 X(0xf6, TAG_GROUP_HANDLE, handle_group_handle, ENFORCE_UNIQUE_TAG) \
78 X(0x21, TAG_DERIVATION_PATH, handle_derivation_path, ENFORCE_UNIQUE_TAG) \
79 X(0x23, TAG_CHAIN_ID, handle_chain_id, ENFORCE_UNIQUE_TAG) \
80 X(0x29, TAG_HMAC_PROOF, handle_hmac_proof, ENFORCE_UNIQUE_TAG) \
81 X(0xf7, TAG_HMAC_REST, handle_hmac_rest, ENFORCE_UNIQUE_TAG) \
82 X(0x51, TAG_BLOCKCHAIN_FAMILY, handle_blockchain_family, ENFORCE_UNIQUE_TAG)
95static bool handle_struct_type(
const tlv_data_t *data, s_edit_ctx *context)
98 if (!tlv_enforce_u8_value(data, TYPE_EDIT_IDENTIFIER)) {
99 PRINTF(
"[Edit Identifier] Invalid STRUCTURE_TYPE value\n");
112static bool handle_struct_version(
const tlv_data_t *data, s_edit_ctx *context)
115 if (!tlv_enforce_u8_value(data, STRUCT_VERSION)) {
116 PRINTF(
"[Edit Identifier] Invalid STRUCTURE_VERSION value\n");
129static bool handle_contact_name(
const tlv_data_t *data, s_edit_ctx *context)
131 if (!address_book_handle_printable_string(data,
132 context->edit->identity.contact_name,
133 sizeof(context->edit->identity.contact_name))) {
134 PRINTF(
"[Edit Identifier] CONTACT_NAME: failed to parse\n");
147static bool handle_scope(
const tlv_data_t *data, s_edit_ctx *context)
149 if (!address_book_handle_printable_string(
150 data, context->edit->identity.scope,
sizeof(context->edit->identity.scope))) {
151 PRINTF(
"[Edit Identifier] SCOPE: failed to parse\n");
164static bool handle_identifier(
const tlv_data_t *data, s_edit_ctx *context)
167 if (!get_buffer_from_tlv_data(data, &buf, 1, IDENTIFIER_MAX_LENGTH)) {
168 PRINTF(
"[Edit Identifier] IDENTIFIER: failed to extract\n");
171 memmove(context->edit->identity.identifier, buf.
ptr, buf.
size);
172 context->edit->identity.identifier_len = (uint8_t) buf.
size;
185static bool handle_previous_identifier(
const tlv_data_t *data, s_edit_ctx *context)
188 if (!get_buffer_from_tlv_data(data, &buf, 1, IDENTIFIER_MAX_LENGTH)) {
189 PRINTF(
"[Edit Identifier] PREVIOUS_IDENTIFIER: failed to extract\n");
192 memmove(context->edit->old_identifier, buf.
ptr, buf.
size);
193 context->edit->old_identifier_len = (uint8_t) buf.
size;
204static bool handle_group_handle(
const tlv_data_t *data, s_edit_ctx *context)
207 if (!get_buffer_from_tlv_data(data, &buf, GROUP_HANDLE_SIZE, GROUP_HANDLE_SIZE)) {
208 PRINTF(
"[Edit Identifier] GROUP_HANDLE: invalid length (expected %d bytes)\n",
212 memmove(context->group_handle, buf.
ptr, GROUP_HANDLE_SIZE);
223static bool handle_derivation_path(
const tlv_data_t *data, s_edit_ctx *context)
225 return address_book_handle_derivation_path(data, &context->edit->identity.bip32_path);
235static bool handle_chain_id(
const tlv_data_t *data, s_edit_ctx *context)
237 return address_book_handle_chain_id(data, &context->edit->identity.chain_id);
247static bool handle_blockchain_family(
const tlv_data_t *data, s_edit_ctx *context)
249 return address_book_handle_blockchain_family(data, &context->edit->identity.blockchain_family);
259static bool handle_hmac_proof(
const tlv_data_t *data, s_edit_ctx *context)
262 if (!get_buffer_from_tlv_data(data, &buf, CX_SHA256_SIZE, CX_SHA256_SIZE)) {
263 PRINTF(
"[Edit Identifier] HMAC_PROOF: invalid length (expected %d bytes)\n",
267 memmove(context->hmac_proof, buf.
ptr, CX_SHA256_SIZE);
278static bool handle_hmac_rest(
const tlv_data_t *data, s_edit_ctx *context)
281 if (!get_buffer_from_tlv_data(data, &buf, CX_SHA256_SIZE, CX_SHA256_SIZE)) {
282 PRINTF(
"[Edit Identifier] HMAC_REST: invalid length (expected %d bytes)\n", CX_SHA256_SIZE);
285 memmove(context->hmac_rest, buf.
ptr, CX_SHA256_SIZE);
289DEFINE_TLV_PARSER(EDIT_IDENTIFIER_TAGS, NULL, edit_identifier_tlv_parser)
297static bool verify_fields(
const s_edit_ctx *context)
299 bool result = TLV_CHECK_RECEIVED_TAGS(context->received_tags,
301 TAG_STRUCTURE_VERSION,
303 TAG_ACCOUNT_IDENTIFIER,
304 TAG_PREVIOUS_IDENTIFIER,
307 TAG_BLOCKCHAIN_FAMILY,
311 PRINTF(
"[Edit Identifier] Missing mandatory fields!\n");
315 result = TLV_CHECK_RECEIVED_TAGS(context->received_tags, TAG_CHAIN_ID);
317 PRINTF(
"[Edit Identifier] Missing CHAIN_ID for Ethereum family!\n");
330static void print_payload(
const s_edit_ctx *context)
333 PRINTF(
"****************************************************************************\n");
334 PRINTF(
"[Edit Identifier] - Retrieved Descriptor:\n");
335 PRINTF(
"[Edit Identifier] - Contact name: %s\n", context->edit->identity.contact_name);
336 if (context->edit->identity.scope[0] !=
'\0') {
337 PRINTF(
"[Edit Identifier] - Scope: %s\n", context->edit->identity.scope);
339 PRINTF(
"[Edit Identifier] - New identifier len: %d\n",
340 context->edit->identity.identifier_len);
341 PRINTF(
"[Edit Identifier] - Old identifier len: %d\n", context->edit->old_identifier_len);
342 PRINTF(
"[Edit Identifier] - Blockchain family: %s\n",
354static bool build_and_send_response(
void)
356 uint8_t hmac_rest[CX_SHA256_SIZE] = {0};
358 if (!address_book_compute_hmac_rest(&g_ab_payload.edit_identifier.identity.bip32_path,
359 g_ab_payload.edit_identifier.identity.gid,
360 g_ab_payload.edit_identifier.identity.scope,
361 g_ab_payload.edit_identifier.identity.identifier,
362 g_ab_payload.edit_identifier.identity.identifier_len,
363 g_ab_payload.edit_identifier.identity.blockchain_family,
364 g_ab_payload.edit_identifier.identity.chain_id,
366 PRINTF(
"[Edit Identifier] Error: Failed to compute new HMAC_REST\n");
370 bool ok = address_book_send_hmac_proof(TYPE_EDIT_IDENTIFIER, hmac_rest);
371 explicit_bzero(hmac_rest,
sizeof(hmac_rest));
380static void review_choice(
bool confirm)
383 bool ok = build_and_send_response();
384 const char *successMsg
385 = (g_ab_payload.edit_identifier.identity.blockchain_family ==
FAMILY_BITCOIN)
386 ?
"Identifier changed"
389 on_edit_identifier_applied(&g_ab_payload.edit_identifier);
392 PRINTF(
"[Edit Identifier] Error: Failed to build and send HMAC proof\n");
394 address_book_finalize_review(
395 ok, successMsg,
"Error during update", finalize_ui_edit_identifier);
398 address_book_handle_review_rejected(finalize_ui_edit_identifier);
405static void ui_display(
void)
407 memset(&g_ab_ui.list, 0,
sizeof(g_ab_ui.list));
408 g_ab_ui.list.nbPairs = 4;
409 g_ab_ui.list.callback = get_edit_identifier_tagValue;
410 address_book_display_review(&LARGE_ADDRESS_BOOK_ICON,
411 "Review change to contact details",
412#ifdef SCREEN_SIZE_WALLET
429bolos_err_t edit_identifier(uint8_t *buffer_in,
size_t buffer_in_length)
431 const buffer_t payload = {.
ptr = buffer_in, .size = buffer_in_length};
432 s_edit_ctx ctx = {0};
435 ctx.edit = &g_ab_payload.edit_identifier;
436 memset(&g_ab_payload.edit_identifier, 0,
sizeof(g_ab_payload.edit_identifier));
439 if (!edit_identifier_tlv_parser(&payload, &ctx, &ctx.received_tags)) {
440 PRINTF(
"[Edit Identifier] TLV parsing failed\n");
441 return SWO_INCORRECT_DATA;
443 if (!verify_fields(&ctx)) {
444 return SWO_INCORRECT_DATA;
449 if (!address_book_verify_group_handle(&g_ab_payload.edit_identifier.identity.bip32_path,
451 g_ab_payload.edit_identifier.identity.gid)) {
452 PRINTF(
"[Edit Identifier] Group handle verification failed\n");
453 return SWO_SECURITY_CONDITION_NOT_SATISFIED;
457 if (!address_book_verify_hmac_proof(&g_ab_payload.edit_identifier.identity.bip32_path,
458 g_ab_payload.edit_identifier.identity.gid,
459 g_ab_payload.edit_identifier.identity.contact_name,
461 PRINTF(
"[Edit Identifier] HMAC_PROOF verification failed\n");
462 return SWO_SECURITY_CONDITION_NOT_SATISFIED;
466 if (!address_book_verify_hmac_rest(&g_ab_payload.edit_identifier.identity.bip32_path,
467 g_ab_payload.edit_identifier.identity.gid,
468 g_ab_payload.edit_identifier.identity.scope,
469 g_ab_payload.edit_identifier.old_identifier,
470 g_ab_payload.edit_identifier.old_identifier_len,
471 g_ab_payload.edit_identifier.identity.blockchain_family,
472 g_ab_payload.edit_identifier.identity.chain_id,
474 PRINTF(
"[Edit Identifier] HMAC_REST verification failed\n");
475 return SWO_SECURITY_CONDITION_NOT_SATISFIED;
479 if (!handle_check_edit_identifier(&g_ab_payload.edit_identifier)) {
480 PRINTF(
"[Edit Identifier] Rejected by coin application\n");
481 return SWO_WRONG_PARAMETER_VALUE;
486 return SWO_NO_RESPONSE;
Register / Edit Contact Name / Edit Scope / Edit Identifier.
API of the Advanced BOLOS Graphical Library, for typical application use-cases.
size_t size
Pointer to byte buffer.