diff --git a/tests/test_msg_eos_signtx.py b/tests/test_msg_eos_signtx.py index f04c990d..1b9610ab 100644 --- a/tests/test_msg_eos_signtx.py +++ b/tests/test_msg_eos_signtx.py @@ -568,7 +568,15 @@ def test_updateauth(self): num_actions=1), [self.action_updateauth(True)]) - self.assertEqual(binascii.hexlify(res.hash), "fb936ef1be4bda680d93bd10b6d062357d8dd7272038a706dc0d61a91f39c5ee") + # Firmware 7.15 serializes waits_count here. Older firmware hashed a + # phantom zero wait by iterating accounts_count instead. + version = (self.client.features.major_version, + self.client.features.minor_version, + self.client.features.patch_version) + expected = ("5938294e65cf9e8b5dd5f2b204503b4825f277e6f4a2d5ab7a55a31065a23af1" + if version >= (7, 15, 0) + else "fb936ef1be4bda680d93bd10b6d062357d8dd7272038a706dc0d61a91f39c5ee") + self.assertEqual(binascii.hexlify(res.hash), expected) def test_deleteauth(self): self.requires_fullFeature() diff --git a/tests/test_msg_ethereum_erc20_approve.py b/tests/test_msg_ethereum_erc20_approve.py index 9fdba114..e69fdec5 100644 --- a/tests/test_msg_ethereum_erc20_approve.py +++ b/tests/test_msg_ethereum_erc20_approve.py @@ -69,6 +69,7 @@ def test_approve_cvc_0(self): def test_approve_cvc_all(self): self.requires_fullFeature() + self.requires_firmware("7.15.0") self.setup_mnemonic_nopin_nopassphrase() with self.assertRaises(CallException) as caught: diff --git a/tests/test_msg_ethereum_erc20_uniswap_liquidity.py b/tests/test_msg_ethereum_erc20_uniswap_liquidity.py index bb2c1049..ab4d9cd6 100644 --- a/tests/test_msg_ethereum_erc20_uniswap_liquidity.py +++ b/tests/test_msg_ethereum_erc20_uniswap_liquidity.py @@ -29,7 +29,7 @@ class TestMsgEthereumUniswaptxERC20(common.KeepKeyTest): def test_sign_uni_approve_liquidity_ETH(self): self.requires_fullFeature() - self.requires_firmware("7.1.0") + self.requires_firmware("7.15.0") self.setup_mnemonic_nopin_nopassphrase() self.client.apply_policy("AdvancedMode", 1) diff --git a/tests/test_msg_signtx_ethereum_erc20.py b/tests/test_msg_signtx_ethereum_erc20.py index 73a671af..79ce8b2c 100644 --- a/tests/test_msg_signtx_ethereum_erc20.py +++ b/tests/test_msg_signtx_ethereum_erc20.py @@ -69,6 +69,7 @@ def test_approve_some(self): def test_approve_all(self): self.requires_fullFeature() + self.requires_firmware("7.15.0") self.setup_mnemonic_nopin_nopassphrase() with self.assertRaises(CallException) as caught: diff --git a/tests/test_msg_solana_signtx.py b/tests/test_msg_solana_signtx.py index 1c4a8cda..ff45bd09 100644 --- a/tests/test_msg_solana_signtx.py +++ b/tests/test_msg_solana_signtx.py @@ -73,6 +73,7 @@ def setUp(self): def setup_mnemonic_allallall(self): policy_negative = self._testMethodName in { "test_solana_sign_message_blocked_without_advanced_mode", + "test_solana_sign_plain_text_message_without_advanced_mode", "test_solana_sign_malformed_bad_account_count", "test_solana_sign_versioned_v0_opaque", } @@ -153,9 +154,11 @@ def test_solana_sign_message(self): self.client.apply_policy('AdvancedMode', False) def test_solana_sign_message_blocked_without_advanced_mode(self): - """Solana message signing BLOCKED without AdvancedMode. + """Non-text Solana message signing BLOCKED without AdvancedMode. Without domain separation, a signed message is indistinguishable from - a signed transaction. Device refuses to sign without explicit opt-in.""" + a signed transaction. Device refuses to sign without explicit opt-in. + The payload is binary so this remains true when bounded plain text is + allowed.""" self.requires_firmware("7.14.0") self.requires_fullFeature() self.requires_message("SolanaSignMessage") @@ -165,10 +168,27 @@ def test_solana_sign_message_blocked_without_advanced_mode(self): with pytest.raises(CallException) as exc: self.client.call(messages.SolanaSignMessage( address_n=parse_path("m/44'/501'/0'/0'"), - message=b"Hello Solana!", + message=b"\x01\x00\x01\x02" + b"\x00" * 64, )) self.assertIn("disabled by policy", str(exc.value)) + def test_solana_sign_plain_text_message_without_advanced_mode(self): + """Bounded printable login text signs without AdvancedMode.""" + self.requires_firmware("7.15.0") + self.requires_fullFeature() + self.requires_message("SolanaSignMessage") + self.setup_mnemonic_allallall() + self.client.apply_policy('AdvancedMode', False) + + text = (b"example.com wants you to sign in with your Solana account:\n" + b"Sign in to Example.\n\nNonce: 9d9972a1f2ed0aaa") + resp = self.client.call(messages.SolanaSignMessage( + address_n=parse_path("m/44'/501'/0'/0'"), + message=text, + )) + self.assertEqual(len(resp.signature), 64) + self.assertEqual(len(resp.public_key), 32) + def test_solana_sign_empty_rejected(self): """Test that empty raw_tx is rejected.""" self.requires_fullFeature()