ct_tool.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/usr/bin/env python3
  2. #
  3. # MMGen Wallet, a terminal-based cryptocurrency wallet
  4. # Copyright (C)2013-2024 The MMGen Project <mmgen@tuta.io>
  5. #
  6. # Project source code repository: https://github.com/mmgen/mmgen-wallet
  7. # Licensed according to the terms of GPL Version 3. See LICENSE for details.
  8. """
  9. test.cmdtest_d.ct_tool: tool tests for the MMGen cmdtest.py test suite
  10. """
  11. import sys, os
  12. from mmgen.util import suf
  13. from mmgen.color import cyan
  14. from ..include.common import (
  15. cfg,
  16. vmsg,
  17. read_from_file,
  18. write_to_file,
  19. cmp_or_die,
  20. joinpath,
  21. getrand
  22. )
  23. from .common import hincog_fn, incog_id_fn, hincog_offset, tool_enc_passwd, ref_dir
  24. from .ct_base import CmdTestBase
  25. from .ct_main import CmdTestMain
  26. class CmdTestTool(CmdTestMain, CmdTestBase):
  27. "interactive 'mmgen-tool' commands"
  28. networks = ('btc',)
  29. segwit_opts_ok = False
  30. tmpdir_nums = [9]
  31. enc_infn = 'tool_encrypt.in'
  32. cmd_group = (
  33. ('tool_find_incog_data',
  34. (9, '‘mmgen-tool find_incog_data’', [[[hincog_fn], 1], [[incog_id_fn], 1]])
  35. ),
  36. ('tool_rand2file',
  37. (9, '‘mmgen-tool rand2file’', [])
  38. ),
  39. ('tool_encrypt',
  40. (9, '‘mmgen-tool encrypt’ (random data)', [])
  41. ),
  42. ('tool_decrypt',
  43. (9, '‘mmgen-tool decrypt’ (random data)', [[[enc_infn+'.mmenc'], 9]])
  44. ),
  45. ('tool_twview_bad_comment',
  46. (9, '‘mmgen-tool twview’ (with bad comment)', [])
  47. ),
  48. ('tool_decrypt_keystore',
  49. (9, '‘mmgen-tool decrypt_keystore’', [])
  50. ),
  51. ('tool_decrypt_geth_keystore',
  52. (9, '‘mmgen-tool decrypt_geth_keystore’', [])
  53. ),
  54. ('tool_api',
  55. (9, 'tool API (initialization, config methods, wif2addr)', [])
  56. ),
  57. # ('tool_encrypt_ref', (9, '‘mmgen-tool encrypt’ (reference text)', [])),
  58. )
  59. def tool_rand2file(self):
  60. from mmgen.util2 import parse_bytespec
  61. for nbytes in ('1', '1023', '1K', '1048575', '1M', '1048577', '123M'):
  62. t = self.spawn(
  63. 'mmgen-tool',
  64. ['-d', self.tmpdir, '-r0', 'rand2file', 'rand2file.out', nbytes],
  65. extra_desc='({} byte{})'.format(nbytes, suf(parse_bytespec(nbytes)))
  66. )
  67. t.expect('random data written to file')
  68. t.read()
  69. t.p.wait()
  70. t.ok()
  71. t.skip_ok = True
  72. return t
  73. def tool_encrypt(self):
  74. infile = joinpath(self.tmpdir, self.enc_infn)
  75. write_to_file(infile, getrand(1033), binary=True)
  76. t = self.spawn('mmgen-tool', ['-d', self.tmpdir, self.usr_rand_arg, 'encrypt', infile])
  77. t.usr_rand(self.usr_rand_chars)
  78. t.hash_preset('data', '1')
  79. t.passphrase_new('data', tool_enc_passwd)
  80. t.written_to_file('Encrypted data')
  81. return t
  82. def tool_decrypt(self, f1):
  83. out_fn = 'tool_encrypt.out'
  84. t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'decrypt', f1, 'outfile='+out_fn, 'hash_preset=1'])
  85. t.passphrase('data', tool_enc_passwd)
  86. t.written_to_file('Decrypted data')
  87. d1 = self.read_from_tmpfile(self.enc_infn, binary=True)
  88. d2 = self.read_from_tmpfile(out_fn, binary=True)
  89. cmp_or_die(d1, d2)
  90. return t
  91. def tool_find_incog_data(self, f1, f2):
  92. i_id = read_from_file(f2).rstrip()
  93. vmsg(f'Incog ID: {cyan(i_id)}')
  94. t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'find_incog_data', f1, i_id])
  95. o = t.expect_getend(f'Incog data for ID {i_id} found at offset ')
  96. if not sys.platform == 'win32':
  97. os.unlink(f1) # causes problems with MSYS2
  98. cmp_or_die(hincog_offset, int(o))
  99. return t
  100. def tool_twview_bad_comment(self): # test correct operation of get_tw_label()
  101. t = self.spawn(
  102. 'mmgen-tool',
  103. ['twview'],
  104. env = {'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir, 'bad-comment-unspent.json')},
  105. exit_val = 2)
  106. t.expect('cannot be converted to TwComment')
  107. return t
  108. def _decrypt_keystore(self, cmd, fn, pw, chk):
  109. if cfg.no_altcoin:
  110. return 'skip'
  111. t = self.spawn('mmgen-tool', ['-d', self.tmpdir, cmd, fn])
  112. t.expect('Enter passphrase: ', pw+'\n')
  113. t.expect(chk)
  114. return t
  115. def tool_decrypt_keystore(self):
  116. return self._decrypt_keystore(
  117. cmd = 'decrypt_keystore',
  118. fn = 'test/ref/altcoin/98831F3A-keystore-wallet.json',
  119. pw = 'abc',
  120. chk = read_from_file('test/ref/98831F3A.bip39').strip())
  121. def tool_decrypt_geth_keystore(self):
  122. return self._decrypt_keystore(
  123. cmd = 'decrypt_geth_keystore',
  124. fn = 'test/ref/ethereum/geth-wallet.json',
  125. pw = '',
  126. chk = '9627ddb68354f5e0ff45fb2da49d7a20a013b7257a83ef4adbbbd87aeaccc75e')
  127. def tool_api(self):
  128. t = self.spawn(
  129. 'tool_api_test.py',
  130. (['no_altcoin'] if cfg.no_altcoin else []),
  131. cmd_dir = 'test/misc')
  132. t.expect('legacy.*compressed.*segwit.*bech32', regex=True)
  133. return t