|
1 | 1 | #include "apdu_constants.h" |
2 | 2 | #include "public_keys.h" |
3 | 3 | #include "network.h" |
4 | | -#include "manage_asset_info.h" |
5 | 4 | #include "os_pki.h" |
| 5 | +#include "token_info.h" |
6 | 6 |
|
7 | | -uint16_t handle_provide_erc20_token_information(const uint8_t *workBuffer, |
8 | | - uint8_t dataLength, |
| 7 | +uint16_t handle_provide_erc20_token_information(uint8_t p1, |
| 8 | + uint8_t p2, |
| 9 | + uint8_t lc, |
| 10 | + const uint8_t *data, |
9 | 11 | unsigned int *tx) { |
10 | 12 | uint32_t offset = 0; |
11 | | - uint8_t tickerLength; |
| 13 | + uint8_t ticker_length; |
| 14 | + const char *ticker; |
| 15 | + const uint8_t *address; |
| 16 | + uint32_t decimals_32; |
| 17 | + uint32_t chain_id_32; |
12 | 18 | uint64_t chain_id; |
13 | 19 | uint8_t hash[INT256_LENGTH]; |
14 | | - tokenDefinition_t *token = &get_current_asset_info()->token; |
| 20 | + int index; |
| 21 | + s_token_info info = {0}; |
15 | 22 |
|
16 | | - PRINTF("Provisioning currentAssetIndex %d\n", tmpCtx.transactionContext.currentAssetIndex); |
17 | | - |
18 | | - if (dataLength < 1) { |
| 23 | + if ((p1 != 0) || (p2 != 0)) { |
| 24 | + return SWO_INCORRECT_P1_P2; |
| 25 | + } |
| 26 | + if ((offset + sizeof(ticker_length)) > lc) { |
19 | 27 | return SWO_INCORRECT_DATA; |
20 | 28 | } |
21 | | - tickerLength = workBuffer[offset++]; |
22 | | - dataLength--; |
23 | | - if ((tickerLength + 1) > sizeof(token->ticker)) { |
| 29 | + ticker_length = data[offset]; |
| 30 | + offset += sizeof(ticker_length); |
| 31 | + |
| 32 | + if ((offset + ticker_length) > lc) { |
24 | 33 | return SWO_INCORRECT_DATA; |
25 | 34 | } |
26 | | - if (dataLength < tickerLength + 20 + 4 + 4) { |
| 35 | + ticker = (const char *) &data[offset]; |
| 36 | + offset += ticker_length; |
| 37 | + |
| 38 | + if ((offset + ADDRESS_LENGTH) > lc) { |
27 | 39 | return SWO_INCORRECT_DATA; |
28 | 40 | } |
29 | | - cx_hash_sha256(workBuffer + offset, tickerLength + 20 + 4 + 4, hash, 32); |
30 | | - memmove(token->ticker, workBuffer + offset, tickerLength); |
31 | | - token->ticker[tickerLength] = '\0'; |
32 | | - offset += tickerLength; |
33 | | - dataLength -= tickerLength; |
34 | | - memmove(token->address, workBuffer + offset, 20); |
35 | | - offset += 20; |
36 | | - dataLength -= 20; |
| 41 | + address = &data[offset]; |
| 42 | + offset += ADDRESS_LENGTH; |
| 43 | + |
37 | 44 | // TODO: 4 bytes for this is overkill |
38 | | - token->decimals = U4BE(workBuffer, offset); |
39 | | - offset += 4; |
40 | | - dataLength -= 4; |
| 45 | + if ((offset + sizeof(decimals_32)) > lc) { |
| 46 | + return SWO_INCORRECT_DATA; |
| 47 | + } |
| 48 | + decimals_32 = U4BE(data, offset); |
| 49 | + offset += sizeof(decimals_32); |
| 50 | + |
41 | 51 | // TODO: Handle 64-bit long chain IDs |
42 | | - chain_id = U4BE(workBuffer, offset); |
| 52 | + if ((offset + sizeof(chain_id_32)) > lc) { |
| 53 | + return SWO_INCORRECT_DATA; |
| 54 | + } |
| 55 | + chain_id_32 = U4BE(data, offset); |
| 56 | + chain_id = (uint64_t) chain_id_32; |
| 57 | + offset += sizeof(chain_id_32); |
| 58 | + |
| 59 | + if (offset >= lc) { |
| 60 | + // no signature |
| 61 | + return SWO_INCORRECT_DATA; |
| 62 | + } |
| 63 | + |
| 64 | + // sanity checks |
| 65 | + if (decimals_32 > UINT8_MAX) { |
| 66 | + PRINTF("Error: decimals received does not fit on one byte!\n"); |
| 67 | + return SWO_INCORRECT_DATA; |
| 68 | + } |
| 69 | + if ((ticker_length + 1) > sizeof(info.ticker)) { |
| 70 | + return SWO_INCORRECT_DATA; |
| 71 | + } |
43 | 72 | if (!app_compatible_with_chain_id(&chain_id)) { |
44 | 73 | UNSUPPORTED_CHAIN_ID_MSG(chain_id); |
45 | 74 | return SWO_INCORRECT_DATA; |
46 | 75 | } |
47 | | - offset += 4; |
48 | | - dataLength -= 4; |
49 | 76 |
|
| 77 | + // signature is computed on everything but the ticker length |
| 78 | + cx_hash_sha256(&data[sizeof(ticker_length)], |
| 79 | + offset - sizeof(ticker_length), |
| 80 | + hash, |
| 81 | + CX_SHA256_SIZE); |
50 | 82 | if (check_signature_with_pubkey(hash, |
51 | 83 | sizeof(hash), |
52 | 84 | LEDGER_SIGNATURE_PUBLIC_KEY, |
53 | 85 | sizeof(LEDGER_SIGNATURE_PUBLIC_KEY), |
54 | 86 | CERTIFICATE_PUBLIC_KEY_USAGE_COIN_META, |
55 | | - (uint8_t *) (workBuffer + offset), |
56 | | - dataLength) != true) { |
| 87 | + &data[offset], |
| 88 | + lc - offset) != true) { |
| 89 | + return SWO_INCORRECT_DATA; |
| 90 | + } |
| 91 | + |
| 92 | + memcpy(info.address, address, sizeof(info.address)); |
| 93 | + memcpy(info.ticker, ticker, ticker_length); |
| 94 | + info.decimals = (uint8_t) decimals_32; |
| 95 | + info.chain_id = (uint64_t) chain_id_32; |
| 96 | + |
| 97 | + if ((index = set_token_info(&info)) == -1) { |
| 98 | + return SWO_INSUFFICIENT_MEMORY; |
| 99 | + } |
| 100 | + if (index > UINT8_MAX) { |
| 101 | + // Could not represent it on one byte |
57 | 102 | return SWO_INCORRECT_DATA; |
58 | 103 | } |
59 | 104 |
|
60 | | - G_io_tx_buffer[0] = tmpCtx.transactionContext.currentAssetIndex; |
61 | | - validate_current_asset_info(); |
| 105 | + G_io_tx_buffer[0] = (uint8_t) index; |
62 | 106 | *tx += 1; |
63 | 107 | return SWO_SUCCESS; |
64 | 108 | } |
0 commit comments