1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 12:00:59 +00:00

Merge branch 'master' into matejcik/refactor

This commit is contained in:
matejcik 2018-05-24 19:18:26 +02:00
commit 9982ef98f9
43 changed files with 228 additions and 423 deletions

View File

@ -26,8 +26,9 @@ python:
install:
# Optimisation: build requirements as wheels, which get cached by Travis
- pip install "pip>=7.0" wheel
- pip install "setuptools>=38"
- pip install "pip>=9.0" wheel # pip 9.0 understands `python_requires` constraints
- pip install "setuptools>=38" # setuptools >= 38 are capable of using prebuilt wheels
- pip install "virtualenv<16.0.0" # virtualenv 16.0.0 drops support for py33 without properly declaring it
- pip install tox-travis
- pip install flake8
# protobuf-related dependencies

View File

@ -894,33 +894,6 @@ def lisk_get_public_key(connect, address, show_display):
return output
@cli.command(help='Sign message with Lisk address.')
@click.option('-n', '--address', required=True, help="BIP-32 path, e.g. m/44'/134'/0'/0'")
@click.argument('message')
@click.pass_obj
def lisk_sign_message(connect, address, message):
client = connect()
address_n = tools.parse_path(address)
res = client.lisk_sign_message(address_n, message)
output = {
'message': message,
'address': res.address,
'signature': binascii.hexlify(res.signature).decode()
}
return output
@cli.command(help='Verify message signed with Lisk address.')
@click.argument('pubkey')
@click.argument('signature')
@click.argument('message')
@click.pass_obj
def lisk_verify_message(connect, pubkey, signature, message):
signature = bytes.fromhex(signature)
pubkey = bytes.fromhex(pubkey)
return connect().lisk_verify_message(pubkey, signature, message)
@cli.command(help='Sign Lisk transaction.')
@click.option('-n', '--address', required=True, help="BIP-32 path to signing key, e.g. m/44'/134'/0'/0'")
@click.option('-f', '--file', type=click.File('r'), default='-', help='Transaction in JSON format')
@ -979,51 +952,17 @@ def stellar_get_address(connect, address):
return stellar.address_from_public_key(response.public_key)
@cli.command(help='Sign a string with a Stellar key')
@click.option('-n', '--address', required=False, help="BIP32 path. Default primary account is m/44'/148'/0'. Always use hardened paths and the m/44'/148'/ prefix")
@click.argument('message')
@click.pass_obj
def stellar_sign_message(connect, address, message):
client = connect()
address_n = stellar.expand_path_or_default(client, address)
response = client.stellar_sign_message(address_n, message)
return base64.b64encode(response.signature)
@cli.command(help='Verify that a signature is valid')
@click.option('--message-is-b64/--no-message-is-b64', default=False, required=False, help="If set, the message argument will be interpreted as a base64-encoded string")
@click.argument('address')
@click.argument('signatureb64')
@click.argument('message')
@click.pass_obj
def stellar_verify_message(connect, address, message_is_b64, signatureb64, message):
if message_is_b64:
message = base64.b64decode(message)
else:
message = message.encode('utf-8')
pubkey_bytes = stellar.address_to_public_key(address)
client = connect()
is_verified = client.stellar_verify_message(pubkey_bytes, base64.b64decode(signatureb64), message)
if is_verified:
return "Success: message verified"
else:
print("ERROR: invalid signature, verification failed")
sys.exit(1)
@cli.command(help='Sign a base64-encoded transaction envelope')
@click.option('-n', '--address', required=False, help="BIP32 path. Default primary account is m/44'/148'/0'. Always use hardened paths and the m/44'/148'/ prefix")
@click.option('-n', '--network-passphrase', required=False, help="Network passphrase (blank for public network). Testnet is: 'Test SDF Network ; September 2015'")
@click.option('-n', '--network-passphrase', default='Public Global Stellar Network ; September 2015', required=False, help="Network passphrase (blank for public network). Testnet is: 'Test SDF Network ; September 2015'")
@click.argument('b64envelope')
@click.pass_obj
def stellar_sign_transaction(connect, b64envelope, address, network_passphrase):
client = connect()
address_n = stellar.expand_path_or_default(client, address)
# raw signature bytes
resp = client.stellar_sign_transaction(base64.b64decode(b64envelope), address_n, network_passphrase)
tx, operations = stellar.parse_transaction_bytes(base64.b64decode(b64envelope))
resp = client.stellar_sign_transaction(tx, operations, address_n, network_passphrase)
return base64.b64encode(resp.signature)

View File

