Add setExternalPlugin command

This commit is contained in:
TamtamHero
2020-12-03 16:32:40 +01:00
committed by pscott
parent fbbc11a54a
commit b821c0d8a7
8 changed files with 137 additions and 22 deletions

View File

@@ -20,6 +20,9 @@ Application version 1.5.0 - 25th of September 2020
- Add SIGN ETH EIP 712
- Add GET ETH2 PUBLIC KEY
## 1.6.3
- Add SET EXTERNAL PLUGIN
## About
This application describes the APDU messages interface to communicate with the Ethereum application.
@@ -237,6 +240,39 @@ signed by the following secp256k1 public key 0482bbf2f34f367b2e5bc21847b6566f21f
None
### SET EXTERNAL PLUGIN
#### Description
This commands provides the name of a plugin that should be called to interpret contract data in the following transaction signing command.
It shall be run immediately before performing a transaction involving a contract supported by this plugin to display the proper information to the user if necessary.
The function returns an error sw (0x6984) if the plugin requested is not installed on the device, 0x9000 otherwise.
#### Coding
'Command'
[width="80%"]
|==============================================================================================================================
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
| E0 | 12 | 00 | 00 | variable | 00
|==============================================================================================================================
'Input data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Plugin name | variable
|==============================================================================================================================
'Output data'
None
### GET APP CONFIGURATION
#### Description

View File

