1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-11 16:00:57 +00:00

tests: expand on multi-session tests

This commit is contained in:
matejcik 2020-02-20 11:50:08 +01:00 committed by Tomas Susanka
parent f93f6e445b
commit 8fed67de08

View File

@ -14,6 +14,8 @@
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import random
import pytest
from trezorlib import messages
@ -88,61 +90,122 @@ def test_session_with_passphrase(client):
@pytest.mark.skip_ui
@pytest.mark.timeout(300)
@pytest.mark.setup_client(passphrase=True)
def test_multiple_sessions(client):
# start SESSIONS_STORED sessions
session_ids = []
# start a session
for _ in range(SESSIONS_STORED):
session_ids.append(_init_session(client))
# Resume each session
for session_id in session_ids:
new_session_id = _init_session(client, session_id)
assert session_id == new_session_id
# Creating a new session replaces the least-recently-used session
_init_session(client)
# Resuming session 1 through SESSIONS_STORED will still work
for session_id in session_ids[1:]:
new_session_id = _init_session(client, session_id)
assert session_id == new_session_id
# Resuming session 0 will not work
new_session_id = _init_session(client, session_ids[0])
assert new_session_id != session_ids[0]
# New session bumped out the least-recently-used anonymous session.
# Resuming session 1 through SESSIONS_STORED will still work
for session_id in session_ids[1:]:
new_session_id = _init_session(client, session_id)
assert session_id == new_session_id
# Creating a new session replaces session_ids[0] again
_init_session(client)
# Resuming all sessions one by one will in turn bump out the previous session.
for session_id in session_ids:
new_session_id = _init_session(client, session_id)
assert session_id != new_session_id
@pytest.mark.skip_ui
@pytest.mark.setup_client(passphrase=True)
def test_multiple_passphrases(client):
# start a session
session_a = _init_session(client)
assert _get_xpub(client, passphrase="A") == XPUB_PASSPHRASES["A"]
# start it again wit the same session id
new_session_id = _init_session(client, session_id=session_ids[0])
new_session_id = _init_session(client, session_id=session_a)
# session is the same
assert new_session_id == session_ids[0]
assert new_session_id == session_a
# passphrase is not prompted
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["A"]
# start a second session
session_ids.append(_init_session(client))
session_b = _init_session(client)
# new session -> new session id and passphrase prompt
assert _get_xpub(client, passphrase="B") == XPUB_PASSPHRASES["B"]
# provide the same session id -> must not ask for passphrase again.
new_session_id = _init_session(client, session_id=session_ids[1])
assert new_session_id == session_ids[1]
new_session_id = _init_session(client, session_id=session_b)
assert new_session_id == session_b
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["B"]
# provide the first session id -> must not ask for passphrase again and return the same result.
new_session_id = _init_session(client, session_id=session_ids[0])
assert new_session_id == session_ids[0]
new_session_id = _init_session(client, session_id=session_a)
assert new_session_id == session_a
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["A"]
passphrases = list(XPUB_PASSPHRASES.keys())
xpubs = list(XPUB_PASSPHRASES.values())
# start as many sessions as the limit is (2 were started already)
for i in range(2, SESSIONS_STORED):
new_session_id = _init_session(client)
assert new_session_id not in session_ids
session_ids.append(new_session_id)
assert _get_xpub(client, passphrase=passphrases[i]) == xpubs[i]
# provide the second session id -> must not ask for passphrase again and return the same result.
new_session_id = _init_session(client, session_id=session_b)
assert new_session_id == session_b
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES["B"]
@pytest.mark.skip_ui
@pytest.mark.timeout(600)
@pytest.mark.slow
@pytest.mark.setup_client(passphrase=True)
def test_max_sessions_with_passphrases(client):
# for the following tests, we are using as many passphrases as there are available sessions
assert len(XPUB_PASSPHRASES) == SESSIONS_STORED
# start as many sessions as the limit is
session_ids = {}
for passphrase, xpub in XPUB_PASSPHRASES.items():
session_id = _init_session(client)
assert session_id not in session_ids.values()
session_ids[passphrase] = session_id
assert _get_xpub(client, passphrase=passphrase) == xpub
# passphrase is not prompted for the started the sessions, regardless the order
for i in reversed(range(0, SESSIONS_STORED)):
_init_session(client, session_id=session_ids[i])
assert _get_xpub(client, passphrase=None) == xpubs[i]
# let's try 20 different orderings
passphrases = list(XPUB_PASSPHRASES.keys())
shuffling = passphrases[:]
for _ in range(20):
random.shuffle(shuffling)
for passphrase in shuffling:
session_id = _init_session(client, session_id=session_ids[passphrase])
assert session_id == session_ids[passphrase]
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES[passphrase]
# creating one more will exceed the limit, the LRU item is at the moment the last one (see above)
# it should have been removed -> must ask for passphrase
_init_session(client)
_get_xpub(client, passphrase="XX") # create one more
_init_session(client, session_id=session_ids[SESSIONS_STORED - 1])
_get_xpub(client, passphrase="whatever") # the session is gone
# make sure the usage order is the reverse of the creation order
for passphrase in reversed(passphrases):
session_id = _init_session(client, session_id=session_ids[passphrase])
assert session_id == session_ids[passphrase]
assert _get_xpub(client, passphrase=None) == XPUB_PASSPHRASES[passphrase]
# now the second to last is the next LRU
# creating one more session will exceed the limit
_init_session(client)
_get_xpub(client, passphrase="XXXX")
_init_session(client, session_id=session_ids[SESSIONS_STORED - 2])
_get_xpub(client, passphrase="whatever")
# new session asks for passphrase
_get_xpub(client, passphrase="XX")
# restoring the sessions in reverse will evict the next-up session
for passphrase in reversed(passphrases):
_init_session(client, session_id=session_ids[passphrase])
_get_xpub(client, passphrase="whatever") # passphrase is prompted
@pytest.mark.skip_ui
@ -235,7 +298,7 @@ def test_passphrase_always_on_device(client):
_init_session(client)
response = client.call_raw(XPUB_REQUEST)
assert isinstance(response, messages.ButtonRequest)
client.debug.input("A") # Input empty passphrase.
client.debug.input("A") # Input non-empty passphrase.
response = client.call_raw(messages.ButtonAck())
assert isinstance(response, messages.PublicKey)
assert response.xpub == XPUB_PASSPHRASES["A"]