- 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)
85 lines
3.9 KiB
Python
85 lines
3.9 KiB
Python
|
|
import re
|
|
import usb.core
|
|
from binascii import *
|
|
from util import assert_status
|
|
from struct import unpack
|
|
from usb.util import claim_interface, release_interface
|
|
|
|
def unhex(x):
|
|
return unhexlify(re.sub('\W', '', x))
|
|
|
|
init_hardcoded=unhex('''
|
|
06020000015cb560afa595d0dcf4fca09ebb69301e2b9e24a5dfb6f2602833427d3bd65222c418ff15b54587ab2854c4fe9aea74fa55567
|
|
2036fa3ec73c6912c58b1b49cbdcc7664165482cd70d5bb95d9d469626fdc2e012d74157c5792260968a2a4572b1ccccc26ec2e2ed0ddda
|
|
1b0931d3d0566460915d43e0a654a0582706be9113ea88f0c15ba058507efb0dadecb4a4cc64444dddf050b6e8d4ebb34ebba33e8651c75
|
|
e5fb28f85c83197df1de460d9e1cb82208753ceff0ef60a823dba75d05548f5b3a5a0e2972232f7403bd6869da90e5371a0ab8ad23972f1
|
|
597630f5ff7c8b8272800563477288b5591bbb0341d3975efc1778225767fa35480ff7f8dd633e4034ac32e4af58b86ebc63552cb35b12b
|
|
285255deaf3a32bf46cdc5ad3bc1c9ed1bcc112c72143f9aec568e2cacfa89ba0c7bb65590d8b93e6871a33c6c6983c0acd04e737ff55ee
|
|
e024ca6b9a48332c1a69a5a3fdd24b964cf7e7c55229bb0b48a6e339eb2c42d07ec850a4ee780660ad6c77ffa302a63bd19426134c4533d
|
|
69192ef2e16591df26394791a4ecb994a24f5a7f70f1eb2604e6bfb67a452cb74ead8b0d9808f890ac386750cbac06ee03a852145094053
|
|
b2b074b9905de5cdbf2272b67e51f159164778d6d2ef7a1ccb81df9f896ddb38ce11e8140cf6cb9c82
|
|
''')
|
|
init_hardcoded_clean_slate=unhex('''
|
|
06020000012c40c9d271378bc0912ef5dced69bd81b7fc16972c7b46e621af54a00e2cc6baca6eb83ea30222dfc6c925262006ae93412ea
|
|
cf482f2034ee7b13297474b7e1e91f279cac2ccb7195443e4dd3328cfd292ade073fcc2eaa8f07b77231130ba997f921b9be7b4fb6cc691
|
|
0d2976b3e050913b27dbe73afd6e964260b9435ebab5117e71f7cb68464d4b6f8afc7e1a421f671f5854a1d0c8ab93ed3b88b2bc1a42875
|
|
e40b15f0e78496ac40e4a4a7fd39a97534ce1866479e0384f0789bbfc2fea0ce982bf7a9df97d60b237edbe1b26c9791043a96b81e435d6
|
|
de5971c758d374905df95b0cddabfbf531749ba191f07a6f5e2722852f137a53513a9ec6ab30c3f09aa6ce21b391e55cf81dcda6422011b
|
|
f163317a9a4382546141d45f2274bd660103bd3af705f3ed12e493bc4f834d5d7f162e2c3405cf857b00129789a3353bf7fab7796e267e3
|
|
062d55660dbbb857911ac8e871c460dd31c56a86a5631475f0f2ee5e9ce2af0faec0931a640ba2394025f29ffeca3a7e99c15a78ce1f1f7
|
|
808cedd7601b9b6382d72ca873257d4f6af70e29e22afea15e36e0282b8f0bfc68ffa3417d212b8bbe11bb73b363a19872e6e947d45de30
|
|
fbc493ca083a0a4650615d8628606362081ca6df5d67527971d1776ad76a7a28c932f0317b59cb4a82a14b2bcb7b01fb662be1496d24d91
|
|
9140ec80068b21a818daa2fb8e05f63edbd4bd5797c74a28b3e7cf81c9045248584977711341fca3f08ba91ff853b62dc24ce4bba4ed57f
|
|
47bd458545d805b6bb14fe0cde01440b60bf7be937f6444a8e2a10ed8fa9ddb8604bb95fe411b97112e78dbf5a4a0f004669c93765a9f38
|
|
665cb55f5658895c1c06a7aedf694bfb3afa9b8b1dea5ab85c821ac20b0663b95023642fda36ad78e3e00140b966f404f7e55f0b416ea43
|
|
b4c74c39900830abc6906a1004bef1b5b7dbbbeb5ec1b22604ac86429b9f56511b746a7124c449b8c9498f49144abc2d64f6a114f1d7f91
|
|
aa41249faeef4d838e280cb5d6fc19cfe86c75f
|
|
''')
|
|
|
|
class Usb():
|
|
def __init__(self):
|
|
self.trace_enabled = False
|
|
|
|
def open(self):
|
|
self.dev = usb.core.find(idVendor=0x138a, idProduct=0x0097)
|
|
self.dev.default_timeout = 5000
|
|
|
|
def send_init(self):
|
|
self.dev.set_configuration()
|
|
|
|
# TODO analyse responses, detect hardware type
|
|
assert_status(self.cmd(unhexlify('01')))
|
|
assert_status(self.cmd(unhexlify('19')))
|
|
|
|
rsp=self.cmd(unhexlify('4302'))
|
|
|
|
assert_status(self.cmd(init_hardcoded))
|
|
|
|
(err,), rsp = unpack('<H', rsp[:2]), rsp[2:]
|
|
if err != 0:
|
|
print('Clean slate')
|
|
self.cmd(init_hardcoded_clean_slate)
|
|
|
|
self.cmd(unhexlify('3e'))
|
|
# why twice?
|
|
self.cmd(unhexlify('3e'))
|
|
|
|
def cmd(self, out):
|
|
self.trace('>cmd> %s' % hexlify(out).decode())
|
|
self.dev.write(1, out)
|
|
resp = self.dev.read(129, 100*1024)
|
|
resp = bytes(resp)
|
|
self.trace('<cmd< %s' % hexlify(resp).decode())
|
|
return resp
|
|
|
|
def wait_int(self):
|
|
resp = self.dev.read(131, 1024, timeout=0)
|
|
resp = bytes(resp)
|
|
self.trace('<int< %s' % hexlify(resp).decode())
|
|
return resp
|
|
|
|
def trace(self, s):
|
|
if self.trace_enabled:
|
|
print(s)
|
|
|