diff --git a/python/src/trezorlib/cli/webauthn.py b/python/src/trezorlib/cli/fido.py similarity index 75% rename from python/src/trezorlib/cli/webauthn.py rename to python/src/trezorlib/cli/fido.py index e6bb3f493..8f920c043 100644 --- a/python/src/trezorlib/cli/webauthn.py +++ b/python/src/trezorlib/cli/fido.py @@ -16,15 +16,15 @@ import click -from .. import device, webauthn +from .. import fido -@click.group(name="webauthn") +@click.group(name="fido") def cli(): - """WebAuthn, FIDO2 and U2F management commands.""" + """FIDO2, U2F and WebAuthN management commands.""" -@click.group() +@cli.group() def credentials(): """Manage FIDO2 resident credentials.""" @@ -33,7 +33,7 @@ def credentials(): @click.pass_obj def credentials_list(connect): """List all resident credentials on the device.""" - creds = webauthn.list_credentials(connect()) + creds = fido.list_credentials(connect()) for cred in creds: click.echo("") click.echo("WebAuthn credential at index {}:".format(cred.index)) @@ -62,49 +62,49 @@ def credentials_list(connect): @credentials.command(name="add") @click.argument("hex_credential_id") @click.pass_obj -def credential_add(connect, hex_credential_id): +def credentials_add(connect, hex_credential_id): """Add the credential with the given ID as a resident credential. HEX_CREDENTIAL_ID is the credential ID as a hexadecimal string. """ - return webauthn.add_credential(connect(), bytes.fromhex(hex_credential_id)) + return fido.add_credential(connect(), bytes.fromhex(hex_credential_id)) -@cli.command() +@credentials.command(name="remove") @click.option( "-i", "--index", required=True, type=click.IntRange(0, 99), help="Credential index." ) @click.pass_obj -def remove_credential(connect, index): +def credentials_remove(connect, index): """Remove the resident credential at the given index.""" - return webauthn.remove_credential(connect(), index) + return fido.remove_credential(connect(), index) # -# U2F counter operations +# FIDO counter operations # @cli.group() -def u2f(): - """Get or set the U2F counter value.""" +def counter(): + """Get or set the FIDO/U2F counter value.""" -@u2f.command(name="set") +@counter.command(name="set") @click.argument("counter", type=int) @click.pass_obj -def u2f_set(connect, counter): - """Set U2F counter value.""" - return device.set_u2f_counter(connect(), counter) +def counter_set(connect, counter): + """Set FIDO/U2F counter value.""" + return fido.set_counter(connect(), counter) -@u2f.command(name="get-next") +@counter.command(name="get-next") @click.pass_obj -def u2f_get_next(connect): - """Get-and-increase value of U2F counter. +def counter_get_next(connect): + """Get-and-increase value of FIDO/U2F counter. - U2F counter value cannot be read directly. On each U2F exchange, the counter value + FIDO counter value cannot be read directly. On each U2F exchange, the counter value is returned and atomically increased. This command performs the same operation and returns the counter value. """ - return device.get_next_u2f_counter(connect()) + return fido.get_next_counter(connect()) diff --git a/python/src/trezorlib/cli/trezorctl.py b/python/src/trezorlib/cli/trezorctl.py index d97383d04..2db84a42c 100755 --- a/python/src/trezorlib/cli/trezorctl.py +++ b/python/src/trezorlib/cli/trezorctl.py @@ -34,6 +34,7 @@ from . import ( device, eos, ethereum, + fido, firmware, lisk, monero, @@ -42,7 +43,6 @@ from . import ( settings, stellar, tezos, - webauthn, ) COMMAND_ALIASES = { @@ -262,6 +262,7 @@ cli.add_command(crypto.cli) cli.add_command(device.cli) cli.add_command(eos.cli) cli.add_command(ethereum.cli) +cli.add_command(fido.cli) cli.add_command(lisk.cli) cli.add_command(monero.cli) cli.add_command(nem.cli) @@ -269,7 +270,6 @@ cli.add_command(ripple.cli) cli.add_command(settings.cli) cli.add_command(stellar.cli) cli.add_command(tezos.cli) -cli.add_command(webauthn.cli) cli.add_command(firmware.firmware_update) diff --git a/python/src/trezorlib/client.py b/python/src/trezorlib/client.py index fccddaf08..2eaaf2f40 100644 --- a/python/src/trezorlib/client.py +++ b/python/src/trezorlib/client.py @@ -337,7 +337,7 @@ class ProtocolMixin(object): reset_device = MovedTo("device.reset") backup_device = MovedTo("device.backup") - set_u2f_counter = MovedTo("device.set_u2f_counter") + set_u2f_counter = MovedTo("fido.set_counter") apply_settings = MovedTo("device.apply_settings") apply_flags = MovedTo("device.apply_flags") @@ -386,8 +386,7 @@ class ProtocolMixin(object): decrypt_keyvalue = MovedTo("misc.decrypt_keyvalue") # Debug device functionality - load_device_by_mnemonic = MovedTo("debuglink.load_device_by_mnemonic") - load_device_by_xprv = MovedTo("debuglink.load_device_by_xprv") + load_device_by_mnemonic = MovedTo("debuglink.load_device") class BaseClient: diff --git a/python/src/trezorlib/device.py b/python/src/trezorlib/device.py index f362beee2..823d1c94b 100644 --- a/python/src/trezorlib/device.py +++ b/python/src/trezorlib/device.py @@ -97,16 +97,6 @@ def sd_protect(client, operation): return ret -@expect(proto.Success, field="message") -def set_u2f_counter(client, u2f_counter): - return client.call(proto.SetU2FCounter(u2f_counter=u2f_counter)) - - -@expect(proto.NextU2FCounter, field="u2f_counter") -def get_next_u2f_counter(client): - return client.call(proto.GetNextU2FCounter()) - - @expect(proto.Success, field="message") def wipe(client): ret = client.call(proto.WipeDevice()) diff --git a/python/src/trezorlib/webauthn.py b/python/src/trezorlib/fido.py similarity index 54% rename from python/src/trezorlib/webauthn.py rename to python/src/trezorlib/fido.py index 97cd4fbbe..671dcf503 100644 --- a/python/src/trezorlib/webauthn.py +++ b/python/src/trezorlib/fido.py @@ -14,20 +14,30 @@ # You should have received a copy of the License along with this library. # If not, see . -from . import messages as proto +from . import messages from .tools import expect -@expect(proto.WebAuthnCredentials, field="credentials") +@expect(messages.WebAuthnCredentials, field="credentials") def list_credentials(client): - return client.call(proto.WebAuthnListResidentCredentials()) + return client.call(messages.WebAuthnListResidentCredentials()) -@expect(proto.Success, field="message") +@expect(messages.Success, field="message") def add_credential(client, credential_id): - return client.call(proto.WebAuthnAddResidentCredential(credential_id)) + return client.call(messages.WebAuthnAddResidentCredential(credential_id)) -@expect(proto.Success, field="message") +@expect(messages.Success, field="message") def remove_credential(client, index): - return client.call(proto.WebAuthnRemoveResidentCredential(index)) + return client.call(messages.WebAuthnRemoveResidentCredential(index)) + + +@expect(messages.Success, field="message") +def set_counter(client, u2f_counter): + return client.call(messages.SetU2FCounter(u2f_counter=u2f_counter)) + + +@expect(messages.NextU2FCounter, field="u2f_counter") +def get_next_counter(client): + return client.call(messages.GetNextU2FCounter()) diff --git a/tests/device_tests/test_msg_webauthn.py b/tests/device_tests/test_msg_webauthn.py index dd3dd92e4..d386d4d2d 100644 --- a/tests/device_tests/test_msg_webauthn.py +++ b/tests/device_tests/test_msg_webauthn.py @@ -16,7 +16,7 @@ import pytest -from trezorlib import webauthn +from trezorlib import fido from trezorlib.exceptions import Cancelled, TrezorFailure from ..common import MNEMONIC12 @@ -32,16 +32,16 @@ class TestMsgWebAuthn: def test_add_remove(self, client): # Remove index 0 should fail. with pytest.raises(TrezorFailure): - webauthn.remove_credential(client, 0) + fido.remove_credential(client, 0) # List should be empty. - assert webauthn.list_credentials(client) == [] + assert fido.list_credentials(client) == [] # Add valid credential #1. - webauthn.add_credential(client, CRED1) + fido.add_credential(client, CRED1) # Check that the credential was added and parameters are correct. - creds = webauthn.list_credentials(client) + creds = fido.list_credentials(client) assert len(creds) == 1 assert creds[0].rp_id == "example.com" assert creds[0].rp_name == "Example" @@ -54,10 +54,10 @@ class TestMsgWebAuthn: assert creds[0].hmac_secret is True # Add valid credential #2, which has same rpId and userId as credential #1. - webauthn.add_credential(client, CRED2) + fido.add_credential(client, CRED2) # Check that the credential #2 replaced credential #1 and parameters are correct. - creds = webauthn.list_credentials(client) + creds = fido.list_credentials(client) assert len(creds) == 1 assert creds[0].rp_id == "example.com" assert creds[0].rp_name is None @@ -71,41 +71,41 @@ class TestMsgWebAuthn: # Adding an invalid credential should appear as if user cancelled. with pytest.raises(Cancelled): - webauthn.add_credential(client, CRED1[:-2]) + fido.add_credential(client, CRED1[:-2]) # Check that the invalid credential was not added. - creds = webauthn.list_credentials(client) + creds = fido.list_credentials(client) assert len(creds) == 1 # Add valid credential, which has same userId as #2, but different rpId. - webauthn.add_credential(client, CRED3) + fido.add_credential(client, CRED3) # Check that the credential was added. - creds = webauthn.list_credentials(client) + creds = fido.list_credentials(client) assert len(creds) == 2 # Fill up the credential storage to maximum capacity. for cred in CREDS[: RK_CAPACITY - 2]: - webauthn.add_credential(client, cred) + fido.add_credential(client, cred) # Adding one more valid credential to full storage should fail. with pytest.raises(TrezorFailure): - webauthn.add_credential(client, CREDS[-1]) + fido.add_credential(client, CREDS[-1]) # Removing the index, which is one past the end, should fail. with pytest.raises(TrezorFailure): - webauthn.remove_credential(client, RK_CAPACITY) + fido.remove_credential(client, RK_CAPACITY) # Remove index 2. - webauthn.remove_credential(client, 2) + fido.remove_credential(client, 2) # Check that the credential was removed. - creds = webauthn.list_credentials(client) + creds = fido.list_credentials(client) assert len(creds) == RK_CAPACITY - 1 # Adding another valid credential should succeed now. - webauthn.add_credential(client, CREDS[-1]) + fido.add_credential(client, CREDS[-1]) # Check that the credential was added. - creds = webauthn.list_credentials(client) + creds = fido.list_credentials(client) assert len(creds) == RK_CAPACITY diff --git a/tests/device_tests/test_u2f_counter.py b/tests/device_tests/test_u2f_counter.py index b993b6d1e..46bca968d 100644 --- a/tests/device_tests/test_u2f_counter.py +++ b/tests/device_tests/test_u2f_counter.py @@ -14,14 +14,14 @@ # You should have received a copy of the License along with this library. # If not, see . -from trezorlib import device +from trezorlib import fido def test_u2f_counter(client): - assert device.get_next_u2f_counter(client) == 0 - assert device.get_next_u2f_counter(client) == 1 - device.set_u2f_counter(client, 111111) - assert device.get_next_u2f_counter(client) == 111112 - assert device.get_next_u2f_counter(client) == 111113 - device.set_u2f_counter(client, 0) - assert device.get_next_u2f_counter(client) == 1 + assert fido.get_next_counter(client) == 0 + assert fido.get_next_counter(client) == 1 + fido.set_counter(client, 111111) + assert fido.get_next_counter(client) == 111112 + assert fido.get_next_counter(client) == 111113 + fido.set_counter(client, 0) + assert fido.get_next_counter(client) == 1 diff --git a/tests/upgrade_tests/test_firmware_upgrades.py b/tests/upgrade_tests/test_firmware_upgrades.py index 54326ede8..3504a9606 100644 --- a/tests/upgrade_tests/test_firmware_upgrades.py +++ b/tests/upgrade_tests/test_firmware_upgrades.py @@ -16,7 +16,7 @@ import pytest -from trezorlib import MINIMUM_FIRMWARE_VERSION, btc, debuglink, device +from trezorlib import MINIMUM_FIRMWARE_VERSION, btc, debuglink, device, fido from trezorlib.messages import BackupType from trezorlib.tools import H_ @@ -253,15 +253,15 @@ def test_upgrade_u2f(gen, from_tag, to_tag): Check U2F counter stayed the same after an upgrade. """ with EmulatorWrapper(gen, from_tag) as emu: - success = device.set_u2f_counter(emu.client, 10) + success = fido.set_counter(emu.client, 10) assert "U2F counter set" in success - counter = device.get_next_u2f_counter(emu.client) + counter = fido.get_next_counter(emu.client) assert counter == 11 storage = emu.storage() with EmulatorWrapper(gen, to_tag, storage=storage) as emu: - counter = device.get_next_u2f_counter(emu.client) + counter = fido.get_next_counter(emu.client) assert counter == 12