diff --git a/app/Makefile b/app/Makefile index d4ebccfa..76840ea3 100755 --- a/app/Makefile +++ b/app/Makefile @@ -54,9 +54,9 @@ ifndef COIN COIN=ICP endif -APPVERSION_M=0 -APPVERSION_N=9 -APPVERSION_P=1 +APPVERSION_M=10 +APPVERSION_N=0 +APPVERSION_P=0 $(info COIN = [$(COIN)]) diff --git a/app/src/coin.h b/app/src/coin.h index 044949ae..9928df4b 100644 --- a/app/src/coin.h +++ b/app/src/coin.h @@ -35,6 +35,8 @@ extern "C" { #define HDPATH_0_TESTNET (0x80000000u | 0x2cu) #define HDPATH_1_TESTNET (0x80000000u | 0xdfu) +#define HDPATH_RESTRICTED_MASK 0xFFFFFF00u + #define SECP256K1_PK_LEN 65u #define DFINITY_ADDR_LEN 32u #define DFINITY_SUBACCOUNT_LEN 32u diff --git a/app/src/common/app_main.c b/app/src/common/app_main.c index 14dfbe12..536f712c 100644 --- a/app/src/common/app_main.c +++ b/app/src/common/app_main.c @@ -114,6 +114,14 @@ void extractHDPath(uint32_t rx, uint32_t offset) { if (!mainnet && !testnet) { THROW(APDU_CODE_DATA_INVALID); } + + const bool is_valid = ((hdPath[2] & HDPATH_RESTRICTED_MASK) == 0x80000000u) && + (hdPath[3] == 0x00000000u) && + ((hdPath[4] & HDPATH_RESTRICTED_MASK) == 0x00000000u); + + if (!is_valid && !app_mode_expert()){ + THROW(APDU_CODE_DATA_INVALID); + } } bool process_chunk(volatile uint32_t *tx, uint32_t rx) { diff --git a/tests_zemu/snapshots/s-mainmenu/00004.png b/tests_zemu/snapshots/s-mainmenu/00004.png index 7605878b..8b2f01e8 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00004.png and b/tests_zemu/snapshots/s-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/s-mainmenu/00011.png b/tests_zemu/snapshots/s-mainmenu/00011.png index 7605878b..8b2f01e8 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00011.png and b/tests_zemu/snapshots/s-mainmenu/00011.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00004.png b/tests_zemu/snapshots/x-mainmenu/00004.png index b8c3f1f8..95312b57 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00004.png and b/tests_zemu/snapshots/x-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00011.png b/tests_zemu/snapshots/x-mainmenu/00011.png index b8c3f1f8..95312b57 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00011.png and b/tests_zemu/snapshots/x-mainmenu/00011.png differ diff --git a/tests_zemu/tests/addresses.test.ts b/tests_zemu/tests/addresses.test.ts index f3a28fba..702edc2d 100644 --- a/tests_zemu/tests/addresses.test.ts +++ b/tests_zemu/tests/addresses.test.ts @@ -21,6 +21,15 @@ const Resolve = require('path').resolve const APP_PATH_S = Resolve('../app/output/app_s.elf') const APP_PATH_X = Resolve('../app/output/app_x.elf') +const APP_SEED = 'equip will roof matter pink blind book anxiety banner elbow sun young' + +const defaultOptions = { + ...DEFAULT_START_OPTIONS, + logging: true, + custom: `-s "${APP_SEED}"`, + X11: false, +} + const TEST_CASES = [ { seed: 'drip bus mind armor hole ice glory manage speed busy hobby cup', @@ -44,6 +53,33 @@ const TEST_CASES = [ } ] +const TEST_CASES_BIP32 = [ + { + path: "m/44'/223'/0'/0/0", + valid: true, + }, + { + path: "m/44'/223'/255'/0/0", + valid: true, + }, + { + path: "m/44'/223'/0'/0/255", + valid: true, + }, + { + path: "m/44'/223'/256'/0/0", + valid: false, + }, + { + path: "m/44'/223'/0'/1/0", + valid: false, + }, + { + path: "m/44'/223'/0'/0/256", + valid: false, + }, +] + jest.setTimeout(60000) const models: DeviceModel[] = [ @@ -87,4 +123,32 @@ describe('Addresses', function () { } }) + test.each(models)('test derivation paths', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + for (const TEST of TEST_CASES_BIP32) { + const resp = await app.getAddressAndPubKey(TEST.path) + console.log(resp) + const expected_returncode = TEST.valid ? 0x9000 : 0x6984; + expect(resp.returnCode).toEqual(expected_returncode) + } + // Enable expert mode + console.log('Set expert mode') + await sim.clickRight() + await sim.clickBoth() + await sim.clickLeft() + + for (const TEST of TEST_CASES_BIP32) { + const resp = await app.getAddressAndPubKey(TEST.path) + console.log(resp) + expect(resp.returnCode).toEqual(0x9000) + } + + } finally { + await sim.close() + } + }) })