resident keys

This commit is contained in:
Conor Patrick
2019-08-06 13:35:09 +08:00
parent f607b8bc2a
commit 77cf91e559
5 changed files with 5061 additions and 9 deletions
+4945
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -65,7 +65,7 @@ def GARes(device,MCRes):
def RegRes(resetDevice,):
req = FidoRequest()
res = resetDevice.register(
req.chal, req.appid
req.challenge, req.appid
)
setattr(res,'request',req)
return res
@@ -74,7 +74,7 @@ def RegRes(resetDevice,):
def AuthRes(device, RegRes):
req = FidoRequest()
res = device.authenticate(
req.chal, req.appid, RegRes.key_handle
req.challenge, req.appid, RegRes.key_handle
)
setattr(res,'request',req)
return res
+2 -2
View File
@@ -10,10 +10,10 @@ from tests.utils import FidoRequest
class TestCtap1WithCtap2(object):
def test_ctap1_register(self, RegRes):
RegRes.verify(RegRes.request.appid, RegRes.request.chal)
RegRes.verify(RegRes.request.appid, RegRes.request.challenge)
def test_ctap1_authenticate(self, RegRes, AuthRes):
AuthRes.verify(AuthRes.request.appid, AuthRes.request.chal, 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"}])
+92
View File
@@ -0,0 +1,92 @@
import pytest
from fido2.ctap import CtapError
from tests.utils import *
@pytest.fixture(scope="module", params = ['', '123456'])
def SetPINRes(request,device,):
device.reset()
pin = request.param
req = FidoRequest()
if pin:
device.client.pin_protocol.set_pin(pin)
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)
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)
return 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)
return res
class TestResidentKey(object):
def test_resident_key(self,MC_RK_Res, info):
pass
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):
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,):
auths = []
regs = [MC_RK_Res]
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() )
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() )
with pytest.raises(CtapError) as e:
device.ctap2.get_next_assertion()
if MC_RK_Res.request.pin_protocol:
for x in auths:
for y in ("name", "icon", "displayName", "id"):
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)
+20 -5
View File
@@ -1,9 +1,15 @@
import secrets
import random
from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData
from fido2.utils import sha256, hmac_sha256
name_list = open('data/first-names.txt').readlines()
def verify(reg,auth,cdh = None):
credential_data = AttestedCredentialData(reg.auth_data.credential_data)
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
@@ -14,11 +20,20 @@ def generate_rp():
return {"id": "example.org", "name": "ExampleRP"}
def generate_user():
return {"id": b"user_id", "name": "A User"}
# https://www.w3.org/TR/webauthn/#user-handle
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/'
display_name = "Displayed " + name
return {"id": user_id, "name": name, 'icon': icon, 'displayName': display_name}
def generate_challenge():
return "Y2hhbGxlbmdl"
return sha256("Y2hhbGxlbmdl".encode("utf8"))
return secrets.token_bytes(32)
def get_key_params():
return [{"type": "public-key", "alg": ES256.ALGORITHM}]
@@ -62,7 +77,7 @@ class FidoRequest():
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):
"""