wizard: fix regression: allow passphrase for some '2fa' seeds
fixes https://github.com/spesmilo/electrum/issues/9088
This commit is contained in:
@@ -276,6 +276,23 @@ def seed_type(x: str) -> str:
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def can_seed_have_passphrase(seed: str) -> bool:
|
||||||
|
stype = seed_type(seed)
|
||||||
|
if not stype:
|
||||||
|
raise Exception(f'unexpected seed type: {stype!r}')
|
||||||
|
if stype == 'old':
|
||||||
|
return False
|
||||||
|
if stype == '2fa':
|
||||||
|
# post-version-2.7 2fa seeds can have passphrase, but older ones cannot
|
||||||
|
num_words = len(seed.split())
|
||||||
|
if num_words == 12:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
# all other types can have a seed extension/passphrase
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_seed(x: str) -> bool:
|
def is_seed(x: str) -> bool:
|
||||||
return bool(seed_type(x))
|
return bool(seed_type(x))
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from electrum.storage import WalletStorage, StorageEncryptionVersion
|
|||||||
from electrum.wallet_db import WalletDB
|
from electrum.wallet_db import WalletDB
|
||||||
from electrum.bip32 import normalize_bip32_derivation, xpub_type
|
from electrum.bip32 import normalize_bip32_derivation, xpub_type
|
||||||
from electrum import keystore, mnemonic, bitcoin
|
from electrum import keystore, mnemonic, bitcoin
|
||||||
from electrum.mnemonic import is_any_2fa_seed_type
|
from electrum.mnemonic import is_any_2fa_seed_type, can_seed_have_passphrase
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from electrum.daemon import Daemon
|
from electrum.daemon import Daemon
|
||||||
@@ -492,8 +492,7 @@ class NewWalletWizard(AbstractWizard):
|
|||||||
seed_type = mnemonic.seed_type(seed)
|
seed_type = mnemonic.seed_type(seed)
|
||||||
if seed_type != '':
|
if seed_type != '':
|
||||||
seed_valid = True
|
seed_valid = True
|
||||||
if seed_type in ['old', '2fa']:
|
can_passphrase = can_seed_have_passphrase(seed)
|
||||||
can_passphrase = False
|
|
||||||
elif seed_variant == 'bip39':
|
elif seed_variant == 'bip39':
|
||||||
is_checksum, is_wordlist = keystore.bip39_is_checksum_valid(seed)
|
is_checksum, is_wordlist = keystore.bip39_is_checksum_valid(seed)
|
||||||
validation_message = ('' if is_checksum else _('BIP39 checksum failed')) if is_wordlist else _('Unknown BIP39 wordlist')
|
validation_message = ('' if is_checksum else _('BIP39 checksum failed')) if is_wordlist else _('Unknown BIP39 wordlist')
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from electrum import mnemonic
|
|||||||
from electrum import slip39
|
from electrum import slip39
|
||||||
from electrum import old_mnemonic
|
from electrum import old_mnemonic
|
||||||
from electrum.util import bfh
|
from electrum.util import bfh
|
||||||
from electrum.mnemonic import is_new_seed, is_old_seed, seed_type, is_matching_seed
|
from electrum.mnemonic import is_new_seed, is_old_seed, seed_type, is_matching_seed, can_seed_have_passphrase
|
||||||
from electrum.version import SEED_PREFIX_SW, SEED_PREFIX
|
from electrum.version import SEED_PREFIX_SW, SEED_PREFIX
|
||||||
|
|
||||||
from . import ElectrumTestCase
|
from . import ElectrumTestCase
|
||||||
@@ -244,6 +244,25 @@ class Test_seeds(ElectrumTestCase):
|
|||||||
self.assertFalse(is_matching_seed(seed="when blade focus", seed_again="when bl4de focus"))
|
self.assertFalse(is_matching_seed(seed="when blade focus", seed_again="when bl4de focus"))
|
||||||
self.assertFalse(is_matching_seed(seed="when blade focus", seed_again="when bla4de focus"))
|
self.assertFalse(is_matching_seed(seed="when blade focus", seed_again="when bla4de focus"))
|
||||||
|
|
||||||
|
def test_can_seed_have_passphrase(self):
|
||||||
|
seed_invalid = 'xxx'
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
self.assertFalse(can_seed_have_passphrase(seed_invalid))
|
||||||
|
seed_old = 'cell dumb heartbeat north boom tease ship baby bright kingdom rare squeeze'
|
||||||
|
self.assertFalse(can_seed_have_passphrase(seed_old))
|
||||||
|
seed_standard = 'cram swing cover prefer miss modify ritual silly deliver chunk behind inform able'
|
||||||
|
self.assertTrue(can_seed_have_passphrase(seed_standard))
|
||||||
|
seed_segwit = 'frost pig brisk excite novel report camera enlist axis nation novel desert'
|
||||||
|
self.assertTrue(can_seed_have_passphrase(seed_segwit))
|
||||||
|
seed_2fa_12 = 'science dawn member doll dutch real can brick knife deny drive list'
|
||||||
|
self.assertTrue(can_seed_have_passphrase(seed_2fa_12))
|
||||||
|
seed_2fa_24 = 'sibling leg cable timber patient foot occur plate travel finger chef scale radio citizen promote immune must chef fluid sea sphere common acid lab'
|
||||||
|
self.assertFalse(can_seed_have_passphrase(seed_2fa_24))
|
||||||
|
seed_2fa_25 = 'bind clever room kidney crucial sausage spy edit canvas soul liquid ribbon slam open alpha suffer gate relax voice carpet law hill woman tonight abstract'
|
||||||
|
self.assertFalse(can_seed_have_passphrase(seed_2fa_25))
|
||||||
|
seed_2fa_segwit = 'agree install'
|
||||||
|
self.assertTrue(can_seed_have_passphrase(seed_2fa_segwit))
|
||||||
|
|
||||||
|
|
||||||
class Test_slip39(ElectrumTestCase):
|
class Test_slip39(ElectrumTestCase):
|
||||||
""" Test SLIP39 test vectors. """
|
""" Test SLIP39 test vectors. """
|
||||||
|
|||||||
Reference in New Issue
Block a user