Regression fix in addr.py, improvements in mmgen-txsign.
This commit is contained in:
parent
2b183c18f3
commit
ea449e652a
8 changed files with 72 additions and 70 deletions
|
|
@ -80,7 +80,8 @@ def generate_addrs(seed, addrnums, opts):
|
|||
addrnums.sort() # needed only if caller didn't sort
|
||||
|
||||
ws = 'key' if 'keys' in opts['gen_what'] else 'address'
|
||||
if t_addrs != 1: wp = ws+"s" if ws == 'key' else ws+"es"
|
||||
if t_addrs == 1: wp = ws
|
||||
else: wp = ws+"s" if ws == 'key' else ws+"es"
|
||||
|
||||
while pos != t_addrs:
|
||||
seed = sha512(seed).digest()
|
||||
|
|
|
|||
|
|
@ -369,10 +369,11 @@ def _get_seed_from_brain_passphrase(words,opts):
|
|||
# Vars for mmgen_*crypt functions only
|
||||
salt_len,sha256_len,nonce_len = 32,32,32
|
||||
|
||||
def mmgen_encrypt(data,what="data",hash_preset='3',opts={}):
|
||||
def mmgen_encrypt(data,what="data",hash_preset='',opts={}):
|
||||
salt,iv,nonce = get_random(salt_len,opts),\
|
||||
get_random(g.aesctr_iv_len,opts), get_random(nonce_len,opts)
|
||||
hp,m = (hash_preset,"user-requested") if hash_preset else ('3',"default")
|
||||
hp = hash_preset or get_hash_preset_from_user('3',what)
|
||||
m = "default" if hp == '3' else "user-requested"
|
||||
vmsg("Encrypting %s" % what)
|
||||
qmsg("Using %s hash preset of '%s'" % (m,hp))
|
||||
passwd = get_new_passphrase("passphrase",{})
|
||||
|
|
@ -382,11 +383,12 @@ def mmgen_encrypt(data,what="data",hash_preset='3',opts={}):
|
|||
return salt+iv+enc_d
|
||||
|
||||
|
||||
def mmgen_decrypt(data,what="data",hash_preset='3',opts={}):
|
||||
def mmgen_decrypt(data,what="data",hash_preset='',opts={}):
|
||||
dstart = salt_len + g.aesctr_iv_len
|
||||
salt,iv,enc_d = data[:salt_len],data[salt_len:dstart],data[dstart:]
|
||||
hp,m = (hash_preset,"user-requested") if hash_preset else ('3',"default")
|
||||
vmsg("Preparing to decrypt %s" % what)
|
||||
hp = hash_preset or get_hash_preset_from_user('3',what)
|
||||
m = "default" if hp == '3' else "user-requested"
|
||||
qmsg("Using %s hash preset of '%s'" % (m,hp))
|
||||
passwd = get_mmgen_passphrase("Enter passphrase: ",{})
|
||||
key = make_key(passwd, salt, hp)
|
||||
|
|
|
|||
|
|
@ -20,25 +20,24 @@
|
|||
main.py - Script launcher for the MMGen suite
|
||||
"""
|
||||
|
||||
import sys, termios
|
||||
from mmgen.util import msg
|
||||
def launch_addrgen(): import mmgen.main_addrgen
|
||||
def launch_addrimport(): import mmgen.main_addrimport
|
||||
def launch_keygen(): import mmgen.main_addrgen
|
||||
def launch_passchg(): import mmgen.main_passchg
|
||||
def launch_pywallet(): import mmgen.main_pywallet
|
||||
def launch_tool(): import mmgen.main_tool
|
||||
def launch_txcreate(): import mmgen.main_txcreate
|
||||
def launch_txsend(): import mmgen.main_txsend
|
||||
def launch_txsign(): import mmgen.main_txsign
|
||||
def launch_walletchk(): import mmgen.main_walletchk
|
||||
def launch_walletgen(): import mmgen.main_walletgen
|
||||
|
||||
def main(progname):
|
||||
import sys, termios
|
||||
fd = sys.stdin.fileno()
|
||||
old = termios.tcgetattr(fd)
|
||||
try:
|
||||
if progname == "addrgen": import mmgen.main_addrgen
|
||||
elif progname == "addrimport": import mmgen.main_addrimport
|
||||
elif progname == "keygen": import mmgen.main_addrgen
|
||||
elif progname == "passchg": import mmgen.main_passchg
|
||||
elif progname == "pywallet": import mmgen.main_pywallet
|
||||
elif progname == "tool": import mmgen.main_tool
|
||||
elif progname == "txcreate": import mmgen.main_txcreate
|
||||
elif progname == "txsend": import mmgen.main_txsend
|
||||
elif progname == "txsign": import mmgen.main_txsign
|
||||
elif progname == "walletchk": import mmgen.main_walletchk
|
||||
elif progname == "walletgen": import mmgen.main_walletgen
|
||||
try: eval("launch_"+progname+"()")
|
||||
except KeyboardInterrupt:
|
||||
msg("\nUser interrupt")
|
||||
sys.stderr.write("\nUser interrupt\n")
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -161,8 +161,7 @@ addr_data_str = format_addr_data(
|
|||
outfile_base = "{}[{}]".format(seed_id, fmt_addr_idxs(addr_idxs))
|
||||
|
||||
if 'flat_list' in opts and user_confirm("Encrypt key list?"):
|
||||
hp = get_hash_preset_from_user('3')
|
||||
addr_data_str = mmgen_encrypt(addr_data_str,"key list",hp,opts)
|
||||
addr_data_str = mmgen_encrypt(addr_data_str,"key list","",opts)
|
||||
enc_ext = "." + g.mmenc_ext
|
||||
else: enc_ext = ""
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ if 'from_incog_hex' in opts or 'from_incog_hidden' in opts:
|
|||
opts['from_incog'] = True
|
||||
if 'all_keys_from_file' in opts:
|
||||
opts['keys_from_file'] = opts['all_keys_from_file']
|
||||
# opts['skip_key_preverify'] = True
|
||||
|
||||
if not infiles: usage(help_data)
|
||||
for i in infiles: check_infile(i)
|
||||
|
|
@ -110,20 +109,19 @@ c = connect_to_bitcoind()
|
|||
saved_seeds = {}
|
||||
tx_files = [i for i in set(infiles) if get_extension(i) == g.rawtx_ext]
|
||||
addrfiles = [a for a in set(infiles) if get_extension(a) == g.addrfile_ext]
|
||||
infiles = list(set(infiles) - set(tx_files) - set(addrfiles))
|
||||
seed_files = list(set(infiles) - set(tx_files) - set(addrfiles))
|
||||
|
||||
if not "info" in opts: do_license_msg(immed=True)
|
||||
|
||||
if 'keys_from_file' in opts:
|
||||
from mmgen.crypto import mmgen_decrypt
|
||||
fn = opts['keys_from_file']
|
||||
d = get_data_from_file(fn,"keylist")
|
||||
if get_extension(fn) == g.mmenc_ext or not \
|
||||
is_b58_str(remove_comments(d.split("\n"))[0][:55]):
|
||||
is_btc_key(remove_comments(d.split("\n"))[0][:55]):
|
||||
qmsg("Keylist appears to be encrypted")
|
||||
from mmgen.crypto import mmgen_decrypt
|
||||
while True:
|
||||
hp = get_hash_preset_from_user('3')
|
||||
d_dec = mmgen_decrypt(d,"encrypted keylist",hp,opts)
|
||||
d_dec = mmgen_decrypt(d,"encrypted keylist","",opts)
|
||||
if d_dec: d = d_dec; break
|
||||
else: msg("Trying again...")
|
||||
keys_from_file = remove_comments(d.split("\n"))
|
||||
|
|
@ -157,8 +155,9 @@ for tx_file in tx_files:
|
|||
sys.exit(2)
|
||||
|
||||
if other_inputs and keys and not 'skip_key_preverify' in opts:
|
||||
a = [i['address'] for i in other_inputs]
|
||||
preverify_keys(a, keys)
|
||||
addrs = [i['address'] for i in other_inputs]
|
||||
mm_inputs = mmgen_inputs if 'all_keys_from_file' in opts else []
|
||||
preverify_keys(addrs, keys, mm_inputs)
|
||||
opts['skip_key_preverify'] = True
|
||||
|
||||
if 'all_keys_from_file' in opts:
|
||||
|
|
@ -168,7 +167,7 @@ for tx_file in tx_files:
|
|||
confirm_or_exit(txmsg['skip_mapping_checks_warning'],"continue")
|
||||
else:
|
||||
check_mmgen_to_btc_addr_mappings(
|
||||
mmgen_inputs,b2m_map,infiles,saved_seeds,opts)
|
||||
mmgen_inputs,b2m_map,seed_files,saved_seeds,opts)
|
||||
|
||||
if len(tx_files) > 1:
|
||||
msg("\nTransaction %s/%s:" % (tx_files.index(tx_file)+1,len(tx_files)))
|
||||
|
|
@ -185,7 +184,7 @@ for tx_file in tx_files:
|
|||
|
||||
if mmgen_inputs and not 'all_keys_from_file' in opts:
|
||||
ml = [i['account'].split()[0] for i in mmgen_inputs]
|
||||
keys += get_keys_for_mmgen_addrs(ml,infiles,saved_seeds,opts)
|
||||
keys += get_keys_for_mmgen_addrs(ml,seed_files,saved_seeds,opts)
|
||||
|
||||
if 'use_wallet_dat' in opts:
|
||||
sig_tx = sign_tx_with_bitcoind_wallet(c,tx_hex,sig_data,keys,opts)
|
||||
|
|
@ -207,7 +206,8 @@ for tx_file in tx_files:
|
|||
repr(inputs_data),
|
||||
repr(b2m_map)
|
||||
)
|
||||
write_to_file(outfile,data,opts,"signed transaction",True,True)
|
||||
confirm = False if g.quiet else True
|
||||
write_to_file(outfile,data,opts,"signed transaction",confirm,True)
|
||||
else:
|
||||
msg("failed\nSome keys were missing. Transaction could not be signed.")
|
||||
sys.exit(3)
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ commands = {
|
|||
"pubkey2addr": ['<public key in hex format> [str]'],
|
||||
"pubkey2hexaddr": ['<public key in hex format> [str]'],
|
||||
"privhex2addr": ['<private key in hex format> [str]','compressed [bool=False]'],
|
||||
"encrypt": ['<infile> [str]','outfile [str=""]','hash_preset [str="3"]'],
|
||||
"decrypt": ['<infile> [str]','outfile [str=""]','hash_preset [str="3"]'],
|
||||
"encrypt": ['<infile> [str]','outfile [str=""]','hash_preset [str=""]'],
|
||||
"decrypt": ['<infile> [str]','outfile [str=""]','hash_preset [str=""]'],
|
||||
"rand2file": ['<outfile> [str]','<nbytes> [str]','threads [int=4]'],
|
||||
"bytespec": ['<bytespec> [str]'],
|
||||
}
|
||||
|
|
@ -416,9 +416,9 @@ def hex2wif(hexpriv,compressed=False):
|
|||
print bitcoin.hextowif(hexpriv,compressed)
|
||||
|
||||
|
||||
def encrypt(infile,outfile="",hash_preset='3'):
|
||||
def encrypt(infile,outfile="",hash_preset=''):
|
||||
data = get_data_from_file(infile,"data for encryption")
|
||||
enc_d = mmgen_encrypt(data,"",hash_preset,opts)
|
||||
enc_d = mmgen_encrypt(data,"user data","",opts)
|
||||
if outfile == '-':
|
||||
write_to_stdout(enc_d,"encrypted data",confirm=True)
|
||||
else:
|
||||
|
|
@ -427,9 +427,9 @@ def encrypt(infile,outfile="",hash_preset='3'):
|
|||
write_to_file(outfile, enc_d, opts,"encrypted data",True,True)
|
||||
|
||||
|
||||
def decrypt(infile,outfile="",hash_preset='3'):
|
||||
def decrypt(infile,outfile="",hash_preset=''):
|
||||
enc_d = get_data_from_file(infile,"encrypted data")
|
||||
dec_d = mmgen_decrypt(enc_d,"",hash_preset,opts)
|
||||
dec_d = mmgen_decrypt(enc_d,"user data","",opts)
|
||||
if outfile == '-':
|
||||
write_to_stdout(dec_d,"decrypted data",confirm=True)
|
||||
else:
|
||||
|
|
|
|||
44
mmgen/tx.py
44
mmgen/tx.py
|
|
@ -137,6 +137,7 @@ def is_btc_amt(amt):
|
|||
|
||||
|
||||
def normalize_btc_amt(amt):
|
||||
# amt must be a string!
|
||||
ret = is_btc_amt(amt)
|
||||
if ret: return ret
|
||||
else: sys.exit(3)
|
||||
|
|
@ -460,10 +461,15 @@ def is_b58_str(s):
|
|||
if ch not in b58a: return False
|
||||
return True
|
||||
|
||||
def is_btc_key(s):
|
||||
if s == "": return False
|
||||
compressed = False if s[0] == '5' else True
|
||||
from mmgen.bitcoin import wiftohex
|
||||
return True if wiftohex(s,compressed) else False
|
||||
|
||||
def mmaddr2btcaddr_bitcoind(c,mmaddr,acct_data):
|
||||
|
||||
# We don't want to create a new object, so we'll use append()
|
||||
# Don't want to create a new object, so use append()
|
||||
if not acct_data:
|
||||
for i in c.listaccounts():
|
||||
acct_data.append(i)
|
||||
|
|
@ -677,31 +683,21 @@ def sign_tx_with_bitcoind_wallet(c,tx_hex,sig_data,keys,opts):
|
|||
return sig_tx
|
||||
|
||||
|
||||
def preverify_keys(addrs_orig, keys_orig):
|
||||
def preverify_keys(addrs_in, keys_in, mm_inputs):
|
||||
|
||||
addrs,keys,wrong_keys = set(addrs_orig[0:]),set(keys_orig[0:]),[]
|
||||
|
||||
if len(keys) < len(addrs):
|
||||
msg("ERROR: not enough keys (%s) for number of non-%s addresses (%s)" %
|
||||
(len(keys),g.proj_name,len(addrs)))
|
||||
sys.exit(2)
|
||||
addrs,keys,extra_keys = set(addrs_in),set(keys_in),[]
|
||||
|
||||
import mmgen.bitcoin as b
|
||||
|
||||
qmsg_r('Checking that user-supplied key list contains valid keys...')
|
||||
|
||||
invalid_keys = []
|
||||
|
||||
for n,k in enumerate(keys,1):
|
||||
c = False if k[0] == '5' else True
|
||||
if b.wiftohex(k,compressed=c) == False:
|
||||
invalid_keys.append(k)
|
||||
|
||||
invalid_keys = [k for k in keys if not is_btc_key(k)]
|
||||
if invalid_keys:
|
||||
s = "" if len(invalid_keys) == 1 else "s"
|
||||
msg("\n%s/%s invalid key%s in keylist!\n" % (len(invalid_keys),len(keys),s))
|
||||
sys.exit(2)
|
||||
else: qmsg("OK")
|
||||
|
||||
qmsg("OK")
|
||||
|
||||
# Check that keys match addresses:
|
||||
msg('Pre-verifying keys in user-supplied key list (Ctrl-C to skip)')
|
||||
|
|
@ -716,19 +712,23 @@ def preverify_keys(addrs_orig, keys_orig):
|
|||
addrs.remove(addr)
|
||||
if not addrs: break
|
||||
else:
|
||||
wrong_keys.append(k)
|
||||
extra_keys.append(k)
|
||||
except KeyboardInterrupt:
|
||||
msg("\nSkipping")
|
||||
else:
|
||||
msg("")
|
||||
if wrong_keys:
|
||||
s = "" if len(wrong_keys) == 1 else "s"
|
||||
msg("%s extra key%s found" % (len(wrong_keys),s))
|
||||
if extra_keys:
|
||||
s = "" if len(extra_keys) == 1 else "s"
|
||||
msg("%s extra key%s found" % (len(extra_keys),s))
|
||||
|
||||
if addrs:
|
||||
mms = dict([(i['address'],i['account'].split()[0])
|
||||
for i in mm_inputs if i['address'] in addrs])
|
||||
s = "" if len(addrs) == 1 else "es"
|
||||
msg("No keys found for the following address%s:" % s)
|
||||
print " %s" % "\n ".join(addrs)
|
||||
msg(
|
||||
"Cannot sign transaction. No keys found for the following address%s:"%s)
|
||||
for a in sorted(addrs):
|
||||
print " %s%s" % (a, " ({})".format(mms[a]) if a in mms else "")
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -347,14 +347,14 @@ def write_to_file(outfile,data,opts,what="data",confirm_overwrite=False,verbose=
|
|||
|
||||
if 'outdir' in opts: outfile = make_full_path(opts['outdir'],outfile)
|
||||
|
||||
if confirm_overwrite:
|
||||
from os import stat
|
||||
try:
|
||||
stat(outfile)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
from os import stat
|
||||
try: stat(outfile)
|
||||
except: pass
|
||||
else:
|
||||
if confirm_overwrite:
|
||||
confirm_or_exit("","File '%s' already exists\nOverwrite?" % outfile)
|
||||
else:
|
||||
msg("Overwriting file '%s'" % outfile)
|
||||
|
||||
f = open_file_or_exit(outfile,'w')
|
||||
try:
|
||||
|
|
@ -685,8 +685,9 @@ def export_to_hidden_incog(incog_enc,opts):
|
|||
|
||||
from mmgen.term import kb_hold_protect,get_char
|
||||
|
||||
def get_hash_preset_from_user(hp='3'):
|
||||
p = "Enter hash preset, or hit ENTER to accept the default ('%s'): " % hp
|
||||
def get_hash_preset_from_user(hp='3',what="data"):
|
||||
p = "Enter hash preset for %s, or ENTER to accept the default ('%s'): " \
|
||||
% (what,hp)
|
||||
while True:
|
||||
ret = my_raw_input(p)
|
||||
if ret:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue