commit c24482c21a7df7e7dc9d1027a738acfa49044a7e
parent 38a59c0b37448bf6fdc384d4a7f52d63fcd15216
Author: ThomasV <thomasv@gitorious>
Date: Sat, 5 Apr 2014 10:34:51 +0200
check seed in gui. fixes #622
Diffstat:
4 files changed, 63 insertions(+), 29 deletions(-)
diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
@@ -134,6 +134,10 @@ class InstallWizard(QDialog):
QMessageBox.warning(None, _('Error'), _('No seed'), _('OK'))
return
+ if not Wallet.is_seed(seed):
+ QMessageBox.warning(None, _('Error'), _('Invalid seed'), _('OK'))
+ return
+
return seed
@@ -272,7 +276,7 @@ class InstallWizard(QDialog):
elif action == 'restore':
seed = self.seed_dialog()
- if not seed:
+ if not Wallet.is_seed(seed):
return
wallet = Wallet.from_seed(seed, self.storage)
ok, old_password, password = self.password_dialog(wallet)
diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
@@ -1141,6 +1141,7 @@ class ElectrumWindow(QMainWindow):
menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(addr))
menu.addAction(_("QR code"), lambda: self.show_qrcode("bitcoin:" + addr, _("Address")) )
menu.addAction(_("Edit label"), lambda: self.edit_label(True))
+ menu.addAction(_("Public keys"), lambda: self.show_public_keys(addr))
if self.wallet.seed:
menu.addAction(_("Private key"), lambda: self.show_private_key(addr))
menu.addAction(_("Sign/verify message"), lambda: self.sign_verify_message(addr))
@@ -1667,6 +1668,30 @@ class ElectrumWindow(QMainWindow):
apply( func, args)
+ def show_public_keys(self, address):
+ if not address: return
+ try:
+ pubkey_list = self.wallet.get_public_keys(address)
+ except Exception as e:
+ traceback.print_exc(file=sys.stdout)
+ self.show_message(str(e))
+ return
+
+ d = QDialog(self)
+ d.setMinimumSize(600, 200)
+ d.setModal(1)
+ vbox = QVBoxLayout()
+ vbox.addWidget( QLabel(_("Address") + ': ' + address))
+ vbox.addWidget( QLabel(_("Public key") + ':'))
+ keys = QTextEdit()
+ keys.setReadOnly(True)
+ keys.setText('\n'.join(pubkey_list))
+ vbox.addWidget(keys)
+ #vbox.addWidget( QRCodeWidget('\n'.join(pk_list)) )
+ vbox.addLayout(close_button(d))
+ d.setLayout(vbox)
+ d.exec_()
+
@protected
def show_private_key(self, address, password):
if not address: return
diff --git a/lib/bitcoin.py b/lib/bitcoin.py
@@ -71,7 +71,25 @@ def mnemonic_to_seed(mnemonic, passphrase):
return PBKDF2(mnemonic, 'mnemonic' + passphrase, iterations = PBKDF2_ROUNDS, macmodule = hmac, digestmodule = hashlib.sha512).read(64)
from version import SEED_PREFIX
-is_seed = lambda x: hmac_sha_512("Seed version", x).encode('hex')[0:2].startswith(SEED_PREFIX)
+is_new_seed = lambda x: hmac_sha_512("Seed version", x).encode('hex')[0:2].startswith(SEED_PREFIX)
+
+def is_old_seed(seed):
+ import mnemonic
+ words = seed.strip().split()
+ try:
+ mnemonic.mn_decode(words)
+ uses_electrum_words = True
+ except Exception:
+ uses_electrum_words = False
+
+ try:
+ seed.decode('hex')
+ is_hex = True
+ except Exception:
+ is_hex = False
+
+ return is_hex or (uses_electrum_words and len(words) == 12)
+
# pywallet openssl private key implementation
diff --git a/lib/wallet.py b/lib/wallet.py
@@ -288,7 +288,7 @@ class NewWallet:
# we keep only 13 words, that's approximately 139 bits of entropy
words = mnemonic.mn_encode(s)[0:13]
seed = ' '.join(words)
- if is_seed(seed):
+ if is_new_seed(seed):
break # this will remove 8 bits of entropy
nonce += 1
@@ -1781,36 +1781,23 @@ class Wallet(object):
@classmethod
- def from_seed(self, seed, storage):
- import mnemonic
+ def is_seed(self, seed):
if not seed:
- return
-
- words = seed.strip().split()
- try:
- mnemonic.mn_decode(words)
- uses_electrum_words = True
- except Exception:
- uses_electrum_words = False
-
- try:
- seed.decode('hex')
- is_hex = True
- except Exception:
- is_hex = False
-
- if is_hex or (uses_electrum_words and len(words) == 12):
- #print "old style wallet", len(words), words
- w = OldWallet(storage)
- w.init_seed(seed) #hex
- else:
- assert is_seed(seed)
- w = NewWallet(storage)
- w.init_seed(seed)
+ return False
+ elif is_old_seed(seed):
+ return OldWallet
+ elif is_new_seed(seed):
+ return NewWallet
+ else:
+ return False
+ @classmethod
+ def from_seed(self, seed, storage):
+ klass = self.is_seed(seed)
+ w = klass(storage)
+ w.init_seed(seed)
return w
-
@classmethod
def from_mpk(self, mpk, storage):