Add Ledger signature checking for external plugins
This commit is contained in:
@@ -245,12 +245,18 @@ None
|
||||
|
||||
#### Description
|
||||
|
||||
This commands provides the name of a plugin that should be called to interpret contract data in the following transaction signing command.
|
||||
This commands provides the name of a trusted binding of a plugin with a contract address and a supported method selector. This plugin will 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.
|
||||
|
||||
The signature is computed on
|
||||
|
||||
len(pluginName) || pluginName || contractAddress || methodSelector
|
||||
|
||||
signed by the following secp256k1 public key 0482bbf2f34f367b2e5bc21847b6566f21f0976b22d3388a9a5e446ac62d25cf725b62a2555b2dd464a4da0ab2f4d506820543af1d242470b1b1a969a27578f353
|
||||
|
||||
#### Coding
|
||||
|
||||
'Command'
|
||||
@@ -266,7 +272,11 @@ The function returns an error sw (0x6984) if the plugin requested is not install
|
||||
[width="80%"]
|
||||
|==============================================================================================================================
|
||||
| *Description* | *Length*
|
||||
| Plugin name | variable
|
||||
| Length of plugin name | 1
|
||||
| plugin name | variable
|
||||
| contract address | 20
|
||||
| method selector | 4
|
||||
| signature | variable
|
||||
|==============================================================================================================================
|
||||
|
||||
'Output data'
|
||||
|
||||
25
src/tokens.h
25
src/tokens.h
@@ -39,7 +39,30 @@ extern tokenDefinition_t const TOKENS_EXTRA[NUM_TOKENS_EXTRA];
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TOKENS_LIST
|
||||
#ifndef HAVE_TOKENS_LIST
|
||||
|
||||
#ifndef LEDGER_TEST_PUBLIC_KEY
|
||||
static const uint8_t const LEDGER_SIGNATURE_PUBLIC_KEY[] = {
|
||||
// production key 2019-01-11 03:07PM (erc20signer)
|
||||
0x04,
|
||||
0x5e, 0x6c, 0x10, 0x20, 0xc1, 0x4d, 0xc4, 0x64, 0x42, 0xfe, 0x89, 0xf9, 0x7c, 0x0b, 0x68, 0xcd,
|
||||
0xb1, 0x59, 0x76, 0xdc, 0x24, 0xf2, 0x4c, 0x31, 0x6e, 0x7b, 0x30, 0xfe, 0x4e, 0x8c, 0xc7, 0x6b,
|
||||
0x14, 0x89, 0x15, 0x0c, 0x21, 0x51, 0x4e, 0xbf, 0x44, 0x0f, 0xf5, 0xde, 0xa5, 0x39, 0x3d, 0x83,
|
||||
0xde, 0x53, 0x58, 0xcd, 0x09, 0x8f, 0xce, 0x8f, 0xd0, 0xf8, 0x1d, 0xaa, 0x94, 0x97, 0x91, 0x83
|
||||
};
|
||||
|
||||
#else
|
||||
static const uint8_t const LEDGER_SIGNATURE_PUBLIC_KEY[] = {
|
||||
// test key 2019-01-11 03:07PM (erc20signer)
|
||||
0x04,
|
||||
0x20, 0xda, 0x62, 0x00, 0x3c, 0x0c, 0xe0, 0x97, 0xe3, 0x36, 0x44, 0xa1, 0x0f, 0xe4, 0xc3, 0x04,
|
||||
0x54, 0x06, 0x9a, 0x44, 0x54, 0xf0, 0xfa, 0x9d, 0x4e, 0x84, 0xf4, 0x50, 0x91, 0x42, 0x9b, 0x52,
|
||||
0x20, 0xaf, 0x9e, 0x35, 0xc0, 0xb2, 0xd9, 0x28, 0x93, 0x80, 0x13, 0x73, 0x07, 0xde, 0x4d, 0xd1,
|
||||
0xd4, 0x18, 0x42, 0x8c, 0xf2, 0x1a, 0x93, 0xb3, 0x35, 0x61, 0xbb, 0x09, 0xd8, 0x8f, 0xe5, 0x79,
|
||||
};
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define NUM_TOKENS_AKROMA 0
|
||||
#define NUM_TOKENS_ELLAISM 1
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
#include "shared_context.h"
|
||||
#include "apdu_constants.h"
|
||||
#include "ui_flow.h"
|
||||
|
||||
static const uint8_t const TOKEN_SIGNATURE_PUBLIC_KEY[] = {
|
||||
// production key 2019-01-11 03:07PM (erc20signer)
|
||||
0x04,
|
||||
|
||||
0x5e, 0x6c, 0x10, 0x20, 0xc1, 0x4d, 0xc4, 0x64, 0x42, 0xfe, 0x89, 0xf9, 0x7c, 0x0b, 0x68, 0xcd,
|
||||
0xb1, 0x59, 0x76, 0xdc, 0x24, 0xf2, 0x4c, 0x31, 0x6e, 0x7b, 0x30, 0xfe, 0x4e, 0x8c, 0xc7, 0x6b,
|
||||
|
||||
0x14, 0x89, 0x15, 0x0c, 0x21, 0x51, 0x4e, 0xbf, 0x44, 0x0f, 0xf5, 0xde, 0xa5, 0x39, 0x3d, 0x83,
|
||||
0xde, 0x53, 0x58, 0xcd, 0x09, 0x8f, 0xce, 0x8f, 0xd0, 0xf8, 0x1d, 0xaa, 0x94, 0x97, 0x91, 0x83};
|
||||
#include "tokens.h"
|
||||
|
||||
#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR
|
||||
|
||||
@@ -87,8 +78,8 @@ void handleProvideErc20TokenInformation(uint8_t p1,
|
||||
offset += 4;
|
||||
dataLength -= 4;
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
TOKEN_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(TOKEN_SIGNATURE_PUBLIC_KEY),
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey);
|
||||
if (!cx_ecdsa_verify(&tokenKey,
|
||||
CX_LAST,
|
||||
@@ -174,8 +165,8 @@ void handleProvideErc20TokenInformation(uint8_t p1,
|
||||
PRINTF("Descriptor whitelisted\n");
|
||||
} else {
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
TOKEN_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(TOKEN_SIGNATURE_PUBLIC_KEY),
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey);
|
||||
if (!cx_ecdsa_verify(&tokenKey,
|
||||
CX_LAST,
|
||||
@@ -192,8 +183,8 @@ void handleProvideErc20TokenInformation(uint8_t p1,
|
||||
#else
|
||||
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
TOKEN_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(TOKEN_SIGNATURE_PUBLIC_KEY),
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey);
|
||||
if (!cx_ecdsa_verify(&tokenKey,
|
||||
CX_LAST,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "shared_context.h"
|
||||
#include "apdu_constants.h"
|
||||
#include "ui_flow.h"
|
||||
#include "tokens.h"
|
||||
|
||||
#define CONTRACT_ADDR_SIZE 20
|
||||
#define SELECTOR_SIZE 4
|
||||
@@ -14,9 +15,12 @@ void handleSetExternalPlugin(uint8_t p1,
|
||||
UNUSED(p1);
|
||||
UNUSED(p2);
|
||||
UNUSED(flags);
|
||||
uint8_t pluginNameLength = *workBuffer++;
|
||||
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;
|
||||
|
||||
if (dataLength < 1 || dataLength != 1 + pluginNameLength + CONTRACT_ADDR_SIZE + SELECTOR_SIZE) {
|
||||
if (dataLength <= payload_size) {
|
||||
THROW(0x6A80);
|
||||
}
|
||||
|
||||
@@ -24,6 +28,19 @@ void handleSetExternalPlugin(uint8_t p1,
|
||||
THROW(0x6A80);
|
||||
}
|
||||
|
||||
// check Ledger's signature over the payload
|
||||
cx_hash_sha256(workBuffer, payload_size, hash, sizeof(hash));
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey);
|
||||
if(!cx_ecdsa_verify(&tokenKey, CX_LAST, CX_SHA256, hash, sizeof(hash), workBuffer+payload_size, dataLength-payload_size)){
|
||||
PRINTF("Invalid external plugin signature %.*H\n", payload_size, workBuffer);
|
||||
THROW(0x6A80);
|
||||
}
|
||||
|
||||
// move on to the rest of the payload parsing
|
||||
workBuffer++;
|
||||
memmove(dataContext.tokenContext.pluginName, workBuffer, pluginNameLength);
|
||||
dataContext.tokenContext.pluginName[pluginNameLength] = '\0';
|
||||
workBuffer += pluginNameLength;
|
||||
|
||||
Reference in New Issue
Block a user