fix issue #1061: normalize trezor passphrases. Add passphrases to restore from seed with trezor.

This commit is contained in:
ThomasV 2015-03-05 17:09:39 +01:00
parent c56fe45ad7
commit 15636282e4
2 changed files with 29 additions and 19 deletions

View File

@ -1321,9 +1321,9 @@ class BIP32_Wallet(Deterministic_Wallet):
seed = self.get_seed(password)
self.add_cosigner_seed(seed, self.root_name, password)
def add_cosigner_seed(self, seed, name, password):
def add_cosigner_seed(self, seed, name, password, passphrase=''):
# we don't store the seed, only the master xpriv
xprv, xpub = bip32_root(self.mnemonic_to_seed(seed,''))
xprv, xpub = bip32_root(self.mnemonic_to_seed(seed, passphrase))
xprv, xpub = bip32_private_derivation(xprv, "m/", self.root_derivation)
self.add_master_public_key(name, xpub)
self.add_master_private_key(name, xprv, password)

View File

@ -5,6 +5,7 @@ from struct import pack
from sys import stderr
from time import sleep
from base64 import b64encode, b64decode
import unicodedata
import electrum
from electrum.account import BIP32_Account
@ -15,7 +16,6 @@ from electrum.transaction import deserialize
from electrum.wallet import BIP32_HD_Wallet
from electrum.util import print_error
from electrum_gui.qt.password_dialog import make_password_dialog, run_password_dialog
from electrum_gui.qt.util import ok_cancel_buttons, EnterButton
try:
@ -36,6 +36,21 @@ def give_error(message):
print_error(message)
raise Exception(message)
def trezor_passphrase_dialog(msg):
from electrum_gui.qt.password_dialog import make_password_dialog, run_password_dialog
d = QDialog()
d.setModal(1)
d.setLayout(make_password_dialog(d, None, msg, False))
confirmed, p, passphrase = run_password_dialog(d, None, None)
if not confirmed:
return None
if passphrase is None:
passphrase = '' # Even blank string is valid Trezor passphrase
passphrase = unicodedata.normalize('NFKD', unicode(passphrase))
return passphrase
class Plugin(BasePlugin):
def fullname(self):
@ -117,9 +132,13 @@ class Plugin(BasePlugin):
return
wallet = TrezorWallet(storage)
self.wallet = wallet
passphrase = trezor_passphrase_dialog(_("Please enter your Trezor passphrase.") + '\n' + _("Press OK if you do not use one."))
if passphrase is None:
QMessageBox.critical(None, _('Error'), _("Password request canceled"), _('OK'))
return
password = wizard.password_dialog()
wallet.add_seed(seed, password)
wallet.add_cosigner_seed(' '.join(seed.split()), 'x/', password)
wallet.add_cosigner_seed(seed, 'x/', password, passphrase)
wallet.create_main_account(password)
# disable trezor plugin
self.set_enabled(False)
@ -244,7 +263,8 @@ class TrezorWallet(BIP32_HD_Wallet):
# trezor uses bip39
import pbkdf2, hashlib, hmac
PBKDF2_ROUNDS = 2048
mnemonic = ' '.join(mnemonic.split())
mnemonic = unicodedata.normalize('NFKD', ' '.join(mnemonic.split()))
passphrase = unicodedata.normalize('NFKD', passphrase)
return pbkdf2.PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64)
def derive_xkeys(self, root, derivation, password):
@ -475,13 +495,12 @@ class TrezorQtGuiMixin(object):
return proto.Cancel()
return proto.PinMatrixAck(pin=pin)
def callback_PassphraseRequest(self, msg):
confirmed, p, passphrase = self.password_dialog()
if not confirmed:
def callback_PassphraseRequest(self, req):
msg = _("Please enter your Trezor passphrase.")
passphrase = trezor_passphrase_dialog(msg)
if passphrase is None:
QMessageBox.critical(None, _('Error'), _("Password request canceled"), _('OK'))
return proto.Cancel()
if passphrase is None:
passphrase='' # Even blank string is valid Trezor passphrase
return proto.PassphraseAck(passphrase=passphrase)
def callback_WordRequest(self, msg):
@ -490,15 +509,6 @@ class TrezorQtGuiMixin(object):
word = raw_input()
return proto.WordAck(word=word)
def password_dialog(self, msg=None):
if not msg:
msg = _("Please enter your Trezor password")
d = QDialog()
d.setModal(1)
d.setLayout( make_password_dialog(d, None, msg, False) )
return run_password_dialog(d, None, None)
def pin_dialog(self, msg):
d = QDialog(None)
d.setModal(1)