mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-14 03:59:30 +00:00
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
import sys
|
|
import pytest
|
|
from unittest.mock import MagicMock, patch
|
|
from keycard.commands.init import init
|
|
from keycard.exceptions import APDUError
|
|
from keycard import constants
|
|
|
|
|
|
PIN = b'1234'
|
|
PUK = b'5678'
|
|
PAIRING_SECRET = b'abcdefgh'
|
|
CARD_PUBLIC_KEY = b'\x04' + b'\x00' * 64 # Valid uncompressed pubkey format
|
|
|
|
|
|
@pytest.fixture
|
|
def ecc_patches():
|
|
init_module = sys.modules['keycard.commands.init']
|
|
with (
|
|
patch.object(init_module, 'urandom', return_value=b'\x00' * 16),
|
|
patch.object(
|
|
init_module,
|
|
'aes_cbc_encrypt',
|
|
side_effect=lambda k, iv,
|
|
pt: b'\xAA' * len(pt)
|
|
),
|
|
patch.object(init_module, 'SigningKey') as mock_signing_key_cls,
|
|
patch.object(init_module, 'VerifyingKey') as mock_verifying_key_cls,
|
|
patch.object(init_module, 'ECDH') as mock_ecdh_cls,
|
|
):
|
|
mock_gen = mock_signing_key_cls.generate
|
|
fake_privkey = MagicMock()
|
|
fake_privkey.verifying_key.to_string.return_value = b'\x01' * 65
|
|
mock_gen.return_value = fake_privkey
|
|
|
|
mock_parse = mock_verifying_key_cls.from_string
|
|
mock_parse.return_value = 'parsed-pubkey'
|
|
|
|
ecdh_instance = MagicMock()
|
|
ecdh_instance.generate_sharedsecret_bytes.return_value = b'\xBB' * 32
|
|
mock_ecdh_cls.return_value = ecdh_instance
|
|
|
|
yield
|
|
|
|
|
|
def test_init_success(card, ecc_patches):
|
|
card.send_apdu.return_value = b''
|
|
card.card_public_key = CARD_PUBLIC_KEY
|
|
|
|
init(card, PIN, PUK, PAIRING_SECRET)
|
|
|
|
card.send_apdu.assert_called_once_with(
|
|
ins=constants.INS_INIT,
|
|
data=bytes.fromhex(
|
|
'4101010101010101010101010101010101010101010101010101010'
|
|
'1010101010101010101010101010101010101010101010101010101'
|
|
'010101010101010101010100000000000000000000000000000000'
|
|
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize('secret_length', [10, 240])
|
|
def test_init_data_length(card, ecc_patches, secret_length):
|
|
card.send_apdu.return_value = b''
|
|
card.card_public_key = CARD_PUBLIC_KEY
|
|
|
|
pairing_secret = b'x' * secret_length
|
|
plaintext = PIN + PUK + pairing_secret
|
|
total_data_len = 1 + 65 + 16 + len(plaintext)
|
|
|
|
if total_data_len > 255:
|
|
with pytest.raises(ValueError, match='Data too long'):
|
|
init(card, PIN, PUK, pairing_secret)
|
|
else:
|
|
init(card, PIN, PUK, pairing_secret)
|
|
assert card.send_apdu.call_count == 1
|
|
|
|
|
|
def test_init_apdu_error(card, ecc_patches):
|
|
card.send_apdu.side_effect = APDUError(0x6A84)
|
|
card.card_public_key = CARD_PUBLIC_KEY
|
|
|
|
with pytest.raises(APDUError) as excinfo:
|
|
init(card, PIN, PUK, PAIRING_SECRET)
|
|
|
|
assert excinfo.value.sw == 0x6A84
|