Add pointer to msg_sender in Eth_plugin_finalize (#170)

* Add some PRINTF debug statements and fir additional screens init

* Memzero struture and use two pointers less

* Clang-format

* Use ADDRESS_LENGTH where possible; Add printf statements when failing to compare contracts

* clang-format

* Remove 'token1' and 'token2' locals

* Fix typo

* apply clang-format

* Add bip32path to sharedRO for plugins

* Change getEthAddressStringFromKey to accept char instead of uint8_t

* Update ethereum plugin sdk

* Add BYPASS_SIGNATURES compilation option

* Remove bip32path and pathLength from sharedRO; add msg_sender pointer to pluginFinalize.address

* clang format eth_plugin_interface

* Update submodule

* Set address BEFORE making the finalize call

* Update SDK

Co-authored-by: TamtamHero <10632523+TamtamHero@users.noreply.github.com>
This commit is contained in:
pscott
2021-07-09 11:16:23 +02:00
committed by TamtamHero
parent 5ef3e77820
commit d541f1f524
13 changed files with 87 additions and 36 deletions

View File

@@ -266,6 +266,12 @@ ifneq ($(ALLOW_DATA),0)
DEFINES += HAVE_ALLOW_DATA
endif
# Bypass the signature verification for setExternalPlugin and provideERC20TokenInfo calls
BYPASS_SIGNATURES:=0
ifneq ($(BYPASS_SIGNATURES),0)
DEFINES += HAVE_BYPASS_SIGNATURES
endif
# Enabling debug PRINTF
DEBUG:=0

View File

@@ -148,7 +148,7 @@ typedef struct ethPluginFinalize_t {
uint8_t *tokenLookup2;
uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS
uint8_t *address; // set to a 20 bytes address pointer if uiType is UI_AMOUNT_ADDRESS
uint8_t *address; // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set to the user's address if uiType is UI_TYPE_GENERIC
uint8_t uiType;
uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS

View File

@@ -21,12 +21,8 @@ void eth_plugin_prepare_finalize(ethPluginFinalize_t *finalize) {
memset((uint8_t *) finalize, 0, sizeof(ethPluginFinalize_t));
}
void eth_plugin_prepare_provide_token(ethPluginProvideToken_t *provideToken,
tokenDefinition_t *token1,
tokenDefinition_t *token2) {
void eth_plugin_prepare_provide_token(ethPluginProvideToken_t *provideToken) {
memset((uint8_t *) provideToken, 0, sizeof(ethPluginProvideToken_t));
provideToken->token1 = token1;
provideToken->token2 = token2;
}
void eth_plugin_prepare_query_contract_ID(ethQueryContractID_t *queryContractID,
@@ -67,11 +63,19 @@ eth_plugin_result_t eth_plugin_perform_init(uint8_t *contractAddress,
if (memcmp(contractAddress,
dataContext.tokenContext.contract_address,
sizeof(dataContext.tokenContext.contract_address)) != 0) {
PRINTF("Got contract: %.*H\n", ADDRESS_LENGTH, contractAddress);
PRINTF("Expected contract: %.*H\n",
ADDRESS_LENGTH,
dataContext.tokenContext.contract_address);
os_sched_exit(0);
}
if (memcmp(init->selector,
dataContext.tokenContext.method_selector,
sizeof(dataContext.tokenContext.method_selector)) != 0) {
PRINTF("Got selector: %.*H\n", SELECTOR_SIZE, init->selector);
PRINTF("Expected selector: %.*H\n",
SELECTOR_SIZE,
dataContext.tokenContext.method_selector);
os_sched_exit(0);
}
PRINTF("External plugin will be used\n");
@@ -145,6 +149,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
switch (method) {
case ETH_PLUGIN_INIT_CONTRACT:
PRINTF("-- PLUGIN INIT CONTRACT --\n");
((ethPluginInitContract_t *) parameter)->interfaceVersion =
ETH_PLUGIN_INTERFACE_VERSION_1;
((ethPluginInitContract_t *) parameter)->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
@@ -157,6 +162,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
((ethPluginInitContract_t *) parameter)->alias = dataContext.tokenContext.pluginName;
break;
case ETH_PLUGIN_PROVIDE_PARAMETER:
PRINTF("-- PLUGIN PROVIDE PARAMETER --\n");
((ethPluginProvideParameter_t *) parameter)->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
((ethPluginProvideParameter_t *) parameter)->pluginSharedRW = &pluginRW;
((ethPluginProvideParameter_t *) parameter)->pluginSharedRO = &pluginRO;
@@ -164,6 +170,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
(uint8_t *) &dataContext.tokenContext.pluginContext;
break;
case ETH_PLUGIN_FINALIZE:
PRINTF("-- PLUGIN FINALIZE --\n");
((ethPluginFinalize_t *) parameter)->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
((ethPluginFinalize_t *) parameter)->pluginSharedRW = &pluginRW;
((ethPluginFinalize_t *) parameter)->pluginSharedRO = &pluginRO;
@@ -171,6 +178,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
(uint8_t *) &dataContext.tokenContext.pluginContext;
break;
case ETH_PLUGIN_PROVIDE_TOKEN:
PRINTF("-- PLUGIN PROVIDE TOKEN --\n");
((ethPluginProvideToken_t *) parameter)->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
((ethPluginProvideToken_t *) parameter)->pluginSharedRW = &pluginRW;
((ethPluginProvideToken_t *) parameter)->pluginSharedRO = &pluginRO;
@@ -178,6 +186,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
(uint8_t *) &dataContext.tokenContext.pluginContext;
break;
case ETH_PLUGIN_QUERY_CONTRACT_ID:
PRINTF("-- PLUGIN QUERY CONTRACT ID --\n");
((ethQueryContractID_t *) parameter)->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
((ethQueryContractID_t *) parameter)->pluginSharedRW = &pluginRW;
((ethQueryContractID_t *) parameter)->pluginSharedRO = &pluginRO;
@@ -185,6 +194,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
(uint8_t *) &dataContext.tokenContext.pluginContext;
break;
case ETH_PLUGIN_QUERY_CONTRACT_UI:
PRINTF("-- PLUGIN QUERY CONTRACT UI --\n");
((ethQueryContractUI_t *) parameter)->pluginSharedRW = &pluginRW;
((ethQueryContractUI_t *) parameter)->pluginSharedRO = &pluginRO;
((ethQueryContractUI_t *) parameter)->pluginContext =
@@ -230,7 +240,6 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
PRINTF("method: %d\n", method);
switch (method) {
case ETH_PLUGIN_INIT_CONTRACT:
PRINTF("parameter result: %d\n", ((ethPluginInitContract_t *) parameter)->result);
switch (((ethPluginInitContract_t *) parameter)->result) {
case ETH_PLUGIN_RESULT_OK:
break;
@@ -263,6 +272,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
}
break;
case ETH_PLUGIN_PROVIDE_TOKEN:
PRINTF("RESULT: %d\n", ((ethPluginProvideToken_t *) parameter)->result);
switch (((ethPluginProvideToken_t *) parameter)->result) {
case ETH_PLUGIN_RESULT_OK:
case ETH_PLUGIN_RESULT_FALLBACK:
@@ -279,7 +289,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
}
break;
case ETH_PLUGIN_QUERY_CONTRACT_UI:
if (((ethQueryContractUI_t *) parameter)->result <= ETH_PLUGIN_RESULT_OK) {
if (((ethQueryContractUI_t *) parameter)->result <= ETH_PLUGIN_RESULT_UNSUCCESSFUL) {
return ETH_PLUGIN_RESULT_UNAVAILABLE;
}
break;

View File

@@ -7,9 +7,7 @@ void eth_plugin_prepare_provide_parameter(ethPluginProvideParameter_t *providePa
uint8_t *parameter,
uint32_t parameterOffset);
void eth_plugin_prepare_finalize(ethPluginFinalize_t *finalize);
void eth_plugin_prepare_provide_token(ethPluginProvideToken_t *provideToken,
tokenDefinition_t *token1,
tokenDefinition_t *token2);
void eth_plugin_prepare_provide_token(ethPluginProvideToken_t *provideToken);
void eth_plugin_prepare_query_contract_ID(ethQueryContractID_t *queryContractID,
char *name,
uint32_t nameLength,

View File

@@ -104,7 +104,8 @@ typedef struct ethPluginFinalize_t {
uint8_t *tokenLookup2;
uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS
uint8_t *address; // set to a 20 bytes address pointer if uiType is UI_AMOUNT_ADDRESS
uint8_t *address; // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set to the
// user's address if uiType is UI_TYPE_GENERIC
uint8_t uiType;
uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS

View File

@@ -23,7 +23,9 @@ void plugin_ui_get_id() {
strings.tmp.tmp2,
sizeof(strings.tmp.tmp2));
// Query the original contract for ID if it's not an internal alias
if (!eth_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_ID, (void *) &pluginQueryContractID)) {
eth_plugin_result_t status =
eth_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_ID, (void *) &pluginQueryContractID);
if (status != ETH_PLUGIN_RESULT_OK) {
PRINTF("Plugin query contract ID call failed\n");
io_seproxyhal_touch_tx_cancel(NULL);
}
@@ -37,8 +39,10 @@ void plugin_ui_get_item() {
sizeof(strings.tmp.tmp),
strings.tmp.tmp2,
sizeof(strings.tmp.tmp2));
if (!eth_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_UI, (void *) &pluginQueryContractUI)) {
PRINTF("Plugin query contract UI call failed\n");
eth_plugin_result_t status =
eth_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_UI, (void *) &pluginQueryContractUI);
if (status != ETH_PLUGIN_RESULT_OK) {
PRINTF("Plugin query contract UI call failed, got: %d\n", status);
io_seproxyhal_touch_tx_cancel(NULL);
}
}

View File

@@ -394,7 +394,7 @@ void handleGetWalletId(volatile unsigned int *tx) {
THROW(0x9000);
}
#endif // HAVE_WALLET_ID_SDK
#endif // HAVE_WALLET_ID_SDK
void handleApdu(unsigned int *flags, unsigned int *tx) {
unsigned short sw = 0;
@@ -409,7 +409,7 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
return;
}
#endif // HAVE_WALLET_ID_SDK
#endif // HAVE_WALLET_ID_SDK
#ifdef HAVE_STARKWARE

View File

@@ -124,7 +124,7 @@ void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3
}
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey,
uint8_t *out,
char *out,
cx_sha3_t *sha3Context,
chain_config_t *chain_config) {
uint8_t hashAddress[INT256_LENGTH];

View File

@@ -40,7 +40,7 @@ bool rlpCanDecode(uint8_t *buffer, uint32_t bufferLength, bool *valid);
void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3_t *sha3Context);
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey,
uint8_t *out,
char *out,
cx_sha3_t *sha3Context,
chain_config_t *chain_config);

View File

@@ -88,8 +88,10 @@ void handleProvideErc20TokenInformation(uint8_t p1,
32,
workBuffer + offset,
dataLength)) {
#ifndef HAVE_BYPASS_SIGNATURES
PRINTF("Invalid token signature\n");
THROW(0x6A80);
#endif
}
tmpCtx.transactionContext.tokenSet[tmpCtx.transactionContext.currentTokenIndex] = 1;
THROW(0x9000);
@@ -175,8 +177,10 @@ void handleProvideErc20TokenInformation(uint8_t p1,
32,
workBuffer + offset,
dataLength)) {
#ifndef HAVE_BYPASS_SIGNATURES
PRINTF("Invalid token signature\n");
THROW(0x6A80);
#endif
}
}
@@ -193,8 +197,10 @@ void handleProvideErc20TokenInformation(uint8_t p1,
32,
workBuffer + offset,
dataLength)) {
#ifndef HAVE_BYPASS_SIGNATURES
PRINTF("Invalid token signature\n");
THROW(0x6A80);
#endif
}
#endif

