1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 06:18:07 +00:00

feat(tests): Add AuthenticateDevice test.

This commit is contained in:
Andrew Kozlik 2023-08-28 09:57:38 +02:00 committed by Andrew Kozlik
parent 1f45e9338a
commit 140e17039a
4 changed files with 95 additions and 7 deletions

View File

@ -263,3 +263,14 @@ def get_test_address(client: "Client") -> str:
"""Fetch a testnet address on a fixed path. Useful to make a pin/passphrase
protected call, or to identify the root secret (seed+passphrase)"""
return btc.get_address(client, "Testnet", TEST_ADDRESS_N)
def compact_size(n) -> bytes:
if n < 253:
return n.to_bytes(1, "little")
elif n < 0x1_0000:
return bytes([253]) + n.to_bytes(2, "little")
elif n < 0x1_0000_0000:
return bytes([254]) + n.to_bytes(4, "little")
else:
return bytes([255]) + n.to_bytes(8, "little")

View File

@ -5,6 +5,8 @@ from ecdsa import ECDH, SECP256k1, SigningKey
from trezorlib import btc, messages
from ...common import compact_size
SLIP44 = 1 # Testnet
TextMemo = namedtuple("TextMemo", "text")
@ -20,13 +22,7 @@ payment_req_signer = SigningKey.from_string(
def hash_bytes_prefixed(hasher, data):
n = len(data)
if n < 253:
hasher.update(n.to_bytes(1, "little"))
elif n < 0x1_0000:
hasher.update(bytes([253]))
hasher.update(n.to_bytes(2, "little"))
hasher.update(compact_size(len(data)))
hasher.update(data)

View File

@ -0,0 +1,77 @@
import pytest
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.x509 import extensions as ext
from trezorlib import device
from trezorlib.debuglink import TrezorClientDebugLink as Client
from ..common import compact_size
pytestmark = [pytest.mark.skip_t1, pytest.mark.skip_t2]
ROOT_PUBLIC_KEY = bytes.fromhex(
"04626d58aca84f0fcb52ea63f0eb08de1067b8d406574a715d5e7928f4b67f113a00fb5c5918e74d2327311946c446b242c20fe7347482999bdc1e229b94e27d96"
)
@pytest.mark.parametrize(
"challenge",
(
b"",
b"hello world",
b"\x00" * 1024,
bytes.fromhex(
"21f3d40e63c304d0312f62eb824113efd72ba1ee02bef6777e7f8a7b6f67ba16"
),
),
)
def test_authenticate_device(client: Client, challenge: bytes) -> None:
# NOTE Applications must generate a random challenge for each request.
# Issue an AuthenticateDevice challenge to Trezor.
proof = device.authenticate(client, challenge)
certs = [x509.load_der_x509_certificate(cert) for cert in proof.certificates]
# Verify the last certificate in the certificate chain against trust anchor.
root_public_key = ec.EllipticCurvePublicKey.from_encoded_point(
ec.SECP256R1(), ROOT_PUBLIC_KEY
)
root_public_key.verify(
certs[-1].signature,
certs[-1].tbs_certificate_bytes,
certs[-1].signature_algorithm_parameters,
)
# Verify the certificate chain.
for cert, ca_cert in zip(certs, certs[1:]):
assert cert.issuer == ca_cert.subject
ca_basic_constraints = ca_cert.extensions.get_extension_for_class(
ext.BasicConstraints
).value
assert ca_basic_constraints.ca is True
try:
basic_constraints = cert.extensions.get_extension_for_class(
ext.BasicConstraints
).value
if basic_constraints.ca:
assert basic_constraints.path_length < ca_basic_constraints.path_length
except ext.ExtensionNotFound:
pass
ca_cert.public_key().verify(
cert.signature,
cert.tbs_certificate_bytes,
cert.signature_algorithm_parameters,
)
# Verify that the common name matches the Trezor model.
common_name = cert.subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)[0]
assert common_name.value.startswith(client.features.internal_model)
# Verify the signature of the challenge.
data = b"\x13AuthenticateDevice:" + compact_size(len(challenge)) + challenge
certs[0].public_key().verify(proof.signature, data, ec.ECDSA(hashes.SHA256()))

View File

@ -1760,6 +1760,10 @@
"TR_stellar-test_stellar.py::test_sign_tx[timebounds-0-1575234180]": "9e1f884816d80415ef9b925309d5502852d8bade9c632f2d715d0a2cdecb1204",
"TR_stellar-test_stellar.py::test_sign_tx[timebounds-461535181-0]": "afc84260d5f7991a516ead25a0f77c34ec14ef2b3de3595adc1c50624657ac0a",
"TR_stellar-test_stellar.py::test_sign_tx[timebounds-461535181-1575234180]": "8fcc98ebb2f76f36f85c313131478d29b3b2ba79e2ef5993afa3cb7a663ed63a",
"TR_test_authenticate_device.py::test_authenticate_device[!\\xf3\\xd4\\x0ec\\xc3\\x04\\xd01-b\\xeb\\x82-e4b4eb3a": "5bbde07a26ce37bd72d0c792c4dc9807c169c9fc731d1bcf30a72a5f2da7f602",
"TR_test_authenticate_device.py::test_authenticate_device[\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\-d824e03c": "5bbde07a26ce37bd72d0c792c4dc9807c169c9fc731d1bcf30a72a5f2da7f602",
"TR_test_authenticate_device.py::test_authenticate_device[]": "5bbde07a26ce37bd72d0c792c4dc9807c169c9fc731d1bcf30a72a5f2da7f602",
"TR_test_authenticate_device.py::test_authenticate_device[hello world]": "5bbde07a26ce37bd72d0c792c4dc9807c169c9fc731d1bcf30a72a5f2da7f602",
"TR_test_autolock.py::test_apply_auto_lock_delay": "cf93576944395035a45cf62f4b4b22387c595af7646e1863b07bdcc38ccfbb20",
"TR_test_autolock.py::test_apply_auto_lock_delay_out_of_range[0]": "674ca13c50b342d80ca47ed49bcfaa846bb07db2ba30d6e1414c96db8375457b",
"TR_test_autolock.py::test_apply_auto_lock_delay_out_of_range[1]": "674ca13c50b342d80ca47ed49bcfaa846bb07db2ba30d6e1414c96db8375457b",