From b5d6aaf77c92ccb6738b3db88aefa4fed0231568 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Mon, 20 Jan 2020 10:22:08 +0000 Subject: [PATCH] tests: test PassphraseAck options --- core/src/apps/common/passphrase.py | 6 +- legacy/firmware/protect.c | 12 +++- .../test_session_id_and_passphrase.py | 56 +++++++++++++++++-- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/core/src/apps/common/passphrase.py b/core/src/apps/common/passphrase.py index 1992a045f..646984f96 100644 --- a/core/src/apps/common/passphrase.py +++ b/core/src/apps/common/passphrase.py @@ -42,11 +42,13 @@ async def _get_from_user(ctx: wire.Context) -> str: ack = await ctx.call(request, PassphraseAck) if ack.on_device: if ack.passphrase is not None: - raise wire.ProcessError("Passphrase provided when it should not be") + raise wire.DataError("Passphrase provided when it should not be") return await request_from_user_on_device(ctx) if ack.passphrase is None: - raise wire.ProcessError("Passphrase not provided") + raise wire.DataError( + "Passphrase not provided and on_device is False. Use empty string to set an empty passphrase." + ) return ack.passphrase diff --git a/legacy/firmware/protect.c b/legacy/firmware/protect.c index 4196d5884..810d931be 100644 --- a/legacy/firmware/protect.c +++ b/legacy/firmware/protect.c @@ -377,9 +377,17 @@ bool protectPassphrase(void) { fsm_sendFailure( FailureType_Failure_DataError, _("This firmware is incapable of passphrase entry on the device.")); - // TODO: write test + result = false; + break; + } + if (!ppa->has_passphrase) { + fsm_sendFailure(FailureType_Failure_DataError, + _("No passphrase provided. Use empty string to set an " + "empty passphrase.")); + result = false; + break; } - session_cachePassphrase(ppa->has_passphrase ? ppa->passphrase : ""); + session_cachePassphrase(ppa->passphrase); result = true; break; } diff --git a/tests/device_tests/test_session_id_and_passphrase.py b/tests/device_tests/test_session_id_and_passphrase.py index c5ab3ace6..5418ad719 100644 --- a/tests/device_tests/test_session_id_and_passphrase.py +++ b/tests/device_tests/test_session_id_and_passphrase.py @@ -131,6 +131,7 @@ def test_session_enable_passphrase(client): @pytest.mark.skip_ui +@pytest.mark.skip_t1 @pytest.mark.setup_client() def test_passphrase_always_on_device(client): # Let's start the communication by calling Initialize. @@ -144,11 +145,6 @@ def test_passphrase_always_on_device(client): # Force passphrase entry on Trezor. response = client.call_raw(messages.ApplySettings(passphrase_always_on_device=True)) - if client.features.model == "1": - assert isinstance(response, messages.Failure) - assert response.code == 3 # DataError - return - assert isinstance(response, messages.ButtonRequest) # confirm dialog client.debug.press_yes() response = client.call_raw(messages.ButtonAck()) @@ -193,3 +189,53 @@ def test_passphrase_always_on_device(client): response.xpub == "xpub6CekxGcnqnJ6osfY4Rrq7W5ogFtR54KUvz4H16XzaQuukMFZCGebEpVznfq4yFcKEmYyShwj2UKjL7CazuNSuhdkofF4mHabHkLxCMVvsqG" ) + + +@pytest.mark.skip_ui +@pytest.mark.skip_t2 +@pytest.mark.setup_client() +def test_passphrase_on_device_not_possible_on_t1(client): + # Let's start the communication by calling Initialize. + response = client.call_raw(messages.Initialize()) + assert isinstance(response, messages.Features) + + # Turn on passphrase. + _enable_passphrase(client) + + # This setting makes no sense on T1. + response = client.call_raw(messages.ApplySettings(passphrase_always_on_device=True)) + + assert isinstance(response, messages.Failure) + assert response.code == 3 # DataError + + response = client.call_raw( + messages.GetPublicKey(address_n=parse_path("44'/0'/0'"), coin_name="Bitcoin") + ) + assert isinstance(response, messages.PassphraseRequest) + response = client.call_raw(messages.PassphraseAck(on_device=True)) + assert isinstance(response, messages.Failure) + assert response.code == 3 # DataError + + +@pytest.mark.skip_ui +@pytest.mark.setup_client(passphrase=True) +def test_passphrase_ack_mismatch(client): + response = client.call_raw( + messages.GetPublicKey(address_n=parse_path("44'/0'/0'"), coin_name="Bitcoin") + ) + assert isinstance(response, messages.PassphraseRequest) + response = client.call_raw(messages.PassphraseAck(passphrase="A", on_device=True)) + assert isinstance(response, messages.Failure) + assert response.code == 3 # DataError + + +@pytest.mark.skip_ui +@pytest.mark.setup_client(passphrase=True) +def test_passphrase_missing(client): + response = client.call_raw( + messages.GetPublicKey(address_n=parse_path("44'/0'/0'"), coin_name="Bitcoin") + ) + assert isinstance(response, messages.PassphraseRequest) + response = client.call_raw(messages.PassphraseAck(passphrase=None)) + assert isinstance(response, messages.Failure) + assert response.code == 3 # DataError