fix code quality issues

This commit is contained in:
Conor Patrick 2019-03-26 16:09:30 -04:00
parent d979420324
commit d2091563ab
6 changed files with 55 additions and 109 deletions

View File

@ -1,8 +1,8 @@
from __future__ import print_function, absolute_import, unicode_literals from __future__ import print_function, absolute_import, unicode_literals
import sys, os, time import sys
import time
from random import randint from random import randint
from binascii import hexlify import array
import array, struct, socket
from fido2.ctap import CtapError from fido2.ctap import CtapError
@ -73,62 +73,7 @@ class FIDO2Tests(Tester):
print("Assertion time: %d ms" % (t2 - t1)) print("Assertion time: %d ms" % (t2 - t1))
def test_fido2_brute_force(self):
creds = []
exclude_list = []
PIN = None
abc = "abcdefghijklnmopqrstuvwxyz"
abc += abc.upper()
self.ctap.reset()
for i in range(0, 2048 ** 2):
creds = []
challenge = "".join([abc[randint(0, len(abc) - 1)] for x in range(0, 32)])
fake_id1 = array.array(
"B", [randint(0, 255) for i in range(0, 150)]
).tobytes()
fake_id2 = array.array(
"B", [randint(0, 255) for i in range(0, 73)]
).tobytes()
exclude_list.append({"id": fake_id1, "type": "public-key"})
exclude_list.append({"id": fake_id2, "type": "public-key"})
# for i in range(0,2048**2):
for i in range(0, 1):
t1 = time.time() * 1000
attest, data = self.client.make_credential(
rp, user, challenge, pin=PIN, exclude_list=[]
)
print(attest.auth_data.counter)
t2 = time.time() * 1000
VerifyAttestation(attest, data)
print("Register valid (%d ms)" % (t2 - t1))
sys.stdout.flush()
cred = attest.auth_data.credential_data
creds.append(cred)
# for i in range(0,2048**2):
for i in range(0, 1):
allow_list = [{"id": creds[0].credential_id, "type": "public-key"}]
t1 = time.time() * 1000
assertions, client_data = self.client.get_assertion(
rp["id"], challenge, allow_list, pin=PIN
)
t2 = time.time() * 1000
assertions[0].verify(client_data.hash, creds[0].public_key)
print(assertions[0].auth_data.counter)
print("Assertion valid (%d ms)" % (t2 - t1))
sys.stdout.flush()
def test_extensions(self,): def test_extensions(self,):
creds = []
exclude_list = []
salt1 = b"\x5a" * 32 salt1 = b"\x5a" * 32
salt2 = b"\x96" * 32 salt2 = b"\x96" * 32
@ -208,7 +153,7 @@ class FIDO2Tests(Tester):
ext = auth.auth_data.extensions ext = auth.auth_data.extensions
assert ext assert ext
assert "hmac-secret" in ext assert "hmac-secret" in ext
assert type(ext["hmac-secret"]) == type(b"") assert isinstance(ext["hmac-secret"], bytes)
assert len(ext["hmac-secret"]) == len(salt_list) * 32 assert len(ext["hmac-secret"]) == len(salt_list) * 32
with Test("Check that shannon_entropy of hmac-secret is good"): with Test("Check that shannon_entropy of hmac-secret is good"):
@ -901,7 +846,7 @@ class FIDO2Tests(Tester):
with Test("Send an extra getNextAssertion request, expect error"): with Test("Send an extra getNextAssertion request, expect error"):
try: try:
auth4 = self.ctap.get_next_assertion() self.ctap.get_next_assertion()
assert 0 assert 0
except CtapError as e: except CtapError as e:
print(e) print(e)
@ -924,7 +869,7 @@ class FIDO2Tests(Tester):
assert "Is P256" and key[-1] == 1 assert "Is P256" and key[-1] == 1
if key[3] != -7: if key[3] != -7:
print("WARNING: algorithm returned is not for ES256 (-7): ", key[3]) 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 isinstance(key[-3], bytes)
with Test("Test setting a new pin"): with Test("Test setting a new pin"):
pin2 = "qwertyuiop\x11\x22\x33\x00123" pin2 = "qwertyuiop\x11\x22\x33\x00123"
@ -961,18 +906,18 @@ class FIDO2Tests(Tester):
expectedError=CtapError.ERR.SUCCESS, expectedError=CtapError.ERR.SUCCESS,
) )
self.testGA( # self.testGA(
"Send GA request with no pinAuth, expect SUCCESS", # "Send GA request with no pinAuth, expect SUCCESS",
rp["id"], # rp["id"],
cdh, # cdh,
[ # [
{ # {
"type": "public-key", # "type": "public-key",
"id": res_mc.auth_data.credential_data.credential_id, # "id": res_mc.auth_data.credential_data.credential_id,
} # }
], # ],
expectedError=CtapError.ERR.SUCCESS, # expectedError=CtapError.ERR.SUCCESS,
) # )
with Test("Check UV flag is set"): with Test("Check UV flag is set"):
assert res_ga.auth_data.flags & (1 << 2) assert res_ga.auth_data.flags & (1 << 2)
@ -1029,12 +974,12 @@ class FIDO2Tests(Tester):
expectedError=CtapError.ERR.PIN_REQUIRED, expectedError=CtapError.ERR.PIN_REQUIRED,
) )
res_mc = self.testGA( # res_mc = self.testGA(
"Send GA request with no pin_auth, expect NO_CREDENTIALS", # "Send GA request with no pin_auth, expect NO_CREDENTIALS",
rp["id"], # rp["id"],
cdh, # cdh,
expectedError=CtapError.ERR.NO_CREDENTIALS, # expectedError=CtapError.ERR.NO_CREDENTIALS,
) # )
res = self.testCP( res = self.testCP(
"Test getRetries, expect SUCCESS", "Test getRetries, expect SUCCESS",
@ -1096,7 +1041,7 @@ class FIDO2Tests(Tester):
if i in (3, 6): if i in (3, 6):
err = CtapError.ERR.PIN_AUTH_BLOCKED err = CtapError.ERR.PIN_AUTH_BLOCKED
elif i >= 8: elif i >= 8:
err = [CtapError.ERR.PIN_BLOCKED, CtapError.ERR.PIN_AUTH_BLOCKED] err = [CtapError.ERR.PIN_BLOCKED, CtapError.ERR.PIN_INVALID]
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,

View File

@ -1,7 +1,7 @@
import sys, struct, os, time import sys, os, time
from binascii import hexlify from binascii import hexlify
from fido2.hid import CtapHidDevice, CTAPHID from fido2.hid import CTAPHID
from fido2.ctap import CtapError from fido2.ctap import CtapError
from .tester import Tester, Test from .tester import Tester, Test
@ -34,7 +34,7 @@ class HIDTests(Tester):
raise RuntimeError("Fob is too slow (%d ms)" % delt) raise RuntimeError("Fob is too slow (%d ms)" % delt)
if r != pingdata: if r != pingdata:
raise ValueError("Ping data not echo'd") raise ValueError("Ping data not echo'd")
except CtapError as e: except CtapError:
raise RuntimeError("ping failed") raise RuntimeError("ping failed")
sys.stdout.flush() sys.stdout.flush()
@ -95,7 +95,7 @@ class HIDTests(Tester):
with Test("Sending packet with too large of a length."): with Test("Sending packet with too large of a length."):
self.send_raw("\x81\x1d\xba\x00") self.send_raw("\x81\x1d\xba\x00")
cmd, resp = self.recv_raw() cmd, resp = self.recv_raw()
self.check_error(resp, CtapError.ERR.INVALID_LENGTH) Tester.check_error(resp, CtapError.ERR.INVALID_LENGTH)
r = self.send_data(CTAPHID.PING, "\x44" * 200) r = self.send_data(CTAPHID.PING, "\x44" * 200)
with Test("Sending packets that skip a sequence number."): with Test("Sending packets that skip a sequence number."):
@ -105,7 +105,7 @@ class HIDTests(Tester):
# skip 2 # skip 2
self.send_raw("\x03") self.send_raw("\x03")
cmd, resp = self.recv_raw() cmd, resp = self.recv_raw()
self.check_error(resp, CtapError.ERR.INVALID_SEQ) Tester.check_error(resp, CtapError.ERR.INVALID_SEQ)
with Test("Resync and send ping"): with Test("Resync and send ping"):
try: try:
@ -207,7 +207,7 @@ class HIDTests(Tester):
self.set_cid(cid2) # send ping on 2nd channel self.set_cid(cid2) # send ping on 2nd channel
self.send_raw("\x81\x00\x63") self.send_raw("\x81\x00\x63")
self.delay(0.1) Tester.delay(0.1)
self.send_raw("\x00") self.send_raw("\x00")
cmd, r = self.recv_raw() # busy response cmd, r = self.recv_raw() # busy response

View File

@ -1,6 +1,6 @@
from solo.client import SoloClient from solo.client import SoloClient
from fido2.ctap1 import ApduError, APDU from fido2.ctap1 import ApduError
from .util import shannon_entropy from .util import shannon_entropy
from .tester import Tester, Test from .tester import Tester, Test
@ -30,9 +30,9 @@ class SoloTests(Tester):
entropy += sc.get_rng() entropy += sc.get_rng()
with Test("Test entropy is close to perfect"): with Test("Test entropy is close to perfect"):
sum = shannon_entropy(entropy) s = shannon_entropy(entropy)
assert sum > 7.98 assert s > 7.98
print("Entropy is %.5f bits per byte." % sum) print("Entropy is %.5f bits per byte." % s)
with Test("Test Solo version command"): with Test("Test Solo version command"):
assert len(sc.solo_version()) == 3 assert len(sc.solo_version()) == 3

View File

@ -1,8 +1,8 @@
import time, struct import time, struct
from fido2.hid import CtapHidDevice, CTAPHID from fido2.hid import CtapHidDevice
from fido2.client import Fido2Client, ClientError from fido2.client import Fido2Client
from fido2.ctap1 import CTAP1, ApduError, APDU from fido2.ctap1 import CTAP1, ApduError
from fido2.utils import Timeout from fido2.utils import Timeout
from fido2.ctap import CtapError from fido2.ctap import CtapError
@ -17,7 +17,6 @@ def ForceU2F(client, device):
class Packet(object): class Packet(object):
def __init__(self, data): def __init__(self, data):
l = len(data)
self.data = data self.data = data
def ToWireFormat(self,): def ToWireFormat(self,):
@ -79,14 +78,14 @@ class Tester:
if self.is_sim: if self.is_sim:
print("Sending restart command...") print("Sending restart command...")
self.send_magic_reboot() self.send_magic_reboot()
self.delay(0.25) Tester.delay(0.25)
else: else:
print("Please reboot authentictor and hit enter") print("Please reboot authentictor and hit enter")
input() input()
self.find_device() self.find_device()
def send_data(self, cmd, data): def send_data(self, cmd, data):
if type(data) != type(b""): if not isinstance(data, bytes):
data = struct.pack("%dB" % len(data), *[ord(x) for x in data]) data = struct.pack("%dB" % len(data), *[ord(x) for x in data])
with Timeout(1.0) as event: with Timeout(1.0) as event:
return self.dev.call(cmd, data, event) return self.dev.call(cmd, data, event)
@ -94,9 +93,9 @@ class Tester:
def send_raw(self, data, cid=None): def send_raw(self, data, cid=None):
if cid is None: if cid is None:
cid = self.dev._dev.cid cid = self.dev._dev.cid
elif type(cid) != type(b""): elif not isinstance(cid, bytes):
cid = struct.pack("%dB" % len(cid), *[ord(x) for x in cid]) cid = struct.pack("%dB" % len(cid), *[ord(x) for x in cid])
if type(data) != type(b""): if not isinstance(data, bytes):
data = struct.pack("%dB" % len(data), *[ord(x) for x in data]) data = struct.pack("%dB" % len(data), *[ord(x) for x in data])
data = cid + data data = cid + data
l = len(data) l = len(data)
@ -127,16 +126,16 @@ class Tester:
return self.dev._dev.cid return self.dev._dev.cid
def set_cid(self, cid): def set_cid(self, cid):
if type(cid) not in [type(b""), type(bytearray())]: if not isinstance(cid, (bytes, bytearray)):
cid = struct.pack("%dB" % len(cid), *[ord(x) for x in cid]) cid = struct.pack("%dB" % len(cid), *[ord(x) for x in cid])
self.dev._dev.cid = cid self.dev._dev.cid = cid
def recv_raw(self,): def recv_raw(self,):
with Timeout(1.0) as t: with Timeout(1.0):
cmd, payload = self.dev._dev.InternalRecv() cmd, payload = self.dev._dev.InternalRecv()
return cmd, payload return cmd, payload
def check_error(self, data, err=None): def check_error(data, err=None):
assert len(data) == 1 assert len(data) == 1
if err is None: if err is None:
if data[0] != 0: if data[0] != 0:
@ -156,11 +155,13 @@ class Tester:
except CtapError as e: except CtapError as e:
if expectedError is not None: if expectedError is not None:
cond = e.code != expectedError cond = e.code != expectedError
if type(expectedError) == type([]): if isinstance(expectedError, list):
cond = e.code not in expectedError cond = e.code not in expectedError
else:
expectedError = [expectedError]
if cond: if cond:
raise RuntimeError( raise RuntimeError(
"Got error code 0x%x, expected %x" % (e.code, expectedError) f"Got error code {hex(e.code)}, expected {[hex(x) for x in expectedError]}"
) )
else: else:
print(e) print(e)
@ -170,7 +171,7 @@ class Tester:
print("Resetting Authenticator...") print("Resetting Authenticator...")
try: try:
self.ctap.reset() self.ctap.reset()
except CtapError as e: except CtapError:
# Some authenticators need a power cycle # Some authenticators need a power cycle
print("You must power cycle authentictor. Hit enter when done.") print("You must power cycle authentictor. Hit enter when done.")
input() input()
@ -192,5 +193,5 @@ class Tester:
self.client.pin_protocol.get_pin_token, test, *args, **kwargs self.client.pin_protocol.get_pin_token, test, *args, **kwargs
) )
def delay(self, secs): def delay(secs):
time.sleep(secs) time.sleep(secs)

View File

@ -41,7 +41,7 @@ class U2FTests(Tester):
with Test("Check bad INS"): with Test("Check bad INS"):
try: try:
res = self.ctap1.send_apdu(0, 0, 0, 0, b"") self.ctap1.send_apdu(0, 0, 0, 0, b"")
except ApduError as e: except ApduError as e:
assert e.code == 0x6D00 assert e.code == 0x6D00

View File

@ -2,11 +2,11 @@ import math
def shannon_entropy(data): def shannon_entropy(data):
sum = 0.0 s = 0.0
total = len(data) total = len(data)
for x in range(0, 256): for x in range(0, 256):
freq = data.count(x) freq = data.count(x)
p = freq / total p = freq / total
if p > 0: if p > 0:
sum -= p * math.log2(p) s -= p * math.log2(p)
return sum return s