Files

548 lines
22 KiB
C
Raw Permalink Normal View History

#include <ctype.h>
2020-06-27 13:24:04 +02:00
#include "shared_context.h"
2024-01-16 13:51:36 +01:00
#include "common_utils.h"
#include "feature_signTx.h"
#include "uint256.h"
2020-09-22 09:22:49 +02:00
#include "eth_plugin_handler.h"
#include "network.h"
2022-08-24 09:25:01 +02:00
#include "common_ui.h"
#include "ui_callbacks.h"
#include "apdu_constants.h"
2024-04-15 11:33:42 +02:00
#include "crypto_helpers.h"
#include "format.h"
2024-04-17 14:18:26 +02:00
#include "manage_asset_info.h"
2020-06-27 13:24:04 +02:00
2020-06-29 15:43:02 +02:00
#define ERR_SILENT_MODE_CHECK_FAILED 0x6001
2024-06-21 11:49:42 +02:00
static bool g_use_standard_ui;
static uint32_t splitBinaryParameterPart(char *result, size_t result_size, uint8_t *parameter) {
2020-06-27 13:24:04 +02:00
uint32_t i;
2020-12-01 16:20:13 +01:00
for (i = 0; i < 8; i++) {
2020-06-27 13:24:04 +02:00
if (parameter[i] != 0x00) {
break;
}
}
if (i == 8) {
result[0] = '0';
result[1] = '0';
result[2] = '\0';
return 2;
2020-12-01 16:20:13 +01:00
} else {
format_hex(parameter + i, 8 - i, result, result_size);
2020-06-27 13:24:04 +02:00
return ((8 - i) * 2);
}
}
customStatus_e customProcessor(txContext_t *context) {
if (((context->txType == LEGACY && context->currentField == LEGACY_RLP_DATA) ||
(context->txType == EIP2930 && context->currentField == EIP2930_RLP_DATA) ||
(context->txType == EIP1559 && context->currentField == EIP1559_RLP_DATA)) &&
(context->currentFieldLength != 0)) {
2021-06-11 11:37:16 +02:00
context->content->dataPresent = true;
2020-06-27 13:24:04 +02:00
// If handling a new contract rather than a function call, abort immediately
if (tmpContent.txContent.destinationLength == 0) {
return CUSTOM_NOT_HANDLED;
}
// If data field is less than 4 bytes long, do not try to use a plugin.
if (context->currentFieldLength < 4) {
return CUSTOM_NOT_HANDLED;
}
2020-06-27 13:24:04 +02:00
if (context->currentFieldPos == 0) {
2020-09-22 09:22:49 +02:00
ethPluginInitContract_t pluginInit;
2020-12-01 16:20:13 +01:00
// If handling the beginning of the data field, assume that the function selector is
// present
2020-06-27 13:24:04 +02:00
if (context->commandLength < 4) {
PRINTF("Missing function selector\n");
return CUSTOM_FAULT;
}
2021-04-23 19:15:30 +02:00
dataContext.tokenContext.pluginStatus = ETH_PLUGIN_RESULT_UNAVAILABLE;
// If contract debugging mode is activated, do not go through the plugin activation
// as they wouldn't be displayed if the plugin consumes all data but fallbacks
if (!N_storage.contractDetails) {
eth_plugin_prepare_init(&pluginInit,
context->workBuffer,
context->currentFieldLength);
2021-04-23 19:15:30 +02:00
dataContext.tokenContext.pluginStatus =
eth_plugin_perform_init(tmpContent.txContent.destination, &pluginInit);
}
2021-04-23 19:15:30 +02:00
PRINTF("pluginstatus %d\n", dataContext.tokenContext.pluginStatus);
2021-04-27 10:36:22 +02:00
eth_plugin_result_t status = dataContext.tokenContext.pluginStatus;
if (status == ETH_PLUGIN_RESULT_ERROR) {
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
PRINTF("Plugin error\n");
2021-04-27 10:37:22 +02:00
return CUSTOM_FAULT;
2021-04-27 10:36:22 +02:00
} else if (status >= ETH_PLUGIN_RESULT_SUCCESSFUL) {
2021-04-27 10:37:22 +02:00
dataContext.tokenContext.fieldIndex = 0;
dataContext.tokenContext.fieldOffset = 0;
copyTxData(context, NULL, 4);
if (context->currentFieldLength == 4) {
return CUSTOM_NOT_HANDLED;
}
2020-06-27 13:24:04 +02:00
}
}
2020-12-01 16:20:13 +01:00
uint32_t blockSize;
uint32_t copySize;
uint32_t fieldPos = context->currentFieldPos;
if (fieldPos == 0) { // not reached if a plugin is available
if (!N_storage.contractDetails) {
2020-09-22 09:22:49 +02:00
return CUSTOM_NOT_HANDLED;
2020-12-01 16:20:13 +01:00
}
dataContext.tokenContext.fieldIndex = 0;
dataContext.tokenContext.fieldOffset = 0;
blockSize = 4;
} else {
2021-04-23 19:15:30 +02:00
if (!N_storage.contractDetails &&
2021-04-24 12:14:36 +02:00
dataContext.tokenContext.pluginStatus <= ETH_PLUGIN_RESULT_UNSUCCESSFUL) {
2020-10-27 11:18:31 +01:00
return CUSTOM_NOT_HANDLED;
2020-12-01 16:20:13 +01:00
}
blockSize = 32 - (dataContext.tokenContext.fieldOffset % 32);
}
2020-06-27 13:24:04 +02:00
// If the last parameter is of type `bytes` then we might have an
// edge case where the data is not a multiple of 32. Set `blockSize` accordingly
2020-12-01 16:20:13 +01:00
if ((context->currentFieldLength - fieldPos) < blockSize) {
blockSize = context->currentFieldLength - fieldPos;
2020-12-01 16:20:13 +01:00
}
2020-06-27 13:24:04 +02:00
2020-12-01 16:20:13 +01:00
copySize = (context->commandLength < blockSize ? context->commandLength : blockSize);
2020-06-27 13:24:04 +02:00
2020-12-01 16:20:13 +01:00
PRINTF("currentFieldPos %d copySize %d\n", context->currentFieldPos, copySize);
2020-06-27 13:24:04 +02:00
2020-12-01 16:20:13 +01:00
copyTxData(context,
dataContext.tokenContext.data + dataContext.tokenContext.fieldOffset,
copySize);
2020-09-22 09:22:49 +02:00
2020-12-01 16:20:13 +01:00
if (context->currentFieldPos == context->currentFieldLength) {
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
PRINTF("\n\nIncrementing one\n");
2020-12-01 16:20:13 +01:00
context->currentField++;
context->processingField = false;
}
2020-09-22 09:22:49 +02:00
2020-12-01 16:20:13 +01:00
dataContext.tokenContext.fieldOffset += copySize;
2020-09-22 09:22:49 +02:00
2020-12-01 16:20:13 +01:00
if (copySize == blockSize) {
// Can process or display
2021-04-24 12:14:36 +02:00
if (dataContext.tokenContext.pluginStatus >= ETH_PLUGIN_RESULT_SUCCESSFUL) {
2020-09-22 09:22:49 +02:00
ethPluginProvideParameter_t pluginProvideParameter;
2020-12-01 16:20:13 +01:00
eth_plugin_prepare_provide_parameter(&pluginProvideParameter,
dataContext.tokenContext.data,
dataContext.tokenContext.fieldIndex * 32 + 4);
if (!eth_plugin_call(ETH_PLUGIN_PROVIDE_PARAMETER,
2020-12-01 16:20:13 +01:00
(void *) &pluginProvideParameter)) {
PRINTF("Plugin parameter call failed\n");
return CUSTOM_FAULT;
2020-06-27 13:24:04 +02:00
}
2020-09-22 09:22:49 +02:00
dataContext.tokenContext.fieldIndex++;
dataContext.tokenContext.fieldOffset = 0;
memset(dataContext.tokenContext.data, 0, sizeof(dataContext.tokenContext.data));
2020-06-27 13:24:04 +02:00
return CUSTOM_HANDLED;
2020-12-01 16:20:13 +01:00
}
2020-06-27 13:24:04 +02:00
2020-12-01 16:20:13 +01:00
if (fieldPos != 0) {
dataContext.tokenContext.fieldIndex++;
}
dataContext.tokenContext.fieldOffset = 0;
if (fieldPos == 0) {
format_hex(dataContext.tokenContext.data,
4,
strings.tmp.tmp,
sizeof(strings.tmp.tmp));
2022-08-24 09:25:01 +02:00
ui_confirm_selector();
2020-12-01 16:20:13 +01:00
} else {
uint32_t offset = 0;
uint32_t i;
snprintf(strings.tmp.tmp2,
sizeof(strings.tmp.tmp2),
"Field %d",
dataContext.tokenContext.fieldIndex);
for (i = 0; i < 4; i++) {
offset += splitBinaryParameterPart(strings.tmp.tmp + offset,
sizeof(strings.tmp.tmp) - offset,
2020-12-01 16:20:13 +01:00
dataContext.tokenContext.data + 8 * i);
if (i != 3) {
strings.tmp.tmp[offset++] = ':';
}
}
2022-08-24 09:25:01 +02:00
ui_confirm_parameter();
2020-12-01 16:20:13 +01:00
}
} else {
return CUSTOM_HANDLED;
}
2020-09-22 09:22:49 +02:00
2020-12-01 16:20:13 +01:00
return CUSTOM_SUSPENDED;
2020-06-27 13:24:04 +02:00
}
return CUSTOM_NOT_HANDLED;
}
2024-06-21 11:49:42 +02:00
void report_finalize_error(void) {
2020-12-01 16:20:13 +01:00
reset_app_context();
2024-06-21 11:49:42 +02:00
io_seproxyhal_send_status(APDU_RESPONSE_INVALID_DATA);
ui_idle();
2020-09-22 09:22:49 +02:00
}
static void address_to_string(uint8_t *in,
size_t in_len,
char *out,
size_t out_len,
uint64_t chainId) {
if (in_len != 0) {
2024-03-18 08:58:05 +01:00
if (!getEthDisplayableAddress(in, out, out_len, chainId)) {
THROW(APDU_RESPONSE_ERROR_NO_INFO);
}
} else {
strlcpy(out, "Contract", out_len);
}
2021-06-11 11:37:16 +02:00
}
static void raw_fee_to_string(uint256_t *rawFee, char *displayBuffer, uint32_t displayBufferSize) {
2023-06-16 15:52:03 +02:00
uint64_t chain_id = get_tx_chain_id();
const char *feeTicker = get_displayable_ticker(&chain_id, chainConfig);
2020-12-01 16:20:13 +01:00
uint8_t tickerOffset = 0;
uint32_t i;
2020-09-22 09:22:49 +02:00
2021-06-11 11:37:16 +02:00
tostring256(rawFee, 10, (char *) (G_io_apdu_buffer + 100), 100);
2020-12-01 16:20:13 +01:00
i = 0;
while (G_io_apdu_buffer[100 + i]) {
i++;
}
adjustDecimals((char *) (G_io_apdu_buffer + 100),
i,
(char *) G_io_apdu_buffer,
100,
WEI_TO_ETHER);
i = 0;
tickerOffset = 0;
memset(displayBuffer, 0, displayBufferSize);
2022-08-09 11:09:51 +02:00
2020-12-01 16:20:13 +01:00
while (feeTicker[tickerOffset]) {
2022-08-09 11:09:51 +02:00
if ((uint32_t) tickerOffset >= displayBufferSize) {
break;
}
2020-12-01 16:20:13 +01:00
displayBuffer[tickerOffset] = feeTicker[tickerOffset];
tickerOffset++;
}
if ((uint32_t) tickerOffset < displayBufferSize) displayBuffer[tickerOffset++] = ' ';
2020-12-01 16:20:13 +01:00
while (G_io_apdu_buffer[i]) {
2022-08-09 11:09:51 +02:00
if ((uint32_t) (tickerOffset) + i >= displayBufferSize) {
break;
}
2020-12-01 16:20:13 +01:00
displayBuffer[tickerOffset + i] = G_io_apdu_buffer[i];
i++;
}
2022-08-09 11:09:51 +02:00
if ((uint32_t) (tickerOffset) + i < displayBufferSize) {
displayBuffer[tickerOffset + i] = '\0';
}
2021-06-11 11:37:16 +02:00
}
2021-06-29 16:07:28 +02:00
// Compute the fees, transform it to a string, prepend a ticker to it and copy everything to
// `displayBuffer` output
static void max_transaction_fee_to_string(const txInt256_t *BEGasPrice,
const txInt256_t *BEGasLimit,
char *displayBuffer,
uint32_t displayBufferSize) {
// Use temporary variables to convert values to uint256_t
uint256_t gasPrice = {0};
uint256_t gasLimit = {0};
// Use temporary variable to store the result of the operation in uint256_t
2021-06-11 11:37:16 +02:00
uint256_t rawFee = {0};
PRINTF("Gas price %.*H\n", BEGasPrice->length, BEGasPrice->value);
PRINTF("Gas limit %.*H\n", BEGasLimit->length, BEGasLimit->value);
convertUint256BE(BEGasPrice->value, BEGasPrice->length, &gasPrice);
convertUint256BE(BEGasLimit->value, BEGasLimit->length, &gasLimit);
mul256(&gasPrice, &gasLimit, &rawFee);
raw_fee_to_string(&rawFee, displayBuffer, displayBufferSize);
2021-06-11 11:37:16 +02:00
}
static void nonce_to_string(const txInt256_t *nonce, char *out, size_t out_size) {
uint256_t nonce_uint256;
convertUint256BE(nonce->value, nonce->length, &nonce_uint256);
tostring256(&nonce_uint256, 10, out, out_size);
}
static void get_network_as_string(char *out, size_t out_size) {
2023-06-16 15:52:03 +02:00
uint64_t chain_id = get_tx_chain_id();
const char *name = get_network_name_from_chain_id(&chain_id);
if (name == NULL) {
// No network name found so simply copy the chain ID as the network name.
if (!u64_to_string(chain_id, out, out_size)) {
THROW(0x6502);
}
} else {
// Network name found, simply copy it.
strlcpy(out, name, out_size);
}
2020-09-22 09:22:49 +02:00
}
static void get_public_key(uint8_t *out, uint8_t outLength) {
2024-03-18 08:58:05 +01:00
uint8_t raw_pubkey[65];
if (outLength < ADDRESS_LENGTH) {
return;
}
2024-03-18 08:58:05 +01:00
if (bip32_derive_get_pubkey_256(CX_CURVE_256K1,
tmpCtx.transactionContext.bip32.path,
tmpCtx.transactionContext.bip32.length,
raw_pubkey,
NULL,
CX_SHA512) != CX_OK) {
THROW(APDU_RESPONSE_UNKNOWN);
}
2024-03-18 08:58:05 +01:00
getEthAddressFromRawKey(raw_pubkey, out);
}
/* Local implementation of strncasecmp, workaround of the segfaulting base implem
2023-04-24 11:30:04 +02:00
* Remove once strncasecmp is fixed
*/
static int strcasecmp_workaround(const char *str1, const char *str2) {
2023-04-24 11:28:42 +02:00
unsigned char c1, c2;
2023-04-24 11:30:04 +02:00
do {
2023-04-24 11:28:42 +02:00
c1 = *str1++;
c2 = *str2++;
if (toupper(c1) != toupper(c2)) {
return toupper(c1) - toupper(c2);
}
2023-04-24 11:30:04 +02:00
} while (c1 != '\0');
2023-04-24 11:28:42 +02:00
return 0;
}
2024-06-21 11:49:42 +02:00
__attribute__((noinline)) static bool finalize_parsing_helper(void) {
2021-02-08 13:19:00 +01:00
char displayBuffer[50];
2020-12-01 16:20:13 +01:00
uint8_t decimals = WEI_TO_ETHER;
2023-06-16 15:52:03 +02:00
uint64_t chain_id = get_tx_chain_id();
const char *ticker = get_displayable_ticker(&chain_id, chainConfig);
2020-12-01 16:20:13 +01:00
ethPluginFinalize_t pluginFinalize;
2024-03-18 08:58:05 +01:00
cx_err_t error = CX_INTERNAL_ERROR;
2020-12-01 16:20:13 +01:00
// Verify the chain
if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) {
2023-05-04 11:52:16 +02:00
uint64_t id = get_tx_chain_id();
if (chainConfig->chainId != id) {
PRINTF("Invalid chainID %u expected %u\n", id, chainConfig->chainId);
2020-12-01 16:20:13 +01:00
reset_app_context();
2024-06-21 11:49:42 +02:00
report_finalize_error();
return false;
2020-06-27 13:24:04 +02:00
}
}
2020-12-01 16:20:13 +01:00
// Store the hash
2024-03-18 08:58:05 +01:00
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3,
CX_LAST,
tmpCtx.transactionContext.hash,
0,
tmpCtx.transactionContext.hash,
32));
2020-09-22 09:22:49 +02:00
2024-03-11 16:14:31 +01:00
uint8_t msg_sender[ADDRESS_LENGTH] = {0};
get_public_key(msg_sender, sizeof(msg_sender));
2024-06-19 11:24:13 +02:00
address_to_string(msg_sender,
ADDRESS_LENGTH,
strings.common.fromAddress,
sizeof(strings.common.fromAddress),
chainConfig->chainId);
PRINTF("FROM address displayed: %s\n", strings.common.fromAddress);
2020-12-01 16:20:13 +01:00
// Finalize the plugin handling
2021-04-24 12:14:36 +02:00
if (dataContext.tokenContext.pluginStatus >= ETH_PLUGIN_RESULT_SUCCESSFUL) {
2020-12-01 16:20:13 +01:00
eth_plugin_prepare_finalize(&pluginFinalize);
pluginFinalize.address = msg_sender;
if (!eth_plugin_call(ETH_PLUGIN_FINALIZE, (void *) &pluginFinalize)) {
2020-12-01 16:20:13 +01:00
PRINTF("Plugin finalize call failed\n");
2024-06-21 11:49:42 +02:00
report_finalize_error();
return false;
2020-12-01 16:20:13 +01:00
}
// Lookup tokens if requested
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
ethPluginProvideInfo_t pluginProvideInfo;
eth_plugin_prepare_provide_info(&pluginProvideInfo);
if ((pluginFinalize.tokenLookup1 != NULL) || (pluginFinalize.tokenLookup2 != NULL)) {
if (pluginFinalize.tokenLookup1 != NULL) {
PRINTF("Lookup1: %.*H\n", ADDRESS_LENGTH, pluginFinalize.tokenLookup1);
pluginProvideInfo.item1 = get_asset_info_by_addr(pluginFinalize.tokenLookup1);
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
if (pluginProvideInfo.item1 != NULL) {
PRINTF("Token1 ticker: %s\n", pluginProvideInfo.item1->token.ticker);
2021-05-11 10:21:17 +02:00
}
}
2020-12-01 16:20:13 +01:00
if (pluginFinalize.tokenLookup2 != NULL) {
PRINTF("Lookup2: %.*H\n", ADDRESS_LENGTH, pluginFinalize.tokenLookup2);
pluginProvideInfo.item2 = get_asset_info_by_addr(pluginFinalize.tokenLookup2);
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
if (pluginProvideInfo.item2 != NULL) {
PRINTF("Token2 ticker: %s\n", pluginProvideInfo.item2->token.ticker);
2021-05-11 10:21:17 +02:00
}
2020-12-01 16:20:13 +01:00
}
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
if (eth_plugin_call(ETH_PLUGIN_PROVIDE_INFO, (void *) &pluginProvideInfo) <=
2021-05-11 17:18:28 +02:00
ETH_PLUGIN_RESULT_UNSUCCESSFUL) {
2020-12-01 16:20:13 +01:00
PRINTF("Plugin provide token call failed\n");
2024-06-21 11:49:42 +02:00
report_finalize_error();
return false;
2020-12-01 16:20:13 +01:00
}
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
pluginFinalize.result = pluginProvideInfo.result;
2020-12-01 16:20:13 +01:00
}
if (pluginFinalize.result != ETH_PLUGIN_RESULT_FALLBACK) {
// Handle the right interface
switch (pluginFinalize.uiType) {
case ETH_UI_TYPE_GENERIC:
// Use the dedicated ETH plugin UI
2024-06-21 11:49:42 +02:00
g_use_standard_ui = false;
2021-06-11 11:37:16 +02:00
tmpContent.txContent.dataPresent = false;
2021-05-20 14:34:45 +02:00
// Add the number of screens + the number of additional screens to get the total
// number of screens needed.
dataContext.tokenContext.pluginUiMaxItems =
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
pluginFinalize.numScreens + pluginProvideInfo.additionalScreens;
2020-12-01 16:20:13 +01:00
break;
case ETH_UI_TYPE_AMOUNT_ADDRESS:
// Use the standard ETH UI as this plugin uses the amount/address UI
2024-06-21 11:49:42 +02:00
g_use_standard_ui = true;
2021-06-11 11:37:16 +02:00
tmpContent.txContent.dataPresent = false;
2020-12-01 16:20:13 +01:00
if ((pluginFinalize.amount == NULL) || (pluginFinalize.address == NULL)) {
PRINTF("Incorrect amount/address set by plugin\n");
2024-06-21 11:49:42 +02:00
report_finalize_error();
return false;
2020-12-01 16:20:13 +01:00
}
memmove(tmpContent.txContent.value.value, pluginFinalize.amount, 32);
tmpContent.txContent.value.length = 32;
memmove(tmpContent.txContent.destination, pluginFinalize.address, 20);
tmpContent.txContent.destinationLength = 20;
Add support for ERC-721 and ERC-1155 (v3) (#218) * First draft for erc721 token allowance * Split ui and provide parameters into their own files * Print txtype when not supported * fix compilation for erc721 * Use pluginType * Add debug statement in compound plugin * add debug error msg in plugin error * Add parameter parsing for all methods * Remove debug logs * Add SET_APPROVAL_FOR_ALL; Add correct parsing method on contract init * Add dst_size parameter to copy functions * Add query contract id code * format * Add UIs * update ethapp.asc * Change setExternalPlugin to setPlugin; Add support for ERC721 * clang-format * Fix typo Unconsistent -> Inconsistent * Add support for 721; use extraInfo * Add extraInfo to ethpluginQueryConractUI * Rename extraInfo to item * Add txFromEtherscan to tests * Add nft key and temp padding * Remove comments around HAVE_BYPASS_SIGNATURES * Rename TESTING_KEY to NFT_TESTING_KEY * Add comments regarding value of queryContractUI->item * Fix comment regarding method selector * Rename provideToken to provideInfo; Update plugin doc * fix caps of eth_plugin_prepare_provide_info * fix caps of handle_provide_info * Use verificationFn insead of hardcoded cx_ecdsa_verify * Add comments about nftInfo_t and tokenDefinition_t * Add erc721 test * Remove comment from plugin interface version * Fix network_ticker duplicate * Add setPlugin and provideNFTInfo to doc.asc * Add back setExternalPlugin; implement new setPlugin * Update plugin sdk * Call setPlugin instead of setExternalPlugin * setPlugin work without checking sig * Remove printf of displayed fees * Add working 721 test * Finalize ERC721 and add simple test * Display NFT address on set approval and operator * Support set approval for all for erc721 * Finish UI for set approval for all erc721 * Move copy_parameter and copy_address to eth_plugin_internal; Add tests for erc721 * update plugin sdk * Add erc1155 plugin and 1155 tests placeholder * Add restriction for AWS key and setPlugin * Add NOT_OLD_INTERNAL variant; Add erc_1155_plugin_call * Fixed compilation warnings (function pointer casting) Co-authored-by: pscott <scott.piriou@ledger.fr>
2021-11-22 14:39:36 +01:00
if (pluginProvideInfo.item1 != NULL) {
decimals = pluginProvideInfo.item1->token.decimals;
ticker = pluginProvideInfo.item1->token.ticker;
2020-12-01 16:20:13 +01:00
}
break;
default:
PRINTF("ui type %d not supported\n", pluginFinalize.uiType);
2024-06-21 11:49:42 +02:00
report_finalize_error();
return false;
2020-12-01 16:20:13 +01:00
}
}
2020-09-22 09:22:49 +02:00
}
2020-12-01 16:20:13 +01:00
if (G_called_from_swap) {
if (G_swap_response_ready) {
// Unreachable given current return to exchange mechanism. Safeguard against regression
PRINTF("FATAL: safety against double sign triggered\n");
os_sched_exit(-1);
}
G_swap_response_ready = true;
}
// User has just validated a swap but ETH received apdus about a non standard plugin / contract
2024-06-21 11:49:42 +02:00
if (G_called_from_swap && !g_use_standard_ui) {
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, G_called_from_swap\n");
THROW(ERR_SILENT_MODE_CHECK_FAILED);
}
// Prepare destination address and amount to display
2024-06-21 11:49:42 +02:00
if (g_use_standard_ui) {
// Format the address in a temporary buffer, if in swap case compare it with validated
// address, else commit it
address_to_string(tmpContent.txContent.destination,
tmpContent.txContent.destinationLength,
displayBuffer,
sizeof(displayBuffer),
chainConfig->chainId);
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
2024-03-11 16:14:31 +01:00
if (strcasecmp_workaround(strings.common.toAddress, displayBuffer) != 0) {
2022-07-08 12:22:36 +02:00
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, address check failed\n");
THROW(ERR_SILENT_MODE_CHECK_FAILED);
}
2020-12-01 16:20:13 +01:00
} else {
2024-03-11 16:14:31 +01:00
strlcpy(strings.common.toAddress, displayBuffer, sizeof(strings.common.toAddress));
2020-12-01 16:20:13 +01:00
}
2024-06-19 11:24:13 +02:00
PRINTF("TO address displayed: %s\n", strings.common.toAddress);
// Format the amount in a temporary buffer, if in swap case compare it with validated
// amount, else commit it
if (!amountToString(tmpContent.txContent.value.value,
tmpContent.txContent.value.length,
decimals,
ticker,
displayBuffer,
sizeof(displayBuffer))) {
PRINTF("OVERFLOW, amount to string failed\n");
THROW(EXCEPTION_OVERFLOW);
}
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
2023-04-24 11:30:04 +02:00
if (strcmp(strings.common.fullAmount, displayBuffer) != 0) {
2022-07-08 12:22:36 +02:00
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, amount check failed\n");
PRINTF("Expected %s\n", strings.common.fullAmount);
PRINTF("Received %s\n", displayBuffer);
THROW(ERR_SILENT_MODE_CHECK_FAILED);
}
} else {
strlcpy(strings.common.fullAmount, displayBuffer, sizeof(strings.common.fullAmount));
}
PRINTF("Amount displayed: %s\n", strings.common.fullAmount);
2020-06-27 13:24:04 +02:00
}
// Compute the max fee in a temporary buffer, if in swap case compare it with validated max fee,
// else commit it
max_transaction_fee_to_string(&tmpContent.txContent.gasprice,
&tmpContent.txContent.startgas,
displayBuffer,
sizeof(displayBuffer));
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
2023-04-24 11:30:04 +02:00
if (strcmp(strings.common.maxFee, displayBuffer) != 0) {
2022-07-08 12:22:36 +02:00
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, fees check failed\n");
PRINTF("Expected %s\n", strings.common.maxFee);
PRINTF("Received %s\n", displayBuffer);
THROW(ERR_SILENT_MODE_CHECK_FAILED);
}
} else {
strlcpy(strings.common.maxFee, displayBuffer, sizeof(strings.common.maxFee));
}
2021-08-27 14:47:59 +02:00
PRINTF("Fees displayed: %s\n", strings.common.maxFee);
2020-06-29 15:43:02 +02:00
// Prepare nonce to display
nonce_to_string(&tmpContent.txContent.nonce,
strings.common.nonce,
sizeof(strings.common.nonce));
PRINTF("Nonce: %s\n", strings.common.nonce);
// Prepare network field
get_network_as_string(strings.common.network_name, sizeof(strings.common.network_name));
2021-08-27 14:47:59 +02:00
PRINTF("Network: %s\n", strings.common.network_name);
return true;
2024-03-18 08:58:05 +01:00
end:
return false;
}
2024-06-21 11:49:42 +02:00
void start_signature_flow(void) {
if (g_use_standard_ui) {
ux_approve_tx(false);
} else {
dataContext.tokenContext.pluginUiState = PLUGIN_UI_OUTSIDE;
dataContext.tokenContext.pluginUiCurrentItem = 0;
ux_approve_tx(true);
}
}
void finalizeParsing(void) {
g_use_standard_ui = true;
2024-06-21 11:49:42 +02:00
if (!finalize_parsing_helper()) {
return;
}
// If called from swap, the user has already validated a standard transaction
// And we have already checked the fields of this transaction above
2024-06-21 11:49:42 +02:00
if (G_called_from_swap && g_use_standard_ui) {
2020-12-01 16:20:13 +01:00
io_seproxyhal_touch_tx_ok(NULL);
} else {
2024-06-21 11:49:42 +02:00
// If blind-signing detected, start the warning flow beforehand
if (tmpContent.txContent.dataPresent) {
ui_warning_contract_data();
2020-12-01 16:20:13 +01:00
} else {
2024-06-21 11:49:42 +02:00
start_signature_flow();
2020-12-01 16:20:13 +01:00
}
2020-06-29 15:43:02 +02:00
}
2020-06-27 13:24:04 +02:00
}