jonesmarvin8 24f6f1f8ca fixes
2026-04-26 21:29:54 -04:00

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