Beispiel #1
0
    def test_nonzero_opreturn(self):
        self.setup_mnemonic_nopin_nopassphrase()

        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = proto_types.TxInputType(address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
                             # amount=390000,
                             prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'),
                             prev_index=0,
                             )

        out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
                              amount=390000 - 10000 - 10000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        out1 = proto_types.TxOutputType(op_return_data=b'test of the op_return data',
                              amount=10000,
                              script_type=proto_types.PAYTOOPRETURN,
                              )

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXMETA, details=proto_types.TxRequestDetailsType(tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXINPUT, details=proto_types.TxRequestDetailsType(request_index=1, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0, tx_hash=binascii.unhexlify("d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882"))),
                proto.TxRequest(request_type=proto_types.TXOUTPUT, details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.Failure()
            ])
            self.assertRaises(CallException, self.client.sign_tx, 'Bitcoin', [inp1, ], [out1, ])
Beispiel #2
0
    def test_not_enough_funds(self):
        self.setup_mnemonic_nopin_nopassphrase()

        # tx: d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882
        # input 0: 0.0039 BTC

        inp1 = proto_types.TxInputType(address_n=[0],  # 14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e
                             # amount=390000,
                             prev_hash=binascii.unhexlify('d5f65ee80147b4bcc70b75e4bbf2d7382021b871bd8867ef8fa525ef50864882'),
                             prev_index=0,
                             )

        out1 = proto_types.TxOutputType(address='1MJ2tj2ThBE62zXbBYA5ZaN3fdve5CPAz1',
                              amount=400000,
                              script_type=proto_types.PAYTOADDRESS,
                              )

        with self.client:
            self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_ConfirmOutput),
                                                proto.Failure(code=proto_types.Failure_NotEnoughFunds)])

            try:
                self.client.simple_sign_tx('Bitcoin', [inp1, ], [out1, ])
            except CallException as e:
                self.assertEqual(e.args[0], proto_types.Failure_NotEnoughFunds)
            else:
                self.assert_(False, "types.Failure_NotEnoughFunds expected")
