fix issue #1061: normalize trezor passphrases. Add passphrases to restore from seed with trezor.
This commit is contained in:
parent
c56fe45ad7
commit
15636282e4
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue