def __enter__(self): args = [self.executable] env = ENV if self.gen == "core": args += ["-m", "main"] # for firmware 2.1.2 and newer env["TREZOR_PROFILE_DIR"] = self.workdir.name # for firmware 2.1.1 and older env["TREZOR_PROFILE"] = self.workdir.name self.process = subprocess.Popen(args, cwd=self.workdir.name, env=env, stdout=open(os.devnull, "w")) # wait until emulator is listening for _ in range(300): try: time.sleep(0.1) transport = get_transport("udp:127.0.0.1:21324") break except TransportException: pass if self.process.poll() is not None: self._cleanup() raise RuntimeError("Emulator proces died") else: # could not connect after 300 attempts * 0.1s = 30s of waiting self._cleanup() raise RuntimeError("Can't connect to emulator") self.client = TrezorClientDebugLink(transport) self.client.open() check_version(self.tag, self.client.version) return self
def test_wipe_device(client: Client): _assert_protection(client) with client: client.set_expected_responses( [messages.ButtonRequest, messages.Success, messages.Features] ) device.wipe(client)
def test_reset_device(client: Client): assert client.features.pin_protection is False assert client.features.passphrase_protection is False os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) with mock.patch("os.urandom", os_urandom), client: client.set_expected_responses( [messages.ButtonRequest] + [messages.EntropyRequest] + [messages.ButtonRequest] * 24 + [messages.Success, messages.Features] ) device.reset(client, False, 128, True, False, "label", "en-US") with pytest.raises(TrezorFailure): # This must fail, because device is already initialized # Using direct call because `device.reset` has its own check client.call( messages.ResetDevice( display_random=False, strength=128, passphrase_protection=True, pin_protection=False, label="label", language="en-US", ) )
def test_pin_fail(client: Client): ret = client.call_raw( messages.RecoveryDevice( word_count=12, passphrase_protection=True, pin_protection=True, label="label", language="en-US", enforce_wordlist=True, ) ) # click through confirmation assert isinstance(ret, messages.ButtonRequest) client.debug.press_yes() ret = client.call_raw(messages.ButtonAck()) assert isinstance(ret, messages.PinMatrixRequest) # Enter PIN for first time pin_encoded = client.debug.encode_pin(PIN4) ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded)) assert isinstance(ret, messages.PinMatrixRequest) # Enter PIN for second time, but different one pin_encoded = client.debug.encode_pin(PIN6) ret = client.call_raw(messages.PinMatrixAck(pin=pin_encoded)) # Failure should be raised assert isinstance(ret, messages.Failure)
def test_device_id_different(client: Client): id1 = client.get_device_id() device.wipe(client) id2 = client.get_device_id() # Device ID must be fresh after every reset assert id1 != id2
def test_autolock_default_value(client: Client): assert client.features.auto_lock_delay_ms is None with client: client.use_pin_sequence([PIN4]) device.apply_settings(client, label="pls unlock") client.refresh_features() assert client.features.auto_lock_delay_ms == 60 * 10 * 1000
def test_word_fail(client: Client): ret = client.call_raw( messages.RecoveryDevice( word_count=12, passphrase_protection=False, pin_protection=False, label="label", language="en-US", enforce_wordlist=True, ) ) # click through confirmation assert isinstance(ret, messages.ButtonRequest) client.debug.press_yes() ret = client.call_raw(messages.ButtonAck()) assert isinstance(ret, messages.WordRequest) for _ in range(int(12 * 2)): (word, pos) = client.debug.read_recovery_word() if pos != 0: ret = client.call_raw(messages.WordAck(word="kwyjibo")) assert isinstance(ret, messages.Failure) break else: client.call_raw(messages.WordAck(word=word))
def test_multisig_mismatch_inputs(client: Client): multisig_out1 = messages.MultisigRedeemScriptType( nodes=[NODE_EXT2, NODE_EXT1, NODE_INT], address_n=[1, 0], signatures=[b"", b"", b""], m=2, ) out1 = messages.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out1, amount=40_000_000, script_type=messages.OutputScriptType.PAYTOMULTISIG, ) out2 = messages.TxOutputType( address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg", amount=65_000_000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses(_responses(INP1, INP3)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [INP1, INP3], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b500483045022100d907b9339951c96ef4515ef7aff8b3c28c4c8c5875d7421aa1de9f3a94e3508302205cdc311a6c91dfbb74f1a9a940a994a65dbfb0cf6dedcaaaeee839e0b8fd016d014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff39f756d82082b580b0d69ae8798ff10a981820ccfe1ab149a708a37bc26d94b000000000b500483045022100fdad4a47d15f47cc364fe0cbed11b1ced1f9ef210bc1bd413ec4384f630c63720220752e4f09ea4e5e6623f5ebe89b3983ec6e5702f63f9bce696f10b2d594d23532014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103b6321a1194e5cc47b6b7edc3f67a096e6f71ccb72440f84f390b6e98df0ea8ec2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948740d2df030000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" )
def test_multisig_mismatch_change(client: Client): multisig_out2 = messages.MultisigRedeemScriptType( nodes=[NODE_EXT1, NODE_INT, NODE_EXT3], address_n=[1, 0], signatures=[b"", b"", b""], m=2, ) out1 = messages.TxOutputType( address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt", amount=40_000_000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) out2 = messages.TxOutputType( address_n=[H_(45), 0, 1, 0], multisig=multisig_out2, amount=44_000_000, script_type=messages.OutputScriptType.PAYTOMULTISIG, ) with client: client.set_expected_responses(_responses(INP1, INP2)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [INP1, INP2], [out1, out2], prev_txes=TX_API, ) assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b40047304402207f9992cc0230527faf54ec6bd233307db82bc8fac039dcee418bc6feb4e96a3a02206bb4cb157ad27c123277328a877572563a45d70b844d9ab07cc42238112f8c2a014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b400473044022078a41bfa87d72d6ba810d84bf568b5a29acf8b851ba6c3a8dbff079b34a7feb0022037b770c776db0b6c883c38a684a121b90a59ed1958774cbf64de70e53e29639f014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914e6a3e2fbadb7f559f8d20c46aceae78c96fcf1d18700000000" )
def _test_secret(client: Client, shares, secret, click_info=False): debug = client.debug def input_flow(): yield # Confirm Recovery debug.press_yes() # Proceed with recovery yield from recovery_enter_shares(debug, shares, groups=True, click_info=click_info) with client: client.set_input_flow(input_flow) ret = device.recover(client, pin_protection=False, passphrase_protection=False, label="label") # Workflow succesfully ended assert ret == messages.Success(message="Device recovered") assert client.features.initialized is True assert client.features.pin_protection is False assert client.features.passphrase_protection is False assert client.features.backup_type is messages.BackupType.Slip39_Advanced assert debug.state().mnemonic_secret.hex() == secret
def setup_device_core(client: Client, pin: str, wipe_code: str) -> None: device.wipe(client) debuglink.load_device( client, MNEMONIC12, pin, passphrase_protection=False, label="WIPECODE" ) def input_flow(): yield # do you want to set/change the wipe_code? client.debug.press_yes() if pin is not None: yield # enter current pin client.debug.input(pin) yield # enter new wipe code client.debug.input(wipe_code) yield # enter new wipe code again client.debug.input(wipe_code) yield # success client.debug.press_yes() with client: client.set_expected_responses( [messages.ButtonRequest()] * 5 + [messages.Success, messages.Features] ) client.set_input_flow(input_flow) device.change_wipe_code(client)
def start(self): if self.process: if self.process.poll() is not None: # process has died, stop and start again LOG.info("Starting from a stopped process.") self.stop() else: # process is running, no need to start again return self.process = self.launch_process() try: self.wait_until_ready() except TimeoutError: # Assuming that after the default 60-second timeout, the process is stuck LOG.warning("Emulator did not come up after {} seconds".format( EMULATOR_WAIT_TIME)) self.process.kill() raise (self.profile_dir / "trezor.pid").write_text(str(self.process.pid) + "\n") (self.profile_dir / "trezor.port").write_text(str(self.port) + "\n") transport = self._get_transport() self.client = TrezorClientDebugLink(transport, auto_interact=self.debug) self.client.open()
def test_softlock_instability(client: Client): def load_device(): debuglink.load_device( client, mnemonic=MNEMONIC12, pin="1234", passphrase_protection=False, label="test", ) # start from a clean slate: resp = client.debug.reseed(0) if isinstance(resp, messages.Failure) and not isinstance( client.transport, udp.UdpTransport): pytest.xfail("reseed only supported on emulator") device.wipe(client) entropy_after_wipe = misc.get_entropy(client, 16) # configure and wipe the device load_device() client.debug.reseed(0) device.wipe(client) assert misc.get_entropy(client, 16) == entropy_after_wipe load_device() # the device has PIN -> lock it client.call(messages.LockDevice()) client.debug.reseed(0) # wipe_device should succeed with no need to unlock device.wipe(client) # the device is now trying to run the lockscreen, which attempts to unlock. # If the device actually called config.unlock(), it would use additional randomness. # That is undesirable. Assert that the returned entropy is still the same. assert misc.get_entropy(client, 16) == entropy_after_wipe
def test_invalid_path_fail_asap(client: Client): inp1 = messages.TxInputType( address_n=parse_path("m/0"), amount=1_000_000, prev_hash=b"\x42" * 32, prev_index=0, script_type=messages.InputScriptType.SPENDWITNESS, sequence=4_294_967_293, ) out1 = messages.TxOutputType( address_n=parse_path("m/84h/0h/0h/1/0"), amount=1_000_000, script_type=messages.OutputScriptType.PAYTOWITNESS, ) with client: client.set_expected_responses([ request_input(0), messages.Failure(code=messages.FailureType.DataError), ]) try: btc.sign_tx(client, "Testnet", [inp1], [out1]) except TrezorFailure: pass
def test_entropy(client: Client, entropy_length): with client: client.set_expected_responses( [m.ButtonRequest(code=m.ButtonRequestType.ProtectCall), m.Entropy]) ent = misc.get_entropy(client, entropy_length) assert len(ent) == entropy_length print(f"{entropy_length} bytes: entropy = {entropy(ent)}")
def start(self): env, args, cwd = self._get_params() self.process = subprocess.Popen(args, cwd=cwd, env=env, stdout=open(os.devnull, "w")) # wait until emulator is listening transport = UdpTransport("127.0.0.1:21324") transport.open() for _ in range(300): if transport._ping(): break if self.process.poll() is not None: self._cleanup() raise RuntimeError("Emulator proces died") time.sleep(0.1) else: # could not connect after 300 attempts * 0.1s = 30s of waiting self._cleanup() raise RuntimeError("Can't connect to emulator") transport.close() self.client = TrezorClientDebugLink(transport) self.client.open() check_version(self.tag, self.client.version)
def test_same_share(client: Client): debug = client.debug first_share = MNEMONIC_SLIP39_BASIC_20_3of6[0].split(" ") # second share is first 4 words of first second_share = MNEMONIC_SLIP39_BASIC_20_3of6[0].split(" ")[:4] def input_flow(): yield # Confirm Recovery debug.press_yes() yield # Homescreen - start process debug.press_yes() yield # Enter number of words debug.input(str(len(first_share))) yield # Homescreen - proceed to share entry debug.press_yes() yield # Enter first share for word in first_share: debug.input(word) yield # Continue to next share debug.press_yes() yield # Enter next share for word in second_share: debug.input(word) br = yield assert br.code == messages.ButtonRequestType.Warning client.cancel() with client: client.set_input_flow(input_flow) with pytest.raises(exceptions.Cancelled): device.recover(client, pin_protection=False, label="label")
def test_2of3_dryrun(client: Client): debug = client.debug def input_flow(): yield # Confirm Dryrun debug.press_yes() # run recovery flow yield from recovery_enter_shares(debug, EXTRA_GROUP_SHARE + MNEMONIC_SLIP39_ADVANCED_20, groups=True) with client: client.set_input_flow(input_flow) ret = device.recover( client, passphrase_protection=False, pin_protection=False, label="label", language="en-US", dry_run=True, ) # Dry run was successful assert ret == messages.Success( message="The seed is valid and matches the one in the device")
def test_cardano_sign_tx_failed(client: Client, parameters, result): client.init_device(new_session=True, derive_cardano=True) signing_mode = messages.CardanoTxSigningMode.__members__[ parameters["signing_mode"]] inputs = [cardano.parse_input(i) for i in parameters["inputs"]] outputs = [cardano.parse_output(o) for o in parameters["outputs"]] certificates = [ cardano.parse_certificate(c) for c in parameters["certificates"] ] withdrawals = [ cardano.parse_withdrawal(w) for w in parameters["withdrawals"] ] auxiliary_data = cardano.parse_auxiliary_data(parameters["auxiliary_data"]) mint = cardano.parse_mint(parameters["mint"]) script_data_hash = cardano.parse_script_data_hash( parameters["script_data_hash"]) collateral_inputs = [ cardano.parse_collateral_input(i) for i in parameters["collateral_inputs"] ] required_signers = [ cardano.parse_required_signer(s) for s in parameters["required_signers"] ] additional_witness_requests = [ cardano.parse_additional_witness_request(p) for p in parameters["additional_witness_requests"] ] if parameters.get("security_checks") == "prompt": device.apply_settings( client, safety_checks=messages.SafetyCheckLevel.PromptTemporarily) else: device.apply_settings(client, safety_checks=messages.SafetyCheckLevel.Strict) with client: with pytest.raises(TrezorFailure, match=result["error_message"]): cardano.sign_tx( client=client, signing_mode=signing_mode, inputs=inputs, outputs=outputs, fee=parameters["fee"], ttl=parameters.get("ttl"), validity_interval_start=parameters.get( "validity_interval_start"), certificates=certificates, withdrawals=withdrawals, protocol_magic=parameters["protocol_magic"], network_id=parameters["network_id"], auxiliary_data=auxiliary_data, mint=mint, script_data_hash=script_data_hash, collateral_inputs=collateral_inputs, required_signers=required_signers, additional_witness_requests=additional_witness_requests, include_network_id=parameters["include_network_id"], )
def test_send_bch_external_presigned(client: Client): inp1 = messages.TxInputType( # address_n=parse_path("44'/145'/0'/1/0"), # bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw amount=1_896_050, prev_hash=TXHASH_502e85, prev_index=0, script_type=messages.InputScriptType.EXTERNAL, script_pubkey=bytes.fromhex( "76a914b1401fce7e8bf123c88a0467e0ed11e3b9fbef5488ac"), script_sig=bytes.fromhex( "47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2d" ), ) inp2 = messages.TxInputType( address_n=parse_path("m/44h/145h/0h/0/1"), # bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4 amount=73_452, prev_hash=TXHASH_502e85, prev_index=1, script_type=messages.InputScriptType.SPENDADDRESS, ) out1 = messages.TxOutputType( address="bitcoincash:qq6wnnkrz7ykaqvxrx4hmjvayvzjzml54uyk76arx4", amount=1_934_960, script_type=messages.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses([ request_input(0), request_input(1), request_output(0), messages.ButtonRequest(code=B.ConfirmOutput), messages.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_502e85), request_input(0, TXHASH_502e85), request_output(0, TXHASH_502e85), request_output(1, TXHASH_502e85), request_input(1), request_meta(TXHASH_502e85), request_input(0, TXHASH_502e85), request_output(0, TXHASH_502e85), request_output(1, TXHASH_502e85), request_input(0), request_input(1), request_output(0), request_finished(), ]) _, serialized_tx = btc.sign_tx(client, "Bcash", [inp1, inp2], [out1], prev_txes=TX_API) assert_tx_matches( serialized_tx, hash_link= "https://bch1.trezor.io/api/tx/5594fd9e5e26dcb4437cbbbba517401720849159bac4e2158e1e6401ffd5fdb7", tx_hex= "01000000022c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50000000006a47304402207a2a955f1cb3dc5f03f2c82934f55654882af4e852e5159639f6349e9386ec4002205fb8419dce4e648eae8f67bc4e369adfb130a87d2ea2d668f8144213b12bb457412103174c61e9c5362507e8061e28d2c0ce3d4df4e73f3535ae0b12f37809e0f92d2dffffffff2c06cf6f215c5cbfd7caa8e71b1b32630cabf1f816a4432815b037b277852e50010000006a473044022062151cf960b71823bbe68c7ed2c2a93ad1b9706a30255fddb02fcbe056d8c26102207bad1f0872bc5f0cfaf22e45c925c35d6c1466e303163b75cb7688038f1a5541412102595caf9aeb6ffdd0e82b150739a83297358b9a77564de382671056ad9e5b8c58ffffffff0170861d00000000001976a91434e9cec317896e818619ab7dc99d2305216ff4af88ac00000000", )
def test_skip_backup_msg(client: Client, backup_type, backup_flow): os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY) with mock.patch("os.urandom", os_urandom), client: device.reset( client, skip_backup=True, passphrase_protection=False, pin_protection=False, backup_type=backup_type, ) assert client.features.initialized is True assert client.features.needs_backup is True assert client.features.unfinished_backup is False assert client.features.no_backup is False assert client.features.backup_type is backup_type secret = backup_flow(client) client.init_device() assert client.features.initialized is True assert client.features.needs_backup is False assert client.features.unfinished_backup is False assert client.features.backup_type is backup_type assert secret is not None state = client.debug.state() assert state.mnemonic_type is backup_type assert state.mnemonic_secret == secret
def backup_flow_bip39(client: Client): mnemonic = None def input_flow(): nonlocal mnemonic # 1. Confirm Reset yield from click_through(client.debug, screens=1, code=B.ResetDevice) # mnemonic phrases mnemonic = yield from read_and_confirm_mnemonic(client.debug) # confirm recovery seed check br = yield assert br.code == B.Success client.debug.press_yes() # confirm success br = yield assert br.code == B.Success client.debug.press_yes() with client: client.set_expected_responses([ messages.ButtonRequest(code=B.ResetDevice), messages.ButtonRequest(code=B.ResetDevice), messages.ButtonRequest(code=B.Success), messages.ButtonRequest(code=B.Success), messages.Success, messages.Features, ]) client.set_input_flow(input_flow) device.backup(client) return mnemonic.encode()
def start(self): if self.process: if self.process.poll() is not None: # process has died, stop and start again self.stop() else: # process is running, no need to start again return self.process = self.launch_process() try: self.wait_until_ready() except TimeoutError: # Assuming that after the default 30-second timeout, the process is stuck self.process.kill() raise (self.profile_dir / "trezor.pid").write_text(str(self.process.pid) + "\n") (self.profile_dir / "trezor.port").write_text(str(self.port) + "\n") transport = self._get_transport() self.client = TrezorClientDebugLink(transport, auto_interact=self.debug) self.client.open()
def test_exponential_backoff_t1(client: Client): for attempt in range(3): start = time.time() with client, pytest.raises(PinException): client.use_pin_sequence([BAD_PIN]) get_test_address(client) _check_backoff_time(attempt, start)
def test_derivation_irrelevant_on_slip39(client: Client, derivation_type): client.init_device(new_session=True, derive_cardano=False) pubkey = get_public_key(client, ADDRESS_N, derivation_type=D.ICARUS) test_pubkey = get_public_key(client, ADDRESS_N, derivation_type=derivation_type) assert pubkey == test_pubkey
def setup_method(self, method): wirelink = conftest.get_device() self.client = TrezorClientDebugLink(wirelink) # self.client.set_buttonwait(3) device.wipe(self.client) self.client.open()
def test_multisig_external_external(client: Client): out1 = messages.TxOutputType( address="3B23k4kFBRtu49zvpG3Z9xuFzfpHvxBcwt", amount=40_000_000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) out2 = messages.TxOutputType( address="3PkXLsY7AUZCrCKGvX8FfP2EawowUBMbcg", amount=44_000_000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses(_responses(INP1, INP2)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [INP1, INP2], [out1, out2], prev_txes=TX_API, ) # Transaction does not exist on the blockchain, not using assert_tx_matches() assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022059394e0dfcb2d2f4a6108703f801545ca5a820c0ac6a1859d0a3854813de55fa02207b6a57d70b82932ff58163336c461653a2dc82c78ed8157159e5178ac7325390014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b40047304402205a911685f5b974b2fc4a19d5ce056218773a4d20b5eaae2c2f9594929308182002201e03449f5a8813ec19f408bf1b6f4f334886d6fcf9920e300fd7678ef0724f81014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a62020000000017a91466528dd543f94d162c8111d2ec248d25ba9b90948700639f020000000017a914f1fc92c0aed1712911c70a2e09ac15ff0922652f8700000000" )
def test_internal_external(client: Client): out1 = messages.TxOutputType( address_n=parse_path("m/45h/0/1/0"), amount=40_000_000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) out2 = messages.TxOutputType( address="1H7uXJQTVwXca2BXF2opTrvuZapk8Cm8zY", amount=44_000_000, script_type=messages.OutputScriptType.PAYTOADDRESS, ) with client: client.set_expected_responses(_responses(INP1, INP2, change=1)) _, serialized_tx = btc.sign_tx( client, "Bitcoin", [INP1, INP2], [out1, out2], prev_txes=TX_API, ) # Transaction does not exist on the blockchain, not using assert_tx_matches() assert ( serialized_tx.hex() == "0100000002e53cf4e3fcd37f8c439286ce636476e1faeebf86bbb2f228a6b78d1b47c8c61601000000b400473044022064f13801744a6c21b694f62cdb5d834e852f13ecf85ed4d0a56ba279571c24e3022010fab4cb05bdd7b24c8376dda4f62a418548eea6eb483e58675fa06e0d5c642c014c69522103dc07026aacb5918dac4e09f9da8290d0ae22161699636c22cace78082116a7792103e70db185fad69c2971f0107a42930e5d82a9ed3a11b922a96fdfc4124b63e54c2103f3fe007a1e34ac76c1a2528e9149f90f9f93739929797afab6a8e18d682fa71053aeffffffff185315ae8050e18efa70d6ca96378a1194f57e2b102511f68b3a1414ee340cd800000000b4004730440220727b2522268f913acd213c507d7801b146e5b6cef666ad44b769c26d6c762e4d022021c0c2e9e8298dee2a490d956f7ab1b2d3160c1e37a50cc6d19a5e62eb484fc9014c6952210297ad8a5df42f9e362ef37d9a4ddced89d8f7a143690649aa0d0ff049c7daca842103ed1fd93989595d7ad4b488efd05a22c0239482c9a20923f2f214a38e54f6c41a2103f91460d79e4e463d7d90cb75254bcd62b515a99a950574c721efdc5f711dff3553aeffffffff02005a6202000000001976a9149b139230e4fe91c05a37ec334dc8378f3dbe377088ac00639f02000000001976a914b0d05a10926a7925508febdbab9a5bd4cda8c8f688ac00000000" )
def _check_no_pin(client: Client): client.lock() assert client.features.pin_protection is False with client: client.set_expected_responses([messages.Address]) btc.get_address(client, "Testnet", PASSPHRASE_TEST_PATH)
def test_p2wpkh_with_false_proof(client: Client): inp1 = messages.TxInputType( # tb1qkvwu9g3k2pdxewfqr7syz89r3gj557l3uuf9r9 address_n=parse_path("m/84h/1h/0h/0/0"), prev_hash=TXHASH_70f987, prev_index=0, amount=100_000, script_type=messages.InputScriptType.SPENDWITNESS, ) inp2 = messages.TxInputType( # tb1qldlynaqp0hy4zc2aag3pkenzvxy65saesxw3wd # address_n=parse_path("m/84h/1h/0h/0/1"), prev_hash=TXHASH_65b768, prev_index=0, amount=10_000, script_type=messages.InputScriptType.EXTERNAL, script_pubkey=bytes.fromhex("0014fb7e49f4017dc951615dea221b66626189aa43b9"), ownership_proof=bytes.fromhex( "534c00190001b0b66657a824e41c063299fb4435dc70a6fd2e9db4c87e3c26a7ab7c0283547b000247304402206e285291aa955cb60b16acd69332eaada67ec5192d361fe4e2b384553e7e80c6022023470cfcb9c3251a136c26eb1637142206785a3d91b98583e5a1d6ab64fa91ed012103dcf3bc936ecb2ec57b8f468050abce8c8756e75fd74273c9977744b1a0be7d03" ), ) out1 = messages.TxOutputType( address="tb1qnspxpr2xj9s2jt6qlhuvdnxw6q55jvygcf89r2", amount=50_000, script_type=messages.OutputScriptType.PAYTOWITNESS, ) with client: client.set_expected_responses( [ request_input(0), request_input(1), request_output(0), messages.ButtonRequest(code=B.ConfirmOutput), messages.ButtonRequest(code=B.SignTx), request_input(0), request_meta(TXHASH_70f987), request_input(0, TXHASH_70f987), request_output(0, TXHASH_70f987), request_output(1, TXHASH_70f987), request_input(1), request_meta(TXHASH_65b768), request_input(0, TXHASH_65b768), request_output(0, TXHASH_65b768), request_output(1, TXHASH_65b768), messages.Failure(code=messages.FailureType.DataError), ] ) with pytest.raises(TrezorFailure, match="Invalid external input"): btc.sign_tx( client, "Testnet", [inp1, inp2], [out1], prev_txes=TX_CACHE_TESTNET, )
client.debug.press_yes() if old_pin is not None: # enter old pin yield client.debug.input(old_pin) # enter new pin yield client.debug.input(new_pin) # repeat new pin yield client.debug.input(new_pin) if __name__ == "__main__": wirelink = get_device() client = TrezorClientDebugLink(wirelink) client.open() i = 0 last_pin = None while True: # set private field device.apply_settings(client, auto_lock_delay_ms=(i % 10 + 10) * 1000) # set public field label = "".join(random.choices(string.ascii_uppercase + string.digits, k=17)) device.apply_settings(client, label=label) assert client.features.label == label
client.debug.press_yes() if old_pin is not None: # enter old pin yield client.debug.input(old_pin) # enter new pin yield client.debug.input(new_pin) # repeat new pin yield client.debug.input(new_pin) if __name__ == "__main__": wirelink = get_device() client = TrezorClientDebugLink(wirelink) client.open() i = 0 last_pin = None while True: # set private field device.apply_settings(client, use_passphrase=True) assert client.features.passphrase_protection is True device.apply_settings(client, use_passphrase=False) assert client.features.passphrase_protection is False # set public field label = "".join(random.choices(string.ascii_uppercase + string.digits, k=17))