Beispiel #3
0
    def test_attack_change_input_address(self):
        # This unit test attempts to modify input address after the Trezor checked
        # that it matches the change output

        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiTestnet)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("49'/1'/0'/1/0"),
            # 2N1LGaGg836mqSQqiuUBLfcyGBhyZbremDX
            amount=123456789,
            prev_hash=binascii.unhexlify(
                '20912f98ea3ed849042efed0fdac8cb4fc301961c5988cba56902d8ffb61c337'
            ),
            prev_index=0,
            script_type=proto_types.SPENDP2SHWITNESS,
        )
        out1 = proto_types.TxOutputType(
            address='mhRx1CeVfaayqRwq5zgRQmD7W5aWBfD5mC',
            amount=12300000,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address_n=self.client.expand_path("49'/1'/12345'/1/0"),
            script_type=proto_types.PAYTOP2SHWITNESS,
            amount=123456789 - 11000 - 12300000,
        )

        global run_attack
        run_attack = True

        def attack_processor(req, msg):
            import sys
            global run_attack

            if req.details.tx_hash != b'':
                return msg

            if req.request_type != proto_types.TXINPUT:
                return msg

            if req.details.request_index != 0:
                return msg

            if not run_attack:
                return msg

            msg.inputs[0].address_n[2] = 12345 + 0x80000000
            run_attack = False
            return msg

        # Test if the transaction can be signed normally
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(request_type=proto_types.TXFINISHED),
            ])
            (signatures,
             serialized_tx) = self.client.sign_tx('Testnet', [inp1],
                                                  [out1, out2])

        self.assertEqual(
            binascii.hexlify(serialized_tx),
            b'0100000000010137c361fb8f2d9056ba8c98c5611930fcb48cacfdd0fe2e0449d83eea982f91200000000017160014d16b8c0680c61fc6ed2e407455715055e41052f5ffffffff02e0aebb00000000001976a91414fdede0ddc3be652a0ce1afbc1b509a55b6b94888ac3df39f060000000017a914dae9e09a7fc3bbe5a716fffec1bbb340b82a4fb9870248304502210099b5c4f8fd4402c9c0136fee5f711137d64fc9f14587e01bfa7798f5428f845d0220253e21c98f5b1b64efae69bc2ea9799c5620a43450baa6762a0c3cf4fdc886e5012103e7bfe10708f715e8538c92d46ca50db6f657bbc455b7494e6a0303ccdb868b7900000000'
        )

        # Now run the attack, must trigger the exception
        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.Failure(code=proto_types.Failure_ProcessError),
            ])
            self.assertRaises(CallException,
                              self.client.sign_tx,
                              'Testnet', [inp1], [out1, out2],
                              debug_processor=attack_processor)
    def test_attack_change_input(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiBitcoinCash)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/1000'/0/0"),
            # 1MH9KKcvdCTY44xVDC2k3fjBbX5Cz29N1q
            amount=1995344,
            prev_hash=binascii.unhexlify(
                'bc37c28dfb467d2ecb50261387bf752a3977d7e5337915071bb4151e6b711a78'
            ),
            prev_index=0,
            script_type=proto_types.SPENDADDRESS,
        )
        out1 = proto_types.TxOutputType(
            address_n=self.client.expand_path("44'/145'/1000'/1/0"),
            amount=1896050,
            script_type=proto_types.PAYTOADDRESS,
        )
        out2 = proto_types.TxOutputType(
            address='1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3',
            amount=73452,
            script_type=proto_types.PAYTOADDRESS,
        )

        global attack_ctr
        attack_ctr = 0

        def attack_processor(req, msg):
            import sys
            global attack_ctr

            if req.details.tx_hash != b'':
                return msg

            if req.request_type != proto_types.TXINPUT:
                return msg

            attack_ctr += 1
            if attack_ctr <= 1:
                return msg

            msg.inputs[0].address_n[2] = 1 + 0x80000000
            return msg

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.Failure(code=proto_types.Failure_ProcessError),
            ])
            self.assertRaises(CallException,
                              self.client.sign_tx,
                              'Bcash', [inp1], [out1, out2],
                              debug_processor=attack_processor)
    def test_attack_amount(self):
        self.setup_mnemonic_allallall()
        self.client.set_tx_api(TxApiBitcoinCash)
        inp1 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/0'/1/0"),
            # 1HADRPJpgqBzThepERpVXNi6qRgiLQRNoE
            amount=1896050 - 1,
            prev_hash=binascii.unhexlify(
                '502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'
            ),
            prev_index=0,
            script_type=proto_types.SPENDADDRESS,
        )
        inp2 = proto_types.TxInputType(
            address_n=self.client.expand_path("44'/145'/0'/0/1"),
            # 1LRspCZNFJcbuNKQkXgHMDucctFRQya5a3
            amount=73452,
            prev_hash=binascii.unhexlify(
                '502e8577b237b0152843a416f8f1ab0c63321b1be7a8cad7bf5c5c216fcf062c'
            ),
            prev_index=1,
            script_type=proto_types.SPENDADDRESS,
        )
        out1 = proto_types.TxOutputType(
            address='15pnEDZJo3ycPUamqP3tEDnEju1oW5fBCz',
            amount=1934960,
            script_type=proto_types.PAYTOADDRESS,
        )

        global run_attack
        run_attack = True

        def attack_processor(req, msg):
            import sys
            global run_attack

            if req.details.tx_hash != b'':
                return msg

            if req.request_type != proto_types.TXINPUT:
                return msg

            if req.details.request_index != 0:
                return msg

            if not run_attack:
                return msg

            msg.inputs[0].amount = 1896050
            run_attack = False
            return msg

        with self.client:
            self.client.set_expected_responses([
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=1)),
                proto.TxRequest(
                    request_type=proto_types.TXOUTPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.ButtonRequest(
                    code=proto_types.ButtonRequest_ConfirmOutput),
                proto.ButtonRequest(code=proto_types.ButtonRequest_SignTx),
                proto.TxRequest(
                    request_type=proto_types.TXINPUT,
                    details=proto_types.TxRequestDetailsType(request_index=0)),
                proto.Failure(code=proto_types.Failure_ProcessError),
            ])
            self.assertRaises(CallException,
                              self.client.sign_tx,
                              'Bcash', [inp1, inp2], [out1],
                              debug_processor=attack_processor)