Add setExternalPlugin command
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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 {
|
||||
|
||||
51
src_features/setExternalPlugin/cmd_setExternalPlugin.c
Normal file
51
src_features/setExternalPlugin/cmd_setExternalPlugin.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user