From 1f45e9338a4b275c465d0e882a13b7d0a6f4878b Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Thu, 24 Aug 2023 09:30:40 +0200 Subject: [PATCH] feat(trezorctl): Implement device authenticate command. --- python/.changelog.d/3255.added | 1 + python/src/trezorlib/cli/device.py | 17 +++++++++++++++++ python/src/trezorlib/device.py | 5 +++++ 3 files changed, 23 insertions(+) create mode 100644 python/.changelog.d/3255.added diff --git a/python/.changelog.d/3255.added b/python/.changelog.d/3255.added new file mode 100644 index 000000000..b806f9349 --- /dev/null +++ b/python/.changelog.d/3255.added @@ -0,0 +1 @@ +Implement device authenticate command. diff --git a/python/src/trezorlib/cli/device.py b/python/src/trezorlib/cli/device.py index f2dcb1ef5..6ca2e9b0d 100644 --- a/python/src/trezorlib/cli/device.py +++ b/python/src/trezorlib/cli/device.py @@ -14,6 +14,7 @@ # You should have received a copy of the License along with this library. # If not, see . +import secrets import sys from typing import TYPE_CHECKING, Optional, Sequence @@ -331,3 +332,19 @@ def set_busy( ) return device.set_busy(client, expiry * 1000) + + +@cli.command() +@click.argument("hex_challenge", required=False) +@with_client +def authenticate(client: "TrezorClient", hex_challenge: Optional[str]) -> None: + """Get information to verify the authenticity of the device.""" + if hex_challenge is None: + hex_challenge = secrets.token_hex(32) + click.echo(f"Challenge: {hex_challenge}") + challenge = bytes.fromhex(hex_challenge) + msg = device.authenticate(client, challenge) + click.echo(f"Signature of challenge: {msg.signature.hex()}") + click.echo(f"Device certificate: {msg.certificates[0].hex()}") + for cert in msg.certificates[1:]: + click.echo(f"CA certificate: {cert.hex()}") diff --git a/python/src/trezorlib/device.py b/python/src/trezorlib/device.py index 4ed5cbbfa..930b78ab3 100644 --- a/python/src/trezorlib/device.py +++ b/python/src/trezorlib/device.py @@ -265,3 +265,8 @@ def set_busy(client: "TrezorClient", expiry_ms: Optional[int]) -> "MessageType": ret = client.call(messages.SetBusy(expiry_ms=expiry_ms)) client.refresh_features() return ret + + +@expect(messages.AuthenticityProof) +def authenticate(client: "TrezorClient", challenge: bytes): + return client.call(messages.AuthenticateDevice(challenge=challenge))