View File

@@ -3,8 +3,7 @@
#include "ui_flow.h"
#include "tokens.h"
#define CONTRACT_ADDR_SIZE 20
#define SELECTOR_SIZE 4
#define SELECTOR_SIZE 4
void handleSetExternalPlugin(uint8_t p1,
uint8_t p2,
@@ -19,7 +18,7 @@ void handleSetExternalPlugin(uint8_t p1,
uint8_t hash[32];
cx_ecfp_public_key_t tokenKey;
uint8_t pluginNameLength = *workBuffer;
const size_t payload_size = 1 + pluginNameLength + CONTRACT_ADDR_SIZE + SELECTOR_SIZE;
const size_t payload_size = 1 + pluginNameLength + ADDRESS_LENGTH + SELECTOR_SIZE;
if (dataLength <= payload_size) {
THROW(0x6A80);
@@ -43,7 +42,9 @@ void handleSetExternalPlugin(uint8_t p1,
workBuffer + payload_size,
dataLength - payload_size)) {
PRINTF("Invalid external plugin signature %.*H\n", payload_size, workBuffer);
#ifndef HAVE_BYPASS_SIGNATURES
THROW(0x6A80);
#endif
}
// move on to the rest of the payload parsing
@@ -76,8 +77,8 @@ void handleSetExternalPlugin(uint8_t p1,
PRINTF("Plugin found\n");
memmove(dataContext.tokenContext.contract_address, workBuffer, CONTRACT_ADDR_SIZE);
workBuffer += 20;
memmove(dataContext.tokenContext.contract_address, workBuffer, ADDRESS_LENGTH);
workBuffer += ADDRESS_LENGTH;
memmove(dataContext.tokenContext.method_selector, workBuffer, SELECTOR_SIZE);
externalPluginIsSet = true;

View File

@@ -239,12 +239,32 @@ void computeFees(char *displayBuffer, uint32_t displayBufferSize) {
displayBuffer[tickerOffset + i] = '\0';
}
static void get_public_key(uint8_t *out, uint8_t outLength) {
uint8_t privateKeyData[INT256_LENGTH] = {0};
cx_ecfp_private_key_t privateKey = {0};
cx_ecfp_public_key_t publicKey = {0};
if (outLength < ADDRESS_LENGTH) {
return;
}
os_perso_derive_node_bip32(CX_CURVE_256K1,
tmpCtx.transactionContext.bip32Path,
tmpCtx.transactionContext.pathLength,
privateKeyData,
NULL);
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
cx_ecfp_generate_pair(CX_CURVE_256K1, &publicKey, &privateKey, 1);
explicit_bzero(&privateKey, sizeof(privateKey));
explicit_bzero(privateKeyData, sizeof(privateKeyData));
getEthAddressFromKey(&publicKey, out, &global_sha3);
}
void finalizeParsing(bool direct) {
char displayBuffer[50];
uint8_t decimals = WEI_TO_ETHER;
char *ticker = get_network_ticker();
ethPluginFinalize_t pluginFinalize;
tokenDefinition_t *token1 = NULL, *token2 = NULL;
bool genericUI = true;
// Verify the chain
@@ -272,6 +292,11 @@ void finalizeParsing(bool direct) {
if (dataContext.tokenContext.pluginStatus >= ETH_PLUGIN_RESULT_SUCCESSFUL) {
genericUI = false;
eth_plugin_prepare_finalize(&pluginFinalize);
uint8_t msg_sender[ADDRESS_LENGTH] = {0};
get_public_key(msg_sender, sizeof(msg_sender));
pluginFinalize.address = msg_sender;
if (!eth_plugin_call(ETH_PLUGIN_FINALIZE, (void *) &pluginFinalize)) {
PRINTF("Plugin finalize call failed\n");
reportFinalizeError(direct);
@@ -281,22 +306,22 @@ void finalizeParsing(bool direct) {
}
// Lookup tokens if requested
ethPluginProvideToken_t pluginProvideToken;
eth_plugin_prepare_provide_token(&pluginProvideToken);
if ((pluginFinalize.tokenLookup1 != NULL) || (pluginFinalize.tokenLookup2 != NULL)) {
if (pluginFinalize.tokenLookup1 != NULL) {
PRINTF("Lookup1: %.*H\n", ADDRESS_LENGTH, pluginFinalize.tokenLookup1);
token1 = getKnownToken(pluginFinalize.tokenLookup1);
if (token1 != NULL) {
PRINTF("Token1 ticker: %s\n", token1->ticker);
pluginProvideToken.token1 = getKnownToken(pluginFinalize.tokenLookup1);
if (pluginProvideToken.token1 != NULL) {
PRINTF("Token1 ticker: %s\n", pluginProvideToken.token1->ticker);
}
}
if (pluginFinalize.tokenLookup2 != NULL) {
PRINTF("Lookup2: %.*H\n", ADDRESS_LENGTH, pluginFinalize.tokenLookup2);
token2 = getKnownToken(pluginFinalize.tokenLookup2);
if (token2 != NULL) {
PRINTF("Token2 ticker: %s\n", token2->ticker);
pluginProvideToken.token2 = getKnownToken(pluginFinalize.tokenLookup2);
if (pluginProvideToken.token2 != NULL) {
PRINTF("Token2 ticker: %s\n", pluginProvideToken.token2->ticker);
}
}
eth_plugin_prepare_provide_token(&pluginProvideToken, token1, token2);
if (eth_plugin_call(ETH_PLUGIN_PROVIDE_TOKEN, (void *) &pluginProvideToken) <=
ETH_PLUGIN_RESULT_UNSUCCESSFUL) {
PRINTF("Plugin provide token call failed\n");
@@ -331,9 +356,9 @@ void finalizeParsing(bool direct) {
tmpContent.txContent.value.length = 32;
memmove(tmpContent.txContent.destination, pluginFinalize.address, 20);
tmpContent.txContent.destinationLength = 20;
if (token1 != NULL) {
decimals = token1->decimals;
ticker = (char *) token1->ticker;
if (pluginProvideToken.token1 != NULL) {
decimals = pluginProvideToken.token1->decimals;
ticker = (char *) pluginProvideToken.token1->ticker;
}
break;
default: