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:
parent
1f45e9338a
commit
140e17039a
@ -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")
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
77
tests/device_tests/test_authenticate_device.py
Normal file
77
tests/device_tests/test_authenticate_device.py
Normal 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()))
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user