@ -554,20 +554,6 @@ class ProtocolMixin(object):
n = self._convert_prime(n)
return self.call(proto.LiskGetPublicKey(address_n=n, show_display=show_display))
@expect(proto.LiskMessageSignature)
def lisk_sign_message(self, n, message):
n = self._convert_prime(n)
message = normalize_nfc(message)
return self.call(proto.LiskSignMessage(address_n=n, message=message))
def lisk_verify_message(self, pubkey, signature, message):
message = normalize_nfc(message)
try:
resp = self.call(proto.LiskVerifyMessage(signature=signature, public_key=pubkey, message=message))
except CallException as e:
resp = e
return isinstance(resp, proto.Success)
@expect(proto.LiskSignedTx)
def lisk_sign_tx(self, n, transaction):
n = self._convert_prime(n)
@ -1093,16 +1079,14 @@ class ProtocolMixin(object):
def stellar_get_public_key(self, address_n):
return self.call(proto.StellarGetPublicKey(address_n=address_n))
def stellar_sign_transaction(self, tx_envelope, address_n, network_passphrase=None):
def stellar_sign_transaction(self, tx, operations, address_n, network_passphrase=None):
# default networkPassphrase to the public network
if network_passphrase is None:
network_passphrase = "Public Global Stellar Network ; September 2015"
tx, operations = stellar.parse_transaction_bytes(tx_envelope)
tx.network_passphrase = network_passphrase
tx.address_n = address_n
tx.num_operations = len(operations)
# Signing loop works as follows:
#
# 1. Start with tx (header information for the transaction) and operations (an array of operation protobuf messagess)
@ -1128,15 +1112,6 @@ class ProtocolMixin(object):
return resp
@expect(proto.StellarMessageSignature)
def stellar_sign_message(self, address_n, message):
return self.call(proto.StellarSignMessage(address_n=address_n, message=message))
def stellar_verify_message(self, pubkey_bytes, signature, message):
resp = self.call(proto.StellarVerifyMessage(public_key=pubkey_bytes, message=message, signature=signature))
return isinstance(resp, proto.Success)
class TrezorClient(ProtocolMixin, TextUIMixin, BaseClient):
def __init__(self, transport, *args, **kwargs):

View File

@ -6,10 +6,13 @@ class Initialize(p.MessageType):
MESSAGE_WIRE_TYPE = 0
FIELDS = {
1: ('state', p.BytesType, 0),
2: ('skip_passphrase', p.BoolType, 0),
}
def __init__(
self,
state: bytes = None
state: bytes = None,
skip_passphrase: bool = None
) -> None:
self.state = state
self.skip_passphrase = skip_passphrase

View File

@ -1,18 +0,0 @@
# Automatically generated by pb2py
from .. import protobuf as p
class LiskMessageSignature(p.MessageType):
MESSAGE_WIRE_TYPE = 119
FIELDS = {
1: ('address', p.UnicodeType, 0),
2: ('signature', p.BytesType, 0),
}
def __init__(
self,
address: str = None,
signature: bytes = None
) -> None:
self.address = address
self.signature = signature

View File

@ -1,23 +0,0 @@
# Automatically generated by pb2py
from .. import protobuf as p
if __debug__:
try:
from typing import List
except ImportError:
List = None
class LiskSignMessage(p.MessageType):
MESSAGE_WIRE_TYPE = 118
FIELDS = {
1: ('address_n', p.UVarintType, p.FLAG_REPEATED),
2: ('message', p.BytesType, 0),
}
def __init__(
self,
address_n: List[int] = None,
message: bytes = None
) -> None:
self.address_n = address_n if address_n is not None else []
self.message = message

View File

@ -1,21 +0,0 @@
# Automatically generated by pb2py
from .. import protobuf as p
class LiskVerifyMessage(p.MessageType):
MESSAGE_WIRE_TYPE = 120
FIELDS = {
1: ('signature', p.BytesType, 0),
2: ('public_key', p.BytesType, 0),
3: ('message', p.BytesType, 0),
}
def __init__(
self,
signature: bytes = None,
public_key: bytes = None,
message: bytes = None
) -> None:
self.signature = signature
self.public_key = public_key
self.message = message

View File

@ -88,18 +88,12 @@ LiskGetAddress = 114
LiskAddress = 115
LiskSignTx = 116
LiskSignedTx = 117
LiskSignMessage = 118
LiskMessageSignature = 119
LiskVerifyMessage = 120
LiskGetPublicKey = 121
LiskPublicKey = 122
StellarGetPublicKey = 200
StellarPublicKey = 201
StellarSignTx = 202
StellarTxOpRequest = 203
StellarSignMessage = 204
StellarMessageSignature = 205
StellarVerifyMessage = 206
StellarCreateAccountOp = 210
StellarPaymentOp = 211
StellarPathPaymentOp = 212

View File

@ -1,18 +0,0 @@
# Automatically generated by pb2py
from .. import protobuf as p
class StellarMessageSignature(p.MessageType):
MESSAGE_WIRE_TYPE = 205
FIELDS = {
1: ('public_key', p.BytesType, 0),
2: ('signature', p.BytesType, 0),
}
def __init__(
self,
public_key: bytes = None,
signature: bytes = None
) -> None:
self.public_key = public_key
self.signature = signature

View File

@ -1,23 +0,0 @@
# Automatically generated by pb2py
from .. import protobuf as p
if __debug__:
try:
from typing import List
except ImportError:
List = None
class StellarSignMessage(p.MessageType):
MESSAGE_WIRE_TYPE = 204
FIELDS = {
1: ('address_n', p.UVarintType, p.FLAG_REPEATED),
2: ('message', p.UnicodeType, 0),
}
def __init__(
self,
address_n: List[int] = None,
message: str = None
) -> None:
self.address_n = address_n if address_n is not None else []
self.message = message

View File

