works with yubikey5
This commit is contained in:
parent
0a7845459c
commit
5076af1be4
@ -43,15 +43,6 @@ if __name__ == "__main__":
|
|||||||
# t.test_fido2()
|
# t.test_fido2()
|
||||||
FIDO2Tests(t).run()
|
FIDO2Tests(t).run()
|
||||||
|
|
||||||
if "fido2-ext" in sys.argv:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if "rk" in sys.argv:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if "ping" in sys.argv:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# hid tests are a bit invasive and should be done last
|
# hid tests are a bit invasive and should be done last
|
||||||
if "hid" in sys.argv:
|
if "hid" in sys.argv:
|
||||||
HIDTests(t).run()
|
HIDTests(t).run()
|
||||||
|
@ -8,7 +8,7 @@ import array, struct, socket
|
|||||||
from fido2.ctap import CtapError
|
from fido2.ctap import CtapError
|
||||||
|
|
||||||
from fido2.ctap2 import ES256, PinProtocolV1
|
from fido2.ctap2 import ES256, PinProtocolV1
|
||||||
from fido2.utils import Timeout, sha256, hmac_sha256
|
from fido2.utils import sha256, hmac_sha256
|
||||||
from fido2.attestation import Attestation
|
from fido2.attestation import Attestation
|
||||||
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
@ -825,6 +825,10 @@ class FIDO2Tests(Tester):
|
|||||||
def test_rk(self, pin_code=None):
|
def test_rk(self, pin_code=None):
|
||||||
|
|
||||||
pin_auth = None
|
pin_auth = None
|
||||||
|
if pin_code:
|
||||||
|
pin_protocol = 1
|
||||||
|
else:
|
||||||
|
pin_protocol = None
|
||||||
if pin_code:
|
if pin_code:
|
||||||
with Test("Set pin code"):
|
with Test("Set pin code"):
|
||||||
self.client.pin_protocol.set_pin(pin_code)
|
self.client.pin_protocol.set_pin(pin_code)
|
||||||
@ -837,7 +841,11 @@ class FIDO2Tests(Tester):
|
|||||||
rp,
|
rp,
|
||||||
user,
|
user,
|
||||||
key_params,
|
key_params,
|
||||||
other={"options": {"rk": True}, "pin_auth": pin_auth},
|
other={
|
||||||
|
"options": {"rk": True},
|
||||||
|
"pin_auth": pin_auth,
|
||||||
|
"pin_protocol": pin_protocol,
|
||||||
|
},
|
||||||
expectedError=CtapError.ERR.SUCCESS,
|
expectedError=CtapError.ERR.SUCCESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -856,7 +864,11 @@ class FIDO2Tests(Tester):
|
|||||||
rp2,
|
rp2,
|
||||||
x,
|
x,
|
||||||
key_params,
|
key_params,
|
||||||
other={"options": options, "pin_auth": pin_auth},
|
other={
|
||||||
|
"options": options,
|
||||||
|
"pin_auth": pin_auth,
|
||||||
|
"pin_protocol": pin_protocol,
|
||||||
|
},
|
||||||
expectedError=CtapError.ERR.SUCCESS,
|
expectedError=CtapError.ERR.SUCCESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -864,7 +876,7 @@ class FIDO2Tests(Tester):
|
|||||||
"Send GA request with no allow_list, expect SUCCESS",
|
"Send GA request with no allow_list, expect SUCCESS",
|
||||||
rp2["id"],
|
rp2["id"],
|
||||||
cdh,
|
cdh,
|
||||||
other={"options": options, "pin_auth": pin_auth},
|
other={"pin_auth": pin_auth, "pin_protocol": pin_protocol},
|
||||||
expectedError=CtapError.ERR.SUCCESS,
|
expectedError=CtapError.ERR.SUCCESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -884,8 +896,8 @@ class FIDO2Tests(Tester):
|
|||||||
with Test("Check that all user info was returned"):
|
with Test("Check that all user info was returned"):
|
||||||
for x in (auth1, auth2, auth3):
|
for x in (auth1, auth2, auth3):
|
||||||
for y in ("name", "icon", "displayName", "id"):
|
for y in ("name", "icon", "displayName", "id"):
|
||||||
assert y in x.user.keys()
|
if y not in x.user.keys():
|
||||||
assert len(x.user.keys()) == 4
|
print("FAIL: %s was not in user: " % y, x.user)
|
||||||
|
|
||||||
with Test("Send an extra getNextAssertion request, expect error"):
|
with Test("Send an extra getNextAssertion request, expect error"):
|
||||||
try:
|
try:
|
||||||
@ -910,7 +922,8 @@ class FIDO2Tests(Tester):
|
|||||||
key = res[1]
|
key = res[1]
|
||||||
assert "Is public key" and key[1] == 2
|
assert "Is public key" and key[1] == 2
|
||||||
assert "Is P256" and key[-1] == 1
|
assert "Is P256" and key[-1] == 1
|
||||||
assert "Is right alg" and key[3] == -7
|
if key[3] != -7:
|
||||||
|
print("WARNING: algorithm returned is not for ES256 (-7): ", key[3])
|
||||||
assert "Right key" and len(key[-3]) == 32 and type(key[-3]) == type(bytes())
|
assert "Right key" and len(key[-3]) == 32 and type(key[-3]) == type(bytes())
|
||||||
|
|
||||||
with Test("Test setting a new pin"):
|
with Test("Test setting a new pin"):
|
||||||
@ -927,7 +940,7 @@ class FIDO2Tests(Tester):
|
|||||||
rp,
|
rp,
|
||||||
user,
|
user,
|
||||||
key_params,
|
key_params,
|
||||||
other={"pin_auth": pin_auth},
|
other={"pin_auth": pin_auth, "pin_protocol": pin_protocol},
|
||||||
expectedError=CtapError.ERR.SUCCESS,
|
expectedError=CtapError.ERR.SUCCESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -935,7 +948,21 @@ class FIDO2Tests(Tester):
|
|||||||
assert res_mc.auth_data.flags & (1 << 2)
|
assert res_mc.auth_data.flags & (1 << 2)
|
||||||
|
|
||||||
res_ga = self.testGA(
|
res_ga = self.testGA(
|
||||||
"Send GA request with no allow_list, expect SUCCESS",
|
"Send GA request with pinAuth, expect SUCCESS",
|
||||||
|
rp["id"],
|
||||||
|
cdh,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "public-key",
|
||||||
|
"id": res_mc.auth_data.credential_data.credential_id,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
other={"pin_auth": pin_auth, "pin_protocol": pin_protocol},
|
||||||
|
expectedError=CtapError.ERR.SUCCESS,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.testGA(
|
||||||
|
"Send GA request with no pinAuth, expect SUCCESS",
|
||||||
rp["id"],
|
rp["id"],
|
||||||
cdh,
|
cdh,
|
||||||
[
|
[
|
||||||
@ -944,7 +971,6 @@ class FIDO2Tests(Tester):
|
|||||||
"id": res_mc.auth_data.credential_data.credential_id,
|
"id": res_mc.auth_data.credential_data.credential_id,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
other={"pin_auth": pin_auth},
|
|
||||||
expectedError=CtapError.ERR.SUCCESS,
|
expectedError=CtapError.ERR.SUCCESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1004,10 +1030,10 @@ class FIDO2Tests(Tester):
|
|||||||
)
|
)
|
||||||
|
|
||||||
res_mc = self.testGA(
|
res_mc = self.testGA(
|
||||||
"Send GA request with no pin_auth, expect PIN_REQUIRED",
|
"Send GA request with no pin_auth, expect NO_CREDENTIALS",
|
||||||
rp["id"],
|
rp["id"],
|
||||||
cdh,
|
cdh,
|
||||||
expectedError=CtapError.ERR.PIN_REQUIRED,
|
expectedError=CtapError.ERR.NO_CREDENTIALS,
|
||||||
)
|
)
|
||||||
|
|
||||||
res = self.testCP(
|
res = self.testCP(
|
||||||
@ -1057,7 +1083,7 @@ class FIDO2Tests(Tester):
|
|||||||
rp,
|
rp,
|
||||||
user,
|
user,
|
||||||
key_params,
|
key_params,
|
||||||
other={"pin_auth": pin_auth},
|
other={"pin_auth": pin_auth, "pin_protocol": pin_protocol},
|
||||||
expectedError=CtapError.ERR.SUCCESS,
|
expectedError=CtapError.ERR.SUCCESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1069,8 +1095,8 @@ class FIDO2Tests(Tester):
|
|||||||
err = CtapError.ERR.PIN_INVALID
|
err = CtapError.ERR.PIN_INVALID
|
||||||
if i in (3, 6):
|
if i in (3, 6):
|
||||||
err = CtapError.ERR.PIN_AUTH_BLOCKED
|
err = CtapError.ERR.PIN_AUTH_BLOCKED
|
||||||
elif i >= 9:
|
elif i >= 8:
|
||||||
err = CtapError.ERR.PIN_BLOCKED
|
err = [CtapError.ERR.PIN_BLOCKED, CtapError.ERR.PIN_AUTH_BLOCKED]
|
||||||
self.testPP(
|
self.testPP(
|
||||||
"Lock out authentictor and check correct error codes %d/9" % i,
|
"Lock out authentictor and check correct error codes %d/9" % i,
|
||||||
pin_wrong,
|
pin_wrong,
|
||||||
@ -1089,13 +1115,12 @@ class FIDO2Tests(Tester):
|
|||||||
self.reboot()
|
self.reboot()
|
||||||
|
|
||||||
res_mc = self.testMC(
|
res_mc = self.testMC(
|
||||||
"Send MC request with correct pin_auth, expect PIN_BLOCKED",
|
"Send MC request with correct pin_auth, expect error",
|
||||||
cdh,
|
cdh,
|
||||||
rp,
|
rp,
|
||||||
user,
|
user,
|
||||||
key_params,
|
key_params,
|
||||||
other={"pin_auth": pin_auth},
|
other={"pin_auth": pin_auth, "pin_protocol": pin_protocol},
|
||||||
expectedError=CtapError.ERR.PIN_BLOCKED,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.reboot()
|
self.reboot()
|
||||||
@ -1108,8 +1133,7 @@ class FIDO2Tests(Tester):
|
|||||||
|
|
||||||
def test_fido2(self,):
|
def test_fido2(self,):
|
||||||
|
|
||||||
creds = []
|
self.testReset()
|
||||||
exclude_list = []
|
|
||||||
|
|
||||||
self.test_get_info()
|
self.test_get_info()
|
||||||
|
|
||||||
@ -1123,77 +1147,6 @@ class FIDO2Tests(Tester):
|
|||||||
|
|
||||||
self.testReset()
|
self.testReset()
|
||||||
|
|
||||||
print("Done")
|
self.test_extensions()
|
||||||
|
|
||||||
# def test_rk(self,):
|
print("Done")
|
||||||
# creds = []
|
|
||||||
# rp = {"id": self.host, "name": "ExaRP"}
|
|
||||||
#
|
|
||||||
# users = [
|
|
||||||
# {"id": b"user" + os.urandom(16), "name": "Username%d" % i}
|
|
||||||
# for i in range(0, self.user_count)
|
|
||||||
# ]
|
|
||||||
# challenge = "Y2hhbGxlbmdl"
|
|
||||||
# PIN = None
|
|
||||||
# self.ctap.reset()
|
|
||||||
# # if PIN: self.client.pin_protocol.set_pin(PIN)
|
|
||||||
#
|
|
||||||
# with Test("registering 1 user with RK"):
|
|
||||||
# t1 = time.time() * 1000
|
|
||||||
# attest, data = self.client.make_credential(
|
|
||||||
# rp, users[-1], challenge, pin=PIN, exclude_list=[], rk=True
|
|
||||||
# )
|
|
||||||
# t2 = time.time() * 1000
|
|
||||||
# VerifyAttestation(attest, data)
|
|
||||||
# creds.append(attest.auth_data.credential_data)
|
|
||||||
#
|
|
||||||
# with Test("1 assertion"):
|
|
||||||
# t1 = time.time() * 1000
|
|
||||||
# assertions, client_data = self.client.get_assertion(
|
|
||||||
# rp["id"], challenge, pin=PIN
|
|
||||||
# )
|
|
||||||
# t2 = time.time() * 1000
|
|
||||||
# assertions[0].verify(client_data.hash, creds[0].public_key)
|
|
||||||
#
|
|
||||||
# with Test("registering %d users with RK" % len(users)):
|
|
||||||
# for i in range(0, len(users) - 1):
|
|
||||||
# t1 = time.time() * 1000
|
|
||||||
# attest, data = self.client.make_credential(
|
|
||||||
# rp, users[i], challenge, pin=PIN, exclude_list=[], rk=True
|
|
||||||
# )
|
|
||||||
# t2 = time.time() * 1000
|
|
||||||
# VerifyAttestation(attest, data)
|
|
||||||
# creds.append(attest.auth_data.credential_data)
|
|
||||||
#
|
|
||||||
# t1 = time.time() * 1000
|
|
||||||
# assertions, client_data = self.client.get_assertion(
|
|
||||||
# rp["id"], challenge, pin=PIN
|
|
||||||
# )
|
|
||||||
# t2 = time.time() * 1000
|
|
||||||
#
|
|
||||||
# print("Got %d assertions for %d users" % (len(assertions), len(users)))
|
|
||||||
# assert len(assertions) == len(users)
|
|
||||||
#
|
|
||||||
# for x, y in zip(assertions, creds):
|
|
||||||
# x.verify(client_data.hash, y.public_key)
|
|
||||||
#
|
|
||||||
# print("Assertion(s) valid (%d ms)" % (t2 - t1))
|
|
||||||
#
|
|
||||||
# with Test("register a duplicate user "):
|
|
||||||
# t1 = time.time() * 1000
|
|
||||||
# attest, data = self.client.make_credential(
|
|
||||||
# rp, users[1], challenge, pin=PIN, exclude_list=[], rk=True
|
|
||||||
# )
|
|
||||||
# t2 = time.time() * 1000
|
|
||||||
# VerifyAttestation(attest, data)
|
|
||||||
# creds = creds[:2] + creds[3:] + [attest.auth_data.credential_data]
|
|
||||||
#
|
|
||||||
# t1 = time.time() * 1000
|
|
||||||
# assertions, client_data = self.client.get_assertion(
|
|
||||||
# rp["id"], challenge, pin=PIN
|
|
||||||
# )
|
|
||||||
# t2 = time.time() * 1000
|
|
||||||
# with Test("check %d assertions, %d users" % (len(assertions), len(users))):
|
|
||||||
# assert len(assertions) == len(users)
|
|
||||||
# for x, y in zip(assertions, creds):
|
|
||||||
# x.verify(client_data.hash, y.public_key)
|
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
import sys, struct, os, time
|
||||||
|
from binascii import hexlify
|
||||||
|
|
||||||
|
from fido2.hid import CtapHidDevice, CTAPHID
|
||||||
|
from fido2.ctap import CtapError
|
||||||
|
|
||||||
from .tester import Tester, Test
|
from .tester import Tester, Test
|
||||||
|
|
||||||
|
|
||||||
@ -10,6 +16,7 @@ class HIDTests(Tester):
|
|||||||
self.check_timeouts = en
|
self.check_timeouts = en
|
||||||
|
|
||||||
def run(self,):
|
def run(self,):
|
||||||
|
self.test_long_ping()
|
||||||
self.test_hid(self.check_timeouts)
|
self.test_hid(self.check_timeouts)
|
||||||
|
|
||||||
def test_long_ping(self):
|
def test_long_ping(self):
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import time
|
import time, struct
|
||||||
|
|
||||||
from fido2.hid import CtapHidDevice, CTAPHID
|
from fido2.hid import CtapHidDevice, CTAPHID
|
||||||
from fido2.client import Fido2Client, ClientError
|
from fido2.client import Fido2Client, ClientError
|
||||||
from fido2.ctap1 import CTAP1, ApduError, APDU
|
from fido2.ctap1 import CTAP1, ApduError, APDU
|
||||||
|
from fido2.utils import Timeout
|
||||||
|
|
||||||
from fido2.ctap import CtapError
|
from fido2.ctap import CtapError
|
||||||
|
|
||||||
|
|
||||||
@ -153,7 +155,10 @@ class Tester:
|
|||||||
raise RuntimeError("Expected error to occur for test: %s" % test)
|
raise RuntimeError("Expected error to occur for test: %s" % test)
|
||||||
except CtapError as e:
|
except CtapError as e:
|
||||||
if expectedError is not None:
|
if expectedError is not None:
|
||||||
if e.code != expectedError:
|
cond = e.code != expectedError
|
||||||
|
if type(expectedError) == type([]):
|
||||||
|
cond = e.code not in expectedError
|
||||||
|
if cond:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"Got error code 0x%x, expected %x" % (e.code, expectedError)
|
"Got error code 0x%x, expected %x" % (e.code, expectedError)
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user