diff --git a/releases/ChangeLog.md b/releases/ChangeLog.md index 473558e3..fecd60e0 100644 --- a/releases/ChangeLog.md +++ b/releases/ChangeLog.md @@ -5,6 +5,12 @@ - Enhancement: Promoted the address explorer to the main menu. It's useful! - Bugfix: zero-length BIP39 passphrase, when saved, would cause a crash when restore attempted. We recommend longer passphrases, but fixed the issue. +- Enhancement: Move the "blockchain" setting deep into the "Danger Zone" and add + warning screen. This mitigates a concern raised by @benma (Marko Bencun) where + an attacker could socially-engineer you to sign a transaction on Testnet, which + corresponds to UTXO on main net being stolen. Only developers should be using + Testnet anyway. + ## 3.1.9 - Aug 6, 2020 diff --git a/shared/actions.py b/shared/actions.py index 743f800a..703c80f3 100644 --- a/shared/actions.py +++ b/shared/actions.py @@ -426,6 +426,18 @@ async def pick_scramble(*a): from menu import start_chooser start_chooser(scramble_keypad_chooser) +async def confirm_testnet_mode(*a): + from choosers import chain_chooser + from menu import start_chooser + from chains import current_chain + + if settings.get('chain') != 'XTN': + if not await ux_confirm("Testnet must only be used by developers because \ +correctly- crafted transactions signed on Testnet could be broadcast on Mainnet."): + return + + start_chooser(chain_chooser) + async def pick_inputs_delete(*a): # Setting: delete input PSBT if await ux_show_story('''\ diff --git a/shared/auth.py b/shared/auth.py index ac1669de..d8018a7f 100644 --- a/shared/auth.py +++ b/shared/auth.py @@ -939,8 +939,7 @@ async def interact(self): def start_bip39_passphrase(pw): - # tell the local user the secret words, and then save to SPI flash - # USB caller has to come back and download encrypted contents. + # new passphrase has come in via USB. offer to switch to it. UserAuthorizedAction.cleanup() UserAuthorizedAction.active_request = NewPassphrase(pw) diff --git a/shared/choosers.py b/shared/choosers.py index 87f77bca..f87a1cd7 100644 --- a/shared/choosers.py +++ b/shared/choosers.py @@ -81,6 +81,7 @@ def set_login_countdown(idx, text): def chain_chooser(): + # Pick Bitcoin or Testnet3 blockchains from chains import AllChains chain = settings.get('chain', 'BTC') diff --git a/shared/flow.py b/shared/flow.py index 1eff73a7..f5371fb4 100644 --- a/shared/flow.py +++ b/shared/flow.py @@ -63,7 +63,6 @@ def has_secrets(): MenuItem('Set Nickname', f=pick_nickname), MenuItem('Scramble Keypad', f=pick_scramble), MenuItem('Delete PSBTs', f=pick_inputs_delete), - MenuItem('Blockchain', chooser=chain_chooser), ] WalletExportMenu = [ @@ -143,6 +142,7 @@ def has_secrets(): MenuItem("Set High-Water", f=set_highwater), MenuItem('Wipe HSM Policy', f=wipe_hsm_policy, predicate=hsm_policy_available), MenuItem('Clear OV cache', f=wipe_ovc), + MenuItem('Testnet Mode', f=confirm_testnet_mode), MenuItem('Settings space', f=show_settings_space), ] diff --git a/shared/menu.py b/shared/menu.py index c63e3e1f..c6714de2 100644 --- a/shared/menu.py +++ b/shared/menu.py @@ -16,7 +16,7 @@ def start_chooser(chooser): # get which one to show as selected, list of choices, and fcn to call after selected, choices, setter = chooser() - def picked(menu, picked, xx_self): + async def picked(menu, picked, xx_self): menu.chosen = picked menu.show() await sleep_ms(100) # visual feedback that we changed it diff --git a/testing/test_pwsave.py b/testing/test_pwsave.py index 70228eae..38da6bb9 100644 --- a/testing/test_pwsave.py +++ b/testing/test_pwsave.py @@ -43,6 +43,7 @@ def doit(): 'aBc1 aBc2 aBc3', 'abcd defg', '1aaa 2aaa', + '1aaa2aaa', 'ab'*25, ]) def test_first_time(pws, need_keypress, cap_story, pick_menu_item, goto_home, enter_complex, cap_menu, get_to_pwmenu): diff --git a/testing/test_sign.py b/testing/test_sign.py index 3a06428c..de03d668 100644 --- a/testing/test_sign.py +++ b/testing/test_sign.py @@ -309,10 +309,11 @@ def EncodeDecimal(o): network = a2b_hex(resp['hex']) # assert resp['complete'] - #print("Final txn: %r" % network) + print("Final txn: %r" % network) open('debug/finalized-by-btcd.txn', 'wb').write(network) # try to send it + assert 0 txed = bitcoind.sendrawtransaction(B2A(network)) print("Final txn hash: %r" % txed) @@ -321,6 +322,7 @@ def EncodeDecimal(o): #print("Final txn: %s" % B2A(signed)) open('debug/finalized-by-cc.txn', 'wb').write(signed) + assert 0 txed = bitcoind.sendrawtransaction(B2A(signed)) print("Final txn hash: %r" % txed)