Firmware for the Pico / Pico 2 that acts as a USB FIDO2 authenticator: CTAP2 and U2F, passkeys, BOOTSEL as the touch button, and clientPIN with PIN/UV auth protocols 1 and 2. A host simulator runs the same core so the python-fido2 test suite exercises it without hardware. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
import hashlib
|
|
import os
|
|
|
|
import pytest
|
|
from fido2.ctap1 import APDU, ApduError, Ctap1
|
|
from fido2.ctap2 import Ctap2
|
|
|
|
APP_ID = hashlib.sha256(b"example.com").digest()
|
|
|
|
|
|
def test_version(device):
|
|
assert Ctap1(device).get_version() == "U2F_V2"
|
|
|
|
|
|
def test_register_and_authenticate(device):
|
|
ctap1 = Ctap1(device)
|
|
challenge = os.urandom(32)
|
|
reg = ctap1.register(challenge, APP_ID)
|
|
reg.verify(APP_ID, challenge)
|
|
|
|
challenge = os.urandom(32)
|
|
sig = ctap1.authenticate(challenge, APP_ID, reg.key_handle)
|
|
sig.verify(APP_ID, challenge, reg.public_key)
|
|
assert sig.user_presence & 1
|
|
|
|
|
|
def test_check_only(device):
|
|
ctap1 = Ctap1(device)
|
|
reg = ctap1.register(os.urandom(32), APP_ID)
|
|
with pytest.raises(ApduError) as e:
|
|
ctap1.authenticate(os.urandom(32), APP_ID, reg.key_handle, check_only=True)
|
|
assert e.value.code == APDU.USE_NOT_SATISFIED
|
|
|
|
|
|
def test_wrong_app_id(device):
|
|
ctap1 = Ctap1(device)
|
|
reg = ctap1.register(os.urandom(32), APP_ID)
|
|
with pytest.raises(ApduError) as e:
|
|
ctap1.authenticate(os.urandom(32), hashlib.sha256(b"evil.com").digest(), reg.key_handle)
|
|
assert e.value.code == APDU.WRONG_DATA
|
|
|
|
|
|
def test_u2f_credential_works_with_ctap2(device):
|
|
reg = Ctap1(device).register(os.urandom(32), APP_ID)
|
|
client_data_hash = os.urandom(32)
|
|
assertion = Ctap2(device).get_assertion(
|
|
"example.com", client_data_hash, allow_list=[{"type": "public-key", "id": reg.key_handle}]
|
|
)
|
|
assert assertion.credential["id"] == reg.key_handle
|
|
|
|
|
|
def test_unknown_instruction(device):
|
|
with pytest.raises(ApduError) as e:
|
|
Ctap1(device).send_apdu(ins=0x55)
|
|
assert e.value.code == 0x6D00 # INS not supported
|