@ -1,21 +0,0 @@
# Automatically generated by pb2py
from .. import protobuf as p
class StellarVerifyMessage(p.MessageType):
MESSAGE_WIRE_TYPE = 206
FIELDS = {
1: ('public_key', p.BytesType, 0),
2: ('message', p.BytesType, 0),
3: ('signature', p.BytesType, 0),
}
def __init__(
self,
public_key: bytes = None,
message: bytes = None,
signature: bytes = None
) -> None:
self.public_key = public_key
self.message = message
self.signature = signature

View File

@ -22,6 +22,7 @@ class TransactionType(p.MessageType):
8: ('extra_data', p.BytesType, 0),
9: ('extra_data_len', p.UVarintType, 0),
10: ('decred_expiry', p.UVarintType, 0),
11: ('overwintered', p.BoolType, 0),
}
def __init__(
@ -35,7 +36,8 @@ class TransactionType(p.MessageType):
outputs_cnt: int = None,
extra_data: bytes = None,
extra_data_len: int = None,
decred_expiry: int = None
decred_expiry: int = None,
overwintered: bool = None
) -> None:
self.version = version
self.inputs = inputs if inputs is not None else []
@ -47,3 +49,4 @@ class TransactionType(p.MessageType):
self.extra_data = extra_data
self.extra_data_len = extra_data_len
self.decred_expiry = decred_expiry
self.overwintered = overwintered

View File

@ -96,12 +96,9 @@ from .Initialize import Initialize
from .LiskAddress import LiskAddress
from .LiskGetAddress import LiskGetAddress
from .LiskGetPublicKey import LiskGetPublicKey
from .LiskMessageSignature import LiskMessageSignature
from .LiskPublicKey import LiskPublicKey
from .LiskSignMessage import LiskSignMessage
from .LiskSignTx import LiskSignTx
from .LiskSignedTx import LiskSignedTx
from .LiskVerifyMessage import LiskVerifyMessage
from .LoadDevice import LoadDevice
from .MessageSignature import MessageSignature
from .NEMAddress import NEMAddress
@ -136,16 +133,13 @@ from .StellarCreatePassiveOfferOp import StellarCreatePassiveOfferOp
from .StellarGetPublicKey import StellarGetPublicKey
from .StellarManageDataOp import StellarManageDataOp
from .StellarManageOfferOp import StellarManageOfferOp
from .StellarMessageSignature import StellarMessageSignature
from .StellarPathPaymentOp import StellarPathPaymentOp
from .StellarPaymentOp import StellarPaymentOp
from .StellarPublicKey import StellarPublicKey
from .StellarSetOptionsOp import StellarSetOptionsOp
from .StellarSignMessage import StellarSignMessage
from .StellarSignTx import StellarSignTx
from .StellarSignedTx import StellarSignedTx
from .StellarTxOpRequest import StellarTxOpRequest
from .StellarVerifyMessage import StellarVerifyMessage
from .Success import Success
from .TxAck import TxAck
from .TxRequest import TxRequest

View File

