From 87c3fdb8a14c3e8a76529f7c0e396f1fafc415cd Mon Sep 17 00:00:00 2001 From: Nicolas Stalder Date: Thu, 8 Aug 2019 03:05:15 +0200 Subject: [PATCH] Add black and pre-commit hook --- .pre-commit-config.yaml | 6 + Makefile | 14 ++ dev-requirements.txt | 2 + tests/conftest.py | 64 +++--- tests/standard/fido2/pin/test_lockout.py | 11 +- tests/standard/fido2/pin/test_pin.py | 99 +++++----- tests/standard/fido2/pin/test_set_pin.py | 34 ++-- tests/standard/fido2/test_ctap1_interop.py | 9 +- tests/standard/fido2/test_get_assertion.py | 128 ++++++------ tests/standard/fido2/test_getinfo.py | 17 +- tests/standard/fido2/test_make_credential.py | 183 +++++++++--------- tests/standard/fido2/test_reset_credential.py | 1 + tests/standard/fido2/test_resident_key.py | 69 +++---- tests/standard/transport/test_hid.py | 24 +-- tests/standard/u2f/test_u2f.py | 59 +++--- tests/utils.py | 102 ++++++---- tests/vendor/solo/test_solo.py | 64 +++--- 17 files changed, 460 insertions(+), 426 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 dev-requirements.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..66cdd34 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: + - repo: https://github.com/psf/black + rev: stable + hooks: + - id: black + language_version: python3.7 diff --git a/Makefile b/Makefile index 3bb249d..d3c851f 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,22 @@ venv: python3 -m venv venv venv/bin/pip install -U pip venv/bin/pip install -U -r requirements.txt + venv/bin/pip install -U -r dev-requirements.txt + venv/bin/precommit install # re-run if dependencies change update: venv/bin/pip install -U pip venv/bin/pip install -U -r requirements.txt + venv/bin/pip install -U -r dev-requirements.txt + +# ensure this passes before commiting +check: + venv/bin/black --check tests/ + +# automatic code fixes +fix: black + +black: + venv/bin/black tests/ + diff --git a/dev-requirements.txt b/dev-requirements.txt new file mode 100644 index 0000000..81fc38c --- /dev/null +++ b/dev-requirements.txt @@ -0,0 +1,2 @@ +black +pre-commit diff --git a/tests/conftest.py b/tests/conftest.py index 14f3a74..e4c5fd6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -32,58 +32,55 @@ def is_simulation(pytestconfig): def is_nfc(pytestconfig): return pytestconfig.getoption("nfc") + @pytest.fixture(scope="module") def info(device): info = device.ctap2.get_info() - #print("data:", bytes(info)) - #print("decoded:", cbor.decode_from(bytes(info))) + # print("data:", bytes(info)) + # print("decoded:", cbor.decode_from(bytes(info))) return info + @pytest.fixture(scope="module") def MCRes(resetDevice,): req = FidoRequest() - res = resetDevice.sendMC( - *req.toMC(), - ) - setattr(res,'request',req) + res = resetDevice.sendMC(*req.toMC()) + setattr(res, "request", req) return res -@pytest.fixture(scope='class') -def GARes(device,MCRes): - req = FidoRequest(allow_list = [{ - "id": MCRes.auth_data.credential_data.credential_id, - "type": "public-key", - }]) - res = device.sendGA( - *req.toGA(), + +@pytest.fixture(scope="class") +def GARes(device, MCRes): + req = FidoRequest( + allow_list=[ + {"id": MCRes.auth_data.credential_data.credential_id, "type": "public-key"} + ] ) - setattr(res,'request',req) + res = device.sendGA(*req.toGA()) + setattr(res, "request", req) return res @pytest.fixture(scope="module") def RegRes(resetDevice,): req = FidoRequest() - res = resetDevice.register( - req.challenge, req.appid - ) - setattr(res,'request',req) + res = resetDevice.register(req.challenge, req.appid) + setattr(res, "request", req) return res -@pytest.fixture(scope='class') + +@pytest.fixture(scope="class") def AuthRes(device, RegRes): req = FidoRequest() - res = device.authenticate( - req.challenge, req.appid, RegRes.key_handle - ) - setattr(res,'request',req) + res = device.authenticate(req.challenge, req.appid, RegRes.key_handle) + setattr(res, "request", req) return res - -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def allowListItem(MCRes): - return + return + @pytest.fixture(scope="session") def device(pytestconfig): @@ -98,16 +95,19 @@ def device(pytestconfig): return dev -@pytest.fixture(scope='class') + +@pytest.fixture(scope="class") def rebootedDevice(device): device.reboot() return device -@pytest.fixture(scope='module') + +@pytest.fixture(scope="module") def resetDevice(device): device.reset() return device + class Packet(object): def __init__(self, data): self.data = data @@ -120,7 +120,6 @@ class Packet(object): return Packet(data) - class TestDevice: def __init__(self, tester=None): self.origin = "https://examplo.org" @@ -270,9 +269,7 @@ class TestDevice: self.ctap2.reset() def sendMC(self, *args, **kwargs): - attestation_object = self.ctap2.make_credential( - *args, **kwargs - ) + attestation_object = self.ctap2.make_credential(*args, **kwargs) if attestation_object: verifier = Attestation.for_type(attestation_object.fmt) client_data = args[0] @@ -292,6 +289,5 @@ class TestDevice: def sendPP(self, *args, **kwargs): return self.client.pin_protocol.get_pin_token(*args, **kwargs) - def delay(secs): time.sleep(secs) diff --git a/tests/standard/fido2/pin/test_lockout.py b/tests/standard/fido2/pin/test_lockout.py index 0a1644b..47fc353 100644 --- a/tests/standard/fido2/pin/test_lockout.py +++ b/tests/standard/fido2/pin/test_lockout.py @@ -6,12 +6,12 @@ from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData from tests.utils import * -def test_lockout(device,resetDevice): - pin = 'TestPin' +def test_lockout(device, resetDevice): + pin = "TestPin" device.client.pin_protocol.set_pin(pin) pin_token = device.client.pin_protocol.get_pin_token(pin) - req = FidoRequest(pin_token = pin_token) + req = FidoRequest(pin_token=pin_token) req.pin_auth = hmac_sha256(pin_token, req.cdh)[:16] @@ -23,9 +23,7 @@ def test_lockout(device,resetDevice): err = [CtapError.ERR.PIN_BLOCKED, CtapError.ERR.PIN_INVALID] with pytest.raises(CtapError) as e: - device.sendPP( - "WrongPin", - ) + device.sendPP("WrongPin") assert e.value.code == err or e.value.code in err attempts = 8 - i @@ -46,4 +44,3 @@ def test_lockout(device,resetDevice): with pytest.raises(CtapError) as e: device.sendPP(pin) assert e.value.code == CtapError.ERR.PIN_BLOCKED - diff --git a/tests/standard/fido2/pin/test_pin.py b/tests/standard/fido2/pin/test_pin.py index aeb1c66..453ecea 100644 --- a/tests/standard/fido2/pin/test_pin.py +++ b/tests/standard/fido2/pin/test_pin.py @@ -5,11 +5,12 @@ from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData from tests.utils import * -PIN1 = '123456789A' -PIN2 = 'ABCDEF' +PIN1 = "123456789A" +PIN2 = "ABCDEF" -@pytest.fixture(scope="module", params = [PIN1]) -def SetPinRes(request,device): + +@pytest.fixture(scope="module", params=[PIN1]) +def SetPinRes(request, device): device.reset() pin = request.param @@ -19,44 +20,41 @@ def SetPinRes(request,device): pin_token = device.client.pin_protocol.get_pin_token(pin) pin_auth = hmac_sha256(pin_token, req.cdh)[:16] - req = FidoRequest(req, pin_protocol = 1, pin_auth = pin_auth) + req = FidoRequest(req, pin_protocol=1, pin_auth=pin_auth) - res = device.sendMC( - *req.toMC(), - ) - setattr(res,'request',req) - setattr(res,'PIN',pin) + res = device.sendMC(*req.toMC()) + setattr(res, "request", req) + setattr(res, "PIN", pin) return res @pytest.fixture(scope="module") -def CPRes(request,device,SetPinRes): +def CPRes(request, device, SetPinRes): res = device.sendCP(1, PinProtocolV1.CMD.GET_KEY_AGREEMENT) return res + @pytest.fixture(scope="module") -def MCPinRes(device,SetPinRes): +def MCPinRes(device, SetPinRes): req = FidoRequest(SetPinRes) - res = device.sendMC( - *req.toMC(), - ) - setattr(res,'request',req) + res = device.sendMC(*req.toMC()) + setattr(res, "request", req) return res -@pytest.fixture(scope='class') -def GAPinRes(device,MCPinRes): + +@pytest.fixture(scope="class") +def GAPinRes(device, MCPinRes): req = FidoRequest(MCPinRes) - res = device.sendGA( - *req.toGA(), - ) - setattr(res,'request',req) + res = device.sendGA(*req.toGA()) + setattr(res, "request", req) return res + class TestPin(object): - def test_pin(self,CPRes): + def test_pin(self, CPRes): pass - def test_get_key_agreement_fields(self,CPRes): + def test_get_key_agreement_fields(self, CPRes): key = CPRes[1] assert "Is public key" and key[1] == 2 assert "Is P256" and key[-1] == 1 @@ -68,8 +66,7 @@ class TestPin(object): reg = device.sendMC(*FidoRequest(SetPinRes).toMC()) assert reg.auth_data.flags & (1 << 2) - - def test_change_pin(self, device, SetPinRes, ): + def test_change_pin(self, device, SetPinRes): device.client.pin_protocol.change_pin(PIN1, PIN2) pin_token = device.client.pin_protocol.get_pin_token(PIN2) @@ -81,49 +78,61 @@ class TestPin(object): reg = device.sendMC(*FidoRequest(SetPinRes).toMC()) auth = device.sendGA( - *FidoRequest(SetPinRes, allow_list = [{'type': 'public-key', 'id': reg.auth_data.credential_data.credential_id}] - ).toGA()) + *FidoRequest( + SetPinRes, + allow_list=[ + { + "type": "public-key", + "id": reg.auth_data.credential_data.credential_id, + } + ], + ).toGA() + ) assert reg.auth_data.flags & (1 << 2) assert auth.auth_data.flags & (1 << 2) - verify(reg,auth, cdh = SetPinRes.request.cdh) + verify(reg, auth, cdh=SetPinRes.request.cdh) def test_get_no_pin_auth(self, device, SetPinRes): reg = device.sendMC(*FidoRequest(SetPinRes).toMC()) - allow_list = [{'type': 'public-key', 'id': reg.auth_data.credential_data.credential_id}] + allow_list = [ + {"type": "public-key", "id": reg.auth_data.credential_data.credential_id} + ] auth = device.sendGA( - *FidoRequest(SetPinRes, allow_list = allow_list, pin_auth = None, pin_protocol = None - ).toGA()) - + *FidoRequest( + SetPinRes, allow_list=allow_list, pin_auth=None, pin_protocol=None + ).toGA() + ) + assert not (auth.auth_data.flags & (1 << 2)) - with pytest.raises(CtapError) as e: - reg = device.sendMC(*FidoRequest(SetPinRes, pin_auth = None, pin_protocol = None).toMC()) + reg = device.sendMC( + *FidoRequest(SetPinRes, pin_auth=None, pin_protocol=None).toMC() + ) - assert(e.value.code == CtapError.ERR.PIN_REQUIRED) + assert e.value.code == CtapError.ERR.PIN_REQUIRED def test_zero_length_pin_auth(self, device, SetPinRes): with pytest.raises(CtapError) as e: - reg = device.sendMC(*FidoRequest(SetPinRes, pin_auth = b'',).toMC()) - assert(e.value.code == CtapError.ERR.PIN_AUTH_INVALID) + reg = device.sendMC(*FidoRequest(SetPinRes, pin_auth=b"").toMC()) + assert e.value.code == CtapError.ERR.PIN_AUTH_INVALID with pytest.raises(CtapError) as e: - reg = device.sendGA(*FidoRequest(SetPinRes, pin_auth = b'',).toGA()) - assert(e.value.code == CtapError.ERR.PIN_AUTH_INVALID) + reg = device.sendGA(*FidoRequest(SetPinRes, pin_auth=b"").toGA()) + assert e.value.code == CtapError.ERR.PIN_AUTH_INVALID def test_make_credential_no_pin(self, device, SetPinRes): with pytest.raises(CtapError) as e: reg = device.sendMC(*FidoRequest().toMC()) - assert(e.value.code == CtapError.ERR.PIN_REQUIRED) + assert e.value.code == CtapError.ERR.PIN_REQUIRED def test_get_assertion_no_pin(self, device, SetPinRes): with pytest.raises(CtapError) as e: reg = device.sendGA(*FidoRequest().toGA()) - assert(e.value.code == CtapError.ERR.NO_CREDENTIALS) - + assert e.value.code == CtapError.ERR.NO_CREDENTIALS def test_pin_attempts(device, SetPinRes): @@ -152,7 +161,9 @@ def test_pin_attempts(device, SetPinRes): device.reboot() SetPinRes.request.pin_token = device.client.pin_protocol.get_pin_token(pin) - SetPinRes.request.pin_auth = hmac_sha256(SetPinRes.request.pin_token, SetPinRes.request.cdh)[:16] + SetPinRes.request.pin_auth = hmac_sha256( + SetPinRes.request.pin_token, SetPinRes.request.cdh + )[:16] reg = device.sendMC(*FidoRequest(SetPinRes).toMC()) diff --git a/tests/standard/fido2/pin/test_set_pin.py b/tests/standard/fido2/pin/test_set_pin.py index e5393d1..d3a65d7 100644 --- a/tests/standard/fido2/pin/test_set_pin.py +++ b/tests/standard/fido2/pin/test_set_pin.py @@ -5,53 +5,49 @@ from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData from tests.utils import * + class TestSetPin(object): - def test_send_zero_length_pin_auth(self,resetDevice): + def test_send_zero_length_pin_auth(self, resetDevice): with pytest.raises(CtapError) as e: - reg = resetDevice.sendMC(*FidoRequest(pin_auth = b'',).toMC()) - assert(e.value.code == CtapError.ERR.PIN_NOT_SET) + reg = resetDevice.sendMC(*FidoRequest(pin_auth=b"").toMC()) + assert e.value.code == CtapError.ERR.PIN_NOT_SET with pytest.raises(CtapError) as e: - reg = resetDevice.sendGA(*FidoRequest(pin_auth = b'',).toGA()) - assert(e.value.code in (CtapError.ERR.PIN_NOT_SET, CtapError.ERR.NO_CREDENTIALS)) + reg = resetDevice.sendGA(*FidoRequest(pin_auth=b"").toGA()) + assert e.value.code in (CtapError.ERR.PIN_NOT_SET, CtapError.ERR.NO_CREDENTIALS) - - def test_set_pin(self,device): - device.client.pin_protocol.set_pin('TestPin') + def test_set_pin(self, device): + device.client.pin_protocol.set_pin("TestPin") device.reset() - def test_set_pin_too_big(self, device): with pytest.raises(CtapError) as e: - device.client.pin_protocol.set_pin('A' * 64) + device.client.pin_protocol.set_pin("A" * 64) assert e.value.code == CtapError.ERR.PIN_POLICY_VIOLATION - def test_get_pin_token_but_no_pin_set(self, device): with pytest.raises(CtapError) as e: - device.client.pin_protocol.get_pin_token('TestPin') + device.client.pin_protocol.get_pin_token("TestPin") assert e.value.code == CtapError.ERR.PIN_NOT_SET def test_change_pin_but_no_pin_set(self, device): with pytest.raises(CtapError) as e: - device.client.pin_protocol.change_pin('TestPin', "1234") + device.client.pin_protocol.change_pin("TestPin", "1234") assert e.value.code == CtapError.ERR.PIN_NOT_SET def test_setting_pin_and_get_info(self, device): - device.client.pin_protocol.set_pin('TestPin') + device.client.pin_protocol.set_pin("TestPin") with pytest.raises(CtapError) as e: - device.client.pin_protocol.set_pin('TestPin') + device.client.pin_protocol.set_pin("TestPin") info = device.ctap2.get_info() - assert info.options['clientPin'] + assert info.options["clientPin"] - pin_token = device.client.pin_protocol.get_pin_token('TestPin') + pin_token = device.client.pin_protocol.get_pin_token("TestPin") res = device.sendCP(1, PinProtocolV1.CMD.GET_RETRIES) assert res[3] == 8 device.reset() - - diff --git a/tests/standard/fido2/test_ctap1_interop.py b/tests/standard/fido2/test_ctap1_interop.py index 4e407bd..e8c7d92 100644 --- a/tests/standard/fido2/test_ctap1_interop.py +++ b/tests/standard/fido2/test_ctap1_interop.py @@ -8,15 +8,16 @@ from tests.utils import FidoRequest class TestCtap1WithCtap2(object): - def test_ctap1_register(self, RegRes): RegRes.verify(RegRes.request.appid, RegRes.request.challenge) def test_ctap1_authenticate(self, RegRes, AuthRes): - AuthRes.verify(AuthRes.request.appid, AuthRes.request.challenge, RegRes.public_key) + AuthRes.verify( + AuthRes.request.appid, AuthRes.request.challenge, RegRes.public_key + ) def test_authenticate_ctap1_through_ctap2(self, device, RegRes): - req = FidoRequest(allow_list = [{"id": RegRes.key_handle, "type": "public-key"}]) + req = FidoRequest(allow_list=[{"id": RegRes.key_handle, "type": "public-key"}]) auth = device.sendGA(*req.toGA()) @@ -25,5 +26,3 @@ class TestCtap1WithCtap2(object): ) auth.verify(req.cdh, credential_data.public_key) assert auth.credential["id"] == RegRes.key_handle - - diff --git a/tests/standard/fido2/test_get_assertion.py b/tests/standard/fido2/test_get_assertion.py index 67890be..b21bf39 100644 --- a/tests/standard/fido2/test_get_assertion.py +++ b/tests/standard/fido2/test_get_assertion.py @@ -7,29 +7,26 @@ from tests.utils import * class TestGetAssertion(object): - def test_get_assertion(self,device, MCRes, GARes): + def test_get_assertion(self, device, MCRes, GARes): verify(MCRes, GARes) - def test_assertion_auth_data(self,GARes): + def test_assertion_auth_data(self, GARes): 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 - def test_that_user_credential_and_numberOfCredentials_are_not_present(self,GARes): + def test_that_user_credential_and_numberOfCredentials_are_not_present(self, GARes): assert GARes.user == None assert GARes.number_of_credentials == None - - def test_empty_allowList(self,device): + def test_empty_allowList(self, device): with pytest.raises(CtapError) as e: - device.sendGA( - *FidoRequest(allow_list = []).toGA() - ) + device.sendGA(*FidoRequest(allow_list=[]).toGA()) assert e.value.code == CtapError.ERR.NO_CREDENTIALS - def test_corrupt_credId(self,device,MCRes): + def test_corrupt_credId(self, device, MCRes): # apply bit flip badid = list(MCRes.auth_data.credential_data.credential_id[:]) badid[len(badid) // 2] = badid[len(badid) // 2] ^ 1 @@ -38,110 +35,103 @@ class TestGetAssertion(object): allow_list = [{"id": badid, "type": "public-key"}] with pytest.raises(CtapError) as e: - device.sendGA( - *FidoRequest(allow_list = allow_list).toGA() - ) + device.sendGA(*FidoRequest(allow_list=allow_list).toGA()) assert e.value.code == CtapError.ERR.NO_CREDENTIALS - - def test_missing_rp(self,device,GARes): + def test_missing_rp(self, device, GARes): with pytest.raises(CtapError) as e: - device.sendGA( - *FidoRequest(GARes, rp = None).toGA() - ) + device.sendGA(*FidoRequest(GARes, rp=None).toGA()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_bad_rp(self,device,GARes): + def test_bad_rp(self, device, GARes): with pytest.raises(CtapError) as e: - device.sendGA( - *FidoRequest(GARes, rp = {'id':{"type": "wrong"}}).toGA() - ) + device.sendGA(*FidoRequest(GARes, rp={"id": {"type": "wrong"}}).toGA()) - def test_missing_cdh(self,device,GARes): + def test_missing_cdh(self, device, GARes): with pytest.raises(CtapError) as e: - device.sendGA( - *FidoRequest(GARes, cdh = None).toGA() - ) + device.sendGA(*FidoRequest(GARes, cdh=None).toGA()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_bad_cdh(self,device,GARes): + 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): with pytest.raises(CtapError) as e: device.sendGA( - *FidoRequest(GARes, cdh = {'type':'wrong'}).toGA() + *FidoRequest( + GARes, allow_list=["wrong"] + GARes.request.allow_list + ).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_unknown_option(self, device, GARes): + device.sendGA(*FidoRequest(GARes, options={"unknown": True}).toGA()) - def test_bad_allow_list_item(self,device,GARes): - with pytest.raises(CtapError) as e: - device.sendGA( - *FidoRequest(GARes, allow_list = ['wrong'] + GARes.request.allow_list).toGA(), - ) - - def test_unknown_option(self,device,GARes): - device.sendGA( - *FidoRequest(GARes, options = {'unknown': True}).toGA(), - ) - - def test_option_uv(self,device,info,GARes): + def test_option_uv(self, device, info, GARes): if "uv" in info.options: if info.options["uv"]: - res = device.sendGA( - *FidoRequest(GARes, options = {"uv": True},).toGA() - ) + res = device.sendGA(*FidoRequest(GARes, options={"uv": True}).toGA()) assert res.auth_data.flags & (1 << 2) - def test_option_up(self,device,info,GARes): + def test_option_up(self, device, info, GARes): if "up" in info.options: if info.options["up"]: - res = device.sendGA( - *FidoRequest(GARes, options = {"up": True},).toGA() - ) + res = device.sendGA(*FidoRequest(GARes, options={"up": True}).toGA()) assert res.auth_data.flags & (1 << 0) - def test_allow_list_fake_item(self,device,GARes): + def test_allow_list_fake_item(self, device, GARes): device.sendGA( - *FidoRequest(GARes, allow_list = [{"type": "rot13", "id": b"1234"}] + GARes.request.allow_list).toGA(), + *FidoRequest( + GARes, + allow_list=[{"type": "rot13", "id": b"1234"}] + + GARes.request.allow_list, + ).toGA() ) - def test_allow_list_missing_field(self,device,GARes): + def test_allow_list_missing_field(self, device, GARes): with pytest.raises(CtapError) as e: device.sendGA( - *FidoRequest(GARes, allow_list = [{"id": b"1234"}] + GARes.request.allow_list).toGA(), + *FidoRequest( + GARes, allow_list=[{"id": b"1234"}] + GARes.request.allow_list + ).toGA() ) - - def test_allow_list_field_wrong_type(self,device,GARes): + def test_allow_list_field_wrong_type(self, device, GARes): with pytest.raises(CtapError) as e: device.sendGA( - *FidoRequest(GARes, allow_list = [{"type": b"public-key","id": b"1234"}] + GARes.request.allow_list).toGA(), + *FidoRequest( + GARes, + allow_list=[{"type": b"public-key", "id": b"1234"}] + + GARes.request.allow_list, + ).toGA() ) - def test_allow_list_id_wrong_type(self,device,GARes): + def test_allow_list_id_wrong_type(self, device, GARes): with pytest.raises(CtapError) as e: device.sendGA( - *FidoRequest(GARes, allow_list = [{"type": b"public-key","id": 42}] + GARes.request.allow_list).toGA(), + *FidoRequest( + GARes, + allow_list=[{"type": b"public-key", "id": 42}] + + GARes.request.allow_list, + ).toGA() ) - def test_allow_list_missing_id(self,device,GARes): + def test_allow_list_missing_id(self, device, GARes): with pytest.raises(CtapError) as e: device.sendGA( - *FidoRequest(GARes, allow_list = [{"type": b"public-key"}] + GARes.request.allow_list).toGA(), + *FidoRequest( + GARes, + allow_list=[{"type": b"public-key"}] + GARes.request.allow_list, + ).toGA() ) class TestGetAssertionAfterBoot(object): - def test_assertion_after_reboot(self,rebootedDevice, MCRes, GARes): + def test_assertion_after_reboot(self, rebootedDevice, MCRes, GARes): credential_data = AttestedCredentialData(MCRes.auth_data.credential_data) verify(MCRes, GARes) - - - - - - diff --git a/tests/standard/fido2/test_getinfo.py b/tests/standard/fido2/test_getinfo.py index 3eb4a95..ceaa539 100644 --- a/tests/standard/fido2/test_getinfo.py +++ b/tests/standard/fido2/test_getinfo.py @@ -5,6 +5,7 @@ from fido2.ctap import CtapError from tests.utils import * + def test_get_info(info): pass @@ -17,23 +18,21 @@ def test_Check_pin_protocols_field(info): if len(info.pin_protocols): assert sum(info.pin_protocols) > 0 + def test_Check_options_field(info): for x in info.options: assert info.options[x] in [True, False] -def test_Check_uv_option(device, info, ): + +def test_Check_uv_option(device, info): if "uv" in info.options: if info.options["uv"]: - device.sendMC( - *FidoRequest().toMC(), - options = {"uv": True}, - ) + device.sendMC(*FidoRequest().toMC(), options={"uv": True}) -def test_Check_up_option(device,info,): + +def test_Check_up_option(device, info): if "up" in info.options: if info.options["up"]: with pytest.raises(CtapError) as e: - device.sendMC( - *FidoRequest(options = {"up": True}).toMC(), - ) + device.sendMC(*FidoRequest(options={"up": True}).toMC()) assert e.value.code == CtapError.ERR.INVALID_OPTION diff --git a/tests/standard/fido2/test_make_credential.py b/tests/standard/fido2/test_make_credential.py index 6d24c86..eb82fae 100644 --- a/tests/standard/fido2/test_make_credential.py +++ b/tests/standard/fido2/test_make_credential.py @@ -8,236 +8,231 @@ from tests.utils import FidoRequest class TestMakeCredential(object): - def test_make_credential(self,MCRes): + def test_make_credential(self, MCRes): pass - def test_attestation_format(self,MCRes): + def test_attestation_format(self, MCRes): assert MCRes.fmt in ["packed", "tpm", "android-key", "adroid-safetynet"] - - def test_authdata_length(self,MCRes): + + def test_authdata_length(self, MCRes): assert len(MCRes.auth_data) >= 77 - - def test_missing_cdh(self,device,MCRes): - req = FidoRequest(MCRes, cdh = None) + def test_missing_cdh(self, device, MCRes): + req = FidoRequest(MCRes, cdh=None) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_bad_type_cdh(self,device,MCRes): - req = FidoRequest(MCRes, cdh = 5) + def test_bad_type_cdh(self, device, MCRes): + req = FidoRequest(MCRes, cdh=5) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_missing_user(self,device,MCRes): - req = FidoRequest(MCRes, user = None) + def test_missing_user(self, device, MCRes): + req = FidoRequest(MCRes, user=None) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_bad_type_user(self,device,MCRes): - req = FidoRequest(MCRes, user = b'1234abcdf') + def test_bad_type_user(self, device, MCRes): + req = FidoRequest(MCRes, user=b"1234abcdf") with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_missing_rp(self,device,MCRes): - req = FidoRequest(MCRes, rp = None) + def test_missing_rp(self, device, MCRes): + req = FidoRequest(MCRes, rp=None) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_bad_type_rp(self,device,MCRes): - req = FidoRequest(MCRes, rp = b'1234abcdef') + def test_bad_type_rp(self, device, MCRes): + req = FidoRequest(MCRes, rp=b"1234abcdef") with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_missing_pubKeyCredParams(self,device,MCRes): - req = FidoRequest(MCRes, key_params = None) + def test_missing_pubKeyCredParams(self, device, MCRes): + req = FidoRequest(MCRes, key_params=None) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_bad_type_pubKeyCredParams(self,device,MCRes): - req = FidoRequest(MCRes, key_params = b'1234a') + def test_bad_type_pubKeyCredParams(self, device, MCRes): + req = FidoRequest(MCRes, key_params=b"1234a") with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_bad_type_excludeList(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list = 8) + def test_bad_type_excludeList(self, device, MCRes): + req = FidoRequest(MCRes, exclude_list=8) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_bad_type_extensions(self,device,MCRes): - req = FidoRequest(MCRes, extensions = 8) + def test_bad_type_extensions(self, device, MCRes): + req = FidoRequest(MCRes, extensions=8) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_bad_type_options(self,device,MCRes): - req = FidoRequest(MCRes, options = 8) + def test_bad_type_options(self, device, MCRes): + req = FidoRequest(MCRes, options=8) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_bad_type_rp_name(self,device,MCRes): - req = FidoRequest(MCRes, rp = {"id": 'test.org', "name": 8, "icon": "icon"}) + def test_bad_type_rp_name(self, device, MCRes): + req = FidoRequest(MCRes, rp={"id": "test.org", "name": 8, "icon": "icon"}) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_bad_type_rp_id(self,device,MCRes): - req = FidoRequest(MCRes, rp = {"id": 8, "name": "name", "icon": "icon"}) + def test_bad_type_rp_id(self, device, MCRes): + req = FidoRequest(MCRes, rp={"id": 8, "name": "name", "icon": "icon"}) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_bad_type_rp_icon(self,device,MCRes): - req = FidoRequest(MCRes, rp = {"id": "test.org", "name": "name", "icon": 8}) + def test_bad_type_rp_icon(self, device, MCRes): + req = FidoRequest(MCRes, rp={"id": "test.org", "name": "name", "icon": 8}) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_bad_type_user_name(self,device,MCRes): - req = FidoRequest(MCRes, user = {"id": b"user_id", "name": 8}) + def test_bad_type_user_name(self, device, MCRes): + req = FidoRequest(MCRes, user={"id": b"user_id", "name": 8}) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - - def test_bad_type_user_id(self,device,MCRes): - req = FidoRequest(MCRes, user = {"id": "user_id", "name": "name"}) + def test_bad_type_user_id(self, device, MCRes): + req = FidoRequest(MCRes, user={"id": "user_id", "name": "name"}) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - - def test_bad_type_user_displayName(self,device,MCRes): - req = FidoRequest(MCRes, user = {"id": "user_id", "name": "name", "displayName": 8}) + def test_bad_type_user_displayName(self, device, MCRes): + req = FidoRequest( + MCRes, user={"id": "user_id", "name": "name", "displayName": 8} + ) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_bad_type_user_icon(self,device,MCRes): - req = FidoRequest(MCRes, user = {"id": "user_id", "name": "name", "icon": 8}) + def test_bad_type_user_icon(self, device, MCRes): + req = FidoRequest(MCRes, user={"id": "user_id", "name": "name", "icon": 8}) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_bad_type_pubKeyCredParams(self,device,MCRes): - req = FidoRequest(MCRes, key_params = ['wrong']) + def test_bad_type_pubKeyCredParams(self, device, MCRes): + req = FidoRequest(MCRes, key_params=["wrong"]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_missing_pubKeyCredParams_type(self,device,MCRes): - req = FidoRequest(MCRes, key_params = [{"alg": ES256.ALGORITHM}]) + def test_missing_pubKeyCredParams_type(self, device, MCRes): + req = FidoRequest(MCRes, key_params=[{"alg": ES256.ALGORITHM}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_missing_pubKeyCredParams_alg(self,device,MCRes): - req = FidoRequest(MCRes, key_params = [{"type": "public-key"}]) + def test_missing_pubKeyCredParams_alg(self, device, MCRes): + req = FidoRequest(MCRes, key_params=[{"type": "public-key"}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) assert e.value.code == CtapError.ERR.MISSING_PARAMETER - def test_bad_type_pubKeyCredParams_alg(self,device,MCRes): - req = FidoRequest(MCRes, key_params = [{"alg": "7", "type": "public-key"}]) + def test_bad_type_pubKeyCredParams_alg(self, device, MCRes): + req = FidoRequest(MCRes, key_params=[{"alg": "7", "type": "public-key"}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - def test_unsupported_algorithm(self,device,MCRes): - req = FidoRequest(MCRes, key_params = [{"alg": 1337, "type": "public-key"}]) + def test_unsupported_algorithm(self, device, MCRes): + req = FidoRequest(MCRes, key_params=[{"alg": 1337, "type": "public-key"}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - + assert e.value.code == CtapError.ERR.UNSUPPORTED_ALGORITHM - def test_exclude_list(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list= [{"id": b"1234", "type": "rot13"}]) + def test_exclude_list(self, device, MCRes): + req = FidoRequest(MCRes, exclude_list=[{"id": b"1234", "type": "rot13"}]) device.sendMC(*req.toMC()) - - def test_exclude_list2(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list= [{"id": b"1234", "type": "mangoPapayaCoconutNotAPublicKey"}]) + + def test_exclude_list2(self, device, MCRes): + req = FidoRequest( + MCRes, + exclude_list=[{"id": b"1234", "type": "mangoPapayaCoconutNotAPublicKey"}], + ) device.sendMC(*req.toMC()) - - def test_bad_type_exclude_list(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list= ['1234']) + + def test_bad_type_exclude_list(self, device, MCRes): + req = FidoRequest(MCRes, exclude_list=["1234"]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_missing_exclude_list_type(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list= [{"id": b"1234"}]) + + def test_missing_exclude_list_type(self, device, MCRes): + req = FidoRequest(MCRes, exclude_list=[{"id": b"1234"}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_missing_exclude_list_id(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list= [{"type": "public-key"}]) + + def test_missing_exclude_list_id(self, device, MCRes): + req = FidoRequest(MCRes, exclude_list=[{"type": "public-key"}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_bad_type_exclude_list_id(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list= [{"type": "public-key", "id": "1234"}]) + + def test_bad_type_exclude_list_id(self, device, MCRes): + req = FidoRequest(MCRes, exclude_list=[{"type": "public-key", "id": "1234"}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_bad_type_exclude_list_type(self,device,MCRes): - req = FidoRequest(MCRes, exclude_list= [{"type": b"public-key", "id": b"1234"}]) + + def test_bad_type_exclude_list_type(self, device, MCRes): + req = FidoRequest(MCRes, exclude_list=[{"type": b"public-key", "id": b"1234"}]) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) - - def test_bad_type_exclude_list_type(self,device,MCRes,GARes): + def test_bad_type_exclude_list_type(self, device, MCRes, GARes): req = FidoRequest(MCRes, exclude_list=GARes.request.allow_list) with pytest.raises(CtapError) as e: device.sendMC(*req.toMC()) assert e.value.code == CtapError.ERR.CREDENTIAL_EXCLUDED - - def test_unknown_option(self,device,MCRes): - req = FidoRequest(MCRes, options = {'unknown': False}) - print('MC',req.toMC()) + + def test_unknown_option(self, device, MCRes): + req = FidoRequest(MCRes, options={"unknown": False}) + print("MC", req.toMC()) device.sendMC(*req.toMC()) - - #self.testReset() + # self.testReset() - #self.testGA( - #"Send GA request with reset auth, expect NO_CREDENTIALS", - #rp["id"], - #cdh, - #allow_list, - #expectedError=CtapError.ERR.NO_CREDENTIALS, - #) + # self.testGA( + # "Send GA request with reset auth, expect NO_CREDENTIALS", + # rp["id"], + # cdh, + # allow_list, + # expectedError=CtapError.ERR.NO_CREDENTIALS, + # ) diff --git a/tests/standard/fido2/test_reset_credential.py b/tests/standard/fido2/test_reset_credential.py index 0dcdfc5..ea70234 100644 --- a/tests/standard/fido2/test_reset_credential.py +++ b/tests/standard/fido2/test_reset_credential.py @@ -4,6 +4,7 @@ from fido2.ctap import CtapError from tests.utils import * + def test_credential_resets(device, MCRes, GARes): verify(MCRes, GARes) device.reset() diff --git a/tests/standard/fido2/test_resident_key.py b/tests/standard/fido2/test_resident_key.py index ddff73f..d31ef79 100644 --- a/tests/standard/fido2/test_resident_key.py +++ b/tests/standard/fido2/test_resident_key.py @@ -4,8 +4,9 @@ from fido2.ctap import CtapError from tests.utils import * -@pytest.fixture(scope="module", params = ['', '123456']) -def SetPINRes(request,device,): + +@pytest.fixture(scope="module", params=["", "123456"]) +def SetPINRes(request, device): device.reset() @@ -17,66 +18,57 @@ def SetPINRes(request,device,): pin_token = device.client.pin_protocol.get_pin_token(pin) pin_auth = hmac_sha256(pin_token, req.cdh)[:16] - req = FidoRequest(req, pin_protocol = 1, pin_auth = pin_auth) + req = FidoRequest(req, pin_protocol=1, pin_auth=pin_auth) - res = device.sendMC( - *req.toMC(), - ) - setattr(res,'request',req) + res = device.sendMC(*req.toMC()) + setattr(res, "request", req) return res @pytest.fixture(scope="module") -def MC_RK_Res(device,SetPINRes): - req = FidoRequest(SetPINRes,options = {"rk": True}) - res = device.sendMC( - *req.toMC(), - ) - setattr(res,'request',req) +def MC_RK_Res(device, SetPINRes): + req = FidoRequest(SetPINRes, options={"rk": True}) + res = device.sendMC(*req.toMC()) + setattr(res, "request", req) return res -@pytest.fixture(scope='class') -def GA_RK_Res(device,MC_RK_Res): + +@pytest.fixture(scope="class") +def GA_RK_Res(device, MC_RK_Res): req = FidoRequest(MC_RK_Res) - res = device.sendGA( - *req.toGA(), - ) - setattr(res,'request',req) + res = device.sendGA(*req.toGA()) + setattr(res, "request", req) return res class TestResidentKey(object): - - def test_resident_key(self,MC_RK_Res, info): + def test_resident_key(self, MC_RK_Res, info): pass - def test_resident_key_auth(self,MC_RK_Res, GA_RK_Res): + def test_resident_key_auth(self, MC_RK_Res, GA_RK_Res): verify(MC_RK_Res, GA_RK_Res) - def test_user_info_returned(self,MC_RK_Res, GA_RK_Res): + def test_user_info_returned(self, MC_RK_Res, GA_RK_Res): if not MC_RK_Res.request.pin_protocol: assert "id" in GA_RK_Res.user.keys() and len(GA_RK_Res.user.keys()) == 1 - - def test_multiple_rk(self,device, MC_RK_Res,): + def test_multiple_rk(self, device, MC_RK_Res): auths = [] regs = [MC_RK_Res] - for i in range(0,3): - req = FidoRequest(MC_RK_Res, user = generate_user()) - res = device.sendMC( *req.toMC() ) + for i in range(0, 3): + req = FidoRequest(MC_RK_Res, user=generate_user()) + res = device.sendMC(*req.toMC()) regs.append(res) - - req = FidoRequest(MC_RK_Res, user = generate_user()) - res = device.sendGA( *req.toGA() ) + req = FidoRequest(MC_RK_Res, user=generate_user()) + res = device.sendGA(*req.toGA()) - assert(res.number_of_credentials == 4) + assert res.number_of_credentials == 4 auths.append(res) - auths.append( device.ctap2.get_next_assertion() ) - auths.append( device.ctap2.get_next_assertion() ) - auths.append( device.ctap2.get_next_assertion() ) - + auths.append(device.ctap2.get_next_assertion()) + auths.append(device.ctap2.get_next_assertion()) + auths.append(device.ctap2.get_next_assertion()) with pytest.raises(CtapError) as e: device.ctap2.get_next_assertion() @@ -87,6 +79,5 @@ class TestResidentKey(object): if y not in x.user.keys(): print("FAIL: %s was not in user: " % y, x.user) - for x,y in zip(regs, auths): - verify(x,y,req.cdh) - + for x, y in zip(regs, auths): + verify(x, y, req.cdh) diff --git a/tests/standard/transport/test_hid.py b/tests/standard/transport/test_hid.py index 74ca883..5acc6b1 100644 --- a/tests/standard/transport/test_hid.py +++ b/tests/standard/transport/test_hid.py @@ -6,11 +6,8 @@ from fido2.hid import CTAPHID from fido2.ctap import CtapError - - class TestHID(object): - - def test_long_ping(self,device): + def test_long_ping(self, device): amt = 1000 pingdata = os.urandom(amt) @@ -19,11 +16,10 @@ class TestHID(object): t2 = time.time() * 1000 delt = t2 - t1 - assert not ( delt > 555 * (amt / 1000) ) + assert not (delt > 555 * (amt / 1000)) assert r == pingdata - def test_init(self, device, check_timeouts=False): if check_timeouts: with pytest.raises(socket.timeout): @@ -32,7 +28,7 @@ class TestHID(object): payload = b"\x11\x11\x11\x11\x11\x11\x11\x11" r = device.send_data(CTAPHID.INIT, payload) print(r) - assert(r[:8] == payload) + assert r[:8] == payload def test_ping(self, device): @@ -64,7 +60,7 @@ class TestHID(object): def test_oversize_packet(self, device): device.send_raw("\x81\x1d\xba\x00") cmd, resp = device.recv_raw() - assert(resp[0] == CtapError.ERR.INVALID_LENGTH) + assert resp[0] == CtapError.ERR.INVALID_LENGTH def test_skip_sequence_number(self, device): r = device.send_data(CTAPHID.PING, "\x44" * 200) @@ -74,7 +70,7 @@ class TestHID(object): # skip 2 device.send_raw("\x03") cmd, resp = device.recv_raw() - assert(resp[0] == CtapError.ERR.INVALID_SEQ) + assert resp[0] == CtapError.ERR.INVALID_SEQ def test_resync_and_ping(self, device): r = device.send_data(CTAPHID.INIT, "\x11\x22\x33\x44\x55\x66\x77\x88") @@ -121,7 +117,7 @@ class TestHID(object): assert r[0] == CtapError.ERR.TIMEOUT assert delt < 1000 and delt > 400 - def test_not_cont(self, device,check_timeouts=False): + def test_not_cont(self, device, check_timeouts=False): device.send_data(CTAPHID.INIT, "\x11\x22\x33\x44\x55\x66\x77\x88") device.send_raw("\x81\x04\x00") device.send_raw("\x00") @@ -137,7 +133,7 @@ class TestHID(object): with pytest.raises(socket.timeout): cmd, r = device.recv_raw() # timeout response - def test_check_busy(self, device,): + def test_check_busy(self, device): t1 = time.time() * 1000 device.send_data(CTAPHID.INIT, "\x11\x22\x33\x44\x55\x66\x77\x88") oldcid = device.cid() @@ -156,7 +152,7 @@ class TestHID(object): assert cmd == 0xBF assert r[0] == CtapError.ERR.TIMEOUT - def test_check_busy_interleaved(self, device,): + def test_check_busy_interleaved(self, device): cid1 = "\x11\x22\x33\x44" cid2 = "\x01\x22\x33\x44" device.set_cid(cid2) @@ -185,7 +181,7 @@ class TestHID(object): assert cmd == 0x81 assert len(r) == 0x63 - def test_cid_0(self, device,): + def test_cid_0(self, device): device.set_cid("\x00\x00\x00\x00") device.send_raw( "\x86\x00\x08\x11\x22\x33\x44\x55\x66\x77\x88", cid="\x00\x00\x00\x00" @@ -195,7 +191,7 @@ class TestHID(object): assert r[0] == CtapError.ERR.INVALID_CHANNEL device.set_cid("\x05\x04\x03\x02") - def test_cid_ffffffff(self, device,): + def test_cid_ffffffff(self, device): device.set_cid("\xff\xff\xff\xff") device.send_raw( diff --git a/tests/standard/u2f/test_u2f.py b/tests/standard/u2f/test_u2f.py index 16e8d0d..1933d30 100644 --- a/tests/standard/u2f/test_u2f.py +++ b/tests/standard/u2f/test_u2f.py @@ -6,27 +6,33 @@ from tests.utils import verify, FidoRequest class TestU2F(object): - def test_u2f_reg(self,device,RegRes): + def test_u2f_reg(self, device, RegRes): RegRes.verify(RegRes.request.appid, RegRes.request.challenge) - def test_u2f_auth(self,device,RegRes,AuthRes): - AuthRes.verify(AuthRes.request.appid, AuthRes.request.challenge, RegRes.public_key) + def test_u2f_auth(self, device, RegRes, AuthRes): + AuthRes.verify( + AuthRes.request.appid, AuthRes.request.challenge, RegRes.public_key + ) - def test_u2f_auth_check_only(self,device,RegRes,): + def test_u2f_auth_check_only(self, device, RegRes): with pytest.raises(ApduError) as e: - device.ctap1.authenticate(RegRes.request.challenge, RegRes.request.appid, RegRes.key_handle, check_only = True) + device.ctap1.authenticate( + RegRes.request.challenge, + RegRes.request.appid, + RegRes.key_handle, + check_only=True, + ) assert e.value.code == APDU.USE_NOT_SATISFIED - - def test_version(self,device,): + def test_version(self, device): assert device.ctap1.get_version() == "U2F_V2" - def test_bad_ins(self,device,): + def test_bad_ins(self, device): with pytest.raises(ApduError) as e: device.ctap1.send_apdu(0, 0, 0, 0, b"") assert e.value.code == 0x6D00 - def test_bad_cla(self,device): + def test_bad_cla(self, device): with pytest.raises(ApduError) as e: device.ctap1.send_apdu(1, CTAP1.INS.VERSION, 0, 0, b"abc") assert e.value.code == 0x6E00 @@ -74,29 +80,36 @@ class TestU2F(object): assert e.value.code == APDU.USE_NOT_SATISFIED def test_bad_key_handle(self, device, RegRes): - kh = bytearray(RegRes.key_handle) - kh[0] = kh[0] ^ (0x40) + kh = bytearray(RegRes.key_handle) + kh[0] = kh[0] ^ (0x40) - with pytest.raises(ApduError) as e: - device.ctap1.authenticate(RegRes.request.challenge, RegRes.request.appid, kh, check_only=True) - assert e.value.code == APDU.WRONG_DATA + with pytest.raises(ApduError) as e: + device.ctap1.authenticate( + RegRes.request.challenge, RegRes.request.appid, kh, check_only=True + ) + assert e.value.code == APDU.WRONG_DATA - with pytest.raises(ApduError) as e: - device.ctap1.authenticate(RegRes.request.challenge, RegRes.request.appid, kh, ) - assert e.value.code == APDU.WRONG_DATA + with pytest.raises(ApduError) as e: + device.ctap1.authenticate( + RegRes.request.challenge, RegRes.request.appid, kh + ) + assert e.value.code == APDU.WRONG_DATA def test_bad_key_handle_length(self, device, RegRes): - kh = bytearray(RegRes.key_handle) - - with pytest.raises(ApduError) as e: - device.ctap1.authenticate(RegRes.request.challenge, RegRes.request.appid, kh[: len(kh) // 2]) - assert e.value.code == APDU.WRONG_DATA + kh = bytearray(RegRes.key_handle) + with pytest.raises(ApduError) as e: + device.ctap1.authenticate( + RegRes.request.challenge, RegRes.request.appid, kh[: len(kh) // 2] + ) + assert e.value.code == APDU.WRONG_DATA def test_incorrect_appid(self, device, RegRes): badid = bytearray(RegRes.request.appid) badid[0] = badid[0] ^ (0x40) with pytest.raises(ApduError) as e: - auth = device.ctap1.authenticate(RegRes.request.challenge, badid, RegRes.key_handle) + auth = device.ctap1.authenticate( + RegRes.request.challenge, badid, RegRes.key_handle + ) assert e.value.code == APDU.WRONG_DATA diff --git a/tests/utils.py b/tests/utils.py index f26e9d9..8dec6ff 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -5,81 +5,98 @@ from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData from fido2.utils import sha256, hmac_sha256 -name_list = open('data/first-names.txt').readlines() +name_list = open("data/first-names.txt").readlines() -def verify(reg,auth,cdh = None): + +def verify(reg, auth, cdh=None): credential_data = AttestedCredentialData(reg.auth_data.credential_data) - if cdh is None: cdh = auth.request.cdh + if cdh is None: + cdh = auth.request.cdh auth.verify(cdh, credential_data.public_key) - assert ( - auth.credential["id"] == reg.auth_data.credential_data.credential_id - ) + assert auth.credential["id"] == reg.auth_data.credential_data.credential_id def generate_rp(): return {"id": "example.org", "name": "ExampleRP"} + def generate_user(): # https://www.w3.org/TR/webauthn/#user-handle - user_id_length = random.randint(1,64) + user_id_length = random.randint(1, 64) user_id = secrets.token_bytes(user_id_length) # https://www.w3.org/TR/webauthn/#dictionary-pkcredentialentity - name = ' '.join(random.choice(name_list).strip() for i in range(0,3)) - icon = 'https://www.w3.org/TR/webauthn/' + name = " ".join(random.choice(name_list).strip() for i in range(0, 3)) + icon = "https://www.w3.org/TR/webauthn/" display_name = "Displayed " + name - return {"id": user_id, "name": name, 'icon': icon, 'displayName': display_name} + return {"id": user_id, "name": name, "icon": icon, "displayName": display_name} + def generate_challenge(): return secrets.token_bytes(32) + def get_key_params(): return [{"type": "public-key", "alg": ES256.ALGORITHM}] + def generate_cdh(): return b"123456789abcdef0123456789abcdef0" + def generate(param): - if param == 'rp': + if param == "rp": return generate_rp() - if param == 'user': + if param == "user": return generate_user() - if param == 'challenge': + if param == "challenge": return generate_challenge() - if param == 'cdh': + if param == "cdh": return generate_cdh() - if param == 'key_params': + if param == "key_params": return get_key_params() - if param == 'allow_list': + if param == "allow_list": return [] return None + class Empty: pass -class FidoRequest(): - def __init__(self, request = None, **kwargs): + +class FidoRequest: + def __init__(self, request=None, **kwargs): if not isinstance(request, FidoRequest) and request is not None: request = request.request self.request = request - for i in ('cdh', 'key_params', 'allow_list', 'challenge', - 'rp', 'user', 'pin_protocol', 'options', 'appid', - 'exclude_list', 'extensions', 'pin_auth'): + for i in ( + "cdh", + "key_params", + "allow_list", + "challenge", + "rp", + "user", + "pin_protocol", + "options", + "appid", + "exclude_list", + "extensions", + "pin_auth", + ): self.save_attr(i, kwargs.get(i, Empty), request) - - if isinstance(self.rp,dict) and 'id' in self.rp: - if hasattr(self.rp["id"], 'encode'): + if isinstance(self.rp, dict) and "id" in self.rp: + if hasattr(self.rp["id"], "encode"): self.appid = sha256(self.rp["id"].encode("utf8")) - #self.chal = sha256(self.challenge.encode("utf8")) + # self.chal = sha256(self.challenge.encode("utf8")) - def save_attr(self,attr,value,request): + def save_attr(self, attr, value, request): """ Will assign attribute from source, in following priority: Argument, request object, generated @@ -87,23 +104,32 @@ class FidoRequest(): if value != Empty: setattr(self, attr, value) elif request is not None: - setattr(self, attr, getattr(request,attr)) + setattr(self, attr, getattr(request, attr)) else: setattr(self, attr, generate(attr)) def toGA(self,): - return [None if not self.rp else self.rp['id'], - self.cdh, self.allow_list, self.extensions, self.options, - self.pin_auth, self.pin_protocol] + return [ + None if not self.rp else self.rp["id"], + self.cdh, + self.allow_list, + self.extensions, + self.options, + self.pin_auth, + self.pin_protocol, + ] def toMC(self,): - return [self.cdh, self.rp, self.user, self.key_params, - self.exclude_list, self.extensions, self.options, - self.pin_auth, self.pin_protocol] - + return [ + self.cdh, + self.rp, + self.user, + self.key_params, + self.exclude_list, + self.extensions, + self.options, + self.pin_auth, + self.pin_protocol, + ] return args + self.get_optional_args() - - - - diff --git a/tests/vendor/solo/test_solo.py b/tests/vendor/solo/test_solo.py index 2d21a4b..2b22a6f 100644 --- a/tests/vendor/solo/test_solo.py +++ b/tests/vendor/solo/test_solo.py @@ -12,6 +12,7 @@ from fido2.utils import sha256 from fido2.hid import CTAPHID from fido2.ctap import CtapError + def shannon_entropy(data): s = 0.0 total = len(data) @@ -22,21 +23,23 @@ def shannon_entropy(data): s -= p * math.log2(p) return s -@pytest.fixture(scope="module", params = ['u2f']) -def solo(request,device): - sc = SoloClient() - sc.find_device(device.dev) - if request.param == 'u2f': - sc.use_u2f() - else: - sc.use_hid() - return sc + +@pytest.fixture(scope="module", params=["u2f"]) +def solo(request, device): + sc = SoloClient() + sc.find_device(device.dev) + if request.param == "u2f": + sc.use_u2f() + else: + sc.use_hid() + return sc + class TestSolo(object): - def test_solo(self,solo): + def test_solo(self, solo): pass - def test_rng(self,solo): + def test_rng(self, solo): total = 1024 * 16 entropy = b"" @@ -47,14 +50,14 @@ class TestSolo(object): assert s > 7.98 print("Entropy is %.5f bits per byte." % s) - def test_version(self,solo): + def test_version(self, solo): assert len(solo.solo_version()) == 3 - def test_bootloader_not(self,solo): + def test_bootloader_not(self, solo): with pytest.raises(ApduError) as e: solo.write_flash(0x0, b"1234") - def test_fido2_bridge(self,solo): + def test_fido2_bridge(self, solo): exchange = solo.exchange solo.exchange = solo.exchange_fido2 @@ -72,24 +75,23 @@ class TestSolo(object): solo.exchange = exchange + # def test_bootloader(self,): + # solo = SoloClient() + # solo.find_device(self.dev) + # solo.use_u2f() - #def test_bootloader(self,): - #solo = SoloClient() - #solo.find_device(self.dev) - #solo.use_u2f() + # memmap = (0x08005000, 0x08005000 + 198 * 1024 - 8) + # data = b"A" * 64 - #memmap = (0x08005000, 0x08005000 + 198 * 1024 - 8) - #data = b"A" * 64 + # with Test("Test version command"): + # assert len(solo.bootloader_version()) == 3 - #with Test("Test version command"): - #assert len(solo.bootloader_version()) == 3 + # with Test("Test write command"): + # solo.write_flash(memmap[0], data) - #with Test("Test write command"): - #solo.write_flash(memmap[0], data) - - #for addr in (memmap[0] - 8, memmap[0] - 4, memmap[1], memmap[1] - 8): - #with Test("Test out of bounds write command at 0x%04x" % addr): - #try: - #solo.write_flash(addr, data) - #except CtapError as e: - #assert e.code == CtapError.ERR.NOT_ALLOWED + # for addr in (memmap[0] - 8, memmap[0] - 4, memmap[1], memmap[1] - 8): + # with Test("Test out of bounds write command at 0x%04x" % addr): + # try: + # solo.write_flash(addr, data) + # except CtapError as e: + # assert e.code == CtapError.ERR.NOT_ALLOWED