Skip to content

Commit 3d4f4a4

Browse files
Merge pull request #852 from lcastillo-ledger/feat/erc20-extra-data
Add support for displaying extra data trailing calldata in ERC20 calls
2 parents 9efa84e + 93d8a66 commit 3d4f4a4

File tree

215 files changed

+455
-189
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

215 files changed

+455
-189
lines changed

src/eth_plugin_handler.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -135,20 +135,21 @@ eth_plugin_result_t eth_plugin_perform_init(uint8_t *contractAddress,
135135

136136
PRINTF("Selector %.*H\n", 4, init->selector);
137137
switch (pluginType) {
138-
case ERC1155:
139-
case ERC721:
140-
case EXTERNAL:
141-
PRINTF("eth_plugin_perform_init_default\n");
142-
eth_plugin_perform_init_default(contractAddress, init);
143-
contractAddress = NULL;
144-
break;
145-
case OLD_INTERNAL:
138+
case PLUGIN_TYPE_NONE:
146139
PRINTF("eth_plugin_perform_init_old_internal\n");
147140
if (eth_plugin_perform_init_old_internal(contractAddress, init)) {
141+
pluginType = PLUGIN_TYPE_OLD_INTERNAL;
148142
contractAddress = NULL;
149143
}
150144
break;
151-
case SWAP_WITH_CALLDATA:
145+
case PLUGIN_TYPE_ERC1155:
146+
case PLUGIN_TYPE_ERC721:
147+
case PLUGIN_TYPE_EXTERNAL:
148+
PRINTF("eth_plugin_perform_init_default\n");
149+
eth_plugin_perform_init_default(contractAddress, init);
150+
contractAddress = NULL;
151+
break;
152+
case PLUGIN_TYPE_SWAP_WITH_CALLDATA:
152153
PRINTF("contractAddress == %.*H\n", 20, contractAddress);
153154
PRINTF("Fallback on swap_with_calldata plugin\n");
154155
contractAddress = NULL;
@@ -249,7 +250,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
249250
}
250251

251252
switch (pluginType) {
252-
case EXTERNAL: {
253+
case PLUGIN_TYPE_EXTERNAL: {
253254
uint32_t params[3];
254255
params[0] = (uint32_t) alias;
255256
params[1] = method;
@@ -268,19 +269,19 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
268269
END_TRY;
269270
break;
270271
}
271-
case SWAP_WITH_CALLDATA: {
272+
case PLUGIN_TYPE_SWAP_WITH_CALLDATA: {
272273
swap_with_calldata_plugin_call(method, parameter);
273274
break;
274275
}
275-
case ERC721: {
276+
case PLUGIN_TYPE_ERC721: {
276277
erc721_plugin_call(method, parameter);
277278
break;
278279
}
279-
case ERC1155: {
280+
case PLUGIN_TYPE_ERC1155: {
280281
erc1155_plugin_call(method, parameter);
281282
break;
282283
}
283-
case OLD_INTERNAL: {
284+
case PLUGIN_TYPE_OLD_INTERNAL: {
284285
// Perform the call
285286
for (i = 0;; i++) {
286287
if (INTERNAL_ETH_PLUGINS[i].alias[0] == 0) {

src/eth_swap_utils.c

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@
1515
* limitations under the License.
1616
********************************************************************************/
1717

18-
#include <stdint.h>
1918
#include <string.h>
20-
#include <stdbool.h>
21-
22-
#include "asset_info.h"
19+
#include <ctype.h>
2320
#include "eth_swap_utils.h"
21+
#include "asset_info.h"
22+
#include "apdu_constants.h"
23+
#include "utils.h"
24+
#include "swap_error_code_helpers.h"
25+
#include "feature_signTx.h"
26+
27+
bool G_swap_checked;
2428

2529
bool parse_swap_config(const uint8_t *config,
2630
uint8_t config_len,
@@ -56,3 +60,66 @@ bool parse_swap_config(const uint8_t *config,
5660
}
5761
return true;
5862
}
63+
64+
/* Local implementation of strncasecmp, workaround of the segfaulting base implem on return value
65+
* Remove once strncasecmp is fixed
66+
*/
67+
static int strcasecmp_workaround(const char *str1, const char *str2) {
68+
unsigned char c1, c2;
69+
do {
70+
c1 = *str1++;
71+
c2 = *str2++;
72+
if (toupper(c1) != toupper(c2)) {
73+
return toupper(c1) - toupper(c2);
74+
}
75+
} while (c1 != '\0');
76+
return 0;
77+
}
78+
79+
bool swap_check_destination(const char *destination) {
80+
// Ensure the values are the same that the ones that have been previously validated
81+
if (strcasecmp_workaround(strings.common.toAddress, destination) != 0) {
82+
PRINTF("Error comparing destination addresses\n");
83+
send_swap_error_with_string(APDU_RESPONSE_MODE_CHECK_FAILED,
84+
SWAP_EC_ERROR_WRONG_DESTINATION,
85+
APP_CODE_DEFAULT,
86+
"%s != %s",
87+
strings.common.toAddress,
88+
destination);
89+
// unreachable
90+
os_sched_exit(0);
91+
}
92+
return true;
93+
}
94+
95+
bool swap_check_amount(const char *amount) {
96+
// Ensure the values are the same that the ones that have been previously validated
97+
if (strcmp(strings.common.fullAmount, amount) != 0) {
98+
PRINTF("Error comparing amounts\n");
99+
send_swap_error_with_string(APDU_RESPONSE_MODE_CHECK_FAILED,
100+
SWAP_EC_ERROR_WRONG_AMOUNT,
101+
APP_CODE_DEFAULT,
102+
"%s != %s",
103+
strings.common.fullAmount,
104+
amount);
105+
// unreachable
106+
os_sched_exit(0);
107+
}
108+
return true;
109+
}
110+
111+
bool swap_check_fee(const char *fee) {
112+
// Ensure the values are the same that the ones that have been previously validated
113+
if (strcmp(strings.common.maxFee, fee) != 0) {
114+
PRINTF("Error comparing fees\n");
115+
send_swap_error_with_string(APDU_RESPONSE_MODE_CHECK_FAILED,
116+
SWAP_EC_ERROR_WRONG_FEES,
117+
APP_CODE_DEFAULT,
118+
"%s != %s",
119+
strings.common.maxFee,
120+
fee);
121+
// unreachable
122+
os_sched_exit(0);
123+
}
124+
return true;
125+
}

src/eth_swap_utils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717

1818
#pragma once
1919

20+
#include <stdbool.h>
2021
#include <stdint.h>
2122
#include "swap_lib_calls.h"
2223
#include "chainConfig.h"
2324
#include "caller_api.h"
2425

26+
extern bool G_swap_checked;
27+
2528
typedef struct eth_libargs_s {
2629
unsigned int id;
2730
unsigned int command;
@@ -39,3 +42,6 @@ bool parse_swap_config(const uint8_t *config,
3942
char *ticker,
4043
uint8_t *decimals,
4144
uint64_t *chain_id);
45+
bool swap_check_destination(const char *destination);
46+
bool swap_check_amount(const char *amount);
47+
bool swap_check_fee(const char *fee);

src/features/provide_network_info/network_info.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static bool handle_name(const s_tlv_data *data, s_network_info_ctx *context) {
120120
return false;
121121
}
122122
// Check if the name is printable
123-
if (!check_name(data->value, data->length)) {
123+
if (!is_printable((const char *) data->value, data->length)) {
124124
PRINTF("NETWORK_NAME is not printable!\n");
125125
return false;
126126
}
@@ -142,7 +142,7 @@ static bool handle_ticker(const s_tlv_data *data, s_network_info_ctx *context) {
142142
return false;
143143
}
144144
// Check if the ticker is printable
145-
if (!check_name(data->value, data->length)) {
145+
if (!is_printable((const char *) data->value, data->length)) {
146146
PRINTF("NETWORK_TICKER is not printable!\n");
147147
return false;
148148
}

src/features/provide_tx_simulation/cmd_get_tx_simulation.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ static uint16_t parse_type(const s_tlv_data *data, s_tx_simu_ctx *context) {
270270
static uint16_t parse_provider_msg(const s_tlv_data *data, s_tx_simu_ctx *context) {
271271
CHECK_FIELD_OVERFLOW("TX_CHECKS_PROVIDER_MSG", context->simu->provider_msg, data->length);
272272
// Check if the name is printable
273-
if (!check_name(data->value, data->length)) {
273+
if (!is_printable((const char *) data->value, data->length)) {
274274
PRINTF("TX_CHECKS_PROVIDER_MSG is not printable!\n");
275275
return SWO_INCORRECT_DATA;
276276
}
@@ -289,7 +289,7 @@ static uint16_t parse_provider_msg(const s_tlv_data *data, s_tx_simu_ctx *contex
289289
static uint16_t parse_tiny_url(const s_tlv_data *data, s_tx_simu_ctx *context) {
290290
CHECK_FIELD_OVERFLOW("TX_CHECKS_TINY_URL", context->simu->tiny_url, data->length);
291291
// Check if the name is printable
292-
if (!check_name(data->value, data->length)) {
292+
if (!is_printable((const char *) data->value, data->length)) {
293293
PRINTF("TX_CHECKS_TINY_URL is not printable!\n");
294294
return SWO_INCORRECT_DATA;
295295
}

src/features/setExternalPlugin/cmd_setExternalPlugin.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ uint16_t handleSetExternalPlugin(const uint8_t *workBuffer, uint8_t dataLength)
7878
memmove(dataContext.tokenContext.contractAddress, workBuffer, ADDRESS_LENGTH);
7979
workBuffer += ADDRESS_LENGTH;
8080
memmove(dataContext.tokenContext.methodSelector, workBuffer, SELECTOR_SIZE);
81-
pluginType = EXTERNAL;
81+
pluginType = PLUGIN_TYPE_EXTERNAL;
8282

8383
return SWO_SUCCESS;
8484
}

src/features/setPlugin/cmd_setPlugin.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,25 @@ typedef bool verificationAlgo(const cx_ecfp_public_key_t *,
5454

5555
// Returns the plugin type of a given plugin name.
5656
// If the plugin name is not a specific known internal plugin, this function default return value is
57-
// `EXTERNAL`.
57+
// `PLUGIN_TYPE_EXTERNAL`.
5858
static pluginType_t getPluginType(char *pluginName, uint8_t pluginNameLength) {
5959
if (pluginNameLength == sizeof(ERC721_STR) - 1 &&
6060
strncmp(pluginName, ERC721_STR, pluginNameLength) == 0) {
6161
PRINTF("Using internal plugin ERC721\n");
62-
return ERC721;
62+
return PLUGIN_TYPE_ERC721;
6363
} else if (pluginNameLength == sizeof(ERC1155_STR) - 1 &&
6464
strncmp(pluginName, ERC1155_STR, pluginNameLength) == 0) {
6565
PRINTF("Using internal plugin ERC1155\n");
66-
return ERC1155;
66+
return PLUGIN_TYPE_ERC1155;
6767
} else {
6868
PRINTF("Using external plugin\n");
69-
return EXTERNAL;
69+
return PLUGIN_TYPE_EXTERNAL;
7070
}
7171
}
7272

7373
void set_swap_with_calldata_plugin_type(void) {
74-
PRINTF("Using internal plugin SWAP_WITH_CALLDATA\n");
75-
pluginType = SWAP_WITH_CALLDATA;
74+
PRINTF("Using internal plugin PLUGIN_TYPE_SWAP_WITH_CALLDATA\n");
75+
pluginType = PLUGIN_TYPE_SWAP_WITH_CALLDATA;
7676
}
7777

7878
uint16_t handleSetPlugin(const uint8_t *workBuffer, uint8_t dataLength) {
@@ -213,13 +213,13 @@ uint16_t handleSetPlugin(const uint8_t *workBuffer, uint8_t dataLength) {
213213

214214
pluginType = getPluginType(tokenContext->pluginName, pluginNameLength);
215215
if (keyId == PROD_PLUGIN_KEY) {
216-
if (pluginType != ERC721 && pluginType != ERC1155) {
216+
if (pluginType != PLUGIN_TYPE_ERC721 && pluginType != PLUGIN_TYPE_ERC1155) {
217217
PRINTF("AWS key must only be used to set NFT internal plugins\n");
218218
return SWO_INCORRECT_DATA;
219219
}
220220
}
221221

222-
if (pluginType == EXTERNAL) {
222+
if (pluginType == PLUGIN_TYPE_EXTERNAL) {
223223
PRINTF("Check external plugin %s\n", tokenContext->pluginName);
224224

225225
// Check if the plugin is present on the device

0 commit comments

Comments
 (0)