From d817931c04b0340c0d136b8e78d30fa4f98a98bd Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Wed, 30 Mar 2022 15:49:45 +0000 Subject: [PATCH] mmgen-msg: support display of unsigned message files --- mmgen/main_msg.py | 6 ++++ mmgen/msg.py | 57 ++++++++++++++++++++---------------- test/test_py_d/ts_regtest.py | 10 +++++-- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/mmgen/main_msg.py b/mmgen/main_msg.py index 555dd4b4..77cea14e 100755 --- a/mmgen/main_msg.py +++ b/mmgen/main_msg.py @@ -49,6 +49,9 @@ class MsgOps: m.write_to_file( ask_overwrite=False ) + if getattr(m,'failed_sids',None): + sys.exit(1) + class verify(sign): async def __init__(self,msgfile,addr=None): @@ -59,6 +62,9 @@ class MsgOps: await m.verify(addr,summary=True) + if getattr(m,'failed_sids',None): + sys.exit(1) + opts_data = { 'text': { 'desc': 'Perform message signing operations for MMGen addresses', diff --git a/mmgen/msg.py b/mmgen/msg.py index e00be611..f0c6fe08 100755 --- a/mmgen/msg.py +++ b/mmgen/msg.py @@ -147,24 +147,26 @@ class coin_msg: yield fs.format( 'Failed Seed IDs:', red(fmt_list(self.failed_sids,fmt='bare')) ) - yield '' - yield 'Signatures:' - for n,(k,v) in enumerate(self.sigs.items()): + if self.sigs: yield '' - yield '{:>3}) {}'.format(n+1,k) - for res in gen_entry(v): - yield res + yield 'Signatures:' + for n,(k,v) in enumerate(self.sigs.items()): + yield '' + yield '{:>3}) {}'.format(n+1,k) + for res in gen_entry(v): + yield res def gen_single(): fs = '{:8s} {}' for k,v in disp_data.items(): yield fs.format( v[0]+':', v[1](self.data[k]) ) - yield 'Signature data:' - k = MMGenID(self.proto,mmid) - if k not in self.sigs: - die(1,f'{k}: address not found in signature data') - for res in gen_entry(self.sigs[k]): - yield res + if self.sigs: + yield 'Signature data:' + k = MMGenID(self.proto,mmid) + if k not in self.sigs: + die(1,f'{k}: address not found in signature data') + for res in gen_entry(self.sigs[k]): + yield res disp_data = { 'message': ('Message', lambda v: grnbg(v) ), @@ -178,7 +180,9 @@ class coin_msg: return '\n'.join(gen_single()) else: fs2 = ' {:12s} {}' - return 'SIGNED MESSAGE DATA:\n\n ' + '\n '.join(gen_all()) + return ( + '{}SIGNED MESSAGE DATA:\n\n '.format('' if self.sigs else 'UN') + + '\n '.join(gen_all()) ) class unsigned(completed): @@ -256,25 +260,28 @@ class coin_msg: async def verify(self,addr=None,summary=False): - from .rpc import rpc_init - self.rpc = await rpc_init(self.proto) - if addr: mmaddr = MMGenID(self.proto,addr) sigs = {k:v for k,v in self.sigs.items() if k == mmaddr} else: sigs = self.sigs - for k,v in sigs.items(): - ret = await self.do_verify( - addr = v.get('addr_p2pkh') or v['addr'], - sig = v['sig'], - message = self.data['message'] ) - if not ret: - die(3,f'Invalid signature for address {k} ({v["addr"]})') + if sigs: + from .rpc import rpc_init + self.rpc = await rpc_init(self.proto) - if summary: - msg('{} signature{} verified'.format( len(sigs), suf(sigs) )) + for k,v in sigs.items(): + ret = await self.do_verify( + addr = v.get('addr_p2pkh') or v['addr'], + sig = v['sig'], + message = self.data['message'] ) + if not ret: + die(3,f'Invalid signature for address {k} ({v["addr"]})') + + if summary: + msg('{} signature{} verified'.format( len(sigs), suf(sigs) )) + else: + die(1,'No signatures') def _get_obj(clsname,coin=None,network='mainnet',infile=None,data=None,*args,**kwargs): diff --git a/test/test_py_d/ts_regtest.py b/test/test_py_d/ts_regtest.py index dd089784..1ba3f1f7 100755 --- a/test/test_py_d/ts_regtest.py +++ b/test/test_py_d/ts_regtest.py @@ -264,6 +264,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared): ('bob_msgsign_userwallet', 'signing the message file (user-specified wallet)'), ('bob_msgsign_userwallets', 'signing the message file (user-specified wallets)'), ('bob_msgverify', 'verifying the message file (all addresses)'), + ('bob_msgverify_raw', 'verifying the raw message file (all addresses)'), ('bob_msgverify_single', 'verifying the message file (single address)'), ('stop', 'stopping regtest daemon'), @@ -1082,15 +1083,20 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared): fn2 = get_file_with_ext(self.tmpdir,'bip39') return self.bob_msgsign([fn2,fn1]) - def bob_msgverify(self,addr=None): + def bob_msgverify(self,addr=None,ext='sigmsg.json'): return self.spawn( 'mmgen-msg', [ '--bob', f'--outdir={self.tmpdir}', 'verify', - get_file_with_ext(self.tmpdir,'sigmsg.json'), + get_file_with_ext(self.tmpdir,ext), ] + ([addr] if addr else []) ) + def bob_msgverify_raw(self): + t = self.bob_msgverify(ext='rawmsg.json') + t.req_exit_val = 1 + return t + def bob_msgverify_single(self): sid = self._user_sid('bob') return self.bob_msgverify(addr=f'{sid}:{self.dfl_mmtype}:1')