@ -28,13 +28,32 @@ def pytest_configure(config):
log.enable_debug_output()
def pytest_addoption(parser):
parser.addini("run_xfail", "List of markers that will run even if marked as xfail", "args", [])
def pytest_runtest_setup(item):
'''
"""
Called for each test item (class, individual tests).
Ensures that 'skip_t2' tests are skipped on T2
and 'skip_t1' tests are skipped on T1.
'''
Performs custom processing, mainly useful for trezor CI testing:
* 'skip_t2' tests are skipped on T2 and 'skip_t1' tests are skipped on T1.
* no test should have both skips at the same time
* allows to 'runxfail' tests specified by 'run_xfail' in pytest.ini
"""
if item.get_marker("skip_t1") and item.get_marker("skip_t2"):
pytest.fail("Don't skip tests for both trezors!")
if item.get_marker("skip_t2") and TREZOR_VERSION == 2:
pytest.skip("Test excluded on Trezor T")
if item.get_marker("skip_t1") and TREZOR_VERSION == 1:
pytest.skip("Test excluded on Trezor 1")
xfail = item.get_marker("xfail")
run_xfail = any(item.get_marker(marker) for marker in item.config.getini("run_xfail"))
if xfail and run_xfail:
# Deep hack: pytest's private _evalxfail helper determines whether the test should xfail or not.
# The helper caches its result even before this hook runs.
# Here we force-set the result to False, meaning "test does NOT xfail, run as normal"
# IOW, this is basically per-item "--runxfail"
item._evalxfail.result = False

View File

@ -16,10 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import hexlify
import pytest
from .common import TrezorTest
@pytest.mark.ethereum
class TestMsgEthereumGetaddress(TrezorTest):
def test_ethereum_getaddress(self):

View File

@ -20,6 +20,7 @@ import pytest
from .common import TrezorTest
@pytest.mark.ethereum
@pytest.mark.skip_t2
class TestMsgEthereumSignmessage(TrezorTest):

View File

@ -16,16 +16,51 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import unhexlify, hexlify
import pytest
from .common import TrezorTest
from trezorlib import messages as proto
@pytest.mark.ethereum
class TestMsgEthereumSigntx(TrezorTest):
def test_ethereum_signtx_erc20_token(self):
def test_ethereum_signtx_known_erc20_token(self):
self.setup_mnemonic_nopin_nopassphrase()
with self.client:
self.client.set_expected_responses([
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
proto.EthereumTxRequest(data_length=None),
])
data = bytearray()
# method id signalizing `transfer(address _to, uint256 _value)` function
data.extend(unhexlify('a9059cbb'))
# 1st function argument (to - the receiver)
data.extend(unhexlify('000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b'))
# 2nd function argument (value - amount to be transferred)
data.extend(unhexlify('000000000000000000000000000000000000000000000000000000000bebc200'))
# 200 000 000 in dec, divisibility of ADT = 9, trezor1 displays 0.2 ADT, Trezor T 200 000 000 Wei ADT
sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
n=[0, 0],
nonce=0,
gas_price=20,
gas_limit=20,
# ADT token address
to=b'\xd0\xd6\xd6\xc5\xfe\x4a\x67\x7d\x34\x3c\xc4\x33\x53\x6b\xb7\x17\xba\xe1\x67\xdd',
chain_id=1,
# value needs to be 0, token value is set in the contract (data)
value=0,
data=data)
# taken from T1 might not be 100% correct but still better than nothing
assert hexlify(sig_r) == b'75cf48fa173d8ceb68af9e4fb6b78ef69e6ed5e7679ba6f8e3e91d74b2fb0f96'
assert hexlify(sig_s) == b'65de4a8c35263b2cfff3954b12146e8e568aa67a1c2461d6865e74ef75c7e190'
def test_ethereum_signtx_unknown_erc20_token(self):
self.setup_mnemonic_nopin_nopassphrase()
with self.client:
@ -42,22 +77,23 @@ class TestMsgEthereumSigntx(TrezorTest):
data.extend(unhexlify('000000000000000000000000574bbb36871ba6b78e27f4b4dcfb76ea0091880b'))
# 2nd function argument (value - amount to be transferred)
data.extend(unhexlify('0000000000000000000000000000000000000000000000000000000000000123'))
# since this token is unknown trezor should display "unknown token value"
sig_v, sig_r, sig_s = self.client.ethereum_sign_tx(
n=[0, 0],
nonce=0,
gas_price=20,
gas_limit=20,
# ALTS token address
to=b'\x63\x8a\xc1\x49\xea\x8e\xf9\xa1\x28\x6c\x41\xb9\x77\x01\x7a\xa7\x35\x9e\x6c\xfa',
# unknown token address (Grzegorz Brzęczyszczykiewicz Token)
to=b'\xfc\x6b\x5d\x6a\xf8\xa1\x32\x58\xf7\xcb\xd0\xd3\x9e\x11\xb3\x5e\x01\xa3\x2f\x93',
chain_id=1,
# value needs to be 0, token value is set in the contract (data)
value=0,
data=data)
# taken from T1 might not be 100% correct but still better than nothing
assert hexlify(sig_r) == b'28bf1b621be9a85d2905fa36511dfbd52ec4b67ba4ad6cb2bd08753c72b93b77'
assert hexlify(sig_s) == b'2fa605244f80a56cb438df55eb9835489288ec2c0ac0280ada2ccaccfe2b7e38'
assert hexlify(sig_r) == b'1707471fbf632e42d18144157aaf4cde101cd9aa9782ad8e30583cfc95ddeef6'
assert hexlify(sig_s) == b'3d2e52ba5904a4bf131abde3f79db826199f5d6f4d241d531d7e8a30a3b9cfd9'
def test_ethereum_signtx_nodata(self):
self.setup_mnemonic_nopin_nopassphrase()

View File

@ -21,6 +21,7 @@ import pytest
from .common import TrezorTest
@pytest.mark.ethereum
@pytest.mark.skip_t2
class TestMsgEthereumVerifymessage(TrezorTest):

View File

@ -47,14 +47,12 @@ class TestMsgGetaddress(TrezorTest):
self.setup_mnemonic_nopin_nopassphrase()
assert self.client.get_address('Testnet', [111, 42]) == 'moN6aN6NP1KWgnPSqzrrRPvx2x1UtZJssa'
@pytest.mark.skip_t2
def test_bch(self):
self.setup_mnemonic_allallall()
assert self.client.get_address('Bcash', parse_path("44'/145'/0'/0/0")) == 'bitcoincash:qr08q88p9etk89wgv05nwlrkm4l0urz4cyl36hh9sv'
assert self.client.get_address('Bcash', parse_path("44'/145'/0'/0/1")) == 'bitcoincash:qr23ajjfd9wd73l87j642puf8cad20lfmqdgwvpat4'
assert self.client.get_address('Bcash', parse_path("44'/145'/0'/1/0")) == 'bitcoincash:qzc5q87w069lzg7g3gzx0c8dz83mn7l02scej5aluw'
@pytest.mark.skip_t2
def test_bch_multisig(self):
self.setup_mnemonic_allallall()
xpubs = []

View File

@ -21,7 +21,7 @@ import pytest
from .common import TrezorTest
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
@pytest.mark.lisk
@pytest.mark.skip_t1
class TestMsgLiskGetaddress(TrezorTest):

View File

@ -21,7 +21,7 @@ import pytest
from .common import TrezorTest
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
@pytest.mark.lisk
@pytest.mark.skip_t1
class TestMsgLiskGetPublicKey(TrezorTest):

View File

@ -1,39 +0,0 @@
# This file is part of the TREZOR project.
#
# Copyright (C) 2016-2017 Pavol Rusnak <stick@satoshilabs.com>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import hexlify
import pytest
from .common import TrezorTest
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
@pytest.mark.skip_t1
class TestMsgLiskSignmessage(TrezorTest):
def test_sign(self):
self.setup_mnemonic_nopin_nopassphrase()
sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648, 2147483648], 'This is an example of a signed message.')
assert sig.address == '7623396847864198749L'
assert hexlify(sig.signature) == b'af1d384cce25354b5af129662caed6f3514c6f1f6a206662d301fd56aa5549aa23c3f82009f213a7a4d9297015c2e5b06584273df7c42d78b4e531fe4d4fc80e'
def test_sign_long(self):
self.setup_mnemonic_nopin_nopassphrase()
sig = self.client.lisk_sign_message([2147483692, 2147483782, 2147483648], 'VeryLongMessage!' * 64)
assert sig.address == '17563781916205589679L'
print(hexlify(sig.signature))
assert hexlify(sig.signature) == b'a675152c2af34e85dbd75740681efb7d67bf910561d6c9d1e075be2f99d9bc544d62c52f6619756b0e329a2f2d82756ced53b4261a028fcee0d37d7e641ef404'

View File

@ -26,7 +26,7 @@ from trezorlib.tools import parse_path
PUBLIC_KEY = unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294')
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
@pytest.mark.lisk
@pytest.mark.skip_t1
class TestMsgLiskSignTx(TrezorTest):

View File

@ -1,55 +0,0 @@
# This file is part of the TREZOR project.
#
# Copyright (C) 2016-2017 Pavol Rusnak <stick@satoshilabs.com>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import unhexlify
import pytest
from .common import TrezorTest
from trezorlib import messages as proto
@pytest.mark.xfail # drop when trezor-core PR #90 is merged
@pytest.mark.skip_t1
class TestMsgLiskVerifymessage(TrezorTest):
def test_verify(self):
self.setup_mnemonic_nopin_nopassphrase()
with self.client:
self.client.set_expected_responses([
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.Success(message='Message verified')
])
self.client.lisk_verify_message(
unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'),
unhexlify('af1d384cce25354b5af129662caed6f3514c6f1f6a206662d301fd56aa5549aa23c3f82009f213a7a4d9297015c2e5b06584273df7c42d78b4e531fe4d4fc80e'),
'This is an example of a signed message.'
)
def test_verify_long(self):
self.setup_mnemonic_nopin_nopassphrase()
with self.client:
self.client.set_expected_responses([
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.ButtonRequest(code=proto.ButtonRequestType.Other),
proto.Success(message='Message verified')
])
self.client.lisk_verify_message(
unhexlify('eb56d7bbb5e8ea9269405f7a8527fe126023d1db2c973cfac6f760b60ae27294'),
unhexlify('7b4b481f6a07a874bdd1b590cd2b933c8b571c721484d9dc303f81b22d1f3c5f55ffe0704dbfd543ff9ea3e795facda871ddb422522257d33a8fe16ab4169601'),
'VeryLongMessage!' * 64
)

View File

@ -21,6 +21,7 @@ from .common import TrezorTest
from trezorlib.tools import parse_path
@pytest.mark.nem
@pytest.mark.xfail # to be removed when nem is merged
class TestMsgNEMGetaddress(TrezorTest):

View File

@ -24,6 +24,7 @@ from trezorlib.tools import parse_path
# assertion data from T1
@pytest.mark.nem
@pytest.mark.skip_t2
class TestMsgNEMSignTxMosaics(TrezorTest):

View File

@ -26,6 +26,7 @@ from trezorlib.tools import parse_path
# assertion data from T1
@pytest.mark.nem
@pytest.mark.skip_t1
@pytest.mark.xfail # to be removed when nem is merged
class TestMsgNEMSignTxMosaics(TrezorTest):

View File

@ -25,6 +25,7 @@ from trezorlib import nem
# assertion data from T1
@pytest.mark.nem
@pytest.mark.xfail # to be removed when nem is merged
class TestMsgNEMSignTxMultisig(TrezorTest):

View File

@ -25,6 +25,7 @@ from trezorlib.tools import parse_path
# assertion data from T1
@pytest.mark.nem
@pytest.mark.xfail # to be removed when nem is merged
class TestMsgNEMSignTxOther(TrezorTest):

View File

@ -26,6 +26,7 @@ from trezorlib.tools import parse_path
# assertion data from T1
@pytest.mark.nem
@pytest.mark.xfail # to be removed when nem is merged
class TestMsgNEMSignTx(TrezorTest):

View File

@ -15,7 +15,6 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
import pytest
from .common import TrezorTest
@ -34,6 +33,11 @@ class TestMsgRecoverydevice(TrezorTest):
language='english',
enforce_wordlist=True))
# click through confirmation
assert isinstance(ret, proto.ButtonRequest)
self.client.debug.press_yes()
ret = self.client.call_raw(proto.ButtonAck())
assert isinstance(ret, proto.PinMatrixRequest)
# Enter PIN for first time
@ -92,6 +96,11 @@ class TestMsgRecoverydevice(TrezorTest):
language='english',
enforce_wordlist=True))
# click through confirmation
assert isinstance(ret, proto.ButtonRequest)
self.client.debug.press_yes()
ret = self.client.call_raw(proto.ButtonAck())
fakes = 0
for _ in range(int(12 * 2)):
assert isinstance(ret, proto.WordRequest)
@ -136,6 +145,11 @@ class TestMsgRecoverydevice(TrezorTest):
language='english',
enforce_wordlist=True))
# click through confirmation
assert isinstance(ret, proto.ButtonRequest)
self.client.debug.press_yes()
ret = self.client.call_raw(proto.ButtonAck())
assert isinstance(ret, proto.WordRequest)
for _ in range(int(12 * 2)):
(word, pos) = self.client.debug.read_recovery_word()
@ -154,6 +168,11 @@ class TestMsgRecoverydevice(TrezorTest):
language='english',
enforce_wordlist=True))
# click through confirmation
assert isinstance(ret, proto.ButtonRequest)
self.client.debug.press_yes()
ret = self.client.call_raw(proto.ButtonAck())
assert isinstance(ret, proto.PinMatrixRequest)
# Enter PIN for first time

View File

@ -17,8 +17,10 @@
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import hexlify, unhexlify
import pytest
from .common import TrezorTest
from .conftest import TREZOR_VERSION
from trezorlib import coins
from trezorlib import messages as proto
@ -517,12 +519,9 @@ class TestMsgSigntx(TrezorTest):
proto.Failure(code=proto.FailureType.NotEnoughFunds)
])
try:
with pytest.raises(CallException) as exc:
self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
except CallException as e:
assert e.args[0] == proto.FailureType.NotEnoughFunds
else:
assert False # types.FailureType.NotEnoughFunds expected
assert exc.value.args[0] == proto.FailureType.NotEnoughFunds
def test_p2sh(self):
self.setup_mnemonic_nopin_nopassphrase()
@ -626,13 +625,10 @@ class TestMsgSigntx(TrezorTest):
assert hexlify(serialized_tx) == b'01000000021c032e5715d1da8115a2fe4f57699e15742fe113b0d2d1ca3b594649d322bec6010000006b483045022100f773c403b2f85a5c1d6c9c4ad69c43de66930fff4b1bc818eb257af98305546a0220443bde4be439f276a6ce793664b463580e210ec6c9255d68354449ac0443c76501210338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6ffffffff6ea42cd8d9c8e5441c4c5f85bfe50311078730d2881494f11f4d2257777a4958010000006b48304502210090cff1c1911e771605358a8cddd5ae94c7b60cc96e50275908d9bf9d6367c79f02202bfa72e10260a146abd59d0526e1335bacfbb2b4401780e9e3a7441b0480c8da0121038caebd6f753bbbd2bb1f3346a43cd32140648583673a31d62f2dfb56ad0ab9e3ffffffff02a0860100000000001976a9142f4490d5263906e4887ca2996b9e207af3e7824088aca0860100000000001976a914812c13d97f9159e54e326b481b8f88a73df8507a88ac00000000'
# Now run the attack, must trigger the exception
try:
with pytest.raises(CallException) as exc:
self.client.sign_tx('Bitcoin', [inp1, inp2], [out1, out2], debug_processor=attack_processor)
except CallException as exc:
assert exc.args[0] == proto.FailureType.ProcessError
assert exc.args[1] == 'Transaction has changed during signing'
else:
assert False # exception expected
assert exc.value.args[0] in (proto.FailureType.ProcessError, proto.FailureType.DataError)
assert exc.value.args[1].endswith('Transaction has changed during signing')
def test_attack_change_input_address(self):
# This unit test attempts to modify input address after the Trezor checked
@ -704,13 +700,14 @@ class TestMsgSigntx(TrezorTest):
proto.Failure(code=proto.FailureType.ProcessError),
])
# Now run the attack, must trigger the exception
try:
with pytest.raises(CallException) as exc:
self.client.sign_tx('Testnet', [inp1], [out1, out2], debug_processor=attack_processor)
except CallException as exc:
assert exc.args[0] == proto.FailureType.ProcessError
assert exc.args[1] == 'Transaction has changed during signing'
assert exc.value.args[0] == proto.FailureType.ProcessError
if TREZOR_VERSION == 1:
assert exc.value.args[1].endswith('Failed to compile input')
else:
assert False # exception expected
assert exc.value.args[1].endswith('Transaction has changed during signing')
def test_spend_coinbase(self):
# 25 TEST generated to m/1 (mfiGQVPcRcaEvQPYDErR34DcCovtxYvUUV)

View File

@ -29,7 +29,6 @@ from trezorlib.tools import parse_path
TxApiBcash = coins.tx_api['Bcash']
@pytest.mark.skip_t2
class TestMsgSigntxBch(TrezorTest):
def test_send_bch_change(self):
@ -224,16 +223,14 @@ class TestMsgSigntxBch(TrezorTest):
proto.ButtonRequest(code=proto.ButtonRequestType.SignTx),
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=1)),
proto.Failure(code=proto.FailureType.ProcessError),
proto.Failure(),
])
try:
with pytest.raises(CallException) as exc:
self.client.sign_tx('Bcash', [inp1, inp2], [out1], debug_processor=attack_processor)
except CallException as exc:
assert exc.args[0] == proto.FailureType.ProcessError
assert exc.args[1] == 'Transaction has changed during signing'
else:
assert False # exception expected
assert exc.value.args[0] in (proto.FailureType.ProcessError, proto.FailureType.DataError)
assert exc.value.args[1].endswith('Transaction has changed during signing')
def test_attack_change_input(self):
self.setup_mnemonic_allallall()

View File

@ -35,8 +35,8 @@ TXHASH_3f7c39 = unhexlify("3f7c395521d38387e7617565fe17628723ef6635a08537ad9c46c
TXHASH_16da18 = unhexlify("16da185052740d85a630e79c140558215b64e26c500212b90e16b55d13ca06a8")
@pytest.mark.skip_t1
@pytest.mark.skip_t2
@pytest.mark.decred
@pytest.mark.xfail(reason="Decred broken for 👻M👻Y👻S👻T👻E👻R👻I👻O👻U👻S reasons... 😱")
class TestMsgSigntxDecred(TrezorTest):
def test_send_decred(self):

View File

@ -16,9 +16,12 @@
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import hexlify, unhexlify
import pytest
from .common import TrezorTest
from ..support.ckd_public import deserialize
from .conftest import TREZOR_VERSION
from .common import TrezorTest
from trezorlib import coins
from trezorlib import messages as proto
from trezorlib.client import CallException
@ -236,10 +239,10 @@ class TestMsgSigntxSegwit(TrezorTest):
proto.TxRequest(request_type=proto.RequestType.TXINPUT, details=proto.TxRequestDetailsType(request_index=0)),
proto.Failure(code=proto.FailureType.ProcessError),
])
try:
with pytest.raises(CallException) as exc:
self.client.sign_tx('Testnet', [inp1], [out1, out2], debug_processor=attack_processor)
except CallException as exc:
assert exc.args[0] == proto.FailureType.ProcessError
assert exc.args[1] == 'Transaction has changed during signing'
assert exc.value.args[0] == proto.FailureType.ProcessError
if TREZOR_VERSION == 1:
assert exc.value.args[1].endswith("Failed to compile input")
else:
assert False # exception expected
assert exc.value.args[1].endswith('Transaction has changed during signing')

View File

@ -30,7 +30,11 @@ TxApiZcash = coins.tx_api["Zcash"]
TXHASH_93373e = unhexlify('93373e63cc626c4a7d049ad775d6511bb5eba985f142db660c9b9f955c722f5c')
@pytest.mark.skip(reason="Broken until we have support for Zcash v3 transactions.")
# Zcash reset their testnet, which broke our test because it was not properly cached.
# Then when we tried to revive it, Overwinter happened and now Trezor is incapable of
# processing v3 transactions. So it's difficult to fix the test until we support v3.
@pytest.mark.zcash
@pytest.mark.xfail(reason="Zcash support is botched due to Overwinter")
class TestMsgSigntxZcash(TrezorTest):
def test_one_one_fee(self):

View File

@ -19,6 +19,7 @@ from trezorlib import stellar
import pytest
@pytest.mark.stellar
@pytest.mark.xfail(TREZOR_VERSION == 2, reason="T2 support is not yet finished")
class TestMsgStellarGetPublicKey(TrezorTest):

View File

@ -17,12 +17,15 @@
# https://www.stellar.org/laboratory/#xdr-viewer
#
from base64 import b64decode, b64encode
from base64 import b64encode
from .common import TrezorTest
from .conftest import TREZOR_VERSION
from binascii import hexlify, unhexlify
from trezorlib import messages as proto
import pytest
@pytest.mark.stellar
@pytest.mark.xfail(TREZOR_VERSION == 2, reason="T2 support is not yet finished")
class TestMsgStellarSignTransaction(TrezorTest):
@ -37,15 +40,29 @@ class TestMsgStellarSignTransaction(TrezorTest):
def test_sign_tx_bump_sequence_op(self):
self.setup_mnemonic_nopin_nopassphrase()
xdr = b64decode("AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAt//////////wAAAAAAAAAA")
op = proto.StellarBumpSequenceOp()
op.bump_to = 0x7fffffffffffffff
tx = self._create_msg()
response = self.client.stellar_sign_transaction(xdr, self.get_address_n(), self.get_network_passphrase())
response = self.client.stellar_sign_transaction(tx, [op], self.get_address_n(), self.get_network_passphrase())
assert b64encode(response.signature) == b'UAOL4ZPYIOzEgM66kBrhyNjLR66dNXtuNrmvd3m0/pc8qCSoLmYY4TybS0lHiMtb+LFZESTaxrpErMHz1sZ6DQ=='
def test_sign_tx_account_merge_op(self):
self.setup_mnemonic_nopin_nopassphrase()
xdr = b64decode("AAAAABXWSL/k028ZbPtXNf/YylTNS4Iz90PyJEnefPMBzbRpAAAAZAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAAAAAAAAQHNtGkAAABAgjoPRj4sW5o7NAXzYOqPK0uxfPbeKb4Qw48LJiCH/XUZ6YVCiZogePC0Z5ISUlozMh6YO6HoYtuLPbm7jq+eCA==")
op = proto.StellarAccountMergeOp()
op.destination_account = unhexlify('5d55642466b185b843152e9e219151dbc5892027ec40101a517bed5ca030c2e0')
response = self.client.stellar_sign_transaction(xdr, self.get_address_n(), self.get_network_passphrase())
tx = self._create_msg()
response = self.client.stellar_sign_transaction(tx, [op], self.get_address_n(), self.get_network_passphrase())
assert b64encode(response.signature) == b'gjoPRj4sW5o7NAXzYOqPK0uxfPbeKb4Qw48LJiCH/XUZ6YVCiZogePC0Z5ISUlozMh6YO6HoYtuLPbm7jq+eCA=='
def _create_msg(self) -> proto.StellarSignTx:
tx = proto.StellarSignTx()
tx.protocol_version = 1
tx.source_account = unhexlify('15d648bfe4d36f196cfb5735ffd8ca54cd4b8233f743f22449de7cf301cdb469')
tx.fee = 100
tx.sequence_number = 0x100000000
tx.memo_type = 0
return tx

View File

@ -17,6 +17,7 @@
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import hexlify, unhexlify
import pytest
from .common import TrezorTest
from ..support import ckd_public as bip32
@ -248,10 +249,8 @@ class TestMultisig(TrezorTest):
script_type=proto.OutputScriptType.PAYTOADDRESS
)
try:
with pytest.raises(CallException) as exc:
self.client.sign_tx('Bitcoin', [inp1, ], [out1, ])
except CallException as exc:
assert exc.args[0] == proto.FailureType.DataError
assert exc.args[1] == 'Pubkey not found in multisig script'
else:
assert False # exception expected
assert exc.value.args[0] == proto.FailureType.DataError
assert exc.value.args[1].endswith('Pubkey not found in multisig script')

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this library. If not, see <http://www.gnu.org/licenses/>.
from binascii import unhexlify, hexlify
import pytest
from .common import TrezorTest
from .conftest import TREZOR_VERSION
from trezorlib import messages as proto
from trezorlib.client import CallException
@ -106,10 +107,12 @@ class TestOpReturn(TrezorTest):
proto.Failure()
])
try:
with pytest.raises(CallException) as exc:
self.client.sign_tx('Bitcoin', [inp1], [out1])
except CallException as exc:
assert exc.args[0] == proto.FailureType.DataError
assert exc.args[1] == 'OP_RETURN output with non-zero amount'
if TREZOR_VERSION == 1:
assert exc.value.args[0] == proto.FailureType.ProcessError
assert exc.value.args[1].endswith("Failed to compile output")
else:
assert False # exception expected
assert exc.value.args[0] == proto.FailureType.DataError
assert exc.value.args[1].endswith('OP_RETURN output with non-zero amount')

View File

@ -131,7 +131,10 @@ class TestProtectionLevels(TrezorTest):
def test_recovery_device(self):
with self.client:
self.client.set_mnemonic(self.mnemonic12)
self.client.set_expected_responses([proto.WordRequest()] * 24 + [proto.Success(), proto.Features()])
self.client.set_expected_responses(
[proto.ButtonRequest()] +
[proto.WordRequest()] * 24 +
[proto.Success(), proto.Features()])
self.client.recovery_device(12, False, False, 'label', 'english')
# This must fail, because device is already initialized
@ -152,7 +155,7 @@ class TestProtectionLevels(TrezorTest):
def test_verify_message(self):
with self.client:
self.setup_mnemonic_pin_passphrase()
self.client.set_expected_responses([proto.ButtonRequest(), proto.Success()])
self.client.set_expected_responses([proto.ButtonRequest(), proto.ButtonRequest(), proto.Success()])
self.client.verify_message(
'Bitcoin',
'14LmW5k4ssUrtbAB4255zdqv3b4w1TuX9e',

View File

@ -2,9 +2,6 @@
# adapted from https://github.com/stephanmg/travis-dependent-builds
# variables
USER=trezor
REPO=trezor-core
BRANCH=master
SOURCE=trezor/python-trezor
if [ "$TRAVIS_REPO_SLUG" != "$SOURCE" ]; then
@ -27,6 +24,12 @@ if [[ "$TRAVIS_JOB_NUMBER" != *.1 ]]; then
exit 0;
fi
function trigger_build() {
USER="$1"
REPO="$2"
BRANCH="$3"
echo "attempting to trigger build of $USER/$REPO"
MESSAGE=",\"message\": \"Triggered from upstream build of $TRAVIS_REPO_SLUG by commit "`git rev-parse --short HEAD`"\""
# curl POST request content body
@ -36,7 +39,6 @@ BODY="{
$MESSAGE
}}"
echo "attempting to trigger build of $USER/$REPO"
# make a POST request with curl (note %2F could be replaced with
# / and additional curl arguments, however this works too!)
curl -s -X POST \
@ -47,6 +49,7 @@ curl -s -X POST \
-d "$BODY" \
https://api.travis-ci.org/repo/${USER}%2F${REPO}/requests \
| tee /tmp/travis-request-output.$$.txt
echo
if grep -q '"@type": "error"' /tmp/travis-request-output.$$.txt; then
cat /tmp/travis-request-output.$$.txt
@ -55,3 +58,8 @@ elif grep -q 'access denied' /tmp/travis-request-output.$$.txt; then
cat /tmp/travis-request-output.$$.txt
exit 1
fi
}
# trigger both core and mcu
trigger_build trezor trezor-core master
trigger_build trezor trezor-mcu master

@ -1 +1 @@
Subproject commit 44dfb07cfaafffada4b2ce0d15ba1d90d17cf35e
Subproject commit 8fc001154e49c2c1747957c4a9a1ab92dcc86edb