From 554703e541a6d26fac2eb04db0f14518a325caa6 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sat, 26 Oct 2019 12:06:46 +0000 Subject: [PATCH] bip39, baseconv: don't leak private data in error messages --- mmgen/bip39.py | 10 +++++----- mmgen/util.py | 12 ++++++------ test/unit_tests_d/ut_baseconv.py | 6 ++++++ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/mmgen/bip39.py b/mmgen/bip39.py index b454cf5e..1dc180f1 100755 --- a/mmgen/bip39.py +++ b/mmgen/bip39.py @@ -2114,9 +2114,9 @@ zoo wl = cls.digits[wl_id] - for w in words: - if w not in wl: - raise MnemonicError('{!r} is not in the BIP39 word list'.format(w)) + for n in range(len(words)): + if words[n] not in wl: + raise MnemonicError('word #{} is not in the BIP39 word list'.format(n+1)) res = ''.join(['{:011b}'.format(wl.index(w)) for w in words]) @@ -2141,13 +2141,13 @@ zoo chk_bin_chk = '{:0{w}b}'.format(int(chk_hex_chk,16),w=256)[:chk_len] if chk_bin != chk_bin_chk: - raise MnemonicError('{}: invalid checksum (should be {})'.format(chk_bin,chk_bin_chk)) + raise MnemonicError('invalid seed phrase checksum') return seed_hex @classmethod def fromhex(cls,seed_hex,wl_id,pad=None,tostr=False): - assert is_hex_str(seed_hex),"{!r}: not a hexadecimal string".format(seed_hex) + assert is_hex_str(seed_hex),'seed data not a hexadecimal string' assert wl_id == 'bip39',"'wl_id' must be 'bip39'" assert tostr == False,"'tostr' must be False for 'bip39'" diff --git a/mmgen/util.py b/mmgen/util.py index 84fb98d9..9dc5556e 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -378,16 +378,16 @@ class baseconv(object): raise BaseConversionError(m.format(len(words),wl_id)) return d[len(words)] * 2 - pad = max(cls.get_pad(pad,get_seed_pad),2) + pad_val = max(cls.get_pad(pad,get_seed_pad),2) wl = cls.digits[wl_id] base = len(wl) if not set(words) <= set(wl): - m = '{!r}: not in {} (base{}) format' - raise BaseConversionError(m.format(words_arg,wl_id,base)) + m = ('{w!r}:','seed data')[pad=='seed'] + ' not in {i} (base{b}) format' + raise BaseConversionError(m.format(w=words_arg,i=wl_id,b=base)) deconv = [wl.index(words[::-1][i])*(base**i) for i in range(len(words))] - ret = ('{:0{w}x}'.format(sum(deconv),w=pad)) + ret = ('{:0{w}x}'.format(sum(deconv),w=pad_val)) return (('','0')[len(ret) % 2] + ret) @classmethod @@ -397,8 +397,8 @@ class baseconv(object): assert tostr == False,"'tostr' must be False for '{}'".format(wl_id) if not is_hex_str(hexstr): - m = '{!r}: not a hexadecimal string' - raise HexadecimalStringError(m.format(hexstr)) + m = ('{h!r}:','seed data')[pad=='seed'] + ' not a hexadecimal string' + raise HexadecimalStringError(m.format(h=hexstr)) if not hexstr: m = 'empty hex strings not allowed in base conversion' diff --git a/test/unit_tests_d/ut_baseconv.py b/test/unit_tests_d/ut_baseconv.py index cf19aadc..5edcc5b4 100755 --- a/test/unit_tests_d/ut_baseconv.py +++ b/test/unit_tests_d/ut_baseconv.py @@ -148,12 +148,18 @@ class unit_test(object): vmsg('') qmsg('Checking error handling:') + bad_b58 = 'I'*22 + bad_b58len = 'a'*23 + th = baseconv.tohex fh = baseconv.fromhex bad_data = ( ('hexstr', 'HexadecimalStringError', ': not a hexadecimal str', lambda:fh('x','b58')), +('hexstr (seed)', 'HexadecimalStringError', 'seed data not a hexadec', lambda:fh('x','b58',pad='seed')), ('hexstr (empty)', 'HexadecimalStringError', 'empty hex strings not', lambda:fh('','b58')), ('b58 data', 'BaseConversionError', ': not in b58', lambda:th('IfFzZ','b58')), +('b58 data (seed)', 'BaseConversionError', 'seed data not in b58', lambda:th(bad_b58,'b58',pad='seed')), +('b58 len (seed)', 'BaseConversionError', 'invalid length for', lambda:th(bad_b58len,'b58',pad='seed')), ('b58 data (empty)','BaseConversionError', 'empty b58 data', lambda:th('','b58')), ('b8 data (empty)' ,'BaseConversionError', 'empty b8 data', lambda:th('','b8')), ('b32 data', 'BaseConversionError', 'not in b32', lambda:th('1az','b32')),