@@ -14,6 +14,7 @@
#define INS_SIGN_EIP_712_MESSAGE 0x0C
#define INS_GET_ETH2_PUBLIC_KEY 0x0E
#define INS_SET_ETH2_WITHDRAWAL_INDEX 0x10
#define INS_SET_EXTERNAL_PLUGIN 0x12
#define P1_CONFIRM 0x01
#define P1_NON_CONFIRM 0x00
#define P2_NO_CHAINCODE 0x00
@@ -88,6 +89,13 @@ void handleSignEIP712Message(uint8_t p1,
unsigned int *flags,
unsigned int *tx);
void handleSetExternalPlugin(uint8_t p1,
uint8_t p2,
uint8_t *workBuffer,
uint16_t dataLength,
unsigned int *flags,
unsigned int *tx);
#ifdef HAVE_ETH2
void handleGetEth2PublicKey(uint8_t p1,

View File

@@ -61,23 +61,31 @@ eth_plugin_result_t eth_plugin_perform_init(uint8_t *contractAddress,
uint8_t i;
const uint8_t **selectors;
dataContext.tokenContext.pluginStatus = ETH_PLUGIN_RESULT_UNAVAILABLE;
// Handle hardcoded plugin list
PRINTF("Selector %.*H\n", 4, init->selector);
for (i = 0;; i++) {
uint8_t j;
selectors = (const uint8_t **) PIC(INTERNAL_ETH_PLUGINS[i].selectors);
if (selectors == NULL) {
break;
}
for (j = 0; ((j < INTERNAL_ETH_PLUGINS[i].num_selectors) && (contractAddress != NULL));
j++) {
if (memcmp(init->selector, (const void *) PIC(selectors[j]), SELECTOR_SIZE) == 0) {
if ((INTERNAL_ETH_PLUGINS[i].availableCheck == NULL) ||
((PluginAvailableCheck) PIC(INTERNAL_ETH_PLUGINS[i].availableCheck))()) {
strcpy(dataContext.tokenContext.pluginName, INTERNAL_ETH_PLUGINS[i].alias);
dataContext.tokenContext.pluginStatus = ETH_PLUGIN_RESULT_OK;
contractAddress = NULL;
break;
if (tmpCtx.transactionContext.externalPluginIsSet) {
PRINTF("External plugin will be used\n");
dataContext.tokenContext.pluginStatus = ETH_PLUGIN_RESULT_OK;
contractAddress = NULL;
}
else {
// Search internal plugin list
for (i = 0;; i++) {
uint8_t j;
selectors = (const uint8_t **) PIC(INTERNAL_ETH_PLUGINS[i].selectors);
if (selectors == NULL) {
break;
}
for (j = 0; ((j < INTERNAL_ETH_PLUGINS[i].num_selectors) && (contractAddress != NULL));
j++) {
if (memcmp(init->selector, (const void *) PIC(selectors[j]), SELECTOR_SIZE) == 0) {
if ((INTERNAL_ETH_PLUGINS[i].availableCheck == NULL) ||
((PluginAvailableCheck) PIC(INTERNAL_ETH_PLUGINS[i].availableCheck))()) {
strcpy(dataContext.tokenContext.pluginName, INTERNAL_ETH_PLUGINS[i].alias);
dataContext.tokenContext.pluginStatus = ETH_PLUGIN_RESULT_OK;
contractAddress = NULL;
break;
}
}
}
}

View File

@@ -16,7 +16,8 @@ typedef enum {
ETH_PLUGIN_FINALIZE = 0x0103,
ETH_PLUGIN_PROVIDE_TOKEN = 0x0104,
ETH_PLUGIN_QUERY_CONTRACT_ID = 0x0105,
ETH_PLUGIN_QUERY_CONTRACT_UI = 0x0106
ETH_PLUGIN_QUERY_CONTRACT_UI = 0x0106,
ETH_PLUGIN_CHECK_PRESENCE = 0x01FF
} eth_plugin_msg_t;

View File

@@ -23,11 +23,12 @@ 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(
(dataContext.tokenContext.pluginName[0] == '-' ? NULL
: tmpContent.txContent.destination),
ETH_PLUGIN_QUERY_CONTRACT_ID,
(void *) &pluginQueryContractID)) {
if (!eth_plugin_call((dataContext.tokenContext.pluginName[0] == '-' ||
tmpCtx.transactionContext.externalPluginIsSet
? NULL
: tmpContent.txContent.destination),
ETH_PLUGIN_QUERY_CONTRACT_ID,
(void *) &pluginQueryContractID)) {
PRINTF("Plugin query contract ID call failed\n");
io_seproxyhal_touch_tx_cancel(NULL);
}

View File

@@ -496,6 +496,15 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
tx);
break;
case INS_SET_EXTERNAL_PLUGIN:
handleSetExternalPlugin(G_io_apdu_buffer[OFFSET_P1],
G_io_apdu_buffer[OFFSET_P2],
G_io_apdu_buffer + OFFSET_CDATA,
G_io_apdu_buffer[OFFSET_LC],
flags,
tx);
break;
case INS_SIGN:
handleSign(G_io_apdu_buffer[OFFSET_P1],
G_io_apdu_buffer[OFFSET_P2],

View File

@@ -83,6 +83,7 @@ typedef struct transactionContext_t {
tokenDefinition_t tokens[MAX_TOKEN];
uint8_t tokenSet[MAX_TOKEN];
uint8_t currentTokenIndex;
bool externalPluginIsSet;
} transactionContext_t;
typedef struct messageSigningContext_t {

View File

@@ -0,0 +1,51 @@
#include "shared_context.h"
#include "apdu_constants.h"
#include "ui_flow.h"
void handleSetExternalPlugin(uint8_t p1,
uint8_t p2,
uint8_t *workBuffer,
uint16_t dataLength,
unsigned int *flags,
unsigned int *tx) {
UNUSED(p1);
UNUSED(p2);
UNUSED(flags);
uint8_t pluginNameLength = dataLength;
if (dataLength < 1) {
THROW(0x6A80);
}
if (pluginNameLength + 1 > sizeof(dataContext.tokenContext.pluginName)) {
THROW(0x6A80);
}
memmove(dataContext.tokenContext.pluginName, workBuffer, pluginNameLength);
dataContext.tokenContext.pluginName[pluginNameLength] = '\0';
PRINTF("Check external plugin %s\n", dataContext.tokenContext.pluginName);
// Check if the plugin is present on the device
uint32_t params[2];
params[0] = (uint32_t) dataContext.tokenContext.pluginName;
params[1] = ETH_PLUGIN_CHECK_PRESENCE;
BEGIN_TRY {
TRY {
os_lib_call(params);
}
CATCH_OTHER(e) {
PRINTF("%s external plugin is not present\n", dataContext.tokenContext.pluginName);
THROW(0x6984);
}
FINALLY {
}
}
END_TRY;
tmpCtx.transactionContext.externalPluginIsSet = true;
PRINTF("Plugin found\n");
G_io_apdu_buffer[(*tx)++] = 0x90;
G_io_apdu_buffer[(*tx)++] = 0x00;
}