ct_tool.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
  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_py_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', (9,"'mmgen-tool find_incog_data'", [[[hincog_fn],1],[[incog_id_fn],1]])),
  34. ('tool_rand2file', (9,"'mmgen-tool rand2file'", [])),
  35. ('tool_encrypt', (9,"'mmgen-tool encrypt' (random data)", [])),
  36. ('tool_decrypt', (9,"'mmgen-tool decrypt' (random data)", [[[enc_infn+'.mmenc'],9]])),
  37. ('tool_twview_bad_comment',(9,"'mmgen-tool twview' (with bad comment)", [])),
  38. ('tool_decrypt_keystore',(9,"'mmgen-tool decrypt_keystore'", [])),
  39. ('tool_decrypt_geth_keystore',(9,"'mmgen-tool decrypt_geth_keystore'", [])),
  40. ('tool_api', (9,'tool API (initialization, config methods, wif2addr)',[])),
  41. # ('tool_encrypt_ref', (9,"'mmgen-tool encrypt' (reference text)", [])),
  42. )
  43. def tool_rand2file(self):
  44. from mmgen.util2 import parse_bytespec
  45. for nbytes in ('1','1023','1K','1048575','1M','1048577','123M'):
  46. t = self.spawn(
  47. 'mmgen-tool',
  48. ['-d',self.tmpdir,'-r0','rand2file','rand2file.out',nbytes],
  49. extra_desc='({} byte{})'.format( nbytes, suf(parse_bytespec(nbytes)) )
  50. )
  51. t.expect('random data written to file')
  52. t.read()
  53. t.p.wait()
  54. t.ok()
  55. t.skip_ok = True
  56. return t
  57. def tool_encrypt(self):
  58. infile = joinpath(self.tmpdir,self.enc_infn)
  59. write_to_file(infile,getrand(1033),binary=True)
  60. t = self.spawn('mmgen-tool',['-d',self.tmpdir,self.usr_rand_arg,'encrypt',infile])
  61. t.usr_rand(self.usr_rand_chars)
  62. t.hash_preset('data','1')
  63. t.passphrase_new('data',tool_enc_passwd)
  64. t.written_to_file('Encrypted data')
  65. return t
  66. def tool_decrypt(self,f1):
  67. out_fn = 'tool_encrypt.out'
  68. t = self.spawn('mmgen-tool',['-d',self.tmpdir,'decrypt',f1,'outfile='+out_fn,'hash_preset=1'])
  69. t.passphrase('data',tool_enc_passwd)
  70. t.written_to_file('Decrypted data')
  71. d1 = self.read_from_tmpfile(self.enc_infn,binary=True)
  72. d2 = self.read_from_tmpfile(out_fn,binary=True)
  73. cmp_or_die(d1,d2)
  74. return t
  75. def tool_find_incog_data(self,f1,f2):
  76. i_id = read_from_file(f2).rstrip()
  77. vmsg(f'Incog ID: {cyan(i_id)}')
  78. t = self.spawn('mmgen-tool',['-d',self.tmpdir,'find_incog_data',f1,i_id])
  79. o = t.expect_getend(f'Incog data for ID {i_id} found at offset ')
  80. if not sys.platform == 'win32':
  81. os.unlink(f1) # causes problems with MSYS2
  82. cmp_or_die(hincog_offset,int(o))
  83. return t
  84. def tool_twview_bad_comment(self): # test correct operation of get_tw_label()
  85. t = self.spawn(
  86. 'mmgen-tool',
  87. ['twview'],
  88. env = { 'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir,'bad-comment-unspent.json') })
  89. t.expect('cannot be converted to TwComment')
  90. t.req_exit_val = 2
  91. return t
  92. def _decrypt_keystore(self,cmd,fn,pw,chk):
  93. if cfg.no_altcoin:
  94. return 'skip'
  95. t = self.spawn('mmgen-tool',['-d',self.tmpdir,cmd,fn])
  96. t.expect('Enter passphrase: ',pw+'\n')
  97. t.expect(chk)
  98. return t
  99. def tool_decrypt_keystore(self):
  100. return self._decrypt_keystore(
  101. cmd = 'decrypt_keystore',
  102. fn = 'test/ref/altcoin/98831F3A-keystore-wallet.json',
  103. pw = 'abc',
  104. chk = read_from_file('test/ref/98831F3A.bip39') )
  105. def tool_decrypt_geth_keystore(self):
  106. return self._decrypt_keystore(
  107. cmd = 'decrypt_geth_keystore',
  108. fn = 'test/ref/ethereum/geth-wallet.json',
  109. pw = '',
  110. chk = '9627ddb68354f5e0ff45fb2da49d7a20a013b7257a83ef4adbbbd87aeaccc75e')
  111. def tool_api(self):
  112. t = self.spawn(
  113. 'tool_api_test.py',
  114. (['no_altcoin'] if cfg.no_altcoin else []),
  115. cmd_dir = 'test/misc' )
  116. t.expect('legacy.*compressed.*segwit.*bech32',regex=True)
  117. return t