mirror of
https://github.com/trussed-dev/fido2-tests.git
synced 2026-06-20 04:16:30 -07:00
pin tests
This commit is contained in:
+1
-1
@@ -290,7 +290,7 @@ class TestDevice:
|
||||
return self.ctap2.client_pin(*args, **kwargs)
|
||||
|
||||
def sendPP(self, *args, **kwargs):
|
||||
return self.client.pin_protocol.get_pin_token(test, *args, **kwargs)
|
||||
return self.client.pin_protocol.get_pin_token(*args, **kwargs)
|
||||
|
||||
|
||||
def delay(secs):
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import pytest
|
||||
|
||||
from fido2.ctap import CtapError
|
||||
from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData
|
||||
|
||||
from tests.utils import *
|
||||
|
||||
|
||||
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.pin_auth = hmac_sha256(pin_token, req.cdh)[:16]
|
||||
|
||||
for i in range(1, 10):
|
||||
err = CtapError.ERR.PIN_INVALID
|
||||
if i in (3, 6):
|
||||
err = CtapError.ERR.PIN_AUTH_BLOCKED
|
||||
elif i >= 8:
|
||||
err = [CtapError.ERR.PIN_BLOCKED, CtapError.ERR.PIN_INVALID]
|
||||
|
||||
with pytest.raises(CtapError) as e:
|
||||
device.sendPP(
|
||||
"WrongPin",
|
||||
)
|
||||
assert e.value.code == err or e.value.code in err
|
||||
|
||||
attempts = 8 - i
|
||||
if i > 8:
|
||||
attempts = 0
|
||||
|
||||
res = device.ctap2.client_pin(1, PinProtocolV1.CMD.GET_RETRIES)
|
||||
assert res[3] == attempts
|
||||
|
||||
if err == CtapError.ERR.PIN_AUTH_BLOCKED:
|
||||
device.reboot()
|
||||
|
||||
with pytest.raises(CtapError) as e:
|
||||
device.sendMC(*req.toMC())
|
||||
|
||||
device.reboot()
|
||||
|
||||
with pytest.raises(CtapError) as e:
|
||||
device.sendPP(pin)
|
||||
assert e.value.code == CtapError.ERR.PIN_BLOCKED
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
import pytest
|
||||
|
||||
from fido2.ctap import CtapError
|
||||
from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData
|
||||
|
||||
from tests.utils import *
|
||||
|
||||
PIN1 = '123456789A'
|
||||
PIN2 = 'ABCDEF'
|
||||
|
||||
@pytest.fixture(scope="module", params = [PIN1])
|
||||
def SetPinRes(request,device):
|
||||
device.reset()
|
||||
|
||||
pin = request.param
|
||||
req = FidoRequest()
|
||||
|
||||
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)
|
||||
setattr(res,'PIN',pin)
|
||||
return res
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def CPRes(request,device,SetPinRes):
|
||||
res = device.sendCP(1, PinProtocolV1.CMD.GET_KEY_AGREEMENT)
|
||||
return res
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def MCPinRes(device,SetPinRes):
|
||||
req = FidoRequest(SetPinRes)
|
||||
res = device.sendMC(
|
||||
*req.toMC(),
|
||||
)
|
||||
setattr(res,'request',req)
|
||||
return res
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
def GAPinRes(device,MCPinRes):
|
||||
req = FidoRequest(MCPinRes)
|
||||
res = device.sendGA(
|
||||
*req.toGA(),
|
||||
)
|
||||
setattr(res,'request',req)
|
||||
return res
|
||||
|
||||
class TestPin(object):
|
||||
def test_pin(self,CPRes):
|
||||
pass
|
||||
|
||||
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
|
||||
assert "Is ALG_ECDH_ES_HKDF_256" and key[3] == -25
|
||||
|
||||
assert "Right key" and len(key[-3]) == 32 and isinstance(key[-3], bytes)
|
||||
|
||||
def test_verify_flag(self, device, SetPinRes):
|
||||
reg = device.sendMC(*FidoRequest(SetPinRes).toMC())
|
||||
assert reg.auth_data.flags & (1 << 2)
|
||||
|
||||
|
||||
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)
|
||||
pin_auth = hmac_sha256(pin_token, SetPinRes.request.cdh)[:16]
|
||||
|
||||
SetPinRes.request.pin_token = pin_token
|
||||
SetPinRes.request.pin_auth = pin_auth
|
||||
SetPinRes.PIN = PIN2
|
||||
|
||||
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())
|
||||
|
||||
assert reg.auth_data.flags & (1 << 2)
|
||||
assert auth.auth_data.flags & (1 << 2)
|
||||
|
||||
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}]
|
||||
auth = device.sendGA(
|
||||
*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())
|
||||
|
||||
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)
|
||||
|
||||
with pytest.raises(CtapError) as e:
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||
def test_pin_attempts(device, SetPinRes):
|
||||
# Flip 1 bit
|
||||
pin = SetPinRes.PIN
|
||||
pin_wrong = list(pin)
|
||||
c = pin[len(pin) // 2]
|
||||
|
||||
pin_wrong[len(pin) // 2] = chr(ord(c) ^ 1)
|
||||
pin_wrong = "".join(pin_wrong)
|
||||
|
||||
for i in range(1, 3):
|
||||
with pytest.raises(CtapError) as e:
|
||||
device.sendPP(pin_wrong)
|
||||
assert e.value.code == CtapError.ERR.PIN_INVALID
|
||||
|
||||
print("Check there is %d pin attempts left" % (8 - i))
|
||||
res = device.ctap2.client_pin(1, PinProtocolV1.CMD.GET_RETRIES)
|
||||
assert res[3] == (8 - i)
|
||||
|
||||
for i in range(1, 3):
|
||||
with pytest.raises(CtapError) as e:
|
||||
device.sendPP(pin_wrong)
|
||||
assert e.value.code == CtapError.ERR.PIN_AUTH_BLOCKED
|
||||
|
||||
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]
|
||||
|
||||
reg = device.sendMC(*FidoRequest(SetPinRes).toMC())
|
||||
|
||||
res = device.ctap2.client_pin(1, PinProtocolV1.CMD.GET_RETRIES)
|
||||
assert res[3] == (8)
|
||||
@@ -0,0 +1,57 @@
|
||||
import pytest
|
||||
|
||||
from fido2.ctap import CtapError
|
||||
from fido2.ctap2 import ES256, PinProtocolV1, AttestedCredentialData
|
||||
|
||||
from tests.utils import *
|
||||
|
||||
class TestSetPin(object):
|
||||
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)
|
||||
|
||||
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))
|
||||
|
||||
|
||||
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)
|
||||
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')
|
||||
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")
|
||||
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')
|
||||
|
||||
with pytest.raises(CtapError) as e:
|
||||
device.client.pin_protocol.set_pin('TestPin')
|
||||
|
||||
info = device.ctap2.get_info()
|
||||
|
||||
assert info.options['clientPin']
|
||||
|
||||
pin_token = device.client.pin_protocol.get_pin_token('TestPin')
|
||||
|
||||
res = device.sendCP(1, PinProtocolV1.CMD.GET_RETRIES)
|
||||
assert res[3] == 8
|
||||
|
||||
device.reset()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user