From 1aee7956e96be11627a8ff454d53b268cb8c66e1 Mon Sep 17 00:00:00 2001 From: slush0 Date: Thu, 12 Jun 2014 16:39:29 +0200 Subject: [PATCH] Demonstration usage of Trezor as a EncFS unlocking key --- tools/encfs_aes_getpass.py | 105 +++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100755 tools/encfs_aes_getpass.py diff --git a/tools/encfs_aes_getpass.py b/tools/encfs_aes_getpass.py new file mode 100755 index 0000000..0b22860 --- /dev/null +++ b/tools/encfs_aes_getpass.py @@ -0,0 +1,105 @@ +#!/usr/bin/python + +''' +Use Trezor as a hardware key for opening EncFS filesystem! + +Demo usage: + +encfs --standard --extpass=./encfs_aes_getpass.py ~/.crypt ~/crypt +''' + +import os +import sys +import base64 +import binascii + +from trezorlib.client import TrezorClient +from trezorlib.transport_hid import HidTransport + +def wait_for_devices(): + devices = HidTransport.enumerate() + while not len(devices): + sys.stderr.write("Please connect Trezor to computer and press Enter...") + raw_input() + devices = HidTransport.enumerate() + + return devices + +def list_devices(devices): + i = 0 + sys.stderr.write("----------------------------\n") + sys.stderr.write("Available devices:\n") + for d in devices: + try: + t = HidTransport(d) + except IOError: + sys.stderr.write("[-] \n") + continue + + client = TrezorClient(t) + + if client.features.label: + sys.stderr.write("[%d] %s\n" % (i, client.features.label)) + else: + sys.stderr.write("[%d] \n" % i) + t.close() + i += 1 + + sys.stderr.write("----------------------------\n") + sys.stderr.write("Please choice device to use: ") + + try: + device_id = int(raw_input()) + HidTransport(devices[device_id]) + except: + raise Exception("Invalid choice, exiting...") + + return device_id + +def main(): + + devices = wait_for_devices() + + if len(devices) > 1: + device_id = list_devices(devices) + else: + device_id = 0 + + transport = HidTransport(devices[device_id]) + client = TrezorClient(transport) + + rootdir = os.environ['encfs_root'] # Read "man encfs" for more + passw_file = os.path.join(rootdir, 'password.dat') + + if os.path.exists(passw_file): + # Existing encfs drive, let's load password + + label, passw_encrypted = open(passw_file, 'r').read().split(',') + passw = client.decrypt_keyvalue([10, 0], + binascii.unhexlify(label), + binascii.unhexlify(passw_encrypted), + False, True) + print passw + + else: + # New encfs drive, let's generate password + + sys.stderr.write('Please provide label for new drive: ') + label = raw_input() + + passw = base64.b64encode(os.urandom(24)) # 32 bytes in base64, good for AES + + if len(passw) != 32: + raise Exception("32 bytes password expected") + + passw_encrypted = client.encrypt_keyvalue([10, 0], + label, passw, False, True) + + f = open(passw_file, 'wb') + f.write(binascii.hexlify(label) + ',' + binascii.hexlify(passw_encrypted)) + f.close() + + print passw + +if __name__ == '__main__': + main()