diff --git a/src/handler/get_wallet_address.c b/src/handler/get_wallet_address.c index 93dc7c648..752ef471d 100644 --- a/src/handler/get_wallet_address.c +++ b/src/handler/get_wallet_address.c @@ -93,6 +93,10 @@ void handler_get_wallet_address(dispatcher_context_t *dc, uint8_t protocol_versi SEND_SW(dc, SW_WRONG_DATA_LENGTH); return; } + if (address_index >= BIP32_FIRST_HARDENED_CHILD) { + SEND_SW(dc, SW_INCORRECT_DATA); // it must be unhardened + return; + } { uint8_t serialized_wallet_policy[MAX_WALLET_POLICY_SERIALIZED_LENGTH]; diff --git a/tests/test_get_wallet_address.py b/tests/test_get_wallet_address.py index 008e0cb50..526637cb8 100644 --- a/tests/test_get_wallet_address.py +++ b/tests/test_get_wallet_address.py @@ -231,3 +231,26 @@ def test_get_wallet_address_tr_script_sortedmulti(client: Client): res = client.get_wallet_address(wallet, wallet_hmac, 0, 0, False) assert res == "tb1pdzk72dnvz3246474p4m5a97u43h6ykt2qcjrrhk6y0fkg8hx2mvswwgvv7" + + +def test_get_wallet_address_large_addr_index(client: Client): + # 2**31 - 1 is the largest index allowed, per BIP-32 + + wallet = MultisigWallet( + name="Cold storage", + address_type=AddressType.WIT, + threshold=2, + keys_info=[ + "[76223a6e/48'/1'/0'/2']tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF", + "[f5acc2fd/48'/1'/0'/2']tpubDFAqEGNyad35aBCKUAXbQGDjdVhNueno5ZZVEn3sQbW5ci457gLR7HyTmHBg93oourBssgUxuWz1jX5uhc1qaqFo9VsybY1J5FuedLfm4dK", + ], + ) + wallet_hmac = bytes.fromhex( + "d7c7a60b4ab4a14c1bf8901ba627d72140b2fb907f2b4e35d2e693bce9fbb371" + ) + + client.get_wallet_address(wallet, wallet_hmac, 0, 2**31 - 1, False) + + # too large address_index, not allowed for an unhardened step + with pytest.raises(IncorrectDataError): + client.get_wallet_address(wallet, wallet_hmac, 0, 2**31, False)