slip-0016: fix pwdreader.py to work with both python2 and python3

parent ec221a8a
#!/usr/bin/env python2 #!/usr/bin/env python
from __future__ import print_function
from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
...@@ -9,15 +9,22 @@ import hmac ...@@ -9,15 +9,22 @@ import hmac
import hashlib import hashlib
import json import json
import os import os
from urlparse import urlparse try:
from urllib.parse import urlparse
except:
from urlparse import urlparse
input = raw_input
from trezorlib.client import TrezorClient
from trezorlib.transport_hid import HidTransport
# Return path by BIP-32 # Return path by BIP-32
def getPath(): def getPath(client):
return client.expand_path("10016'/0") return client.expand_path("10016'/0")
# Deriving master key # Deriving master key
def getMasterKey(): def getMasterKey(client):
bip32_path = getPath() bip32_path = getPath(client)
ENC_KEY = 'Activate TREZOR Password Manager?' ENC_KEY = 'Activate TREZOR Password Manager?'
ENC_VALUE = unhexlify('2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee') ENC_VALUE = unhexlify('2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee')
key = hexlify(client.encrypt_keyvalue( key = hexlify(client.encrypt_keyvalue(
...@@ -31,8 +38,8 @@ def getMasterKey(): ...@@ -31,8 +38,8 @@ def getMasterKey():
# Deriving file name and encryption key # Deriving file name and encryption key
def getFileEncKey(key): def getFileEncKey(key):
filekey, enckey = key[:len(key)/2], key[len(key)/2:] filekey, enckey = key[:len(key) // 2], key[len(key) //2:]
FILENAME_MESS = '5f91add3fa1c3c76e90c90a3bd0999e2bd7833d06a483fe884ee60397aca277a' FILENAME_MESS = b'5f91add3fa1c3c76e90c90a3bd0999e2bd7833d06a483fe884ee60397aca277a'
digest = hmac.new(filekey, FILENAME_MESS, hashlib.sha256).hexdigest() digest = hmac.new(filekey, FILENAME_MESS, hashlib.sha256).hexdigest()
filename = digest + '.pswd' filename = digest + '.pswd'
return [filename, filekey, enckey] return [filename, filekey, enckey]
...@@ -50,11 +57,11 @@ def decryptStorage(path, key): ...@@ -50,11 +57,11 @@ def decryptStorage(path, key):
block = f.read(16) block = f.read(16)
# data are not authenticated yet # data are not authenticated yet
if block: if block:
data = data + decryptor.update(block) data = data + decryptor.update(block).decode()
else: else:
break break
# throws exception when the tag is wrong # throws exception when the tag is wrong
data = data + decryptor.finalize() data = data + decryptor.finalize().decode()
return json.loads(data) return json.loads(data)
def decryptEntryValue(nonce, val): def decryptEntryValue(nonce, val):
...@@ -69,18 +76,18 @@ def decryptEntryValue(nonce, val): ...@@ -69,18 +76,18 @@ def decryptEntryValue(nonce, val):
block = inputData[:16] block = inputData[:16]
inputData = inputData[16:] inputData = inputData[16:]
if block: if block:
data = data + decryptor.update(block) data = data + decryptor.update(block).decode()
else: else:
break break
# throws exception when the tag is wrong # throws exception when the tag is wrong
data = data + decryptor.finalize() data = data + decryptor.finalize().decode()
return json.loads(data) return json.loads(data)
# Decrypt give entry nonce # Decrypt give entry nonce
def getDecryptedNonce(entry): def getDecryptedNonce(client, entry):
print print()
print 'Waiting for TREZOR input ...' print('Waiting for TREZOR input ...')
print print()
if 'item' in entry: if 'item' in entry:
item = entry['item'] item = entry['item']
else: else:
...@@ -93,7 +100,7 @@ def getDecryptedNonce(entry): ...@@ -93,7 +100,7 @@ def getDecryptedNonce(entry):
ENC_KEY = 'Unlock %s for user %s?' % (item, entry['username']) ENC_KEY = 'Unlock %s for user %s?' % (item, entry['username'])
ENC_VALUE = entry['nonce'] ENC_VALUE = entry['nonce']
decrypted_nonce = hexlify(client.decrypt_keyvalue( decrypted_nonce = hexlify(client.decrypt_keyvalue(
getPath(), getPath(client),
ENC_KEY, ENC_KEY,
unhexlify(ENC_VALUE), unhexlify(ENC_VALUE),
False, False,
...@@ -103,63 +110,64 @@ def getDecryptedNonce(entry): ...@@ -103,63 +110,64 @@ def getDecryptedNonce(entry):
# Pretty print of list # Pretty print of list
def printEntries(entries): def printEntries(entries):
print 'Password entries' print('Password entries')
print '================' print('================')
print print()
for k, v in entries.iteritems(): for k, v in entries.items():
print 'Entry id: #%s' % k print('Entry id: #%s' % k)
print '-------------' print('-------------')
for kk, vv in v.iteritems(): for kk, vv in v.items():
if kk in ['nonce', 'safe_note', 'password']: continue # skip these fields if kk in ['nonce', 'safe_note', 'password']: continue # skip these fields
print '*', kk, ': ', vv print('*', kk, ': ', vv)
print print()
return return
def main(): def main():
print devices = HidTransport.enumerate()
print 'Confirm operation on TREZOR' if not devices:
print print('TREZOR is not plugged in. Please, connect TREZOR and retry.')
return
client = TrezorClient(devices[0])
masterKey = getMasterKey() print()
#print 'master key:', masterKey print('Confirm operation on TREZOR')
print()
masterKey = getMasterKey(client)
# print('master key:', masterKey)
fileName = getFileEncKey(masterKey)[0] fileName = getFileEncKey(masterKey)[0]
#print 'file name:', fileName # print('file name:', fileName)
path = os.path.expanduser('~/Dropbox/Apps/TREZOR Password Manager/') path = os.path.expanduser('~/Dropbox/Apps/TREZOR Password Manager/')
#print 'path to file:', path # print('path to file:', path)
encKey = getFileEncKey(masterKey)[2] encKey = getFileEncKey(masterKey)[2]
#print 'enckey:', encKey # print('enckey:', encKey)
full_path = path + fileName full_path = path + fileName
parsed_json = decryptStorage(full_path, encKey) parsed_json = decryptStorage(full_path, encKey)
#list entries # list entries
entries = parsed_json['entries'] entries = parsed_json['entries']
printEntries(entries) printEntries(entries)
entry_id = raw_input('Select entry number to decrypt: ') entry_id = input('Select entry number to decrypt: ')
entry_id = str(entry_id) entry_id = str(entry_id)
plain_nonce = getDecryptedNonce(entries[entry_id]) plain_nonce = getDecryptedNonce(client, entries[entry_id])
pwdArr = entries[entry_id]['password']['data'] pwdArr = entries[entry_id]['password']['data']
pwdHex = ''.join([ hex(x)[2:].zfill(2) for x in pwdArr ]) pwdHex = ''.join([ hex(x)[2:].zfill(2) for x in pwdArr ])
print 'password: ', decryptEntryValue(plain_nonce, unhexlify(pwdHex)) print('password: ', decryptEntryValue(plain_nonce, unhexlify(pwdHex)))
safeNoteArr = entries[entry_id]['safe_note']['data'] safeNoteArr = entries[entry_id]['safe_note']['data']
safeNoteHex = ''.join([ hex(x)[2:].zfill(2) for x in safeNoteArr ]) safeNoteHex = ''.join([ hex(x)[2:].zfill(2) for x in safeNoteArr ])
print 'safe_note:', decryptEntryValue(plain_nonce, unhexlify(safeNoteHex)) print('safe_note:', decryptEntryValue(plain_nonce, unhexlify(safeNoteHex)))
return return
if __name__ == '__main__': if __name__ == '__main__':
try:
# init TREZOR transport
client = TrezorClient(HidTransport(HidTransport.enumerate()[0]))
except:
print 'TREZOR is not plugged in. Please, connect TREZOR and retry.'
else:
main() main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment