Skip to content

Commit f207d0a

Browse files
committed
Add bio tests
1 parent 83e24dc commit f207d0a

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

fido2/ctap2/bio.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class RESULT(IntEnum):
5151
LAST_SAMPLE_STATUS = 0x05
5252
REMAINING_SAMPLES = 0x06
5353
TEMPLATE_INFOS = 0x07
54+
MAX_TEMPLATE_FRIENDLY_NAME = 0x08
5455

5556
@unique
5657
class TEMPLATE_INFO(IntEnum):
@@ -149,8 +150,7 @@ def cancel(self) -> None:
149150

150151

151152
class FPBioEnrollment(BioEnrollment):
152-
"""Implementation of a draft specification of the bio enrollment API.
153-
WARNING: This specification is not final and this class is likely to change.
153+
"""Implementation of the bio enrollment API.
154154
155155
NOTE: The get_fingerprint_sensor_info method does not require authentication, and
156156
can be used by setting pin_uv_protocol and pin_uv_token to None.

tests/device/test_bioenroll.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
from fido2.ctap import CtapError
2+
from fido2.ctap2.bio import BioEnrollment, FPBioEnrollment, CaptureError
3+
from fido2.ctap2.pin import ClientPin
4+
from fido2.server import Fido2Server
5+
from fido2.client import Fido2Client, ClientError
6+
7+
from . import TEST_PIN, CliInteraction
8+
import pytest
9+
10+
11+
@pytest.fixture(autouse=True, scope="module")
12+
def preconditions(dev_manager):
13+
if not BioEnrollment.is_supported(dev_manager.info):
14+
pytest.skip("BioEnrollment not supported by authenticator")
15+
assert dev_manager.info.options["uv"] is False
16+
17+
18+
def get_bio(ctap2, pin_protocol=None, permissions=ClientPin.PERMISSION.BIO_ENROLL):
19+
if pin_protocol:
20+
token = ClientPin(ctap2, pin_protocol).get_pin_token(TEST_PIN, permissions)
21+
else:
22+
token = None
23+
return FPBioEnrollment(ctap2, pin_protocol, token)
24+
25+
26+
def test_get_sensor_info(ctap2):
27+
bio = get_bio(ctap2)
28+
info = bio.get_fingerprint_sensor_info()
29+
assert info.get(2) in (1, None)
30+
assert info.get(3, 1) > 0
31+
assert info.get(8, 1) > 0
32+
33+
34+
def test_enroll_use_delete(device, ctap2, pin_protocol, printer):
35+
bio = get_bio(ctap2, pin_protocol)
36+
assert len(bio.enumerate_enrollments()) == 0
37+
38+
context = bio.enroll()
39+
template_id = None
40+
while template_id is None:
41+
printer.print("Press your fingerprint against the sensor now...")
42+
try:
43+
template_id = context.capture()
44+
printer.print(f"{context.remaining} more scans needed.")
45+
except CaptureError as e:
46+
printer.print(e)
47+
48+
enrollments = bio.enumerate_enrollments()
49+
assert len(enrollments) == 1
50+
assert enrollments[template_id] in ("", None)
51+
52+
# Test name/rename
53+
info = bio.get_fingerprint_sensor_info()
54+
fname = "Test 1"
55+
bio.set_name(template_id, fname)
56+
57+
enrollments = bio.enumerate_enrollments()
58+
assert len(enrollments) == 1
59+
assert enrollments[template_id] == fname
60+
61+
fname = "Test".ljust(info.get(8, 0), "!")
62+
bio.set_name(template_id, fname)
63+
enrollments = bio.enumerate_enrollments()
64+
assert len(enrollments) == 1
65+
assert enrollments[template_id] == fname
66+
67+
# Create a credential using fingerprint
68+
rp = {"id": "example.com", "name": "Example RP"}
69+
server = Fido2Server(rp)
70+
user = {"id": b"user_id", "name": "A. User"}
71+
create_options, state = server.register_begin(user, user_verification="required")
72+
73+
client = Fido2Client(
74+
device,
75+
"https://example.com",
76+
user_interaction=CliInteraction(printer, "WrongPin"),
77+
)
78+
79+
# Allow multiple attempts
80+
for _ in range(3):
81+
try:
82+
result = client.make_credential(create_options.public_key)
83+
break
84+
except ClientError as e:
85+
if e.cause.code == CtapError.ERR.UV_INVALID:
86+
continue
87+
raise
88+
89+
server.register_complete(state, result)
90+
91+
# Delete fingerprint
92+
bio = get_bio(ctap2, pin_protocol)
93+
bio.remove_enrollment(template_id)
94+
assert len(bio.enumerate_enrollments()) == 0

0 commit comments

Comments
 (0)