diff --git a/python/.changelog.d/2239.added b/python/.changelog.d/2239.added new file mode 100644 index 000000000..960c17ff3 --- /dev/null +++ b/python/.changelog.d/2239.added @@ -0,0 +1 @@ +Add firmware get-hash command. diff --git a/python/src/trezorlib/cli/firmware.py b/python/src/trezorlib/cli/firmware.py index dfbba0cd4..fffbc8dbf 100644 --- a/python/src/trezorlib/cli/firmware.py +++ b/python/src/trezorlib/cli/firmware.py @@ -590,3 +590,12 @@ def update( click.echo("Dry run. Not uploading firmware to device.") else: upload_firmware_into_device(client=client, firmware_data=firmware_data) + + +@cli.command() +@click.argument("hex_challenge", required=False) +@with_client +def get_hash(client: "TrezorClient", hex_challenge: Optional[str]) -> str: + """Get a hash of the installed firmware combined with the optional challenge.""" + challenge = bytes.fromhex(hex_challenge) if hex_challenge else None + return firmware.get_hash(client, challenge).hex() diff --git a/python/src/trezorlib/firmware.py b/python/src/trezorlib/firmware.py index 161faf828..54408082c 100644 --- a/python/src/trezorlib/firmware.py +++ b/python/src/trezorlib/firmware.py @@ -23,7 +23,7 @@ import construct as c import ecdsa from . import cosi, messages -from .tools import session +from .tools import expect, session if TYPE_CHECKING: from .client import TrezorClient @@ -518,3 +518,8 @@ def update( return else: raise RuntimeError(f"Unexpected message {resp}") + + +@expect(messages.FirmwareHash, field="hash", ret_type=bytes) +def get_hash(client: "TrezorClient", challenge: Optional[bytes]): + return client.call(messages.GetFirmwareHash(challenge=challenge))