45#include "status_words.h"
46#include "tlv_library.h"
55#if defined(HAVE_ADDRESS_BOOK) && defined(HAVE_ADDRESS_BOOK_LEDGER_ACCOUNT)
58#define STRUCT_VERSION 0x01
63 TLV_reception_t received_tags;
64 uint8_t hmac_proof[CX_SHA256_SIZE];
65} s_provide_ledger_account_ctx;
68#define PROVIDE_LEDGER_ACCOUNT_TAGS(X) \
69 X(0x01, TAG_STRUCTURE_TYPE, handle_struct_type, ENFORCE_UNIQUE_TAG) \
70 X(0x02, TAG_STRUCTURE_VERSION, handle_struct_version, ENFORCE_UNIQUE_TAG) \
71 X(0xf0, TAG_CONTACT_NAME, handle_contact_name, ENFORCE_UNIQUE_TAG) \
72 X(0x21, TAG_DERIVATION_PATH, handle_derivation_path, ENFORCE_UNIQUE_TAG) \
73 X(0x23, TAG_CHAIN_ID, handle_chain_id, ENFORCE_UNIQUE_TAG) \
74 X(0x51, TAG_BLOCKCHAIN_FAMILY, handle_blockchain_family, ENFORCE_UNIQUE_TAG) \
75 X(0x29, TAG_HMAC_PROOF, handle_hmac_proof, ENFORCE_UNIQUE_TAG)
88static bool handle_struct_type(
const tlv_data_t *data, s_provide_ledger_account_ctx *context)
92 PRINTF(
"[Provide Ledger Account] Invalid STRUCTURE_TYPE value\n");
105static bool handle_struct_version(
const tlv_data_t *data, s_provide_ledger_account_ctx *context)
108 if (!tlv_enforce_u8_value(data, STRUCT_VERSION)) {
109 PRINTF(
"[Provide Ledger Account] Invalid STRUCTURE_VERSION value\n");
122static bool handle_contact_name(
const tlv_data_t *data, s_provide_ledger_account_ctx *context)
124 if (!address_book_handle_printable_string(data,
125 context->ledger_account->account_name,
126 sizeof(context->ledger_account->account_name))) {
127 PRINTF(
"[Provide Ledger Account] CONTACT_NAME: failed to parse\n");
140static bool handle_derivation_path(
const tlv_data_t *data, s_provide_ledger_account_ctx *context)
142 return address_book_handle_derivation_path(data, &context->ledger_account->bip32_path);
152static bool handle_chain_id(
const tlv_data_t *data, s_provide_ledger_account_ctx *context)
154 return address_book_handle_chain_id(data, &context->ledger_account->chain_id);
164static bool handle_blockchain_family(
const tlv_data_t *data, s_provide_ledger_account_ctx *context)
166 return address_book_handle_blockchain_family(data, &context->ledger_account->blockchain_family);
176static bool handle_hmac_proof(
const tlv_data_t *data, s_provide_ledger_account_ctx *context)
179 if (!get_buffer_from_tlv_data(data, &buf, CX_SHA256_SIZE, CX_SHA256_SIZE)) {
180 PRINTF(
"[Provide Ledger Account] HMAC_PROOF: invalid length (expected %d bytes)\n",
184 memmove(context->hmac_proof, buf.
ptr, CX_SHA256_SIZE);
188DEFINE_TLV_PARSER(PROVIDE_LEDGER_ACCOUNT_TAGS, NULL, provide_ledger_account_tlv_parser)
196static bool verify_fields(
const s_provide_ledger_account_ctx *context)
198 bool result = TLV_CHECK_RECEIVED_TAGS(context->received_tags,
200 TAG_STRUCTURE_VERSION,
203 TAG_BLOCKCHAIN_FAMILY,
206 PRINTF(
"[Provide Ledger Account] Missing mandatory fields!\n");
210 result = TLV_CHECK_RECEIVED_TAGS(context->received_tags, TAG_CHAIN_ID);
212 PRINTF(
"[Provide Ledger Account] Missing CHAIN_ID for Ethereum family!\n");
224static void print_payload(
const s_provide_ledger_account_ctx *context)
229 PRINTF(
"****************************************************************************\n");
230 PRINTF(
"[Provide Ledger Account] - Retrieved Descriptor:\n");
231 PRINTF(
"[Provide Ledger Account] - Account name: %s\n",
232 context->ledger_account->account_name);
234 PRINTF(
"[Provide Ledger Account] - Derivation path[%d]: %s\n",
235 context->ledger_account->bip32_path.length,
239 PRINTF(
"[Provide Ledger Account] - Derivation path length[%d] (failed to format)\n",
240 context->ledger_account->bip32_path.length);
242 PRINTF(
"[Provide Ledger Account] - Blockchain family: %s\n",
245 PRINTF(
"[Provide Ledger Account] - Chain ID: %llu\n",
246 context->ledger_account->chain_id);
264 const buffer_t payload = {.
ptr = buffer_in, .size = buffer_in_length};
265 s_provide_ledger_account_ctx ctx = {0};
268 ctx.ledger_account = &g_ab_payload.ledger_account;
269 memset(&g_ab_payload.ledger_account, 0,
sizeof(g_ab_payload.ledger_account));
272 if (!provide_ledger_account_tlv_parser(&payload, &ctx, &ctx.received_tags)) {
273 PRINTF(
"[Provide Ledger Account] TLV parsing failed\n");
274 return SWO_INCORRECT_DATA;
276 if (!verify_fields(&ctx)) {
277 return SWO_INCORRECT_DATA;
282 if (!address_book_verify_hmac_proof_ledger_account(
283 &g_ab_payload.ledger_account.bip32_path,
284 g_ab_payload.ledger_account.account_name,
285 g_ab_payload.ledger_account.blockchain_family,
286 g_ab_payload.ledger_account.chain_id,
288 PRINTF(
"[Provide Ledger Account] HMAC proof verification failed\n");
289 return SWO_SECURITY_CONDITION_NOT_SATISFIED;
293 if (!handle_provide_ledger_account(&g_ab_payload.ledger_account)) {
294 PRINTF(
"[Provide Ledger Account] Rejected by coin application\n");
295 return SWO_WRONG_PARAMETER_VALUE;
bool bip32_path_format_simple(path_bip32_t *bip32, char *out, size_t out_len)
Format a BIP32 path as a string.
bolos_err_t provide_ledger_account_contact(uint8_t *buffer_in, size_t buffer_in_length)
#define TYPE_PROVIDE_LEDGER_ACCOUNT_CONTACT
Data extracted from a Register Ledger Account TLV payload.