Files
app-ethereum/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c
pscott b646cf1b28 Fix compilation warnings (#159)
* Fix easy warnings for sdk 2.0

* Add attribute unused to bagl_elemt_t in callback functions

* Add attribute unused to io_event function

* Clang-format

* Use elfs from CI in tests (#167)

* Add Nano X build

* Use CI's build artifacts for CI's tests

* Add network display (#152)

* Add network name display instead of chainID

* Add display of correct ticker along with network

* Add FTM

* Clang-format

* Add comment in python script

* Rename SIZE_MAX to MAX_SIZE

* Change %u to %d in printf

* Remove needless PIC

* Update comment about get_chain_id()

* Update example script to follow EIP155

* Remove unused PIC calls

* Add whitespace between ticker and amount when using EIP155

* Remove decimal config per network, set back 18 everywhere

* Adapt u32_from_BE to swith cases

* Remove chainid from signTx.py

* Switch to switch in stead of if in get_chain_id

* Revert "Remove chainid from signTx.py"

This reverts commit 454e09f280ec3e3ec1c7d7cc0027247ef4390088.

* Change Ethereum chainid to 1

* Rename chainid_step to network_step

* Adapt finalizeParsing to new chainid for Ethereum

* Update snapshots

* clang-format

* Fix network display logic for clones

* Fix tests

* Add clone tests

Co-authored-by: TamtamHero <10632523+TamtamHero@users.noreply.github.com>

Co-authored-by: Jean P <10632523+TamtamHero@users.noreply.github.com>
2021-07-05 11:01:51 +02:00

206 lines
6.8 KiB
C

#include "shared_context.h"
#include "apdu_constants.h"
#include "ui_flow.h"
#include "tokens.h"
#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR
void handleProvideErc20TokenInformation(uint8_t p1,
uint8_t p2,
uint8_t *workBuffer,
uint16_t dataLength,
unsigned int *flags,
unsigned int *tx) {
UNUSED(p1);
UNUSED(p2);
UNUSED(flags);
uint32_t offset = 0;
uint8_t tickerLength, contractNameLength;
uint32_t chainId;
uint8_t hash[INT256_LENGTH];
cx_sha256_t sha256;
cx_ecfp_public_key_t tokenKey;
cx_sha256_init(&sha256);
tmpCtx.transactionContext.currentTokenIndex =
(tmpCtx.transactionContext.currentTokenIndex + 1) % MAX_TOKEN;
tokenDefinition_t *token =
&tmpCtx.transactionContext.tokens[tmpCtx.transactionContext.currentTokenIndex];
if (dataLength < 1) {
THROW(0x6A80);
}
tickerLength = workBuffer[offset++];
dataLength--;
if ((tickerLength + 2) >= sizeof(token->ticker)) { // +2 because ' \0' is appended to ticker
THROW(0x6A80);
}
if (dataLength < tickerLength + 1) {
THROW(0x6A80);
}
cx_hash((cx_hash_t *) &sha256, 0, workBuffer + offset, tickerLength, NULL, 0);
memmove(token->ticker, workBuffer + offset, tickerLength);
token->ticker[tickerLength] = ' ';
token->ticker[tickerLength + 1] = '\0';
offset += tickerLength;
dataLength -= tickerLength;
contractNameLength = workBuffer[offset++];
dataLength--;
if (dataLength < contractNameLength + 20 + 4 + 4) {
THROW(0x6A80);
}
cx_hash((cx_hash_t *) &sha256,
CX_LAST,
workBuffer + offset,
contractNameLength + 20 + 4 + 4,
hash,
32);
memmove(token->contractName,
workBuffer + offset,
MIN(contractNameLength, sizeof(token->contractName) - 1));
token->contractName[MIN(contractNameLength, sizeof(token->contractName) - 1)] = '\0';
offset += contractNameLength;
dataLength -= contractNameLength;
memmove(token->address, workBuffer + offset, 20);
offset += 20;
dataLength -= 20;
token->decimals = U4BE(workBuffer, offset);
offset += 4;
dataLength -= 4;
chainId = U4BE(workBuffer, offset);
if ((chainConfig->chainId != 0) && (chainConfig->chainId != chainId)) {
PRINTF("ChainId token mismatch\n");
THROW(0x6A80);
}
offset += 4;
dataLength -= 4;
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,
32,
workBuffer + offset,
dataLength)) {
PRINTF("Invalid token signature\n");
THROW(0x6A80);
}
tmpCtx.transactionContext.tokenSet[tmpCtx.transactionContext.currentTokenIndex] = 1;
THROW(0x9000);
}
#else
void handleProvideErc20TokenInformation(uint8_t p1,
uint8_t p2,
uint8_t *workBuffer,
uint16_t dataLength,
unsigned int *flags,
__attribute__((unused)) unsigned int *tx) {
UNUSED(p1);
UNUSED(p2);
UNUSED(flags);
uint32_t offset = 0;
uint8_t tickerLength;
uint32_t chainId;
uint8_t hash[INT256_LENGTH];
cx_ecfp_public_key_t tokenKey;
tmpCtx.transactionContext.currentTokenIndex =
(tmpCtx.transactionContext.currentTokenIndex + 1) % MAX_TOKEN;
tokenDefinition_t *token =
&tmpCtx.transactionContext.tokens[tmpCtx.transactionContext.currentTokenIndex];
PRINTF("Provisioning currentTokenIndex %d\n", tmpCtx.transactionContext.currentTokenIndex);
if (dataLength < 1) {
THROW(0x6A80);
}
tickerLength = workBuffer[offset++];
dataLength--;
if ((tickerLength + 1) >= sizeof(token->ticker)) {
THROW(0x6A80);
}
if (dataLength < tickerLength + 20 + 4 + 4) {
THROW(0x6A80);
}
cx_hash_sha256(workBuffer + offset, tickerLength + 20 + 4 + 4, hash, 32);
memmove(token->ticker, workBuffer + offset, tickerLength);
token->ticker[tickerLength] = ' ';
token->ticker[tickerLength + 1] = '\0';
offset += tickerLength;
dataLength -= tickerLength;
memmove(token->address, workBuffer + offset, 20);
offset += 20;
dataLength -= 20;
token->decimals = U4BE(workBuffer, offset);
offset += 4;
dataLength -= 4;
chainId = U4BE(workBuffer, offset);
if ((chainConfig->chainId != 0) && (chainConfig->chainId != chainId)) {
PRINTF("ChainId token mismatch\n");
THROW(0x6A80);
}
offset += 4;
dataLength -= 4;
#ifdef HAVE_TOKENS_EXTRA_LIST
tokenDefinition_t *currentToken = NULL;
uint32_t index;
for (index = 0; index < NUM_TOKENS_EXTRA; index++) {
currentToken = (tokenDefinition_t *) PIC(&TOKENS_EXTRA[index]);
if (memcmp(currentToken->address, token->address, 20) == 0) {
strcpy((char *) token->ticker, (char *) currentToken->ticker);
token->decimals = currentToken->decimals;
break;
}
}
if (index < NUM_TOKENS_EXTRA) {
PRINTF("Descriptor whitelisted\n");
} else {
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,
32,
workBuffer + offset,
dataLength)) {
PRINTF("Invalid token signature\n");
THROW(0x6A80);
}
}
#else
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,
32,
workBuffer + offset,
dataLength)) {
PRINTF("Invalid token signature\n");
THROW(0x6A80);
}
#endif
tmpCtx.transactionContext.tokenSet[tmpCtx.transactionContext.currentTokenIndex] = 1;
THROW(0x9000);
}
#endif