[Python-modules-commits] [python-trezor] 01/02: Import python-trezor_0.6.13.orig.tar.gz

Tristan Seligmann mithrandi at moszumanska.debian.org
Mon Aug 8 03:06:42 UTC 2016


This is an automated email from the git hooks/post-receive script.

mithrandi pushed a commit to branch master
in repository python-trezor.

commit 4140ea0937e56a9acba66450ad3af529bb780a92
Author: Tristan Seligmann <mithrandi at mithrandi.net>
Date:   Mon Aug 8 03:33:46 2016 +0200

    Import python-trezor_0.6.13.orig.tar.gz
---
 MANIFEST.in                       |   1 +
 PKG-INFO                          |   2 +-
 README.rst                        |  28 +-
 setup.py                          |   4 +-
 tests/common.py                   |  41 ++
 tests/config.py                   |  37 ++
 tests/run-separate.sh             |   5 +
 tests/run.sh                      |   3 +
 tests/test_basic.py               |  36 ++
 tests/test_bip32_speed.py         |  56 +++
 tests/test_debuglink.py           |  42 ++
 tests/test_ecies.py               | 134 ++++++
 tests/test_msg_applysettings.py   |  78 ++++
 tests/test_msg_changepin.py       | 204 ++++++++++
 tests/test_msg_cipherkeyvalue.py  |  74 ++++
 tests/test_msg_clearsession.py    |  39 ++
 tests/test_msg_estimatetxsize.py  |  34 ++
 tests/test_msg_getaddress.py      |  44 ++
 tests/test_msg_getaddress_show.py |  49 +++
 tests/test_msg_getentropy.py      |  34 ++
 tests/test_msg_getpublickey.py    |  28 ++
 tests/test_msg_loaddevice.py      |  88 ++++
 tests/test_msg_ping.py            |  48 +++
 tests/test_msg_recoverydevice.py  | 157 +++++++
 tests/test_msg_resetdevice.py     | 206 ++++++++++
 tests/test_msg_signidentity.py    |  73 ++++
 tests/test_msg_signmessage.py     |  45 ++
 tests/test_msg_signtx.py          | 598 +++++++++++++++++++++++++++
 tests/test_msg_simplesigntx.py    | 360 ++++++++++++++++
 tests/test_msg_verifymessage.py   | 132 ++++++
 tests/test_msg_wipedevice.py      |  25 ++
 tests/test_multisig.py            | 224 ++++++++++
 tests/test_multisig_change.py     | 355 ++++++++++++++++
 tests/test_op_return.py           |  92 +++++
 tests/test_protect_call.py        | 117 ++++++
 tests/test_protection_levels.py   | 196 +++++++++
 tests/test_zerosig.py             |  88 ++++
 trezor.egg-info/PKG-INFO          |   2 +-
 trezor.egg-info/SOURCES.txt       |  34 ++
 trezor.egg-info/requires.txt      |   2 +-
 trezorctl                         | 188 ++++++---
 trezorlib/ckd_public.py           |   6 +-
 trezorlib/client.py               | 112 +++--
 trezorlib/debuglink.py            |  24 +-
 trezorlib/mapping.py              |   2 +-
 trezorlib/messages_pb2.py         | 836 ++++++++++++++++++++++++++++++++++----
 trezorlib/protobuf_json.py        |  11 +-
 trezorlib/qt/pinmatrix.py         |  10 +-
 trezorlib/tools.py                |  10 +-
 trezorlib/transport.py            |  43 +-
 trezorlib/transport_bridge.py     |  15 +-
 trezorlib/transport_fake.py       |  12 +-
 trezorlib/transport_hid.py        |  56 +--
 trezorlib/transport_pipe.py       |  39 +-
 trezorlib/transport_serial.py     |  20 +-
 trezorlib/transport_socket.py     |  44 +-
 trezorlib/tx_api.py               |  65 ++-
 trezorlib/types_pb2.py            |  83 ++--
 58 files changed, 5038 insertions(+), 353 deletions(-)

diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..dcb861c
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+recursive-include tests *.py *.sh
diff --git a/PKG-INFO b/PKG-INFO
index 0e63933..67954e6 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: trezor
-Version: 0.6.11
+Version: 0.6.13
 Summary: Python library for communicating with TREZOR Bitcoin Hardware Wallet
 Home-page: https://github.com/trezor/python-trezor
 Author: Bitcoin TREZOR
diff --git a/README.rst b/README.rst
index 0ce7263..73a0358 100644
--- a/README.rst
+++ b/README.rst
@@ -4,7 +4,10 @@ python-trezor
 .. image:: https://travis-ci.org/trezor/python-trezor.svg?branch=master
     :target: https://travis-ci.org/trezor/python-trezor
 
-Client side implementation for Trezor-compatible Bitcoin hardware wallets.
+.. image:: https://badges.gitter.im/trezor/community.svg
+    :target: https://gitter.im/trezor/community
+
+Client side implementation for TREZOR-compatible Bitcoin hardware wallets.
 
 See http://bitcointrezor.com for more information.
 
@@ -26,7 +29,7 @@ also found in ``helloworld.py``
 
       # Check whether we found any
       if len(devices) == 0:
-          print 'No TREZOR found'
+          print('No TREZOR found')
           return
 
       # Use first connected device
