allow encrypting watch-only wallets. initial support for hw wallet storage encryption.
This commit is contained in:
@@ -10,13 +10,13 @@ from PyQt5.QtWidgets import *
|
||||
|
||||
from electrum import Wallet, WalletStorage
|
||||
from electrum.util import UserCancelled, InvalidPassword
|
||||
from electrum.base_wizard import BaseWizard
|
||||
from electrum.base_wizard import BaseWizard, HWD_SETUP_DECRYPT_WALLET
|
||||
from electrum.i18n import _
|
||||
|
||||
from .seed_dialog import SeedLayout, KeysLayout
|
||||
from .network_dialog import NetworkChoiceLayout
|
||||
from .util import *
|
||||
from .password_dialog import PasswordLayout, PW_NEW
|
||||
from .password_dialog import PasswordLayout, PasswordLayoutForHW, PW_NEW
|
||||
|
||||
|
||||
class GoBack(Exception):
|
||||
@@ -29,6 +29,10 @@ MSG_ENTER_SEED_OR_MPK = _("Please enter a seed phrase or a master key (xpub or x
|
||||
MSG_COSIGNER = _("Please enter the master public key of cosigner #%d:")
|
||||
MSG_ENTER_PASSWORD = _("Choose a password to encrypt your wallet keys.") + '\n'\
|
||||
+ _("Leave this field empty if you want to disable encryption.")
|
||||
MSG_HW_STORAGE_ENCRYPTION = _("Set wallet file encryption.") + '\n'\
|
||||
+ _("Your wallet file does not contain secrets, mostly just metadata. ") \
|
||||
+ _("It also contains your master public key that allows watching your addresses.") + '\n\n'\
|
||||
+ _("Note: If you enable this setting, you will need your hardware device to open your wallet.")
|
||||
MSG_RESTORE_PASSPHRASE = \
|
||||
_("Please enter your seed derivation passphrase. "
|
||||
"Note: this is NOT your encryption password. "
|
||||
@@ -196,12 +200,18 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
|
||||
msg =_("This file does not exist.") + '\n' \
|
||||
+ _("Press 'Next' to create this wallet, or choose another file.")
|
||||
pw = False
|
||||
elif self.storage.file_exists() and self.storage.is_encrypted():
|
||||
msg = _("This file is encrypted.") + '\n' + _('Enter your password or choose another file.')
|
||||
pw = True
|
||||
else:
|
||||
msg = _("Press 'Next' to open this wallet.")
|
||||
pw = False
|
||||
if self.storage.is_encrypted_with_user_pw():
|
||||
msg = _("This file is encrypted with a password.") + '\n' \
|
||||
+ _('Enter your password or choose another file.')
|
||||
pw = True
|
||||
elif self.storage.is_encrypted_with_hw_device():
|
||||
msg = _("This file is encrypted using a hardware device.") + '\n' \
|
||||
+ _("Press 'Next' to choose device to decrypt.")
|
||||
pw = False
|
||||
else:
|
||||
msg = _("Press 'Next' to open this wallet.")
|
||||
pw = False
|
||||
else:
|
||||
msg = _('Cannot read file')
|
||||
pw = False
|
||||
@@ -227,17 +237,40 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
|
||||
if not self.storage.file_exists():
|
||||
break
|
||||
if self.storage.file_exists() and self.storage.is_encrypted():
|
||||
password = self.pw_e.text()
|
||||
try:
|
||||
self.storage.decrypt(password)
|
||||
break
|
||||
except InvalidPassword as e:
|
||||
QMessageBox.information(None, _('Error'), str(e))
|
||||
continue
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
QMessageBox.information(None, _('Error'), str(e))
|
||||
return
|
||||
if self.storage.is_encrypted_with_user_pw():
|
||||
password = self.pw_e.text()
|
||||
try:
|
||||
self.storage.decrypt(password)
|
||||
break
|
||||
except InvalidPassword as e:
|
||||
QMessageBox.information(None, _('Error'), str(e))
|
||||
continue
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
QMessageBox.information(None, _('Error'), str(e))
|
||||
return
|
||||
elif self.storage.is_encrypted_with_hw_device():
|
||||
try:
|
||||
self.run('choose_hw_device', HWD_SETUP_DECRYPT_WALLET)
|
||||
except InvalidPassword as e:
|
||||
# FIXME if we get here because of mistyped passphrase
|
||||
# then that passphrase gets "cached"
|
||||
QMessageBox.information(
|
||||
None, _('Error'),
|
||||
_('Failed to decrypt using this hardware device.') + '\n' +
|
||||
_('If you use a passphrase, make sure it is correct.'))
|
||||
self.stack = []
|
||||
return self.run_and_get_wallet()
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
QMessageBox.information(None, _('Error'), str(e))
|
||||
return
|
||||
if self.storage.is_past_initial_decryption():
|
||||
break
|
||||
else:
|
||||
return
|
||||
else:
|
||||
raise Exception('Unexpected encryption version')
|
||||
|
||||
path = self.storage.path
|
||||
if self.storage.requires_split():
|
||||
@@ -386,17 +419,25 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
|
||||
self.exec_layout(slayout)
|
||||
return slayout.is_ext
|
||||
|
||||
def pw_layout(self, msg, kind):
|
||||
playout = PasswordLayout(None, msg, kind, self.next_button)
|
||||
def pw_layout(self, msg, kind, force_disable_encrypt_cb):
|
||||
playout = PasswordLayout(None, msg, kind, self.next_button,
|
||||
force_disable_encrypt_cb=force_disable_encrypt_cb)
|
||||
playout.encrypt_cb.setChecked(True)
|
||||
self.exec_layout(playout.layout())
|
||||
return playout.new_password(), playout.encrypt_cb.isChecked()
|
||||
|
||||
@wizard_dialog
|
||||
def request_password(self, run_next):
|
||||
def request_password(self, run_next, force_disable_encrypt_cb=False):
|
||||
"""Request the user enter a new password and confirm it. Return
|
||||
the password or None for no password."""
|
||||
return self.pw_layout(MSG_ENTER_PASSWORD, PW_NEW)
|
||||
return self.pw_layout(MSG_ENTER_PASSWORD, PW_NEW, force_disable_encrypt_cb)
|
||||
|
||||
@wizard_dialog
|
||||
def request_storage_encryption(self, run_next):
|
||||
playout = PasswordLayoutForHW(None, MSG_HW_STORAGE_ENCRYPTION, PW_NEW, self.next_button)
|
||||
playout.encrypt_cb.setChecked(True)
|
||||
self.exec_layout(playout.layout())
|
||||
return playout.encrypt_cb.isChecked()
|
||||
|
||||
def show_restore(self, wallet, network):
|
||||
# FIXME: these messages are shown after the install wizard is
|
||||
|
||||
Reference in New Issue
Block a user