36#include "status_words.h"
37#include "tlv_library.h"
48#if defined(HAVE_ADDRESS_BOOK) && defined(HAVE_ADDRESS_BOOK_LEDGER_ACCOUNT)
51#define STRUCT_VERSION 0x01
59 TLV_reception_t received_tags;
60 uint8_t hmac_proof[CX_SHA256_SIZE];
61} s_edit_ledger_account_ctx;
64#define EDIT_LEDGER_ACCOUNT_TAGS(X) \
65 X(0x01, TAG_STRUCTURE_TYPE, handle_struct_type, ENFORCE_UNIQUE_TAG) \
66 X(0x02, TAG_STRUCTURE_VERSION, handle_struct_version, ENFORCE_UNIQUE_TAG) \
67 X(0xf0, TAG_CONTACT_NAME, handle_contact_name, ENFORCE_UNIQUE_TAG) \
68 X(0xf3, TAG_PREVIOUS_NAME, handle_previous_name, ENFORCE_UNIQUE_TAG) \
69 X(0x21, TAG_DERIVATION_PATH, handle_derivation_path, ENFORCE_UNIQUE_TAG) \
70 X(0x23, TAG_CHAIN_ID, handle_chain_id, ENFORCE_UNIQUE_TAG) \
71 X(0x29, TAG_HMAC_PROOF, handle_hmac_proof, ENFORCE_UNIQUE_TAG) \
72 X(0x51, TAG_BLOCKCHAIN_FAMILY, handle_blockchain_family, ENFORCE_UNIQUE_TAG)
85static bool handle_struct_type(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
89 PRINTF(
"[Edit Ledger Account] Invalid STRUCTURE_TYPE value\n");
102static bool handle_struct_version(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
105 if (!tlv_enforce_u8_value(data, STRUCT_VERSION)) {
106 PRINTF(
"[Edit Ledger Account] Invalid STRUCTURE_VERSION value\n");
119static bool handle_contact_name(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
121 if (!address_book_handle_printable_string(data,
122 context->edit->ledger_account.account_name,
123 sizeof(context->edit->ledger_account.account_name))) {
124 PRINTF(
"CONTACT_NAME: failed to parse\n");
137static bool handle_previous_name(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
139 if (!address_book_handle_printable_string(
140 data, context->edit->old_account_name,
sizeof(context->edit->old_account_name))) {
141 PRINTF(
"PREVIOUS_NAME: failed to parse\n");
154static bool handle_derivation_path(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
156 return address_book_handle_derivation_path(data, &context->edit->ledger_account.bip32_path);
166static bool handle_chain_id(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
168 return address_book_handle_chain_id(data, &context->edit->ledger_account.chain_id);
178static bool handle_blockchain_family(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
180 return address_book_handle_blockchain_family(data,
181 &context->edit->ledger_account.blockchain_family);
191static bool handle_hmac_proof(
const tlv_data_t *data, s_edit_ledger_account_ctx *context)
194 if (!get_buffer_from_tlv_data(data, &buf, CX_SHA256_SIZE, CX_SHA256_SIZE)) {
195 PRINTF(
"[Edit Ledger Account] HMAC_PROOF: invalid length (expected %d bytes)\n",
199 memmove(context->hmac_proof, buf.
ptr, CX_SHA256_SIZE);
203DEFINE_TLV_PARSER(EDIT_LEDGER_ACCOUNT_TAGS, NULL, edit_ledger_account_tlv_parser)
211static bool verify_fields(
const s_edit_ledger_account_ctx *context)
213 bool result = TLV_CHECK_RECEIVED_TAGS(context->received_tags,
215 TAG_STRUCTURE_VERSION,
219 TAG_BLOCKCHAIN_FAMILY,
222 PRINTF(
"Missing mandatory fields in Edit Ledger Account descriptor!\n");
225 if (context->edit->ledger_account.blockchain_family ==
FAMILY_ETHEREUM) {
226 result = TLV_CHECK_RECEIVED_TAGS(context->received_tags, TAG_CHAIN_ID);
228 PRINTF(
"Missing CHAIN_ID for Ethereum family in Edit Ledger Account descriptor!\n");
241static void print_payload(
const s_edit_ledger_account_ctx *context)
246 PRINTF(
"****************************************************************************\n");
247 PRINTF(
"[Edit Ledger Account] - Retrieved Descriptor:\n");
248 PRINTF(
"[Edit Ledger Account] - Old name: %s\n", context->edit->old_account_name);
249 PRINTF(
"[Edit Ledger Account] - New name: %s\n",
250 context->edit->ledger_account.account_name);
252 PRINTF(
"[Edit Ledger Account] - Derivation path[%d]: %s\n",
253 context->edit->ledger_account.bip32_path.length,
257 PRINTF(
"[Edit Ledger Account] - Derivation path length[%d] (failed to format)\n",
258 context->edit->ledger_account.bip32_path.length);
260 PRINTF(
"[Edit Ledger Account] - Blockchain family: %s\n",
261 FAMILY_AS_STR(context->edit->ledger_account.blockchain_family));
262 if (context->edit->ledger_account.blockchain_family ==
FAMILY_ETHEREUM) {
263 PRINTF(
"[Edit Ledger Account] - Chain ID: %llu\n",
264 context->edit->ledger_account.chain_id);
276static bool build_and_send_response(
void)
278 uint8_t hmac_proof[CX_SHA256_SIZE] = {0};
280 if (!address_book_compute_hmac_proof_ledger_account(
281 &g_ab_payload.edit_ledger_account.ledger_account.bip32_path,
282 (
const char *) g_ab_payload.edit_ledger_account.ledger_account.account_name,
283 g_ab_payload.edit_ledger_account.ledger_account.blockchain_family,
284 g_ab_payload.edit_ledger_account.ledger_account.chain_id,
286 PRINTF(
"[Edit Ledger Account] Error: Failed to compute new HMAC proof\n");
291 explicit_bzero(hmac_proof,
sizeof(hmac_proof));
300static void review_choice(
bool confirm)
303 bool ok = build_and_send_response();
305 on_edit_ledger_account_applied(&g_ab_payload.edit_ledger_account);
308 PRINTF(
"[Edit Ledger Account] Error: Failed to build and send HMAC proof\n");
310 address_book_finalize_review(
311 ok,
"Account name changed",
"Error during update", finalize_ui_edit_ledger_account);
314 address_book_handle_review_rejected(finalize_ui_edit_ledger_account);
321static void ui_display(
void)
324 memset(&g_ab_ui.list, 0,
sizeof(g_ab_ui.list));
325 memset(g_ab_ui.pairs, 0,
sizeof(g_ab_ui.pairs));
326 g_ab_ui.pairs[nbPairs].item =
"Old name";
327 g_ab_ui.pairs[nbPairs].value = g_ab_payload.edit_ledger_account.old_account_name;
329 g_ab_ui.pairs[nbPairs].item =
"New name";
330 g_ab_ui.pairs[nbPairs].value = g_ab_payload.edit_ledger_account.ledger_account.account_name;
332 g_ab_ui.list.pairs = g_ab_ui.pairs;
333 g_ab_ui.list.nbPairs = nbPairs;
334 address_book_display_review(NULL,
336#ifdef SCREEN_SIZE_WALLET
355 const buffer_t payload = {.
ptr = buffer_in, .size = buffer_in_length};
356 s_edit_ledger_account_ctx ctx = {0};
359 ctx.edit = &g_ab_payload.edit_ledger_account;
360 memset(&g_ab_payload.edit_ledger_account, 0,
sizeof(g_ab_payload.edit_ledger_account));
363 if (!edit_ledger_account_tlv_parser(&payload, &ctx, &ctx.received_tags)) {
364 PRINTF(
"[Edit Ledger Account] TLV parsing failed\n");
365 return SWO_INCORRECT_DATA;
367 if (!verify_fields(&ctx)) {
368 return SWO_INCORRECT_DATA;
373 if (!address_book_verify_hmac_proof_ledger_account(
374 &g_ab_payload.edit_ledger_account.ledger_account.bip32_path,
375 g_ab_payload.edit_ledger_account.old_account_name,
376 g_ab_payload.edit_ledger_account.ledger_account.blockchain_family,
377 g_ab_payload.edit_ledger_account.ledger_account.chain_id,
379 PRINTF(
"[Edit Ledger Account] HMAC proof verification failed\n");
380 return SWO_SECURITY_CONDITION_NOT_SATISFIED;
384 if (!handle_check_edit_ledger_account(&g_ab_payload.edit_ledger_account)) {
385 PRINTF(
"[Edit Ledger Account] Coin-app rejected edit\n");
386 return SWO_INCORRECT_DATA;
391 return SWO_NO_RESPONSE;
bool bip32_path_format_simple(path_bip32_t *bip32, char *out, size_t out_len)
Format a BIP32 path as a string.
#define TYPE_EDIT_LEDGER_ACCOUNT
bolos_err_t edit_ledger_account(uint8_t *buffer_in, size_t buffer_in_length)
API of the Advanced BOLOS Graphical Library, for typical application use-cases.
Data extracted from a Rename Ledger Account TLV payload.