Files

165 lines
6.1 KiB
Python
Raw Permalink Normal View History

2019-09-16 16:26:47 +08:00
import sys
2019-08-05 13:40:54 +08:00
import pytest
from fido2.ctap import CtapError
2019-08-13 22:40:20 +02:00
from fido2.utils import hmac_sha256, sha256
2019-08-05 13:40:54 +08:00
from tests.utils import *
class TestGetAssertion(object):
2019-08-08 03:05:15 +02:00
def test_get_assertion(self, device, MCRes, GARes):
2019-08-05 13:40:54 +08:00
verify(MCRes, GARes)
2019-08-08 03:05:15 +02:00
def test_assertion_auth_data(self, GARes):
2019-08-05 13:40:54 +08:00
assert len(GARes.auth_data) == 37
assert sha256(GARes.request.rp["id"].encode()) == GARes.auth_data.rp_id_hash
def test_Check_that_AT_flag_is_not_set(self, GARes):
assert (GARes.auth_data.flags & 0xF8) == 0
2019-08-08 03:05:15 +02:00
def test_that_user_credential_and_numberOfCredentials_are_not_present(self, GARes):
2019-08-05 13:40:54 +08:00
assert GARes.user == None
assert GARes.number_of_credentials == None
2019-08-08 03:05:15 +02:00
def test_empty_allowList(self, device):
2019-08-05 13:40:54 +08:00
with pytest.raises(CtapError) as e:
2019-08-08 03:05:15 +02:00
device.sendGA(*FidoRequest(allow_list=[]).toGA())
2019-08-05 13:40:54 +08:00
assert e.value.code == CtapError.ERR.NO_CREDENTIALS
2019-08-08 03:05:15 +02:00
def test_corrupt_credId(self, device, MCRes):
2019-08-05 13:40:54 +08:00
# apply bit flip
badid = list(MCRes.auth_data.credential_data.credential_id[:])
badid[len(badid) // 2] = badid[len(badid) // 2] ^ 1
badid = bytes(badid)
allow_list = [{"id": badid, "type": "public-key"}]
with pytest.raises(CtapError) as e:
2019-08-08 03:05:15 +02:00
device.sendGA(*FidoRequest(allow_list=allow_list).toGA())
2019-08-05 13:40:54 +08:00
assert e.value.code == CtapError.ERR.NO_CREDENTIALS
2019-09-16 15:34:42 +08:00
def test_mismatched_rp(self, device, GARes):
rp_id = GARes.request.rp['id'][:]
rp_name = GARes.request.rp['name'][:]
rp_id += '.com'
mismatch_rp = {'id': rp_id, 'name': rp_name}
with pytest.raises(CtapError) as e:
device.sendGA(*FidoRequest(GARes, rp=mismatch_rp).toGA())
assert e.value.code == CtapError.ERR.NO_CREDENTIALS
2019-08-08 03:05:15 +02:00
def test_missing_rp(self, device, GARes):
2019-08-05 13:40:54 +08:00
with pytest.raises(CtapError) as e:
2019-08-08 03:05:15 +02:00
device.sendGA(*FidoRequest(GARes, rp=None).toGA())
2019-08-05 13:40:54 +08:00
assert e.value.code == CtapError.ERR.MISSING_PARAMETER
2019-08-08 03:05:15 +02:00
def test_bad_rp(self, device, GARes):
2019-08-05 20:02:20 +08:00
with pytest.raises(CtapError) as e:
2019-08-08 03:05:15 +02:00
device.sendGA(*FidoRequest(GARes, rp={"id": {"type": "wrong"}}).toGA())
2019-08-05 20:02:20 +08:00
2019-08-08 03:05:15 +02:00
def test_missing_cdh(self, device, GARes):
2019-08-05 20:02:20 +08:00
with pytest.raises(CtapError) as e:
2019-08-08 03:05:15 +02:00
device.sendGA(*FidoRequest(GARes, cdh=None).toGA())
2019-08-05 20:02:20 +08:00
assert e.value.code == CtapError.ERR.MISSING_PARAMETER
2019-08-08 03:05:15 +02:00
def test_bad_cdh(self, device, GARes):
with pytest.raises(CtapError) as e:
device.sendGA(*FidoRequest(GARes, cdh={"type": "wrong"}).toGA())
def test_bad_allow_list(self, device, GARes):
with pytest.raises(CtapError) as e:
device.sendGA(*FidoRequest(GARes, allow_list={"type": "wrong"}).toGA())
def test_bad_allow_list_item(self, device, GARes):
2019-08-05 20:02:20 +08:00
with pytest.raises(CtapError) as e:
device.sendGA(
2019-08-08 03:05:15 +02:00
*FidoRequest(
GARes, allow_list=["wrong"] + GARes.request.allow_list
).toGA()
2019-08-05 20:02:20 +08:00
)
2019-08-08 03:05:15 +02:00
def test_unknown_option(self, device, GARes):
device.sendGA(*FidoRequest(GARes, options={"unknown": True}).toGA())
2019-08-05 20:02:20 +08:00
2019-10-08 13:03:41 +02:00
@pytest.mark.skipif('trezor' in sys.argv, reason="User verification flag is intentionally set to true on Trezor even when user verification is not configured. (Otherwise some services refuse registration without giving a reason.)")
2019-08-08 03:05:15 +02:00
def test_option_uv(self, device, info, GARes):
2019-08-05 20:02:20 +08:00
if "uv" in info.options:
if info.options["uv"]:
2019-08-08 03:05:15 +02:00
res = device.sendGA(*FidoRequest(GARes, options={"uv": True}).toGA())
2019-08-05 20:02:20 +08:00
assert res.auth_data.flags & (1 << 2)
2019-08-08 03:05:15 +02:00
def test_option_up(self, device, info, GARes):
2019-08-05 20:02:20 +08:00
if "up" in info.options:
if info.options["up"]:
2019-08-08 03:05:15 +02:00
res = device.sendGA(*FidoRequest(GARes, options={"up": True}).toGA())
2019-08-05 20:02:20 +08:00
assert res.auth_data.flags & (1 << 0)
2019-08-08 03:05:15 +02:00
def test_allow_list_fake_item(self, device, GARes):
2019-08-05 20:02:20 +08:00
device.sendGA(
2019-08-08 03:05:15 +02:00
*FidoRequest(
GARes,
allow_list=[{"type": "rot13", "id": b"1234"}]
+ GARes.request.allow_list,
).toGA()
2019-08-05 20:02:20 +08:00
)
2019-08-08 03:05:15 +02:00
def test_allow_list_missing_field(self, device, GARes):
2019-08-05 20:02:20 +08:00
with pytest.raises(CtapError) as e:
device.sendGA(
2019-08-08 03:05:15 +02:00
*FidoRequest(
GARes, allow_list=[{"id": b"1234"}] + GARes.request.allow_list
).toGA()
2019-08-05 20:02:20 +08:00
)
2019-08-08 03:05:15 +02:00
def test_allow_list_field_wrong_type(self, device, GARes):
2019-08-05 20:02:20 +08:00
with pytest.raises(CtapError) as e:
device.sendGA(
2019-08-08 03:05:15 +02:00
*FidoRequest(
GARes,
allow_list=[{"type": b"public-key", "id": b"1234"}]
+ GARes.request.allow_list,
).toGA()
2019-08-05 20:02:20 +08:00
)
2019-08-08 03:05:15 +02:00
def test_allow_list_id_wrong_type(self, device, GARes):
2019-08-05 20:02:20 +08:00
with pytest.raises(CtapError) as e:
device.sendGA(
2019-08-08 03:05:15 +02:00
*FidoRequest(
GARes,
allow_list=[{"type": "public-key", "id": 42}]
2019-08-08 03:05:15 +02:00
+ GARes.request.allow_list,
).toGA()
2019-08-05 20:02:20 +08:00
)
2019-08-08 03:05:15 +02:00
def test_allow_list_missing_id(self, device, GARes):
2019-08-05 20:02:20 +08:00
with pytest.raises(CtapError) as e:
device.sendGA(
2019-08-08 03:05:15 +02:00
*FidoRequest(
GARes,
allow_list=[{"type": "public-key"}] + GARes.request.allow_list,
2019-08-08 03:05:15 +02:00
).toGA()
2019-08-05 20:02:20 +08:00
)
2019-08-05 13:40:54 +08:00
2019-09-16 16:26:47 +08:00
def test_user_presence_option_false(self, device, MCRes, GARes):
from cryptography.exceptions import InvalidSignature
2019-09-16 16:26:47 +08:00
res = device.sendGA(*FidoRequest(GARes, options = {'up': False}).toGA())
try:
verify(MCRes, res, GARes.request.cdh)
except InvalidSignature:
if 'trezor' not in sys.argv:
raise
2019-09-16 16:26:47 +08:00
if '--nfc' not in sys.argv:
assert((res.auth_data.flags & 1) == 0)
2019-08-05 13:40:54 +08:00
@pytest.mark.skipif('trezor' in sys.argv, reason="Reboot is not supported on Trezor.")
2019-08-05 13:40:54 +08:00
class TestGetAssertionAfterBoot(object):
2019-08-08 03:05:15 +02:00
def test_assertion_after_reboot(self, rebootedDevice, MCRes, GARes):
2019-08-05 13:40:54 +08:00
credential_data = AttestedCredentialData(MCRes.auth_data.credential_data)
verify(MCRes, GARes)