# python-validity Validity fingerprint sensor library. Originally designed to capture some of my findings for 138a:0097, but if you manage to get it working for some other Validity sensor - pull requests are welcome. ## Setting up Use Wine to install official Lenovo device driver. The only reason you need to do this is to find 6_07f_lenovo_mis.xpfwext and copy it to this project location. This file contains firmware and without it the pairing wont work. You will not need wine after this. To install Python dependencies run ``` $ pip3 install -r requirements.txt ``` ## Factory reset If your device was previously paired with another OS or computer, you need to do a factory reset. This will erase all fingers from the internal database and make the device ready for pairing. ``` $ python3 factory-reset.py $ ``` ## Pairing After performing a factory reset you need to pair your device with a host computer. This must be done only once, before you can enroll/identify/verify fingers. ``` $ python3 pair.py Initializing flash... Detected Flash IC: W25Q80B, 1048576 bytes Clean slate Uploading firmware... Sensor: VSI 55E FM209-001 Loaded FWExt version 1.1 (Sat Feb 3 05:07:30 2018), 8 modules Calibrating... Sensor: VSI 55E FM209-001 FWExt version 1.1 (Sat Feb 3 05:07:30 2018), 8 modules Calibration data loaded from the file. Init database... Creating a new user storage object Creating a host machine GUID record That's it, pairing's finished $ ``` ## Examples Here is a couple of examples of how you can use this library. All examples assume that your device is already paired. ### Initialize a session Before talking to a device you will need to open it and start a new TLS session ``` $ python3 Python 3.6.7 (default, Oct 22 2018, 11:32:17) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from prototype import * >>> open97() >>> ``` Or load previosly saved TLS session (see comments in [holdthedoor.py](holdthedoor.py)) ``` $ python3 Python 3.6.7 (default, Oct 22 2018, 11:32:17) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from prototype import * >>> load97() >>> ``` ### Enroll a new user Note: 0xf5 == WINBIO_FINGER_UNSPECIFIED_POS_01 (see [ms docs](https://docs.microsoft.com/en-us/windows/desktop/SecBioMet/winbio-ansi-381-pos-fingerprint-constants)) ``` >>> db.dump_all() 8: User S-1-5-21-111111111-1111111111-1111111111-1000 with 1 fingers: 9: f5 (WINBIO_FINGER_UNSPECIFIED_POS_01) >>> enroll(sid_from_string('S-1-5-21-394619333-3876782012-1672975908-3333'), 0xf5) Waiting for a finger... Progress: 14 % done Progress: 28 % done Progress: 42 % done Progress: 57 % done Progress: 71 % done Progress: 85 % done Progress: 100 % done All done 11 >>> db.dump_all() 8: User S-1-5-21-111111111-1111111111-1111111111-1000 with 1 fingers: 9: f5 (WINBIO_FINGER_UNSPECIFIED_POS_01) 10: User S-1-5-21-394619333-3876782012-1672975908-3333 with 1 fingers: 11: f5 (WINBIO_FINGER_UNSPECIFIED_POS_01) >>> ``` ### Delete database record (user/finger/whatever) ``` >>> db.dump_all() 8: User S-1-5-21-111111111-1111111111-1111111111-1000 with 1 fingers: 9: f5 (WINBIO_FINGER_UNSPECIFIED_POS_01) 10: User S-1-5-21-394619333-3876782012-1672975908-3333 with 1 fingers: 11: f5 (WINBIO_FINGER_UNSPECIFIED_POS_01) >>> db.del_record(11) >>> db.dump_all() 8: User S-1-5-21-111111111-1111111111-1111111111-1000 with 1 fingers: 9: f5 (WINBIO_FINGER_UNSPECIFIED_POS_01) 10: User S-1-5-21-394619333-3876782012-1672975908-3333 with 0 fingers: >>> ``` ### Identify a finger (scan) ``` >>> identify() Recognised finger f5 (WINBIO_FINGER_UNSPECIFIED_POS_01) from user S-1-5-21-111111111-1111111111-1111111111-1000 Template hash: 36bc1fe077e59a3090c816fcf2798c30a85d8a8fbe000ead5c6a946c3bacef7b ``` ## DBus service Sources contain a simple DBus service which can impersonate [fprint](https://www.freedesktop.org/wiki/Software/fprint/) daemon. Install fprint, edit /usr/share/dbus-1/system-services/net.reactivated.Fprint.service by commenting out activation info: ``` #Exec=/usr/lib/fprintd/fprintd #User=root #SystemdService=fprintd.service ``` start a fake service with something like this: ``` while sleep 1; do python3 dbus-service.py echo "====restart===" done ``` ## Debugging If you are curious you can enable tracing to see what flows in and out of device before and after encryption ``` >>> tls.trace_enabled=True >>> usb.trace_enabled=True >>> db.dump_all() >tls> 17: 4b00000b0053746757696e64736f7200 >cmd> 1703030050c00a7ff1cf76e90f168141b4bc519ca9598eacb575ff01b7552a3707be8506b246d5272cb119e7b8b3eccd991cb7d8387245953ff1da62cebfb07fae7e47b9b536fb1a82185cc9399d30625ee3c1451f tls> 17: 4a080000000000 >cmd> 1703030040ef982e5d6c403ff636c44cd53e7d0f98c21f67ff3b5b80f53555e4547028bd4d17cf5b0539ac0489238f1f066b8ba849120380cf979088d6c63249c873868c95 tls> 17: 4a0a0000000000 >cmd> 1703030040b522c55b73480e0d71a322abf8b65d97c9b55e9930206c463f998886cda4410d1b00ab41ec5b213d2ac18bf3bf61ce817446f27d643f99aba5a1d4cb80d18461 >> ```