Fix nft transactions (#229)

* Removed pluginType "hack"

* Fix some ERC 721 & 1155 function signature hashes

* Fix UI for ERC721 operations

* Explicit Batch Transfer UI with ERC1155

* Unified some ERC721 & 1155 non-static functions naming

* Fix UI for ERC1155 operations

* Added missing pin-lock check when signing transactions

* Fix the shell script that builds the elf files for testing

* Add tests dependency ethers

* Removed the space in the test filename

* Tests build script refactoring

* Now works when called from anywhere (not just the script's directory)
* Now handles LNS & LNX builds together (less duplicated code)

* Temporarily disable Nano X tests

Until Zemu supports Nano X 2.0 SDK

* Tests now start with blind signing disabled

Makes it closer to reality & very few of them requires it

* Update to the latest sdk version

* make eth_plugin_perform_init() readable

Introduce 2 functions.

* Now properly parses the apdu and displays the total quantity of NFT IDs transferred in ERC1155 batch transfer

* Add NFT prod public keys

* Added extra checks for the chain ID handling

Following the security review

* NFTs now only supported by LNS

* Version bump

Co-authored-by: Alexandre Paillier <alexandre.paillier@ledger.fr>
Co-authored-by: greenknot <greenknot@users.noreply.github.com>
This commit is contained in:
Jean P
2021-12-17 12:04:51 +01:00
committed by GitHub
parent 586155c0d4
commit a53a2428cc
40 changed files with 735 additions and 208 deletions

View File

@@ -1,3 +1,5 @@
#ifdef HAVE_NFT_SUPPORT
#include "shared_context.h"
#include "apdu_constants.h"
#include "ui_flow.h"
@@ -16,8 +18,8 @@
#define MIN_DER_SIG_SIZE 67
#define MAX_DER_SIG_SIZE 72
#define TESTING_KEY 0
#define NFT_METADATA_KEY_1 1
#define TEST_NFT_METADATA_KEY 0
#define PROD_NFT_METADATA_KEY 1
#define ALGORITHM_ID_1 1
@@ -25,17 +27,22 @@
#define VERSION_1 1
static const uint8_t LEDGER_NFT_METADATA_PUBLIC_KEY[] = {
#ifdef HAVE_NFT_TESTING_KEY
static const uint8_t LEDGER_NFT_PUBLIC_KEY[] = {
0x04, 0xf5, 0x70, 0x0c, 0xa1, 0xe8, 0x74, 0x24, 0xc7, 0xc7, 0xd1, 0x19, 0xe7,
0xe3, 0xc1, 0x89, 0xb1, 0x62, 0x50, 0x94, 0xdb, 0x6e, 0xa0, 0x40, 0x87, 0xc8,
0x30, 0x00, 0x7d, 0x0b, 0x46, 0x9a, 0x53, 0x11, 0xee, 0x6a, 0x1a, 0xcd, 0x1d,
0xa5, 0xaa, 0xb0, 0xf5, 0xc6, 0xdf, 0x13, 0x15, 0x8d, 0x28, 0xcc, 0x12, 0xd1,
0xdd, 0xa6, 0xec, 0xe9, 0x46, 0xb8, 0x9d, 0x5c, 0x05, 0x49, 0x92, 0x59, 0xc4};
0xdd, 0xa6, 0xec, 0xe9, 0x46, 0xb8, 0x9d, 0x5c, 0x05, 0x49, 0x92, 0x59, 0xc4
#else
static const uint8_t LEDGER_NFT_PUBLIC_KEY[] = {};
0x04, 0x98, 0x8d, 0xa6, 0xb2, 0x46, 0xf2, 0x8e, 0x77, 0xc1, 0xba, 0xb6, 0x75,
0xcb, 0x2a, 0x27, 0x44, 0xf7, 0xf5, 0xce, 0xc5, 0x6a, 0xe6, 0xe0, 0x32, 0x23,
0x33, 0x7b, 0x57, 0x94, 0xcd, 0x6a, 0xe0, 0x7d, 0x48, 0xb3, 0x0d, 0xb9, 0xcc,
0xb4, 0x0f, 0x5a, 0x02, 0xa1, 0x1a, 0x3a, 0xb9, 0x9d, 0x5f, 0x59, 0x5a, 0x3d,
0x50, 0xa0, 0xe1, 0x30, 0x23, 0xfd, 0x0d, 0x95, 0x87, 0x92, 0xd7, 0x97, 0x01
#endif
};
typedef bool verificationAlgo(const cx_ecfp_public_key_t *,
int,
@@ -129,9 +136,14 @@ void handleProvideNFTInformation(uint8_t p1,
PRINTF("Address: %.*H\n", ADDRESS_LENGTH, workBuffer + offset);
offset += ADDRESS_LENGTH;
// TODO: store chainID and assert that tx is using the same chainid.
// uint64_t chainid = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE);
// PRINTF("ChainID: %.*H\n", sizeof(chainid), &chainid);
uint64_t chainId = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE);
// this prints raw data, so to have a more meaningful print, display
// the buffer before the endianness swap
PRINTF("ChainID: %.*H\n", sizeof(chainId), (workBuffer + offset));
if ((chainConfig->chainId != 0) && (chainConfig->chainId != chainId)) {
PRINTF("Chain ID token mismatch\n");
THROW(0x6A80);
}
offset += CHAIN_ID_SIZE;
uint8_t keyId = workBuffer[offset];
@@ -141,11 +153,11 @@ void handleProvideNFTInformation(uint8_t p1,
PRINTF("KeyID: %d\n", keyId);
switch (keyId) {
#ifdef HAVE_NFT_TESTING_KEY
case TESTING_KEY:
case TEST_NFT_METADATA_KEY:
#endif
case NFT_METADATA_KEY_1:
rawKey = (uint8_t *) LEDGER_NFT_PUBLIC_KEY;
rawKeyLen = sizeof(LEDGER_NFT_PUBLIC_KEY);
case PROD_NFT_METADATA_KEY:
rawKey = (uint8_t *) LEDGER_NFT_METADATA_PUBLIC_KEY;
rawKeyLen = sizeof(LEDGER_NFT_METADATA_PUBLIC_KEY);
break;
default:
PRINTF("KeyID %d not supported\n", keyId);
@@ -210,10 +222,9 @@ void handleProvideNFTInformation(uint8_t p1,
THROW(0x6A80);
#endif
}
// Set this to `NOT_OLD_INTERNAL` because otherwise the tx might be treated as an
// internal plugin and we might get a collision and hence some BIG problems.
pluginType = NOT_OLD_INTERNAL;
tmpCtx.transactionContext.tokenSet[tmpCtx.transactionContext.currentItemIndex] = 1;
THROW(0x9000);
}
#endif // HAVE_NFT_SUPPORT