crypto.py:get_*passphrase(),get_hash_preset*(): merge with duplicating code in wallet.py
This commit is contained in:
parent
748bf68c15
commit
ccb4894583
5 changed files with 79 additions and 97 deletions
|
|
@ -215,78 +215,101 @@ def add_user_random(rand_bytes,desc):
|
|||
else:
|
||||
return rand_bytes
|
||||
|
||||
def get_hash_preset_from_user(hp=g.dfl_hash_preset,desc='data'):
|
||||
def get_hash_preset_from_user(
|
||||
hash_preset = g.dfl_hash_preset,
|
||||
data_desc = 'data',
|
||||
prompt = None ):
|
||||
|
||||
prompt = prompt or (
|
||||
f'Enter hash preset for {data_desc},\n' +
|
||||
f'or hit ENTER to accept the default value ({hash_preset!r}): ' )
|
||||
|
||||
while True:
|
||||
ret = line_input(
|
||||
f'Enter hash preset for {desc},\n' +
|
||||
f'or hit ENTER to accept the default value ({hp!r}): ' )
|
||||
ret = line_input(prompt)
|
||||
if ret:
|
||||
if ret in g.hash_presets:
|
||||
return ret
|
||||
else:
|
||||
msg(f'Invalid input. Valid choices are {", ".join(g.hash_presets)}')
|
||||
continue
|
||||
msg('Invalid input. Valid choices are {}'.format(', '.join(g.hash_presets)))
|
||||
else:
|
||||
return hp
|
||||
return hash_preset
|
||||
|
||||
def get_new_passphrase(desc,passchg=False):
|
||||
pw_desc = f"{'new ' if passchg else ''}passphrase for {desc}"
|
||||
if opt.passwd_file:
|
||||
def get_new_passphrase(data_desc,hash_preset,passwd_file,pw_desc='passphrase'):
|
||||
message = f"""
|
||||
You must choose a passphrase to encrypt your {data_desc} with.
|
||||
A key will be generated from your passphrase using a hash preset of '{hash_preset}'.
|
||||
Please note that no strength checking of passphrases is performed.
|
||||
For an empty passphrase, just hit ENTER twice.
|
||||
"""
|
||||
if passwd_file:
|
||||
from .fileutil import get_words_from_file
|
||||
pw = ' '.join(get_words_from_file(opt.passwd_file,pw_desc))
|
||||
elif opt.echo_passphrase:
|
||||
pw = ' '.join(get_words_from_user(f'Enter {pw_desc}: '))
|
||||
pw = ' '.join(get_words_from_file(
|
||||
infile = passwd_file,
|
||||
desc = f'{pw_desc} for {data_desc}',
|
||||
quiet = pwfile_reuse_warning(passwd_file).warning_shown ))
|
||||
else:
|
||||
for i in range(g.passwd_max_tries):
|
||||
pw = ' '.join(get_words_from_user(f'Enter {pw_desc}: '))
|
||||
pw_chk = ' '.join(get_words_from_user('Repeat passphrase: '))
|
||||
dmsg(f'Passphrases: [{pw}] [{pw_chk}]')
|
||||
if pw == pw_chk:
|
||||
vmsg('Passphrases match'); break
|
||||
else: msg('Passphrases do not match. Try again.')
|
||||
qmsg('\n'+fmt(message,indent=' '))
|
||||
if opt.echo_passphrase:
|
||||
pw = ' '.join(get_words_from_user(f'Enter {pw_desc} for {data_desc}: '))
|
||||
else:
|
||||
die(2,f'User failed to duplicate passphrase in {g.passwd_max_tries} attempts')
|
||||
for i in range(g.passwd_max_tries):
|
||||
pw = ' '.join(get_words_from_user(f'Enter {pw_desc} for {data_desc}: '))
|
||||
pw_chk = ' '.join(get_words_from_user(f'Repeat {pw_desc}: '))
|
||||
dmsg(f'Passphrases: [{pw}] [{pw_chk}]')
|
||||
if pw == pw_chk:
|
||||
vmsg('Passphrases match')
|
||||
break
|
||||
else:
|
||||
msg('Passphrases do not match. Try again.')
|
||||
else:
|
||||
die(2,f'User failed to duplicate passphrase in {g.passwd_max_tries} attempts')
|
||||
|
||||
if pw == '':
|
||||
qmsg('WARNING: Empty passphrase')
|
||||
|
||||
return pw
|
||||
|
||||
def get_passphrase(desc,passchg=False):
|
||||
pw_desc = f"{'old ' if passchg else ''}passphrase for {desc}"
|
||||
if opt.passwd_file:
|
||||
def get_passphrase(data_desc,passwd_file,pw_desc='passphrase'):
|
||||
if passwd_file:
|
||||
from .fileutil import get_words_from_file
|
||||
pwfile_reuse_warning(opt.passwd_file)
|
||||
return ' '.join(get_words_from_file(opt.passwd_file,pw_desc))
|
||||
return ' '.join(get_words_from_file(
|
||||
infile = passwd_file,
|
||||
desc = f'{pw_desc} for {data_desc}',
|
||||
quiet = pwfile_reuse_warning(passwd_file).warning_shown ))
|
||||
else:
|
||||
return ' '.join(get_words_from_user(f'Enter {pw_desc}: '))
|
||||
return ' '.join(get_words_from_user(f'Enter {pw_desc} for {data_desc}: '))
|
||||
|
||||
mmenc_salt_len = 32
|
||||
mmenc_nonce_len = 32
|
||||
|
||||
def mmgen_encrypt(data,desc='data',hash_preset=''):
|
||||
def mmgen_encrypt(data,desc='data',hash_preset=None):
|
||||
salt = get_random(mmenc_salt_len)
|
||||
iv = get_random(g.aesctr_iv_len)
|
||||
nonce = get_random(mmenc_nonce_len)
|
||||
hp = hash_preset or opt.hash_preset or get_hash_preset_from_user('3',desc)
|
||||
hp = hash_preset or opt.hash_preset or get_hash_preset_from_user(data_desc=desc)
|
||||
m = ('user-requested','default')[hp=='3']
|
||||
vmsg(f'Encrypting {desc}')
|
||||
qmsg(f'Using {m} hash preset of {hp!r}')
|
||||
passwd = get_new_passphrase(desc)
|
||||
passwd = get_new_passphrase(
|
||||
data_desc = desc,
|
||||
hash_preset = hp,
|
||||
passwd_file = opt.passwd_file )
|
||||
key = make_key(passwd,salt,hp)
|
||||
enc_d = encrypt_data( sha256(nonce+data).digest() + nonce + data, key, iv, desc=desc )
|
||||
return salt+iv+enc_d
|
||||
|
||||
def mmgen_decrypt(data,desc='data',hash_preset=''):
|
||||
def mmgen_decrypt(data,desc='data',hash_preset=None):
|
||||
vmsg(f'Preparing to decrypt {desc}')
|
||||
dstart = mmenc_salt_len + g.aesctr_iv_len
|
||||
salt = data[:mmenc_salt_len]
|
||||
iv = data[mmenc_salt_len:dstart]
|
||||
enc_d = data[dstart:]
|
||||
hp = hash_preset or opt.hash_preset or get_hash_preset_from_user('3',desc)
|
||||
hp = hash_preset or opt.hash_preset or get_hash_preset_from_user(data_desc=desc)
|
||||
m = ('user-requested','default')[hp=='3']
|
||||
qmsg(f'Using {m} hash preset of {hp!r}')
|
||||
passwd = get_passphrase(desc)
|
||||
passwd = get_passphrase(
|
||||
data_desc = desc,
|
||||
passwd_file = opt.passwd_file )
|
||||
key = make_key(passwd,salt,hp)
|
||||
dec_d = decrypt_data( enc_d, key, iv, desc )
|
||||
sha256_len = 32
|
||||
|
|
|
|||
|
|
@ -298,15 +298,8 @@ class WalletEnc(Wallet):
|
|||
('',' '+add_desc)[bool(add_desc)],
|
||||
('accept the default','reuse the old')[self.op=='pwchg_new'],
|
||||
hp )
|
||||
while True:
|
||||
ret = line_input(prompt)
|
||||
if ret:
|
||||
if ret in g.hash_presets:
|
||||
return ret
|
||||
else:
|
||||
msg('Invalid input. Valid choices are {}'.format(', '.join(g.hash_presets)))
|
||||
else:
|
||||
return hp
|
||||
from .crypto import get_hash_preset_from_user
|
||||
return get_hash_preset_from_user( hash_preset=hp, prompt=prompt )
|
||||
|
||||
def _get_hash_preset(self,add_desc=''):
|
||||
if hasattr(self,'ss_in') and hasattr(self.ss_in.ssdata,'hash_preset'):
|
||||
|
|
@ -329,54 +322,20 @@ class WalletEnc(Wallet):
|
|||
self.ssdata.hash_preset = hp
|
||||
|
||||
def _get_new_passphrase(self):
|
||||
desc = '{}passphrase for {}{}'.format(
|
||||
('','new ')[self.op=='pwchg_new'],
|
||||
('','new ')[self.op in ('new','conv')],
|
||||
self.desc
|
||||
)
|
||||
if self.passwd_file:
|
||||
from .fileutil import get_words_from_file
|
||||
pw = ' '.join(get_words_from_file(
|
||||
self.passwd_file,
|
||||
desc,
|
||||
quiet = pwfile_reuse_warning(self.passwd_file).warning_shown ))
|
||||
else:
|
||||
qmsg('\n'+fmt(self.msg['choose_passphrase'].format(self.desc,self.ssdata.hash_preset),indent=' '))
|
||||
if opt.echo_passphrase:
|
||||
pw = ' '.join(get_words_from_user(f'Enter {desc}: '))
|
||||
else:
|
||||
for i in range(g.passwd_max_tries):
|
||||
pw = ' '.join(get_words_from_user(f'Enter {desc}: '))
|
||||
pw_chk = ' '.join(get_words_from_user('Repeat passphrase: '))
|
||||
dmsg(f'Passphrases: [{pw}] [{pw_chk}]')
|
||||
if pw == pw_chk:
|
||||
vmsg('Passphrases match')
|
||||
break
|
||||
else:
|
||||
msg('Passphrases do not match. Try again.')
|
||||
else:
|
||||
die(2,f'User failed to duplicate passphrase in {g.passwd_max_tries} attempts')
|
||||
|
||||
if pw == '':
|
||||
qmsg('WARNING: Empty passphrase')
|
||||
self.ssdata.passwd = pw
|
||||
return pw
|
||||
from .crypto import get_new_passphrase
|
||||
self.ssdata.passwd = get_new_passphrase(
|
||||
data_desc = ('new ' if self.op in ('new','conv') else '') + self.desc,
|
||||
hash_preset = self.ssdata.hash_preset,
|
||||
passwd_file = self.passwd_file,
|
||||
pw_desc = ('new ' if self.op=='pwchg_new' else '') + 'passphrase' )
|
||||
return self.ssdata.passwd
|
||||
|
||||
def _get_passphrase(self,add_desc=''):
|
||||
desc = '{}passphrase for {}{}'.format(
|
||||
('','old ')[self.op=='pwchg_old'],
|
||||
self.desc,
|
||||
('',' '+add_desc)[bool(add_desc)]
|
||||
)
|
||||
if self.passwd_file:
|
||||
from .fileutil import get_words_from_file
|
||||
ret = ' '.join(get_words_from_file(
|
||||
self.passwd_file,
|
||||
desc,
|
||||
quiet = pwfile_reuse_warning(self.passwd_file).warning_shown ))
|
||||
else:
|
||||
ret = ' '.join(get_words_from_user(f'Enter {desc}: '))
|
||||
self.ssdata.passwd = ret
|
||||
from .crypto import get_passphrase
|
||||
self.ssdata.passwd = get_passphrase(
|
||||
data_desc = self.desc + (f' {add_desc}' if add_desc else ''),
|
||||
passwd_file = self.passwd_file,
|
||||
pw_desc = ('old ' if self.op == 'pwchg_old' else '') + 'passphrase' )
|
||||
|
||||
def _get_first_pw_and_hp_and_encrypt_seed(self):
|
||||
d = self.ssdata
|
||||
|
|
@ -826,7 +785,7 @@ class MMGenWallet(WalletEnc):
|
|||
d.hash_preset = hp = hpdata[0][:-1] # a string!
|
||||
qmsg(f'Hash preset of wallet: {hp!r}')
|
||||
if opt.hash_preset and opt.hash_preset != hp:
|
||||
qmsg('Warning: ignoring user-requested hash preset {opt.hash_preset}')
|
||||
qmsg(f'Warning: ignoring user-requested hash preset {opt.hash_preset!r}')
|
||||
|
||||
hash_params = tuple(map(int,hpdata[1:]))
|
||||
|
||||
|
|
|
|||
|
|
@ -27,16 +27,16 @@ from mmgen.wallet import Wallet
|
|||
def crypto():
|
||||
desc = 'test data'
|
||||
|
||||
pw = get_new_passphrase(desc=desc)
|
||||
pw = get_new_passphrase(data_desc=desc,hash_preset=g.dfl_hash_preset,passwd_file=None)
|
||||
msg(f'==> got new passphrase: [{pw}]\n')
|
||||
|
||||
pw = get_passphrase(desc=desc)
|
||||
pw = get_passphrase(data_desc=desc,passwd_file=None)
|
||||
msg(f'==> got passphrase: [{pw}]\n')
|
||||
|
||||
hp = get_hash_preset_from_user(desc=desc)
|
||||
hp = get_hash_preset_from_user(data_desc=desc)
|
||||
msg(f'==> got hash preset: [{hp}]')
|
||||
|
||||
hp = get_hash_preset_from_user(desc=desc)
|
||||
hp = get_hash_preset_from_user(data_desc=desc)
|
||||
msg(f'==> got hash preset: [{hp}]')
|
||||
|
||||
def seed():
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class TestSuiteInput(TestSuiteBase):
|
|||
t.expect('unchanged')
|
||||
|
||||
t.expect('new passphrase.*: ','pass1\n',regex=True)
|
||||
t.expect('peat passphrase: ','pass1\n')
|
||||
t.expect('peat new passphrase: ','pass1\n')
|
||||
t.expect('unchanged')
|
||||
|
||||
t.expect('reuse the label .*: ','\n',regex=True)
|
||||
|
|
@ -90,7 +90,7 @@ class TestSuiteInput(TestSuiteBase):
|
|||
t.expect(' changed to')
|
||||
|
||||
t.expect('new passphrase.*: ','pass2\n',regex=True)
|
||||
t.expect('peat passphrase: ','pass2\n')
|
||||
t.expect('peat new passphrase: ','pass2\n')
|
||||
t.expect(' changed')
|
||||
|
||||
t.expect('reuse the label .*: ','lbl2\n',regex=True)
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
|
|||
t.passphrase(wcls.desc,self.cfgs['1']['wpasswd'],pwtype='old')
|
||||
t.expect_getend('Hash preset changed to ')
|
||||
t.passphrase(wcls.desc,self.wpasswd,pwtype='new') # reuse passphrase?
|
||||
t.expect('Repeat passphrase: ',self.wpasswd+'\n')
|
||||
t.expect('Repeat new passphrase: ',self.wpasswd+'\n')
|
||||
t.usr_rand(self.usr_rand_chars)
|
||||
if label_action == 'user':
|
||||
t.expect('Enter a wallet label.*: ','Interactive Label (UTF-8) α\n',regex=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue