From ef6ce24a2683dacc98f513ebceb947aaec6da22f Mon Sep 17 00:00:00 2001 From: Viktor Dragomiretskyy Date: Tue, 21 May 2019 22:30:20 +1200 Subject: [PATCH] A couple of improvements - make TLS session persistent: once open, you can save TLS state with tls.save() and restore it next time by calling tls.load() instad of tls.open(). State is saved in tls.dict file. - a small standalone script added which can be used to keep an open file descriptor to the device. Without it tls.load() wont work. - identify() function added - added methods to associate blobs with fingers. Windows seems to be using these blobs to save certificates for the users to establish trust with potentially removable devices (it is sort of documented in winbio specs) --- .gitignore | 1 + db97.py | 57 ++++++++++++++++++++- holdthedoor.py | 40 +++++++++++++++ prototype.py | 135 ++++++++++++++++++++++++++++++++++++++++++++++--- tls97.py | 22 ++++++++ usb97.py | 41 ++++++++++++--- 6 files changed, 282 insertions(+), 14 deletions(-) create mode 100644 holdthedoor.py diff --git a/.gitignore b/.gitignore index bee8a64..0c0fe4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__ +tls.dict diff --git a/db97.py b/db97.py index 0b933da..e343ec1 100644 --- a/db97.py +++ b/db97.py @@ -23,6 +23,12 @@ class User(): def __repr__(self): return '' % (self.dbid, repr(self.identity), repr(self.fingers)) +def subtype_to_string(s): + if s < 0xf5 or s > 0xfe: + return 'Unknown' + + return 'WINBIO_FINGER_UNSPECIFIED_POS_%02d' % (s - 0xf5 + 1) + def parse_user_storage(rsp): assert_status(rsp[:2]) rsp=rsp[2:] @@ -136,6 +142,24 @@ e3d473d5f1897e05db677c7ff6e260048255fdbe35fae42c791ea57ac0f2334e6ab5c650f59f3b27 eb1e84deb687d2dc3d5cf4b03dbe35d165e ''') +class DbRecord(): + def __init__(self): + self.dbid = 0 + self.type = 0 + self.storage = 0 + self.value = None + self.children = None + + def __repr__(self): + return '' % ( + self.dbid, + self.type, + self.storage, + repr(self.value), + repr(self.children) + ) + + class Db(): def __init__(self, tls): self.tls = tls @@ -163,9 +187,34 @@ class Db(): else: return parse_user(rsp) + def get_record_value(self, dbid): + rsp = self.tls.app(pack(' 0: + (t, l), x = unpack(' 1: + raise Exception('Expected only one child record for finger') + + print('Recognised finger %02x (%s) from user %s' % (subtype, subtype_to_string(subtype), repr(usr.identity))) + print('Template hash: %s' % hexlify(hsh).decode()) + + if len(finger_record.children) > 0: + if finger_record.children[0]['type'] != 8: + raise Exception('Expected data blob as a finger child') + + blob_id = finger_record.children[0]['dbid'] + blob = db.get_record_value(blob_id).value + + tag, sz = unpack('