@@ -36,13 +39,13 @@ also found in ``helloworld.py``
       client = TrezorClient(transport)
 
       # Print out TREZOR's features and settings
-      print client.features
+      print(client.features)
 
       # Get the first address of first BIP44 account
       # (should be the same address as shown in mytrezor.com)
       bip32_path = client.expand_path("44'/0'/0'/0/0")
       address = client.get_address('Bitcoin', bip32_path)
-      print 'Bitcoin address:', address
+      print('Bitcoin address:', address)
 
       client.close()
 
@@ -70,8 +73,17 @@ Example: your PIN is **1234** and TREZOR is displaying the following:
 
 You have to enter: **3795**
 
-How to install (Windows)
-------------------------
+Install
+-------
+
+(Run with sudo if not running in superuser mode)
+
+.. code::
+
+  pip install trezor
+
+How to install from source (Windows)
+------------------------------------
 * Install Python 2.7 (http://python.org)
 * Install Cython (Windows binaries on http://cython.org/#download)
 * Install Microsoft Visual Studio 2008 Express
@@ -79,8 +91,8 @@ How to install (Windows)
 * Clone repository (using TortoiseGit) to local directory
 * Run C:\\python27\\python.exe setup.py install (or develop)
 
-How to install (Debian-Ubuntu)
-------------------------------
+How to install from source (Debian/Ubuntu)
+------------------------------------------
 * sudo apt-get install python-dev python-setuptools cython libusb-1.0-0-dev libudev-dev git
 * git clone https://github.com/trezor/python-trezor.git
 * cd python-trezor
diff --git a/setup.py b/setup.py
index d40560c..09a87e5 100755
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@ from setuptools import setup
 
 setup(
     name='trezor',
-    version='0.6.11',
+    version='0.6.13',
     author='Bitcoin TREZOR',
     author_email='info at bitcointrezor.com',
     description='Python library for communicating with TREZOR Bitcoin Hardware Wallet',
@@ -29,7 +29,7 @@ setup(
     ],
     scripts = ['trezorctl'],
     test_suite='tests',
-    install_requires=['ecdsa>=0.9', 'protobuf==2.6.1', 'mnemonic>=0.8', 'hidapi>=0.7.99'],
+    install_requires=['ecdsa>=0.9', 'protobuf>=2.6.1', 'mnemonic>=0.8', 'hidapi>=0.7.99'],
     include_package_data=True,
     zip_safe=False,
     classifiers=[
diff --git a/tests/common.py b/tests/common.py
new file mode 100644
index 0000000..3a8bd90
--- /dev/null
+++ b/tests/common.py
@@ -0,0 +1,41 @@
+from __future__ import print_function
+
+import unittest
+from trezorlib.client import TrezorDebugClient
+from trezorlib.tx_api import TXAPIBitcoin
+import config
+
+class TrezorTest(unittest.TestCase):
+    def setUp(self):
+        self.debug_transport = config.DEBUG_TRANSPORT(*config.DEBUG_TRANSPORT_ARGS, **config.DEBUG_TRANSPORT_KWARGS)
+        self.transport = config.TRANSPORT(*config.TRANSPORT_ARGS, **config.TRANSPORT_KWARGS)
+        self.client = TrezorDebugClient(self.transport)
+        self.client.set_debuglink(self.debug_transport)
+        self.client.set_tx_api(TXAPIBitcoin())
+        # self.client.set_buttonwait(3)
+
+        #                     1      2     3    4      5      6      7     8      9    10    11    12
+        self.mnemonic12 = 'alcohol woman abuse must during monitor noble actual mixed trade anger aisle'
+        self.mnemonic18 = 'owner little vague addict embark decide pink prosper true fork panda embody mixture exchange choose canoe electric jewel'
+        self.mnemonic24 = 'dignity pass list indicate nasty swamp pool script soccer toe leaf photo multiply desk host tomato cradle drill spread actor shine dismiss champion exotic'
+
+        self.pin4 = '1234'
+        self.pin6 = '789456'
+        self.pin8 = '45678978'
+
+        self.client.wipe_device()
+
+        print("Setup finished")
+        print("--------------")
+
+    def setup_mnemonic_nopin_nopassphrase(self):
+        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12, pin='', passphrase_protection=False, label='test', language='english')
+
+    def setup_mnemonic_pin_nopassphrase(self):
+        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12, pin=self.pin4, passphrase_protection=False, label='test', language='english')
+
+    def setup_mnemonic_pin_passphrase(self):
+        self.client.load_device_by_mnemonic(mnemonic=self.mnemonic12, pin=self.pin4, passphrase_protection=True, label='test', language='english')
+
+    def tearDown(self):
+        self.client.close()
diff --git a/tests/config.py b/tests/config.py
new file mode 100644
index 0000000..7b882e4
--- /dev/null
+++ b/tests/config.py
@@ -0,0 +1,37 @@
+from __future__ import print_function
+
+import sys
+sys.path = ['../',] + sys.path
+
+from trezorlib.transport_pipe import PipeTransport
+from trezorlib.transport_hid import HidTransport
+from trezorlib.transport_socket import SocketTransportClient
+#from trezorlib.transport_bridge import BridgeTransport
+
+devices = HidTransport.enumerate()
+
+if len(devices) > 0:
+    if devices[0][1] != None:
+        print('Using TREZOR')
+        TRANSPORT = HidTransport
+        TRANSPORT_ARGS = (devices[0],)
+        TRANSPORT_KWARGS = {'debug_link': False}
+        DEBUG_TRANSPORT = HidTransport
+        DEBUG_TRANSPORT_ARGS = (devices[0],)
+        DEBUG_TRANSPORT_KWARGS = {'debug_link': True}
+    else:
+        print('Using Raspberry Pi')
+        TRANSPORT = HidTransport
+        TRANSPORT_ARGS = (devices[0],)
+        TRANSPORT_KWARGS = {'debug_link': False}
+        DEBUG_TRANSPORT = SocketTransportClient
+        DEBUG_TRANSPORT_ARGS = ('trezor.bo:2000',)
+        DEBUG_TRANSPORT_KWARGS = {}
+else:
+    print('Using Emulator')
+    TRANSPORT = PipeTransport
+    TRANSPORT_ARGS = ('/tmp/pipe.trezor', False)
+    TRANSPORT_KWARGS = {}
+    DEBUG_TRANSPORT = PipeTransport
+    DEBUG_TRANSPORT_ARGS = ('/tmp/pipe.trezor_debug', False)
+    DEBUG_TRANSPORT_KWARGS = {}
diff --git a/tests/run-separate.sh b/tests/run-separate.sh
new file mode 100755
index 0000000..4b04fb2
--- /dev/null
+++ b/tests/run-separate.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+for i in test_*.py; do
+  echo Starting: $i
+  python $i > $i.out 2> $i.err
+done
diff --git a/tests/run.sh b/tests/run.sh
new file mode 100755
index 0000000..5936b79
--- /dev/null
+++ b/tests/run.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+python -m unittest discover
diff --git a/tests/test_basic.py b/tests/test_basic.py
new file mode 100644
index 0000000..4d25819
--- /dev/null
+++ b/tests/test_basic.py
@@ -0,0 +1,36 @@
+import unittest
+import common
+
+from trezorlib import messages_pb2 as messages
+
+class TestBasic(common.TrezorTest):
+
+    def test_features(self):
+        features = self.client.call(messages.Initialize())
+        self.assertEqual(features, self.client.features)
+
+    def test_ping(self):
+        ping = self.client.call(messages.Ping(message='ahoj!'))
+        self.assertEqual(ping, messages.Success(message='ahoj!'))
+
+    def test_device_id_same(self):
+        id1 = self.client.get_device_id()
+        self.client.init_device()
+        id2 = self.client.get_device_id()
+
+        # ID must be at least 12 characters
+        self.assertTrue(len(id1) >= 12)
+
+        # Every resulf of UUID must be the same
+        self.assertEqual(id1, id2)
+
+    def test_device_id_different(self):
+        id1 = self.client.get_device_id()
+        self.client.wipe_device()
+        id2 = self.client.get_device_id()
+
+        # Device ID must be fresh after every reset
+        self.assertNotEqual(id1, id2)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_bip32_speed.py b/tests/test_bip32_speed.py
new file mode 100644
index 0000000..8c8fa11
--- /dev/null
+++ b/tests/test_bip32_speed.py
@@ -0,0 +1,56 @@
+from __future__ import print_function
+
+import unittest
+import common
+import time
+from trezorlib import tools
+
+class TestBip32Speed(common.TrezorTest):
+
+    def test_public_ckd(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+
+        self.client.get_address('Bitcoin', [])  # to compute root node via BIP39
+
+        for depth in range(8):
+            start = time.time()
+            self.client.get_address('Bitcoin', range(depth))
+            delay = time.time() - start
+            expected = (depth + 1) * 0.26
+            print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
+            self.assertLessEqual(delay, expected)
+
+    def test_private_ckd(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+
+        self.client.get_address('Bitcoin', [])  # to compute root node via BIP39
+
+        for depth in range(8):
+            start = time.time()
+            self.client.get_address('Bitcoin', range(-depth, 0))
+            delay = time.time() - start
+            expected = (depth + 1) * 0.26
+            print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
+            self.assertLessEqual(delay, expected)
+
+    def test_cache(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+
+        start = time.time()
+        for x in range(10):
+            self.client.get_address('Bitcoin', [x, 2, 3, 4, 5, 6, 7, 8])
+        nocache_time = time.time() - start
+
+        start = time.time()
+        for x in range(10):
+            self.client.get_address('Bitcoin', [1, 2, 3, 4, 5, 6, 7, x])
+        cache_time = time.time() - start
+
+        print("NOCACHE TIME", nocache_time)
+        print("CACHED TIME", cache_time)
+
+        # Cached time expected to be at least 2x faster
+        self.assertLessEqual(cache_time, nocache_time / 2.)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_debuglink.py b/tests/test_debuglink.py
new file mode 100644
index 0000000..3ad8044
--- /dev/null
+++ b/tests/test_debuglink.py
@@ -0,0 +1,42 @@
+import time
+import unittest
+import common
+import binascii
+
+from trezorlib import messages_pb2 as proto
+from trezorlib import types_pb2 as types
+from trezorlib.client import PinException
+
+class TestDebugLink(common.TrezorTest):
+
+    def test_layout(self):
+        layout = self.client.debug.read_layout()
+        self.assertEqual(len(layout), 1024)
+
+    def test_mnemonic(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+        mnemonic = self.client.debug.read_mnemonic()
+        self.assertEqual(mnemonic, self.mnemonic12)
+
+    def test_node(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+        node = self.client.debug.read_node()
+        self.assertIsNotNone(node)
+
+    def test_pin(self):
+        self.setup_mnemonic_pin_passphrase()
+
+        # Manually trigger PinMatrixRequest
+        resp = self.client.call_raw(proto.Ping(message='test', pin_protection=True))
+        self.assertIsInstance(resp, proto.PinMatrixRequest)
+
+        pin = self.client.debug.read_pin()
+        self.assertEqual(pin[0], '1234')
+        self.assertNotEqual(pin[1], '')
+
+        pin_encoded = self.client.debug.read_pin_encoded()
+        resp = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+        self.assertIsInstance(resp, proto.Success)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_ecies.py b/tests/test_ecies.py
new file mode 100644
index 0000000..b04b693
--- /dev/null
+++ b/tests/test_ecies.py
@@ -0,0 +1,134 @@
+from __future__ import print_function
+
+import unittest
+import common
+import binascii
+import base64
+
+from trezorlib.client import CallException
+
+# as described here: http://memwallet.info/btcmssgs.html
+
+def test_ecies_backforth(cls, test_string):
+    cls.setup_mnemonic_nopin_nopassphrase()
+
+    pubkey = binascii.unhexlify('0338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6')
+
+    # encrypt without signature
+    enc = cls.client.encrypt_message(pubkey, test_string, display_only=False, coin_name='Bitcoin', n=[])
+    print('base64:', base64.b64encode(enc.nonce + enc.message + enc.hmac))
+    dec = cls.client.decrypt_message([1], enc.nonce, enc.message, enc.hmac)
+    cls.assertEqual(dec.message, test_string)
+    cls.assertEqual(dec.address, '')
+
+    # encrypt with signature
+    enc = cls.client.encrypt_message(pubkey, test_string, display_only=False, coin_name='Bitcoin', n=[5])
+    print('base64:', base64.b64encode(enc.nonce + enc.message + enc.hmac))
+    dec = cls.client.decrypt_message([1], enc.nonce, enc.message, enc.hmac)
+    cls.assertEqual(dec.message, test_string)
+    cls.assertEqual(dec.address, '1Csf6LVPkv24FBs6bpj4ELPszE6mGf6jeV')
+
+    # encrypt without signature, show only on display
+    enc = cls.client.encrypt_message(pubkey, test_string, display_only=True, coin_name='Bitcoin', n=[])
+    dec = cls.client.decrypt_message([1], enc.nonce, enc.message, enc.hmac)
+    cls.assertEqual(dec.message, '')
+    cls.assertEqual(dec.address, '')
+
+    # encrypt with signature, show only on display
+    enc = cls.client.encrypt_message(pubkey, test_string, display_only=True, coin_name='Bitcoin', n=[5])
+    dec = cls.client.decrypt_message([1], enc.nonce, enc.message, enc.hmac)
+    cls.assertEqual(dec.message, '')
+    cls.assertEqual(dec.address, '')
+
+class TestEcies(common.TrezorTest):
+
+# index:   m/1
+# address: 1CK7SJdcb8z9HuvVft3D91HLpLC6KSsGb
+# pubkey:  0338d78612e990f2eea0c426b5e48a8db70b9d7ed66282b3b26511e0b1c75515a6
+# privkey: L5X3rf5hJfRt9ZjQzFopvSBGkpnSotn4jKGLL6ECJxcuT2JgGh65
+
+# index:   m/5
+# address: 1Csf6LVPkv24FBs6bpj4ELPszE6mGf6jeV
+# pubkey:  0234716c01c2dd03fa7ee302705e2b8fbd1311895d94b1dca15e62eedea9b0968f
+# privkey: L4uKPRgaZqL9iGmge3UBSLGTQC7gDFrLRhC1vM4LmGyrzNUBb1Zs
+
+    def test_ecies_backforth_short(self):
+        test_ecies_backforth(self, 'testing message!')
+
+    def test_ecies_backforth_long(self):
+        test_ecies_backforth(self, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin elementum libero in tortor condimentum malesuada. Quisque gravida semper sapien, ut ultrices dolor pharetra nec. Nulla hendrerit metus imperdiet, feugiat sapien eu, fermentum mauris. Suspendisse nec bibendum urna. Vivamus augue libero, mollis vel augue at, venenatis vestibulum nunc. Curabitur condimentum quam non nibh volutpat, at congue libero rutrum. Morbi at sollicitudin lectus. Donec co [...]
+
+    def test_ecies_crosscheck(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+
+        # decrypt message without signature
+        payload = 'AhA1yCZStrmtuGSgliJ7K02eD8xWRoyRU1ryPu9kBloODFv9hATpqukL0YSzISfrQGygYVai5OirxU0='
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, 'testing message!')
+        self.assertEqual(dec.address, '')
+
+        # decrypt message without signature (same message, different nonce)
+        payload = 'A9ragu6UTXisBWw6bTCcM/SeR7fmlQp6Qzg9mpJ5qKBv9BIgWX/v/u+OhdlKLZTx6C0Xooz5aIvWrqw='
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, 'testing message!')
+        self.assertEqual(dec.address, '')
+
+        # decrypt message with signature
+        payload = 'A90Awe+vrQvmzFvm0hh8Ver7jcBbqiCxV4RGU9knKf6F3vvG1N45Q3kc+N1sd4inzXZnW/5KH74CXaCPGAKr/a0n4BUhADVfS2Ic9Luwcs6/cuYHSzJKKLSPUYC6N4hu1K0q1vR/02BJ+iZ0pfvChoGDmpOOO7NaIEoyiKAnZFNsHr6Ffplg3YVGJAAG7GgfSQ=='
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, 'testing message!')
+        self.assertEqual(dec.address, '1Csf6LVPkv24FBs6bpj4ELPszE6mGf6jeV')
+
+        # decrypt message with signature (same message, different nonce)
+        payload = 'AyeglkkBSc3VLNrXETiNtiS+t2nIKeEVGMVfF7KlVM+plBuX3yc+2kf+Yo6L1NKoqEjSlRXn71OTOEWfB2zmtasIX9dQBfyGluEivbeUfqbwneepEzv9/i0XI3ywfSa2HSdic8B68nZ3D6Mms4qOpzk6AEPt/yI7fl8aUsN0lxT8nVBfMmmg10oydvH/86cWYA=='
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, 'testing message!')
+        self.assertEqual(dec.address, '1Csf6LVPkv24FBs6bpj4ELPszE6mGf6jeV')
+
+    def test_ecies_crosscheck_long(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+
+        lipsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin elementum libero in tortor condimentum malesuada. Quisque gravida semper sapien, ut ultrices dolor pharetra nec. Nulla hendrerit metus imperdiet, feugiat sapien eu, fermentum mauris. Suspendisse nec bibendum urna. Vivamus augue libero, mollis vel augue at, venenatis vestibulum nunc. Curabitur condimentum quam non nibh volutpat, at congue libero rutrum. Morbi at sollicitudin lectus. Donec commodo rutrum solli [...]
+
+        # decrypt message without signature
+        payload = 'AhnOXSv+7mI3Tvw0ekCxvEoMvophrWOGAwLT2IpyxaCd+zgftijj2uQoGtSktFwch8oABstTqwBjokH4AllH7PaL/8dWwOELwEVIXlbktf8nktUITBkJ0Abih8Imq451Bwrt8ZMt0tzoDBWeRLtZGHPduHnykGjq1O3A8Qjd4k8W+PkPBum+rNKlPOUqoNpSvOcPD9L6APkMByPKMmTq5K9nSeLKyXjOtWcx4BLRqRe9qgvG+SWFHsJ/90O76XZIB6GXDqGnCNR5rV/8Ho4bfagRL/tQPbeQ4iYWAyqdRlKuwnUrrZSJCdrsQJt1Ye5LcltE0YhJBKRmxob2/P+ziyceZk6cU3hS9k4B1GKlEeGxipvMswfbrEIy/5NYiGXEDwC3dHwM3g1Opz5oXbEKZ3NG/eEh5UxJFjfyx1qumQeSaIo5XFOf81A4dhH1vAT8MMEQN7bXXwCb1fxDC9wblCP9i [...]
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, lipsum)
+        self.assertEqual(dec.address, '')
+
+        # decrypt message without signature (same message, different nonce)
+        payload = 'A2bVIKzpPVYJlPP6WMiwhpabJfJAHH927StDsUyRL2h3xc/aMPVN6rYA9GwcsPSDiZpPZdjCVYM4uDwFQ/kBNA1p5XlDs6IBGtGGgbR7P5wHgJaxcw1zWZ+TsWTIWVj3psy0CFg7zCfqeV2y0OzIvJc/p+ONdVb1f9TmTICPoVGJ9AVXdnfdqdIn+wLYScUklTp10ldfUCmt5iAsJJR1p+h+xa+wwUdyCxpvnxOZDxA0EFmxQskBhcDbLL2nmQkLm5RnLQgpefMCEJrdz5g9htC5y65eod2SFBV8oJrN1ryh4PdRn5+JyVcwWhQeCHTK3m6vOIwwht5lm2uCLpcEttDoxo5k3LcBPE4rlPVYCf8qja6sRKq/WYiLdwXnooX/qmmLQ7Lo2DBs4hB6VQGgPSSTH/3/rUb11bL2Ieyq73ZICeIbHCIvjFqhd/atkNvQTnCrNmFybyxdMqE/4Yrv7b//h [...]
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, lipsum)
+        self.assertEqual(dec.address, '')
+
+        # decrypt message with signature
+        payload = 'ArJoHqnmLY22QiCePXk9yNQSK6g8BMGLkKkj72p35hCW1gxVajIZyptgbBp4A0LV8Fshe6MKnHO5PGw2BPQ6yTES5Q+7c8ZjC4m8JCKOOU8l7et4AcftPElxBdKimEv5B5egQmzSYds6dfB73VsWi2k9J/1RpckB2WDvXSrF1915XA4tMTMefB/DhzdrG9gkVTBqaROTgxlXWJhqdFag4aghVcXS5Ru6CQH0cLoxmZWf8mx/pK4liXyH1Gm+7fl8cd9iDkNTJEapzn/Ohh7JYxJrV/i4p0xE9L5CONL+UIL8DtGB8SgAWtd5cHdpLhMywRFxjDvho20nE3VyGREhqiv9i3ywXRox/zd6OFBkxSA3kuWNRrkDRBx4Q+2j49V5iQquuu5horUuRRYN1HVvoOYjVkfEJV70yvVg3xR2MeJouUa1aP7WF9JPo8vor252/ZU6L15mveE0JZH1HtoierC1Q [...]
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, lipsum)
+        self.assertEqual(dec.address, '1Csf6LVPkv24FBs6bpj4ELPszE6mGf6jeV')
+
+        # decrypt message with signature (same message, different nonce)
+        payload = 'AjFarEh66x2DZ9S3T/n8/xnYZQRwnuugxCDfIIEDPKkdfgwYPjGhtg3k/9ryj42MDgmey71ZvDhUdj+igcBKaPiKAS7p88kQxl6R6sFkL/wKwTdXPboA/n63BnHrtNNDIp12Dlgn2m0nSCLOchlh2maIBqB68qIqy21tT10ZrMpTfPd+4MI4NOzs42BQJAOLy19rMTKoCXGWIsgEERG0qCm38onYVUmj5UvtQIdDLIZ/ta4WD+FqM3Y9pJsU648qV72l/xM27BjIxVqUsw6MHLrAUNTmmd+D7dPAIjL66Gr5hEHCTcHP8oCIkeC+MK2JVcHN12F1Rx+8iwNf4nsixUcZJ/RX9JOTxJj3CdxuTH3b0lDNdFwQQddYhHd6cv4t1cZ3wOWAVh1g+gmB/igmvJD200EfhQudHp/w+9BIFFfxFwAmf4/tlidJ0knIaPjNx5kBSkklhxWdBfen5kgkGFtcQ [...]
+        payload = base64.b64decode(payload)
+        nonce, msg, hmac = payload[:33], payload[33:-8], payload[-8:]
+        dec = self.client.decrypt_message([1], nonce, msg, hmac)
+        self.assertEqual(dec.message, lipsum)
+        self.assertEqual(dec.address, '1Csf6LVPkv24FBs6bpj4ELPszE6mGf6jeV')
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_msg_applysettings.py b/tests/test_msg_applysettings.py
new file mode 100644
index 0000000..0ef5da2
--- /dev/null
+++ b/tests/test_msg_applysettings.py
@@ -0,0 +1,78 @@
+import time
+import unittest
+import common
+
+from trezorlib import messages_pb2 as proto
+
+class TestMsgApplysettings(common.TrezorTest):
+
+    def test_apply_settings(self):
+        self.setup_mnemonic_pin_passphrase()
+        self.assertEqual(self.client.features.label, 'test')
+
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(),
+                                                proto.PinMatrixRequest(),
+                                                proto.Success(),
+                                                proto.Features()])
+            self.client.apply_settings(label='new label')
+
+        self.assertEqual(self.client.features.label, 'new label')
+
+    def test_invalid_language(self):
+        self.setup_mnemonic_pin_passphrase()
+        self.assertEqual(self.client.features.language, 'english')
+
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(),
+                                                proto.PinMatrixRequest(),
+                                                proto.Success(),
+                                                proto.Features()])
+            self.client.apply_settings(language='nonexistent')
+
+        self.assertEqual(self.client.features.language, 'english')
+
+    def test_apply_settings_passphrase(self):
+        self.setup_mnemonic_pin_nopassphrase()
+
+        self.assertEqual(self.client.features.passphrase_protection, False)
+
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(),
+                                                proto.PinMatrixRequest(),
+                                                proto.Success(),
+                                                proto.Features()])
+            self.client.apply_settings(use_passphrase=True)
+
+        self.assertEqual(self.client.features.passphrase_protection, True)
+
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(),
+                                                proto.Success(),
+                                                proto.Features()])
+            self.client.apply_settings(use_passphrase=False)
+
+        self.assertEqual(self.client.features.passphrase_protection, False)
+
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(),
+                                                proto.Success(),
+                                                proto.Features()])
+            self.client.apply_settings(use_passphrase=True)
+
+        self.assertEqual(self.client.features.passphrase_protection, True)
+
+    def test_apply_homescreen(self):
+        self.setup_mnemonic_pin_passphrase()
+
+        img = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x04\x80\x00\x00\x00\x00\x00\x00\x00\x00\x04\x88\x02\x00\x00\x00\x02\x91\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x90@\x00\x11@\x00\x00\x00\x00\x00\x00\x08\x00\x10\x92\x12\x04\x00\x00\x05\x12D\x00\x00\x00\x00\x00 \x00\x00\x08\x00Q\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x10\x02 \x01\x04J\x00)$\x00\x00\x00\x00\x80\x00\x00\x00\x00\x08\x10\xa1\x00\x00\x02\x8 [...]
+
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(),
+                                                proto.PinMatrixRequest(),
+                                                proto.Success(),
+                                                proto.Features()])
+            self.client.apply_settings(homescreen=img)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_msg_changepin.py b/tests/test_msg_changepin.py
new file mode 100644
index 0000000..3a0756a
--- /dev/null
+++ b/tests/test_msg_changepin.py
@@ -0,0 +1,204 @@
+import time
+import unittest
+import common
+
+from trezorlib import messages_pb2 as proto
+from trezorlib import types_pb2 as proto_types
+
+class TestMsgChangepin(common.TrezorTest):
+
+    def test_set_pin(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+        features = self.client.call_raw(proto.Initialize())
+        self.assertFalse(features.pin_protection)
+
+        # Check that there's no PIN protection
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.Success)
+
+        # Let's set new PIN
+        ret = self.client.call_raw(proto.ChangePin())
+        self.assertIsInstance(ret, proto.ButtonRequest)
+
+        # Press button
+        self.client.debug.press_yes()
+        ret = self.client.call_raw(proto.ButtonAck())
+
+        # Send the PIN for first time
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin6)
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Send the PIN for second time
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin6)
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Now we're done
+        self.assertIsInstance(ret, proto.Success)
+
+        # Check that there's PIN protection now
+        features = self.client.call_raw(proto.Initialize())
+        self.assertTrue(features.pin_protection)
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        self.client.call_raw(proto.Cancel())
+
+        # Check that the PIN is correct
+        self.assertEqual(self.client.debug.read_pin()[0], self.pin6)
+
+    def test_change_pin(self):
+        self.setup_mnemonic_pin_passphrase()
+        features = self.client.call_raw(proto.Initialize())
+        self.assertTrue(features.pin_protection)
+
+        # Check that there's PIN protection
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        self.client.call_raw(proto.Cancel())
+
+        # Check current PIN value
+        self.assertEqual(self.client.debug.read_pin()[0], self.pin4)
+
+        # Let's change PIN
+        ret = self.client.call_raw(proto.ChangePin())
+        self.assertIsInstance(ret, proto.ButtonRequest)
+
+        # Press button
+        self.client.debug.press_yes()
+        ret = self.client.call_raw(proto.ButtonAck())
+
+        # Send current PIN
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.read_pin_encoded()
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Send new PIN for first time
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin6)
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Send the PIN for second time
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin6)
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Now we're done
+        self.assertIsInstance(ret, proto.Success)
+
+        # Check that there's still PIN protection now
+        features = self.client.call_raw(proto.Initialize())
+        self.assertTrue(features.pin_protection)
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        self.client.call_raw(proto.Cancel())
+
+        # Check that the PIN is correct
+        self.assertEqual(self.client.debug.read_pin()[0], self.pin6)
+
+    def test_remove_pin(self):
+        self.setup_mnemonic_pin_passphrase()
+        features = self.client.call_raw(proto.Initialize())
+        self.assertTrue(features.pin_protection)
+
+        # Check that there's PIN protection
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        self.client.call_raw(proto.Cancel())
+
+        # Let's remove PIN
+        ret = self.client.call_raw(proto.ChangePin(remove=True))
+        self.assertIsInstance(ret, proto.ButtonRequest)
+
+        # Press button
+        self.client.debug.press_yes()
+        ret = self.client.call_raw(proto.ButtonAck())
+
+        # Send current PIN
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.read_pin_encoded()
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Now we're done
+        self.assertIsInstance(ret, proto.Success)
+
+        # Check that there's no PIN protection now
+        features = self.client.call_raw(proto.Initialize())
+        self.assertFalse(features.pin_protection)
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.Success)
+
+    def test_set_failed(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+        features = self.client.call_raw(proto.Initialize())
+        self.assertFalse(features.pin_protection)
+
+        # Check that there's no PIN protection
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.Success)
+
+        # Let's set new PIN
+        ret = self.client.call_raw(proto.ChangePin())
+        self.assertIsInstance(ret, proto.ButtonRequest)
+
+        # Press button
+        self.client.debug.press_yes()
+        ret = self.client.call_raw(proto.ButtonAck())
+
+        # Send the PIN for first time
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin6)
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Send the PIN for second time, but with typo
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin4)
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Now it should fail, because pins are different
+        self.assertIsInstance(ret, proto.Failure)
+
+        # Check that there's still no PIN protection now
+        features = self.client.call_raw(proto.Initialize())
+        self.assertFalse(features.pin_protection)
+        ret = self.client.call_raw(proto.Ping(pin_protection=True))
+        self.assertIsInstance(ret, proto.Success)
+
+    def test_set_failed_2(self):
+        self.setup_mnemonic_pin_passphrase()
+        features = self.client.call_raw(proto.Initialize())
+        self.assertTrue(features.pin_protection)
+
+        # Let's set new PIN
+        ret = self.client.call_raw(proto.ChangePin())
+        self.assertIsInstance(ret, proto.ButtonRequest)
+
+        # Press button
+        self.client.debug.press_yes()
+        ret = self.client.call_raw(proto.ButtonAck())
+
+        # Send current PIN
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.read_pin_encoded()
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Send the PIN for first time
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin6)
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Send the PIN for second time, but with typo
+        self.assertIsInstance(ret, proto.PinMatrixRequest)
+        pin_encoded = self.client.debug.encode_pin(self.pin6 + '3')
+        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
+
+        # Now it should fail, because pins are different
+        self.assertIsInstance(ret, proto.Failure)
+
+        # Check that there's still old PIN protection
+        features = self.client.call_raw(proto.Initialize())
+        self.assertTrue(features.pin_protection)
+        self.assertEqual(self.client.debug.read_pin()[0], self.pin4)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_msg_cipherkeyvalue.py b/tests/test_msg_cipherkeyvalue.py
new file mode 100644
index 0000000..1af6e19
--- /dev/null
+++ b/tests/test_msg_cipherkeyvalue.py
@@ -0,0 +1,74 @@
+import unittest
+import common
+import binascii
+
+from trezorlib.client import CallException
+
+class TestMsgCipherkeyvalue(common.TrezorTest):
+
+    def test_encrypt(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+
+        # different ask values
+        res = self.client.encrypt_keyvalue([0, 1, 2], "test", "testing message!", ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(binascii.hexlify(res), '676faf8f13272af601776bc31bc14e8f')
+
+        res = self.client.encrypt_keyvalue([0, 1, 2], "test", "testing message!", ask_on_encrypt=True, ask_on_decrypt=False)
+        self.assertEqual(binascii.hexlify(res), '5aa0fbcb9d7fa669880745479d80c622')
+
+        res = self.client.encrypt_keyvalue([0, 1, 2], "test", "testing message!", ask_on_encrypt=False, ask_on_decrypt=True)
+        self.assertEqual(binascii.hexlify(res), '958d4f63269b61044aaedc900c8d6208')
+
+        res = self.client.encrypt_keyvalue([0, 1, 2], "test", "testing message!", ask_on_encrypt=False, ask_on_decrypt=False)
+        self.assertEqual(binascii.hexlify(res), 'e0cf0eb0425947000eb546cc3994bc6c')
+
+        # different key
+        res = self.client.encrypt_keyvalue([0, 1, 2], "test2", "testing message!", ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(binascii.hexlify(res), 'de247a6aa6be77a134bb3f3f925f13af')
+
+        # different message
+        res = self.client.encrypt_keyvalue([0, 1, 2], "test", "testing message! it is different", ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(binascii.hexlify(res), '676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d')
+
+        # different path
+        res = self.client.encrypt_keyvalue([0, 1, 3], "test", "testing message!", ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(binascii.hexlify(res), 'b4811a9d492f5355a5186ddbfccaae7b')
+
+    def test_decrypt(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+
+        # different ask values
+        res = self.client.decrypt_keyvalue([0, 1, 2], "test", binascii.unhexlify("676faf8f13272af601776bc31bc14e8f"), ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(res, 'testing message!')
+
+        res = self.client.decrypt_keyvalue([0, 1, 2], "test", binascii.unhexlify("5aa0fbcb9d7fa669880745479d80c622"), ask_on_encrypt=True, ask_on_decrypt=False)
+        self.assertEqual(res, 'testing message!')
+
+        res = self.client.decrypt_keyvalue([0, 1, 2], "test", binascii.unhexlify("958d4f63269b61044aaedc900c8d6208"), ask_on_encrypt=False, ask_on_decrypt=True)
+        self.assertEqual(res, 'testing message!')
+
+        res = self.client.decrypt_keyvalue([0, 1, 2], "test", binascii.unhexlify("e0cf0eb0425947000eb546cc3994bc6c"), ask_on_encrypt=False, ask_on_decrypt=False)
+        self.assertEqual(res, 'testing message!')
+
+        # different key
+        res = self.client.decrypt_keyvalue([0, 1, 2], "test2", binascii.unhexlify("de247a6aa6be77a134bb3f3f925f13af"), ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(res, 'testing message!')
+
+        # different message
+        res = self.client.decrypt_keyvalue([0, 1, 2], "test", binascii.unhexlify("676faf8f13272af601776bc31bc14e8f3ae1c88536bf18f1b44f1e4c2c4a613d"), ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(res, 'testing message! it is different')
+
+        # different path
+        res = self.client.decrypt_keyvalue([0, 1, 3], "test", binascii.unhexlify("b4811a9d492f5355a5186ddbfccaae7b"), ask_on_encrypt=True, ask_on_decrypt=True)
+        self.assertEqual(res, 'testing message!')
+
+    def test_encrypt_badlen(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+        self.assertRaises(Exception, self.client.encrypt_keyvalue, [0, 1, 2], "test", "testing")
+
+    def test_decrypt_badlen(self):
+        self.setup_mnemonic_nopin_nopassphrase()
+        self.assertRaises(Exception, self.client.decrypt_keyvalue, [0, 1, 2], "test", "testing")
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_msg_clearsession.py b/tests/test_msg_clearsession.py
new file mode 100644
index 0000000..38a87f2
--- /dev/null
+++ b/tests/test_msg_clearsession.py
@@ -0,0 +1,39 @@
+import time
+import unittest
+import common
+
+from trezorlib import messages_pb2 as proto
+from trezorlib import types_pb2 as proto_types
+
+class TestMsgClearsession(common.TrezorTest):
+
+    def test_clearsession(self):
+        self.setup_mnemonic_pin_passphrase()
+
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_ProtectCall), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success()])
+            res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
+            self.assertEqual(res, 'random data')
+
+        with self.client:
+            # pin and passphrase are cached
+            self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_ProtectCall), proto.Success()])
+            res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
+            self.assertEqual(res, 'random data')
+
+        self.client.clear_session()
+
+        # session cache is cleared
+        with self.client:
+            self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_ProtectCall), proto.PinMatrixRequest(), proto.PassphraseRequest(), proto.Success()])
+            res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
+            self.assertEqual(res, 'random data')
+
+        with self.client:
+            # pin and passphrase are cached
+            self.client.set_expected_responses([proto.ButtonRequest(code=proto_types.ButtonRequest_ProtectCall), proto.Success()])
+            res = self.client.ping('random data', button_protection=True, pin_protection=True, passphrase_protection=True)
+            self.assertEqual(res, 'random data')
+
+if __name__ == '__main__':
+    unittest.main()
... 6087 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-trezor.git



More information about the Python-modules-commits mailing list