Merge branch 'master' into matejcik/storage-relocation

pull/665/head
matejcik 5 years ago
commit 33bd4d3ba9

2
.gitmodules vendored

@ -23,4 +23,4 @@
ignore = untracked
[submodule "vendor/fido2-tests"]
path = vendor/fido2-tests
url = https://github.com/solokeys/fido2-tests.git
url = https://github.com/trezor/fido2-tests.git

@ -53,6 +53,21 @@ core fw regular build:
- trezor-fw-regular-*.*.*-$CI_COMMIT_SHORT_SHA.bin
expire_in: 1 week
core fw regular debug build:
stage: build
<<: *only_changes_core
script:
- cd core
- PYOPT=0 pipenv run make build_firmware
- cd ..
- export VERSION=$(./tools/version.sh core/embed/firmware/version.h)
- cp core/build/firmware/firmware.bin trezor-fw-regular-debug-$VERSION-$CI_COMMIT_SHORT_SHA.bin
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA"
paths:
- trezor-fw-regular-debug-*.*.*-$CI_COMMIT_SHORT_SHA.bin
expire_in: 1 week
core fw btconly build:
stage: build
<<: *only_changes_core

@ -6,7 +6,7 @@
[subrepo]
remote = git+ssh://git@github.com/trezor/trezor-common
branch = master
commit = 23ee4ad593dc52750d0f1f9ab7c66032f10e2c20
parent = c617035a3e2f9d727a90f1c873e5056730fe2ac0
commit = e2a54511010109877f029e9ca1afab7952067b09
parent = 159b6d0308d2f8a0061a7b65ff052936f0428d31
method = rebase
cmdver = 0.4.0

@ -1,44 +0,0 @@
{
"coin_name": "Myriad",
"coin_shortcut": "XMY",
"coin_label": "Myriad",
"curve_name": "secp256k1",
"website": "https://www.myriadcoin.org",
"github": "https://github.com/myriadteam/myriadcoin",
"maintainer": "Adam Hickerson <a@hi.ckerson.com>",
"address_type": 50,
"address_type_p2sh": 9,
"maxfee_kb": 2000000,
"minfee_kb": 1000,
"signed_message_header": "Myriadcoin Signed Message:\n",
"hash_genesis_block": "00000ffde4c020b5938441a0ea3d314bf619eff0b38f32f78f7583cffa1ea485",
"xprv_magic": 76066276,
"xpub_magic": 76067358,
"xpub_magic_segwit_p2sh": 77429938,
"xpub_magic_segwit_native": 78792518,
"bech32_prefix": "my",
"cashaddr_prefix": null,
"slip44": 90,
"segwit": true,
"decred": false,
"fork_id": null,
"force_bip143": false,
"bip115": false,
"default_fee_b": {
"Low": 10,
"Economy": 70,
"Normal": 140,
"High": 200
},
"dust_limit": 546,
"blocktime_seconds": 60,
"uri_prefix": "myriadcoin",
"min_address_length": 27,
"max_address_length": 34,
"bitcore": [],
"blockbook": [],
"negative_fee": false,
"cooldown": 100,
"consensus_branch_id": null,
"confidential_assets": null
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

@ -1,43 +0,0 @@
{
"coin_name": "Umbru",
"coin_shortcut": "UMBRU",
"coin_label": "Umbru",
"website": "https://umbru.io",
"github": "https://github.com/umbru/umbru-core",
"maintainer": "Ryxor <team@umbru.io>",
"curve_name": "secp256k1",
"address_type": 68,
"address_type_p2sh": 5,
"maxfee_kb": 100000,
"minfee_kb": 100,
"signed_message_header": "DarkCoin Signed Message:\n",
"hash_genesis_block": "00000cb7859c07ebc3950ff150f5d6dc31150c5da14435fbf200d51be8f4208f",
"xprv_magic": 76066276,
"xpub_magic": 76067358,
"xpub_magic_segwit_p2sh": null,
"xpub_magic_segwit_native": null,
"bech32_prefix": null,
"cashaddr_prefix": null,
"slip44": 395,
"segwit": false,
"decred": false,
"fork_id": null,
"force_bip143": false,
"bip115": false,
"default_fee_b": {
"Normal": 10
},
"dust_limit": 5460,
"blocktime_seconds": 120,
"uri_prefix": "umbru",
"min_address_length": 27,
"max_address_length": 34,
"bitcore": [],
"blockbook": [
"https://blockbook.umbru.io"
],
"negative_fee": false,
"cooldown": 100,
"consensus_branch_id": null,
"confidential_assets": null
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

@ -10,7 +10,7 @@
"address_type_p2sh": 145,
"maxfee_kb": 1000000,
"minfee_kb": 1000,
"signed_message_header": "ZCore Genesis Block mined by Mosqueiro",
"signed_message_header": "DarkNet Signed Message:\n",
"hash_genesis_block": "695b79c8c234b45b2eeb4722f33373e471c9b686ff78efeb39da95f824a9f81b",
"xprv_magic": 78791432,
"xpub_magic": 78792518,

@ -36,7 +36,6 @@
"bitcoin:UNO": true,
"bitcoin:VIA": true,
"bitcoin:VTC": true,
"bitcoin:XMY": true,
"bitcoin:XPM": true,
"bitcoin:XRC": true,
"bitcoin:XSN": true,
@ -140,12 +139,10 @@
"bitcoin:TBTG": "1.7.1",
"bitcoin:TDCR": "1.6.2",
"bitcoin:TEST": "1.5.2",
"bitcoin:UMBRU": "1.8.3",
"bitcoin:UNO": "1.8.4",
"bitcoin:VIA": "1.6.2",
"bitcoin:VIPS": "1.8.2",
"bitcoin:VTC": "1.6.1",
"bitcoin:XMY": "1.7.1",
"bitcoin:XPM": "1.8.0",
"bitcoin:XRC": "1.8.2",
"bitcoin:XSN": "1.8.0",
@ -1611,12 +1608,10 @@
"bitcoin:TBTG": "2.0.8",
"bitcoin:TDCR": "2.0.8",
"bitcoin:TEST": "2.0.5",
"bitcoin:UMBRU": "2.1.5",
"bitcoin:UNO": "2.1.6",
"bitcoin:VIA": "2.0.7",
"bitcoin:VIPS": "2.1.1",
"bitcoin:VTC": "2.0.5",
"bitcoin:XMY": "2.0.8",
"bitcoin:XPM": "2.0.11",
"bitcoin:XRC": "2.1.1",
"bitcoin:XSN": "2.0.11",

@ -93,6 +93,10 @@
"bitcoin:PART": {
"Particl Core": "https://github.com/particl/particl-core/releases"
},
"bitcoin:PIVX": {
"SPMT": "https://github.com/PIVX-Project/PIVX-SPMT/",
"Zephyr": "https://github.com/mrcarlanthony/Zephyr-wallet"
},
"bitcoin:POLIS": {
"PolisPay": "https://polispay.com"
},

@ -0,0 +1,4 @@
{
"label": "mojeID",
"webauthn": ["mojeid.cz"]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@ -5,6 +5,7 @@ Version 2.x.x [not yet released]
Version 2.1.8 [Nov 2019]
* Support Tezos 005-BABYLON hardfork
* Show XPUBs in GetAddress for multisig
* Security improvements
Version 2.1.7 [Oct 2019]
* Fix low memory issue

@ -1093,29 +1093,6 @@ def by_name(name: str) -> CoinInfo:
curve_name='secp256k1',
confidential_assets=None,
)
elif name == "Myriad":
return CoinInfo(
coin_name=name,
coin_shortcut="XMY",
address_type=50,
address_type_p2sh=9,
maxfee_kb=2000000,
signed_message_header="Myriadcoin Signed Message:\n",
xpub_magic=0x0488b21e,
xpub_magic_segwit_p2sh=0x049d7cb2,
xpub_magic_segwit_native=0x04b24746,
bech32_prefix="my",
cashaddr_prefix=None,
slip44=90,
segwit=True,
fork_id=None,
force_bip143=False,
bip115=False,
decred=False,
negative_fee=False,
curve_name='secp256k1',
confidential_assets=None,
)
elif name == "NIX":
return CoinInfo(
coin_name=name,
@ -1507,29 +1484,6 @@ def by_name(name: str) -> CoinInfo:
curve_name='secp256k1',
confidential_assets=None,
)
elif name == "Umbru":
return CoinInfo(
coin_name=name,
coin_shortcut="UMBRU",
address_type=68,
address_type_p2sh=5,
maxfee_kb=100000,
signed_message_header="DarkCoin Signed Message:\n",
xpub_magic=0x0488b21e,
xpub_magic_segwit_p2sh=None,
xpub_magic_segwit_native=None,
bech32_prefix=None,
cashaddr_prefix=None,
slip44=395,
segwit=False,
fork_id=None,
force_bip143=False,
bip115=False,
decred=False,
negative_fee=False,
curve_name='secp256k1',
confidential_assets=None,
)
elif name == "Unobtanium":
return CoinInfo(
coin_name=name,
@ -1629,7 +1583,7 @@ def by_name(name: str) -> CoinInfo:
address_type=142,
address_type_p2sh=145,
maxfee_kb=1000000,
signed_message_header="ZCore Genesis Block mined by Mosqueiro",
signed_message_header="DarkNet Signed Message:\n",
xpub_magic=0x04b24746,
xpub_magic_segwit_p2sh=None,
xpub_magic_segwit_native=None,

@ -58,7 +58,7 @@ def _start_progress() -> None:
# Because we are drawing to the screen manually, without a layout, we
# should make sure that no other layout is running. At this point, only
# the homescreen should be on, so shut it down.
workflow.close_default()
workflow.kill_default()
ui.backlight_fade(ui.BACKLIGHT_DIM)
ui.display.clear()
ui.header("Please wait")

@ -108,10 +108,9 @@ async def handle_Ping(ctx: wire.Context, msg: Ping) -> Success:
return Success(message=msg.message)
def boot(features_only: bool = False) -> None:
def boot() -> None:
register(MessageType.Initialize, handle_Initialize)
register(MessageType.GetFeatures, handle_GetFeatures)
if not features_only:
register(MessageType.Cancel, handle_Cancel)
register(MessageType.ClearSession, handle_ClearSession)
register(MessageType.Ping, handle_Ping)
register(MessageType.Cancel, handle_Cancel)
register(MessageType.ClearSession, handle_ClearSession)
register(MessageType.Ping, handle_Ping)

@ -1,7 +1,7 @@
import storage
import storage.device
import storage.recovery
from trezor import config, ui, wire
from trezor import config, ui, wire, workflow
from trezor.messages import ButtonRequestType
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
@ -13,7 +13,10 @@ from apps.common.request_pin import (
request_pin_confirm,
show_pin_invalid,
)
from apps.management.recovery_device.homescreen import recovery_process
from apps.management.recovery_device.homescreen import (
recovery_homescreen,
recovery_process,
)
if False:
from trezor.messages.RecoveryDevice import RecoveryDevice
@ -28,6 +31,9 @@ async def recovery_device(ctx: wire.Context, msg: RecoveryDevice) -> Success:
"""
_check_state(msg)
if storage.recovery.is_in_progress():
return await recovery_process(ctx)
await _continue_dialog(ctx, msg)
# for dry run pin needs to be entered
@ -53,9 +59,8 @@ async def recovery_device(ctx: wire.Context, msg: RecoveryDevice) -> Success:
if msg.dry_run:
storage.recovery.set_dry_run(msg.dry_run)
result = await recovery_process(ctx)
return result
workflow.replace_default(recovery_homescreen)
return await recovery_process(ctx)
def _check_state(msg: RecoveryDevice) -> None:
@ -64,11 +69,6 @@ def _check_state(msg: RecoveryDevice) -> None:
if msg.dry_run and not storage.is_initialized():
raise wire.NotInitialized("Device is not initialized")
if storage.recovery.is_in_progress():
raise RuntimeError(
"Function recovery_device should not be invoked when recovery is already in progress"
)
if msg.enforce_wordlist is False:
raise wire.ProcessError(
"Value enforce_wordlist must be True, Trezor Core enforces words automatically."

@ -2,7 +2,7 @@ import storage
import storage.device
import storage.recovery
import storage.recovery_shares
from trezor import loop, utils, wire
from trezor import utils, wire, workflow
from trezor.crypto import slip39
from trezor.crypto.hashlib import sha256
from trezor.errors import MnemonicError
@ -13,6 +13,7 @@ from . import recover
from apps.common import mnemonic
from apps.common.layout import show_success
from apps.homescreen.homescreen import homescreen
from apps.management import backup_types
from apps.management.recovery_device import layout
@ -22,20 +23,18 @@ if False:
async def recovery_homescreen() -> None:
if not storage.recovery.is_in_progress():
workflow.replace_default(homescreen)
return
# recovery process does not communicate on the wire
ctx = wire.DummyContext()
try:
await recovery_process(ctx)
finally:
# clear the loop state, so loop.run will exit
loop.clear()
# clear the registered wire handlers to avoid conflicts
wire.clear()
await recovery_process(ctx)
async def recovery_process(ctx: wire.GenericContext) -> Success:
try:
result = await _continue_recovery_process(ctx)
return await _continue_recovery_process(ctx)
except recover.RecoveryAborted:
dry_run = storage.recovery.is_dry_run()
if dry_run:
@ -43,7 +42,6 @@ async def recovery_process(ctx: wire.GenericContext) -> Success:
else:
storage.wipe()
raise wire.ActionCancelled("Cancelled")
return result
async def _continue_recovery_process(ctx: wire.GenericContext) -> Success:

@ -105,6 +105,9 @@ knownapps = {
"label": "Microsoft",
"use_sign_count": False,
},
b"\xab-\xaf\x07C\xdex*p\x18\x9a\x0f^\xfc0\x90/\x92[\x9f\x9a\x18\xc5\xd7\x14\x1b{\x12\xf8\xa0\x10\x0c": {
"label": "mojeID"
},
b"\xa6B\xd2\x1b|mU\xe1\xce#\xc59\x98(\xd2\xc7I\xbfjn\xf2\xfe\x03\xcc\x9e\x10\xcd\xf4\xedS\x08\x8b": {
"label": "webauthn.bin.coffee"
},

@ -1,7 +1,7 @@
import storage
import storage.device
import storage.sd_salt
from trezor import config, io, log, loop, res, ui, utils, wire
from trezor import config, io, log, loop, res, ui, utils
from trezor.pin import pin_to_int, show_pin_timeout
from apps.common.request_pin import PinCancelled, request_pin
@ -34,7 +34,7 @@ async def bootscreen() -> None:
except (OSError, PinCancelled, SdProtectCancelled) as e:
if __debug__:
log.exception(__name__, e)
except Exception as e:
except BaseException as e:
if __debug__:
log.exception(__name__, e)
utils.halt(e.__class__.__name__)

@ -6,7 +6,8 @@ import boot # noqa: F401
# prepare the USB interfaces, but do not connect to the host yet
import usb
from trezor import utils
import storage.recovery
from trezor import loop, utils, wire, workflow
# start the USB
usb.bus.open()
@ -15,21 +16,7 @@ usb.bus.open()
utils.set_mode_unprivileged()
def _boot_recovery() -> None:
# load applications
import apps.homescreen
# boot applications
apps.homescreen.boot(features_only=True)
if __debug__:
apps.debug.boot()
from apps.management.recovery_device.homescreen import recovery_homescreen
loop.schedule(recovery_homescreen())
def _boot_default() -> None:
def _boot_apps() -> None:
# load applications
import apps.homescreen
import apps.management
@ -71,25 +58,23 @@ def _boot_default() -> None:
apps.debug.boot()
# run main event loop and specify which screen is the default
from apps.homescreen.homescreen import homescreen
if storage.recovery.is_in_progress():
from apps.management.recovery_device.homescreen import recovery_homescreen
workflow.start_default(homescreen)
workflow.start_default(recovery_homescreen)
else:
from apps.homescreen.homescreen import homescreen
workflow.start_default(homescreen)
import storage.recovery
from trezor import loop, wire, workflow
while True:
# initialize the wire codec
wire.setup(usb.iface_wire)
if __debug__:
wire.setup(usb.iface_debug)
# initialize the wire codec
wire.setup(usb.iface_wire)
if __debug__:
wire.setup(usb.iface_debug)
# boot either in recovery or default mode
if storage.recovery.is_in_progress():
_boot_recovery()
else:
_boot_default()
loop.run()
_boot_apps()
loop.run()
# loop is empty, reboot
# loop is empty. That should not happen
utils.halt("All tasks have died.")

@ -82,7 +82,7 @@ class Loader(ui.Component):
display.loader(
r, False, Y, s.fg_color, s.bg_color, res.load(s.icon), s.icon_fg_color
)
if r == 0:
if (r == 0) and (self.stop_ms is not None):
self.start_ms = None
self.stop_ms = None
self.on_start()

@ -286,7 +286,7 @@ async def handle_session(iface: WireInterface, session_id: int) -> None:
"%s:%x receive: %s",
iface.iface_num(),
session_id,
req_reader.type,
messages.get_type(req_reader.type),
)
else:
# We have a reader left over from earlier. We should process

@ -49,7 +49,11 @@ def on_close(workflow: loop.Task) -> None:
def start_default(constructor: Callable[[], loop.Task]) -> None:
"""Start a default workflow, created from `constructor`."""
"""Start a default workflow, created from `constructor`.
If a default task is already running, nothing will happen. Use `replace_default`
to set up a new default task for the next run.
"""
global default_task
global default_constructor
@ -57,7 +61,7 @@ def start_default(constructor: Callable[[], loop.Task]) -> None:
default_constructor = constructor
default_task = constructor()
if __debug__:
log.debug(__name__, "start default")
log.debug(__name__, "start default: %s", default_task)
# Schedule the default task. Because the task can complete on its own,
# we need to reset the `default_task` global in a finalizer.
loop.schedule(default_task, None, None, _finalize_default)
@ -66,8 +70,23 @@ def start_default(constructor: Callable[[], loop.Task]) -> None:
log.debug(__name__, "default already started")
def close_default() -> None:
"""Explicitly close the default workflow task."""
def replace_default(constructor: Callable[[], loop.Task]) -> None:
"""Configure a default workflow, which will be started next time it is needed."""
global default_constructor
if __debug__:
log.debug(__name__, "setting a new default: %s", constructor)
default_constructor = constructor
def kill_default() -> None:
"""Forcefully shut down default task.
The purpose of the call is to prevent the default task from interfering with
a synchronous layout-less workflow (e.g., the progress bar in `mnemonic.get_seed`).
This function should only be called from a workflow registered with `on_start`.
Otherwise the default will be restarted immediately.
"""
if default_task:
if __debug__:
log.debug(__name__, "close default")
@ -76,12 +95,24 @@ def close_default() -> None:
def _finalize_default(task: loop.Task, value: Any) -> None:
"""Finalizer for the default task. Cleans up globals and restarts the default
in case no other task is running."""
global default_task
if default_task is task:
if __debug__:
log.debug(__name__, "default closed")
log.debug(__name__, "default closed: %s", task)
default_task = None
if not tasks:
# No registered workflows are running and we are in the default task
# finalizer, so when this function finished, nothing will be running.
# We must schedule a new instance of the default now.
if default_constructor is not None:
start_default(default_constructor)
else:
raise RuntimeError # no tasks and no default constructor
else:
if __debug__:
log.warning(
@ -90,3 +121,9 @@ def _finalize_default(task: loop.Task, value: Any) -> None:
task,
default_task,
)
# TODO
# If required, a function `shutdown_default` should be written, that clears the
# default constructor and shuts down the running default task.
# We currently do not need such function, so I'm just noting how it should work.

@ -144,6 +144,11 @@ static const U2FWellKnown u2f_well_known[] = {
{ 0x35, 0x6c, 0x9e, 0xd4, 0xa0, 0x93, 0x21, 0xb9, 0x69, 0x5f, 0x1e, 0xaf, 0x91, 0x82, 0x03, 0xf1, 0xb5, 0x5f, 0x68, 0x9d, 0xa6, 0x1f, 0xbc, 0x96, 0x18, 0x4c, 0x15, 0x7d, 0xda, 0x68, 0x0c, 0x81 },
"Microsoft"
},
{
// WebAuthn: mojeid.cz
{ 0xab, 0x2d, 0xaf, 0x07, 0x43, 0xde, 0x78, 0x2a, 0x70, 0x18, 0x9a, 0x0f, 0x5e, 0xfc, 0x30, 0x90, 0x2f, 0x92, 0x5b, 0x9f, 0x9a, 0x18, 0xc5, 0xd7, 0x14, 0x1b, 0x7b, 0x12, 0xf8, 0xa0, 0x10, 0x0c },
"mojeID"
},
{
// U2F
{ 0x08, 0xb2, 0xa3, 0xd4, 0x19, 0x39, 0xaa, 0x31, 0x66, 0x84, 0x93, 0xcb, 0x36, 0xcd, 0xcc, 0x4f, 0x16, 0xc4, 0xd9, 0xb4, 0xc8, 0x23, 0x8b, 0x73, 0xc2, 0xf6, 0x72, 0xc0, 0x33, 0x00, 0x71, 0x97 },

@ -2012,7 +2012,7 @@ def webauthn_add_credential(connect, hex_credential_id):
@cli.command(help="Remove the resident credential at the given index.")
@click.option(
"-i", "--index", required=True, type=click.IntRange(0, 15), help="Credential index."
"-i", "--index", required=True, type=click.IntRange(0, 99), help="Credential index."
)
@click.pass_obj
def webauthn_remove_credential(connect, index):

File diff suppressed because one or more lines are too long

@ -181,6 +181,27 @@ class DebugUI:
def button_request(self, code):
if self.input_flow is None:
# XXX
# On Trezor T, in some rare cases, two layouts may be queuing for events at
# the same time. A new workflow will first send out a ButtonRequest, wait
# for a ButtonAck, and only then display a layout (closing the old one).
# That means that if a layout that accepts debuglink decisions is currently
# on screen, it has a good chance of accepting the following `press_yes`
# before it can be closed by the newly open layout from the new workflow.
#
# This happens in particular when the recovery homescreen is on, because
# it is a homescreen that accepts debuglink decisions.
#
# To prevent the issue, we insert a `wait_layout`, which on TT will only
# return after the screen is refreshed, so we are certain that the new
# layout is on. On T1 it is a no-op.
#
# This could run into trouble if some workflow asks for a ButtonRequest
# without refreshing the screen.
# This will also freeze on old bridges, where Read and Write are not
# separate operations, because it relies on ButtonAck being sent without
# waiting for a response.
self.debuglink.wait_layout()
self.debuglink.press_yes()
elif self.input_flow is self.INPUT_FLOW_DONE:
raise AssertionError("input flow ended prematurely")

@ -21,8 +21,14 @@ INFO = (MID, BOTTOM)
CONFIRM_WORD = (MID, TOP)
MINUS = (LEFT, grid(DISPLAY_HEIGHT, 5, 2))
PLUS = (RIGHT, grid(DISPLAY_HEIGHT, 5, 2))
RESET_MINUS = (LEFT, grid(DISPLAY_HEIGHT, 5, 1))
RESET_PLUS = (RIGHT, grid(DISPLAY_HEIGHT, 5, 1))
RESET_WORD_CHECK = [
(MID, grid(DISPLAY_HEIGHT, 6, 3)),
(MID, grid(DISPLAY_HEIGHT, 6, 4)),
(MID, grid(DISPLAY_HEIGHT, 6, 5)),
]
BUTTON_LETTERS = ("ab", "cd", "ef", "ghij", "klm", "nopq", "rs", "tuv", "wxyz")

@ -0,0 +1,73 @@
import shamir_mnemonic as shamir
from trezorlib import messages
from .. import buttons
def confirm_wait(debug, startswith):
layout = debug.wait_layout()
assert layout.text.startswith(startswith)
debug.click(buttons.OK, wait=True)
def confirm_read(debug, startswith):
layout = debug.read_layout()
assert layout.text.startswith(startswith)
debug.click(buttons.OK, wait=True)
def set_selection(debug, button, diff):
layout = debug.read_layout()
assert layout.text.startswith("Slip39NumInput")
for _ in range(diff):
debug.click(button, wait=False)
debug.click(buttons.OK, wait=True)
def read_words(debug, is_advanced=False):
def read_word(line: str):
return line.split()[1]
words = []
layout = debug.read_layout()
if is_advanced:
assert layout.text.startswith("Group")
else:
assert layout.text.startswith("Recovery share")
for i in range(6):
lines = debug.read_layout().lines
if i == 0:
words.append(read_word(lines[3]))
words.append(read_word(lines[4]))
debug.input(swipe=messages.DebugSwipeDirection.UP, wait=True)
elif i == 5:
words.append(read_word(lines[1]))
words.append(read_word(lines[2]))
else:
words.append(read_word(lines[1]))
words.append(read_word(lines[2]))
words.append(read_word(lines[3]))
words.append(read_word(lines[4]))
debug.input(swipe=messages.DebugSwipeDirection.UP, wait=True)
debug.press_yes()
return words
def confirm_words(debug, words):
layout = debug.wait_layout()
layout.text.startswith("Check share")
for _ in range(3):
word_pos = int(debug.state().layout_lines[1].split()[2])
button_pos = debug.state().layout_lines.index(words[word_pos - 1]) - 2
debug.click(buttons.RESET_WORD_CHECK[button_pos], wait=True)
def validate_mnemonics(mnemonics, expected_ems):
# We expect these combinations to recreate the secret properly
# In case of click tests the mnemonics are always XofX so no need for combinations
ms = shamir.combine_mnemonics(mnemonics)
identifier, iteration_exponent, _, _, _ = shamir._decode_mnemonics(mnemonics)
ems = shamir._encrypt(ms, b"", iteration_exponent, identifier)
assert ems == expected_ems

@ -0,0 +1,193 @@
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2019 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# 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 License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from unittest import mock
import pytest
from trezorlib import device, messages
from .. import buttons
from ..common import generate_entropy
from . import reset
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
@pytest.mark.skip_t1
@pytest.mark.setup_client(uninitialized=True)
def test_reset_slip39_advanced_2of2groups_2of2shares(device_handler):
features = device_handler.features()
debug = device_handler.debuglink()
assert features.initialized is False
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
with mock.patch("os.urandom", os_urandom), device_handler:
device_handler.run(
device.reset,
strength=128,
backup_type=messages.BackupType.Slip39_Advanced,
pin_protection=False,
)
# confirm new wallet
reset.confirm_wait(debug, "Create new wallet")
# confirm back up
reset.confirm_wait(debug, "Success")
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set num of groups
reset.set_selection(debug, buttons.RESET_MINUS, 3)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set group threshold
reset.set_selection(debug, buttons.RESET_MINUS, 0)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set share num and threshold for groups
for _ in range(2):
# set num of shares
reset.set_selection(debug, buttons.RESET_MINUS, 3)
# set share threshold
reset.set_selection(debug, buttons.RESET_MINUS, 0)
# confirm backup warning
reset.confirm_read(debug, "Caution")
all_words = []
for _ in range(2):
for _ in range(2):
# read words
words = reset.read_words(debug, True)
# confirm words
reset.confirm_words(debug, words)
# confirm share checked
reset.confirm_read(debug, "Success")
all_words.append(" ".join(words))
# confirm backup done
reset.confirm_read(debug, "Success")
# generate secret locally
internal_entropy = debug.state().reset_entropy
secret = generate_entropy(128, internal_entropy, EXTERNAL_ENTROPY)
# validate that all combinations will result in the correct master secret
reset.validate_mnemonics(all_words, secret)
assert device_handler.result() == "Initialized"
features = device_handler.features()
assert features.initialized is True
assert features.needs_backup is False
assert features.pin_protection is False
assert features.passphrase_protection is False
assert features.backup_type is messages.BackupType.Slip39_Advanced
@pytest.mark.skip_t1
@pytest.mark.setup_client(uninitialized=True)
def test_reset_slip39_advanced_16of16groups_16of16shares(device_handler):
features = device_handler.features()
debug = device_handler.debuglink()
assert features.initialized is False
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
with mock.patch("os.urandom", os_urandom), device_handler:
device_handler.run(
device.reset,
strength=128,
backup_type=messages.BackupType.Slip39_Advanced,
pin_protection=False,
)
# confirm new wallet
reset.confirm_wait(debug, "Create new wallet")
# confirm back up
reset.confirm_wait(debug, "Success")
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set num of groups
reset.set_selection(debug, buttons.RESET_PLUS, 11)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set group threshold
reset.set_selection(debug, buttons.RESET_PLUS, 11)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set share num and threshold for groups
for _ in range(16):
# set num of shares
reset.set_selection(debug, buttons.RESET_PLUS, 11)
# set share threshold
reset.set_selection(debug, buttons.RESET_PLUS, 11)
# confirm backup warning
reset.confirm_read(debug, "Caution")
all_words = []
for _ in range(16):
for _ in range(16):
# read words
words = reset.read_words(debug, True)
# confirm words
reset.confirm_words(debug, words)
# confirm share checked
reset.confirm_read(debug, "Success")
all_words.append(" ".join(words))
# confirm backup done
reset.confirm_read(debug, "Success")
# generate secret locally
internal_entropy = debug.state().reset_entropy
secret = generate_entropy(128, internal_entropy, EXTERNAL_ENTROPY)
# validate that all combinations will result in the correct master secret
reset.validate_mnemonics(all_words, secret)
assert device_handler.result() == "Initialized"
features = device_handler.features()
assert features.initialized is True
assert features.needs_backup is False
assert features.pin_protection is False
assert features.passphrase_protection is False
assert features.backup_type is messages.BackupType.Slip39_Advanced

@ -0,0 +1,174 @@
# This file is part of the Trezor project.
#
# Copyright (C) 2012-2019 SatoshiLabs and contributors
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# 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 License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
from unittest import mock
import pytest
from trezorlib import device, messages
from .. import buttons
from ..common import generate_entropy
from . import reset
EXTERNAL_ENTROPY = b"zlutoucky kun upel divoke ody" * 2
@pytest.mark.skip_t1
@pytest.mark.setup_client(uninitialized=True)
def test_reset_slip39_basic_1of1(device_handler):
features = device_handler.features()
debug = device_handler.debuglink()
assert features.initialized is False
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
with mock.patch("os.urandom", os_urandom), device_handler:
device_handler.run(
device.reset,
strength=128,
backup_type=messages.BackupType.Slip39_Basic,
pin_protection=False,
)
# confirm new wallet
reset.confirm_wait(debug, "Create new wallet")
# confirm back up
reset.confirm_wait(debug, "Success")
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set num of shares
# default is 5 so we press RESET_MINUS 4 times
reset.set_selection(debug, buttons.RESET_MINUS, 4)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set threshold
# threshold will default to 1
reset.set_selection(debug, buttons.RESET_MINUS, 0)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# confirm backup warning
reset.confirm_read(debug, "Caution")
# read words
words = reset.read_words(debug)
# confirm words
reset.confirm_words(debug, words)
# confirm share checked
reset.confirm_read(debug, "Success")
# confirm backup done
reset.confirm_read(debug, "Success")
# generate secret locally
internal_entropy = debug.state().reset_entropy
secret = generate_entropy(128, internal_entropy, EXTERNAL_ENTROPY)
# validate that all combinations will result in the correct master secret
validate = [" ".join(words)]
reset.validate_mnemonics(validate, secret)
assert device_handler.result() == "Initialized"
features = device_handler.features()
assert features.initialized is True
assert features.needs_backup is False
assert features.pin_protection is False
assert features.passphrase_protection is False
assert features.backup_type is messages.BackupType.Slip39_Basic
@pytest.mark.skip_t1
@pytest.mark.setup_client(uninitialized=True)
def test_reset_slip39_basic_16of16(device_handler):
features = device_handler.features()
debug = device_handler.debuglink()
assert features.initialized is False
os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
with mock.patch("os.urandom", os_urandom), device_handler:
device_handler.run(
device.reset,
strength=128,
backup_type=messages.BackupType.Slip39_Basic,
pin_protection=False,
)
# confirm new wallet
reset.confirm_wait(debug, "Create new wallet")
# confirm back up
reset.confirm_wait(debug, "Success")
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set num of shares
# default is 5 so we add 11
reset.set_selection(debug, buttons.RESET_PLUS, 11)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# set threshold
# default is 5 so we add 11
reset.set_selection(debug, buttons.RESET_PLUS, 11)
# confirm checklist
reset.confirm_read(debug, "Checklist")
# confirm backup warning
reset.confirm_read(debug, "Caution")
all_words = []
for _ in range(16):
# read words
words = reset.read_words(debug)
# confirm words
reset.confirm_words(debug, words)
# confirm share checked
reset.confirm_read(debug, "Success")
all_words.append(" ".join(words))
# confirm backup done
reset.confirm_read(debug, "Success")
# generate secret locally
internal_entropy = debug.state().reset_entropy
secret = generate_entropy(128, internal_entropy, EXTERNAL_ENTROPY)
# validate that all combinations will result in the correct master secret
reset.validate_mnemonics(all_words, secret)
assert device_handler.result() == "Initialized"
features = device_handler.features()
assert features.initialized is True
assert features.needs_backup is False
assert features.pin_protection is False
assert features.passphrase_protection is False
assert features.backup_type is messages.BackupType.Slip39_Basic

@ -0,0 +1,453 @@
# Valid credential
# Relying party ID: example.com
# Relying party name: Example
# User ID: 3082019330820138a0030201023082019330820138a003020102308201933082
# User name: johnpsmith@example.com
# User display name: John P. Smith
# Creation time: 3
# hmac-secret enabled: True
# Use signature counter: False
CRED1 = bytes.fromhex(
"f1d00200f8221312f7898e31ea5ec30409527c2b0bde0b9dfdd7eaab4424173f"
"bf75ab67627fff60974460d903d7d96bb9e974c169a01b2c38cf2305da304169"
"d4e28f59053a2564bebb3eb3f06c2182f1ea4a2f7cebd8f92a930a76f3b45334"
"1e3f3285a575a54bcba9cf8a088dbfe24e8e691a5926160174e03aa941828f49"
"e42b47804d"
)
# Valid credential which has same rpId and userId as credential #1.
# Relying party ID: example.com
# User ID: 3082019330820138a0030201023082019330820138a003020102308201933082
# User name: johnpsmith@example.com
# Creation time: 2
# hmac-secret enabled: True
# Use signature counter: False
CRED2 = bytes.fromhex(
"f1d00200eb3b566f4ea0a219552b2efd2c76e1ffc2e641d3bf91ec92d47a4ed4"
"d78cf42845248c4e982a503618bac0cecfb0fa91fa10821df1efe1d59ac8314e"
"b57eb7f32a1a605f91e8692daf1a679b55ab1acadfded5e0c7fd1365e2801759"
"bd3a4450dd5589586ab072da79"
)
# Valid credential which has same userId as #2, but different rpId.
# Relying party ID: www.example.com
# User ID: 3082019330820138a0030201023082019330820138a003020102308201933082
# User name: johnpsmith@example.com
# Creation time: 20
# hmac-secret enabled: True
# Use signature counter: False
CRED3 = bytes.fromhex(
"f1d00200ebee50034eb7affb555602eed0812b63d158b57a4188523ad064a719"
"febf477c52cfcc7ded8d7a7a83af52287ed1ecee9f74f62b7e55ad8e814c062e"
"009bb3b3391dfec79dc93053b0279eca7207358a0962865da55668b2509de773"
"8c819dbeead9997778319ac1f1c7318fd6"
)
# Relying party ID: example.com
# User ID: 0001 ... 0064
# User name: jsmith
# Creation time: 1001 ... 1199
# hmac-secret enabled: False
# Use signature counter: True
CREDS = [
bytes.fromhex(
"f1d00200d1fa3eeffcf5f9f82bd9be7e108c11fe506efd9be94b8ee50e0f5283"
"8608cee3370ec315cb7554ce1eb845a5d6b1b44c85a0f3defa27a1c20e472347"
),
bytes.fromhex(
"f1d0020096d55afffd8fcb403811d9b121425c661c30534dbf2f7d88e8348ad6"
"0410610e9f20723edf82099c2c9d927de292b441d589b8c8407337d76e43ff63"
),
bytes.fromhex(
"f1d00200df6d8a20b26104c669d5f6938a79ca67089d0cc23f2453a17563cc1b"
"34bce1fdf8c9c46898daeb2ee7111ff6613cd483ce2456f306d66a5fe270b549"
),
bytes.fromhex(
"f1d002007c409ddfaba1388b0e4b6ca89242f71690f9ac26ce57940868dfa5ad"
"5c2eb638cc300e63617c4aefd3b2a5be5a7e834766041298fe7e6d2f079e1cea"
),
bytes.fromhex(
"f1d002007dbccce4b85323d6b7838d5c420e008c4671fa352ed24903a36fa04c"
"7ce1c7f58df1dc22783a1f32c2df315bb73fa79779f85b37e1f6dc0f7b3898c9"
),
bytes.fromhex(
"f1d0020032586473e9598db0345a304dd0155fa23498ed89bbe5263c9c2a36d9"
"1299f368a1e065e056113a858774b09ecd21968c6cac8697eef4cdc80043d7ab"
),
bytes.fromhex(
"f1d002002b6a33d78e798b0495b3d0e82ce05165c12492b8f527e040b9bef0a6"
"61bd6d0395a3e32dcbc0096d4c000f79e80a4639fbfb046d1630dd941fcf614c"
),
bytes.fromhex(
"f1d002003896a24f37e402bb2a74e12b8b5e6a69a70051047d20fc3d414baf85"
"c5d5891156484c0f79737183be7088f4e9c51f8abd72b7d5c82990d8dff520a8"
),
bytes.fromhex(
"f1d0020069de9c86b414454b83b8c49a61f5eba20644419aa1ba298bab00d22a"
"9cbf3a32d009b9eb34ca637700d54cfafe95fbc92835e191e973777f78cb6f1d"
),
bytes.fromhex(
"f1d002000ea8377a15109607702283fbd8adf9069d784c085a3492215fc24062"
"c229ef90484a88efc54c34eb9617d184ee688ad3cf79e9c8deeba617981fda10"
),
bytes.fromhex(
"f1d00200b74429cdaa5ac7ce014a480531935f1939a8abe20ce9ce92663e93b8"
"5f6e6e94c5e797f54f64a09acd49183b1e72f694128385d74703d4f6ffb17e49"
),
bytes.fromhex(
"f1d0020034cf7e940331828986a2dde06e58df4a4d37c60c5581f14ffe9a13b7"
"63b9ef25e4a6b788c24f4b555438906b56d9d21811c40ad2c3f36944ec835075"
),
bytes.fromhex(
"f1d00200956c84d2f0d4f84a8f6359fb41fc49d9dac960cb798a9ebc44744315"
"b29c748725c5544b0b5130ff7cd0755b12723fb20a3529f2238aabc4d50de759"
),
bytes.fromhex(
"f1d002002a41aa7181fe2435ec4550879dc53dee7d6da20e053978eaa8c622ae"
"c95654ebcea749e3f087911755120dde2947fd6b5f577334330c2448ed1212df"
),
bytes.fromhex(
"f1d0020083a920a906c16c64ad247384f2d97d3497cd7bc3e32bb3172f8fb738"
"1220a94bbbcaf0010fe9a7fa1da988f43b33a3418b40a7b7965e1f2135e60d0c"
),
bytes.fromhex(
"f1d00200708783380f7403bd22d2508b1e193dc6eb6dafc49fbcc60337ad5e30"
"292618056159eb365947945552baacb7e6f18891af8cea63d12bc129d25b3a19"
),
bytes.fromhex(
"f1d0020001b3dac46c70f5d9dbb03c1309476352a44025c475d64ec314558fab"
"112b856c8ab0532c38f7796398000328c351d4fbc68921328fd0422eda045f68"
),
bytes.fromhex(
"f1d0020086df68432db1e745a8e02f678838b033ccfeb92b205e44f5b8ab6733"
"5c53638905209b0a42432b19d830683aca23ace901c7f56ee1388dcdb0ef95c2"
),
bytes.fromhex(
"f1d002008f84bee5a2a8e3c1990f0142903acf6b82ee4be4c0a687d2e0aa05bd"
"4f88e82e4fce1f8b306adda855c79b27966f1ab59e58b96ae4e050ba7f998e6d"
),
bytes.fromhex(
"f1d00200ec9a9fea5bd94fdffe3efa9db90a218f3134ae6450d3731f7678c754"
"3e6f930cc660d2f2c2d6f3a876470b6fbd82f758d0d23c66c8352cf6aeb0d500"
),
bytes.fromhex(
"f1d00200ad3de50b28038b33670ca88c1ad1ef9a9a0f1ea8532cede675259f0b"
"c192c5839bf53116c3c55fdcaf00103cb5d16184f28f607e840db7ac018375f5"
),
bytes.fromhex(
"f1d00200227f531419f4a5f3a44e8f914c398daa1d16c8e64f9adb61c3f891b6"
"32f86406e3f97b1423909118037f44edc07fdf134ad83534de6b467f07f29050"
),
bytes.fromhex(
"f1d00200db01a4b17e4de3c8c5162892086a2dfb5f39d96f1d943e92a23c7355"
"d04b117a054750b7e1738d20b339b0a6738b3ec31ff6ba3186716f5f3dbfef2b"
),
bytes.fromhex(
"f1d00200a825db1ae7ccf8971a654418b3f98c4fcd4afc8d0746c2537b844c2e"
"f075f4ce3577b71211b1bb39c6b2da2d487f813839066fa3a82f529d908f3357"
),
bytes.fromhex(
"f1d0020099d8836f24e95e953322a967f177fe91b1cf052a3a9e8dcb3144a591"
"6d9fd56507cfd02ebefaf1b126e8a638aeb7438d487e5bd64628403c85c1022c"
),
bytes.fromhex(
"f1d00200fe5b192545d32d35e02badd3ff1042c6717572199fd477b5c1057ab2"
"7117f06b2880bbbbc2fae7c3d1341aa1dab25954a23a14373ab2146ac86ff81c"
),
bytes.fromhex(
"f1d00200678dba619a2b4e563186d005ce22f818f968fc6f3e9cbe53c10fa2dd"
"7a31fcb2e8e78fbc0ec3ed47c6b26235d6ef723f6aadc4eb51ce9ae195d1987e"
),
bytes.fromhex(
"f1d00200a48313beb3fae3847600614d82b77bd3d15a4343e085f69001adb64d"
"57931fa60ead81035ccacb7935052d86ceabb2d91a8cf5fe8c94128b576976ee"
),
bytes.fromhex(
"f1d00200c58f1cb960be670e3fdeede488e83ee4aec29a6310b15ff54da2e162"
"326aa0e2f90978da7a7e35ffbbae1a28349f4489bb92321f9776714581159848"
),
bytes.fromhex(
"f1d002001af21420b19a7fda5c54d5477e19db70249faf4b0c6c06fd9d832e0c"
"20c7e4538b6206518468f67fb12169e0e08aa80bad6c2dffb7c5093fae8a9ee2"
),
bytes.fromhex(
"f1d0020033d3bfe1f6fe4dc1dde90007a05a4d61457aff3c16a842325f03a858"
"f1fa9f255375c5dfc687a18fc1ca9a98c3ff1cbf1e94122234a6b82b9ed643bb"
),
bytes.fromhex(
"f1d00200e050f794bf4e173d120da550c0c6b8639d51971992ea4cc181d118cd"
"37241b13846cc19773bb23cab988377ed71543b1972a9a0916051f55eac3bb8b"
),
bytes.fromhex(
"f1d0020031afc727dc5e29ed8b6cd00691cb601543940a04035cad49bc2f3967"
"7661a3f99cfc4ceb6c321710ff17bd76626fe8c9264c8fbcc3157cdf667a5ea3"
),
bytes.fromhex(
"f1d0020076fd67505dd6398118e4dcc65fea2e83621d05d4f0494b0741f2229b"
"7ebd687dbf73dacc1aa739f83098ae59faca6314de05039496244612909f4b94"
),
bytes.fromhex(
"f1d002003fbf11cf92c3af7fc90d8ad91737ca26915d900ca02da27327e59928"
"9b893a3cb0b4c426455034c387b5892a040cbb63a809c126b104cfa4830188f9"
),
bytes.fromhex(
"f1d002005c6942920bf5c469eec62403dd0cf472c0243c8a024befabc57908c5"
"82183ac1885f72b2b11d6946fc17689e3bda6bd119c5f9a806a1589fa66a656f"
),
bytes.fromhex(
"f1d00200ddc2bbbc98e630a91739a3d4e53a3d80d536ca64b44383ab15c41d2f"
"a1d877326ffc77e193c031ca1fecff7935818ac53f25e3831e584e64376df72d"
),
bytes.fromhex(
"f1d00200127a577e4952456d1437de70e0197600c6f51ca28ada429e93e56f1d"
"709f143b62c54d9d89c8effe8c76116ea50a9f7d0532583fd911c0761608536a"
),
bytes.fromhex(
"f1d002008b7dba296eb57febf5fdf2cbccde7f95d589e2b2adf3f0473c0ce83b"
"95bab01bfac2938b4c7f626d9ef77961c0cc5a577212e220481242fa02edbd76"
),
bytes.fromhex(
"f1d0020018e9393c975997210aaa8ffe8eb722cc86c3f5758c772de05a629150"
"46758ca8f9ae66e87f2c1395540fe6397d601055624d003a9985ff30fa58ff79"
),
bytes.fromhex(
"f1d00200c996f9eb94b1d063e3ef3ccc1f62a644229ec49bf723efc4452bc172"
"4ff009a53d6257450212bbc258cf3af53e21721956552fa90b5f159a75ae2f28"
),
bytes.fromhex(
"f1d00200eea3e76c751ac11150e934a948876ed28fb8a6f90c1bcbea583aa6ac"
"e167067f24684e15f1360d81862d76754603b61f6f38b7c7126b4431afc1c895"
),
bytes.fromhex(
"f1d00200177abcc78a50e5656106a5a467bcf4f9d53a6217e91ff1488b0f6274"
"2daf383737849be9afb417bfb84604af7d22a281d7e442ba4b5722939d907568"
),
bytes.fromhex(
"f1d00200142c682563283df266724cd945758b2c4b182038694eb61102d4c77b"
"dc83d5fb2bf39c2589d356ff970b7c9b7277754d61c8574251558bd7011a4a0e"
),
bytes.fromhex(
"f1d00200f536387dd05b1c5cef7cc42d287e5ad12d02043e78c84bb8bb13dd3e"
"706b666218b672e6742ab9348de1157177d311f84c5eb78b0b622386c975c5aa"
),
bytes.fromhex(
"f1d002000af7b734e17a2e56ccd6b921bbc050608ef1fd5b76c128589ff1064c"
"ec7d280ad3db773d2aa95b363b7a8e8b48e9c2574d30573eb7bf72789a9d2c98"
),
bytes.fromhex(
"f1d00200e3609ef6e6503f530db35797cd9374bc6a16d7fa6836e4f9dfbb73e2"
"ec095e39ee563cf8d9f2685fe754f7072d96b17d46201f8fdfa17ff9d066a62b"
),
bytes.fromhex(
"f1d0020050ce98d86f4d3544021cd57f578381c4dd77c54e24bc5815e357b71a"
"7059767b1c00462deee16324123b486cf55e08dda98137576794c9bae8dae799"
),
bytes.fromhex(
"f1d0020061ef10a94cc124f23b0cbd0dd3f87da13abd0a5c93000fe06728e3a1"
"d428af29fcfe8cb36b8499d6d32c4e159f55da76449827331b9bc8b8b120db58"
),
bytes.fromhex(
"f1d00200662f1ff88dffdce3881b3fd1b3927d443d93af22321074791895b55b"
"4d2c5db565c2b876c1d862a3e8f20df75d548ce32e6e82f81cd6ac15df5f874d"
),
bytes.fromhex(
"f1d00200ef1d37f782b27facf9cfbc4e69d8ab322d843f6c2db6cae0baaee2af"
"2f292740734287c01eff348ec5643ca2a6ea7133348dc4fd696c9046360a05d8"
),
bytes.fromhex(
"f1d00200ccab14d4bbf4da04dee2529f39352a600ce9a050f10e7516b1a19e8b"
"50bcdb7289bd17765cb52c720a3d1549f34dae6685e0a3aac4ee8ad295d28d66"
),
bytes.fromhex(
"f1d002000d4c6bbe08fe7315c7095259095edd40707746f81fdbd9c69a9898ea"
"adc1b3b9ec15a1a2103d9912190a5b50918411fa0b709daa0eee80c8c4cd706d"
),
bytes.fromhex(
"f1d00200024987ac7974960784134cf153cfe8f18e09e9b55a1f0ea2d84c4075"
"a6eba109758f0f7ad9f4d98d02d110c5ee83e74224bb49b7ad93e12ecbb190ca"
),
bytes.fromhex(
"f1d002003bddb93f5eb1c72125696cd6faf2091ec8f50d2830d6addbf9533dd1"
"065db96e625030a45da63b86ba7ce3c330c90c63afdf0a80fcfb6ed48517f424"
),
bytes.fromhex(
"f1d0020088e01d70478ab1c2fa427a5df05c37f5259318e37b07feda27ea2240"
"39bced35732f1e8b855cad4e691ce8c592cbacb22da84f8f90940a1db45ae90d"
),
bytes.fromhex(
"f1d00200f91829dc046ec93a9321e338708288a3ab7ebc935440f0114387eeb0"
"b36cd1b15c0b6d9bf517acf9af4dd77317a8031a8f1545e84c30c3847bd7b689"
),
bytes.fromhex(
"f1d00200de7f09f5a5e58af3c05a195f0205c3a503de9c886e5c796d83444167"
"12d0ce1f73acbeb5caba771ced77958ab6c76d655747801ea30f0e4d14c43942"
),
bytes.fromhex(
"f1d00200c70a02b07ac9430a91ca1071eddc6250605b13ad15e2a26aae4fd192"
"d56ec3c162633aa5dbe4adbecb904f6e047d329b5bc8e8d2bf4e6aecbecd7e85"
),
bytes.fromhex(
"f1d0020084c8abcc13baf0a756f8a6d9afcc33839ec30ab48aa82dc41330605b"
"bd9c1b72d08e22e4b0ecb59de3c34db1e5f9d42569f16f75dd3ee5ce326746b0"
),
bytes.fromhex(
"f1d002002562128b40ad15359f3fd07c81a0a0a45041cdf42bcdd9c0be45c903"
"7761ce4c335198db6d1d12aebc53dce9406bef0eb2451f4d2f3f77a7e0d6ffdc"
),
bytes.fromhex(
"f1d00200fa4f4a4a119f7c6d3ccdccfb2c84eeda5304e76f43d65780ab096282"
"9036153e70751f3fdf2e5092517145bb0e1b1cb8e2996b0a776cf115ce6f2fca"
),
bytes.fromhex(
"f1d0020093521f24d6b6479d3d80d2a6e3ae0865052f0339001eaeded9f845af"
"24c65975b321a16b8ae58bd138a1801ecd3f927aa1463144fcf0eeb111b3b374"
),
bytes.fromhex(
"f1d00200c0ff66221f7050fff2fe3733944b9afbe2cf87ed6a470d00ed506135"
"92093ed4de0c1028e24453033a14d8622cd6fb582528517f24fd1d422f24b599"
),
bytes.fromhex(
"f1d0020091730144bc97b68deb8f850089eb7f0f6d162be6b385038fa01a5f36"
"51124c42d57b45dd1f4046960d0a241b8e21b874f989ca27feee9ef5dd6318f3"
),
bytes.fromhex(
"f1d00200567595ebbd2c2c35f886f5e7797d8008744ee2a2d4cba66d2e5d6f78"
"836915eebc583c76c7c5a43678606b0ab2bdeee6d75cbe0b2058f3742ee0d95b"
),
bytes.fromhex(
"f1d002009fa021117275aa30295604185d3de969d7cdec36d2d689de8ab94712"
"9e8b2383ce1e8e3073d2ed5e4a209b0f63a4192b81a08f166e10487fce7e2720"
),
bytes.fromhex(
"f1d002003c62e5126bd8142fce922b116708e06da1299f9178bee0f3d48fa01f"
"bc571e70ff369beae6ce813b42674879d92d559791b1c5d26560860e5d004f2e"
),
bytes.fromhex(
"f1d002003dd94e2e7849f337777ec72f1e3382e1ac69df227a85a6b0e5d94021"
"8fcaa17ee11f25ace0f3f58cc4b21804198a59713ff280dcc0471c0437a57ee9"
),
bytes.fromhex(
"f1d00200f2eb3955a95a04aff4e347b639e28dbb8bbc5cb212a20f4d2eb7e572"
"a7356e8ce1f39504044e27f6a0f5cc0b67b02f9d25462a36fa2246d7d5025a4d"
),
bytes.fromhex(
"f1d00200eb2025184e41627855580fe0e889d72725aa5bf0555e581900d22bee"
"83731d45596362b2d21338bca6a8aa5ba1228f1b51178cd888a52bc7f89f8422"
),
bytes.fromhex(
"f1d00200f80b26d4f75e5a56ea2ffbe611a9d53affbeb34866165f08e9b167df"
"264cc4924ffc18677ce157cb10ab1c320843d73b5eefcc9334e0ef401d3f5fca"
),
bytes.fromhex(
"f1d00200295f7da2741eb8bb43b73e1a6d124aa516ab017b65a67bc2b817abf2"
"2a5e5ed122f80c3b4758c0e4e3155210bdb87ccf41d2b0538d462c156630b38a"
),
bytes.fromhex(
"f1d00200ceef2538d534069f308099f18ca66837cbd73510e6dca90fa6e822a4"
"63d3b2d9ccca10d31eaba9ab4f5b3eba9e209b69671b90c96913cb624b91d3e4"
),
bytes.fromhex(
"f1d00200773f9ebb6a966003c1d29e94034840e1da6d0c749dfcbaa957ca1cc8"
"3d95730b74ec9af06c7210e5106f8600e2c5b69770a1089098a927c7813cef07"
),
bytes.fromhex(
"f1d00200f4584d53c3afa1f84692b772b1964b2fddb0e9e6e85e88b05deddeef"
"fc0a6d465b2cb74e6c29ea43ba3420a96ede4db2771d7677064fe68c07fc3eb7"
),
bytes.fromhex(
"f1d002005511263db0b292334f2644c1072ea93f198085b58abd3b0bab63925e"
"8f633fc2179618da8484831c2214d2a378f7de77ac5d70b7e57fa1932722bee7"
),
bytes.fromhex(
"f1d00200eafcc22e4107f5ffac371d9217b7419d5e5a50b81353f9ed13b423d2"
"9862713c776e82dbbf084c9c6c4a04d57964e3f3dc1a39b694e8ee609903edbb"
),
bytes.fromhex(
"f1d0020043a8e5a2c630ae716d510c2d5099936ce8ae20b31588729f06ffce29"
"133d560779b9665713e5f86426909f9484cb3e13d536f2901abbc92f8ddc7429"
),
bytes.fromhex(
"f1d0020030e5a0aacfb69b63e2b5643091fdd241a149a2f53f312f7cc9b14d32"
"da85cb400cd98b79314e361b0fd6daa65e1af40601ec9d31d7585a49261b6c33"
),
bytes.fromhex(
"f1d00200c13b248e2ce2edb99bf7ec8bed66a9f106f241452b5df2c8d34fd5fd"
"a60d2fd9181f31fc51a8ca113161a569d94857f4848658a1a7097d58f0354279"
),
bytes.fromhex(
"f1d0020046cf11abed5dc2426826df3d5677423b19e1bb93bf35f7597555d8f0"
"0a845f4427156e00d0bbec00b34646a8cf3ab6687d0c4358043522d176afe1a3"
),
bytes.fromhex(
"f1d002004f470418620cc71f59a00b5e4e266c39db094b53890614d34f5f6f43"
"7238b441ccb4d26a5a4094f798f6d207ecbc5f42ef63dd71953cd0ad97f43619"
),
bytes.fromhex(
"f1d00200ac8cc3861ba035bbbed695be922e4900a9e615ae973b39407a053638"
"f361261856eed733f4652ad3467f04a315ae9423d837a08c55ee90d25f69199a"
),
bytes.fromhex(
"f1d002006d6a01b0e8c88d212797560de12f16bd07920ef73d3554946034d901"
"8a8f649f16d918f91c0e3511c06496f673e57b2340992676a1383fb94daa3157"
),
bytes.fromhex(
"f1d00200e26206dad9043a8264a880703b905e752115899348f027c318b2651e"
"b6b4bda5cad639e0a05e6d7255c95ec47088c0f9b38104e8f8b09b8459030cfc"
),
bytes.fromhex(
"f1d002009b48bfab3e65364385cb9635dcb59a31b946dc2ce083d6c942d9c8a7"
"cd3a964a8e803a21f285fc208d2c95fac10c103e1df2b32d4232804a4349aae2"
),
bytes.fromhex(
"f1d00200686b3157a7d7e4d7da704970c300a47656ef5063ef7367f3714e1161"
"6b9990de98088ef19c20c3cae50c898d8d6223bc1a5690bd70bf5aa4c57d0485"
),
bytes.fromhex(
"f1d002005969a153e4c24b15f3b03289a4f0b0a9b118f7a099859ff23e2351fd"
"b8dc168b9f48f13eb1f4ce42c8f6d8f96f84caf3ca4f2659feb117092e44c891"
),
bytes.fromhex(
"f1d00200bef323780508ee76a05934e6caa842f03aacce20e2b2ab38814dbc60"
"a647503e27cac10cd991aeb1d94ef25fbe22ee77b40c7e3a747c5bd977366272"
),
bytes.fromhex(
"f1d002002718e42b5ab772b4f11e1a03d23484fba3b191c9840601676316f4bb"
"701097fa51ce330ee5e94d3644a9ea6fd4022018cbe4ae43073486be40bc9368"
),
bytes.fromhex(
"f1d0020064ddfb657309336336400588853497f7e33ecf8c0b0faa2a0cad9692"
"f0b16351750ae97d87f3c6c2a326f6bf83aaf320751cf97951f4eb7c541a5855"
),
bytes.fromhex(
"f1d0020085442e0c206c12fbff3093e2bacf8726dd6d91c3853a3e1cbad04545"
"9eb3587b8aeff00d7cdb516075c204bd31f8686e22c6218d29f2c9a982cebeb5"
),
bytes.fromhex(
"f1d00200dafd58d371b362371c16fae5c88c830767e0908190e5a0a461d418b5"
"4e5506e306996f8f7031ff6403603b077a28c9de2464339622bcb91f39fb8c20"
),
bytes.fromhex(
"f1d00200f361d457b6bef9e19d26e0d7df45fcd2899b2777b902b36c52ff17be"
"757e26a82d5a1ded2cec0346b4bbcb9e9582dcba78894b4fc538de08c3915cfc"
),
bytes.fromhex(
"f1d00200a07ec5327f218aded24032d88d25f9820e30f98712e576c0c54a4b5a"
"97922ddaa38c426cd58e8e9687a5c4fb47b9b16ee84dbfc205af7d34758c8973"
),
bytes.fromhex(
"f1d00200f14744e79ca019364b43f6e096f40edd2e02eed78e3e77960d261e61"
"32aef6d4eb9a889403b3d7cd3bf5a75921e66f1fac3d28d0296abe951795ccc1"
),
bytes.fromhex(
"f1d00200363d1b761d937a10d8f91a470bbc3672466719468b3eef3086b240b1"
"5210cf8c7470d99562ded2773d983087d128ab59cdfb6859cfa8dfde325510a0"
),
bytes.fromhex(
"f1d00200ff1152ff5277aca889aebd2b63e3de24b4d71e0e3ba8d7bc69d3c4fd"
"8ec7589ad2f0c0baf41063d44b2da593dc5f615af7d2bc9d4ce8d9b17ca6e6cb"
),
bytes.fromhex(
"f1d002001c2bfeaccb4b4080aeaeb8c47aae7c469672abeb0b28bb921e3ff91b"
"aa4e90200faeafda36fbaff7140dd6e727bc05942baafe8a9f45b43ed4ef8caf"
),
]

@ -24,6 +24,7 @@ from trezorlib.tools import H_
@pytest.mark.flaky(max_runs=5)
class TestBip32Speed:
@pytest.mark.skip_t2
def test_public_ckd(self, client):
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39
@ -35,6 +36,7 @@ class TestBip32Speed:
print("DEPTH", depth, "EXPECTED DELAY", expected, "REAL DELAY", delay)
assert delay <= expected
@pytest.mark.skip_t2
def test_private_ckd(self, client):
btc.get_address(client, "Bitcoin", []) # to compute root node via BIP39

@ -20,91 +20,9 @@ from trezorlib import webauthn
from trezorlib.exceptions import Cancelled, TrezorFailure
from ..common import MNEMONIC12
from .data_webauthn import CRED1, CRED2, CRED3, CREDS
CRED1 = bytes.fromhex(
"f1d00200f8221312f7898e31ea5ec30409527c2b0bde0b9dfdd7eaab4424173f"
"bf75ab67627fff60974460d903d7d96bb9e974c169a01b2c38cf2305da304169"
"d4e28f59053a2564bebb3eb3f06c2182f1ea4a2f7cebd8f92a930a76f3b45334"
"1e3f3285a575a54bcba9cf8a088dbfe24e8e691a5926160174e03aa941828f49"
"e42b47804d"
)
CRED2 = bytes.fromhex(
"f1d00200eb3b566f4ea0a219552b2efd2c76e1ffc2e641d3bf91ec92d47a4ed4"
"d78cf42845248c4e982a503618bac0cecfb0fa91fa10821df1efe1d59ac8314e"
"b57eb7f32a1a605f91e8692daf1a679b55ab1acadfded5e0c7fd1365e2801759"
"bd3a4450dd5589586ab072da79"
)
CRED3 = bytes.fromhex(
"f1d00200ebee50034eb7affb555602eed0812b63d158b57a4188523ad064a719"
"febf477c52cfcc7ded8d7a7a83af52287ed1ecee9f74f62b7e55ad8e814c062e"
"009bb3b3391dfec79dc93053b0279eca7207358a0962865da55668b2509de773"
"8c819dbeead9997778319ac1f1c7318fd6"
)
CREDS = [
bytes.fromhex(
"f1d0020029a297837485bf2b43f2a8cc53b759a03201cf6902cf25794a375214"
"aea1357cee1e2fa9188e8fb74e5b5501767ca740cd1f0c745bb72afd"
),
bytes.fromhex(
"f1d00200ce4e44a4d5076b7d3037ca039894738183f18b0ef5edfa84b59ba4e9"
"2e9ce5fe02ddd6cd397c459636dfb45af740d268bd67610578581cc1"
),
bytes.fromhex(
"f1d00200776ac8476ac5a621c135e9ab3d5c5c1d836843eddad88f94ff044989"
"cc941f5971bd3df1a3008e12ad16a11753cdfe113d023784a29bbbe0"
),
bytes.fromhex(
"f1d00200f4bf428bc3ea21a64691bc1cfb3ae14d4ed29621777856ea81b8936e"
"51293fb8b073ab1c03fe7016b01f9e2bcac796f3c3c33515ffbf88c2"
),
bytes.fromhex(
"f1d0020055e4d0a8b06951564f71dd601287929b396013d1b1cfd1ab237a6e1d"
"b53b7f562465ed53b3fc8ba7f0b5e05498fd13badfaac358694e76f2"
),
bytes.fromhex(
"f1d00200ea2b8789416aa55dac3e8446da76a9fba3f52722329bf4820480faf1"
"ed35f2eb8577a0e3bbcecd6177d1a4c21faafc3411281ebbc2a8f100"
),
bytes.fromhex(
"f1d0020043e37bb7c62fd11b6d446da96741123b38ab9123d695537357373970"
"8d0e7aaff1ed90306da2779c23fde88c68cd37171c871af4f6c6cc08"
),
bytes.fromhex(
"f1d00200309ced39cf016b1ae284cd63e48310dd73e14f5f3af681fcfd84e121"
"6cbab4b1d00f505445b839bca1909521e4ba06209fd161bb98eb2b7d"
),
bytes.fromhex(
"f1d00200c19e3a3e2ce982419b52487e84ceb42a92bbda1c029b1bb3e832ffa7"
"0321c22edfb6163ee5ec2be03b1b291f451667a6020a720c41653745"
),
bytes.fromhex(
"f1d0020046ce52d1ed50a900687d6ba20863cc9c0cd6ee9fb72129a0f63eb598"
"dcd3cd79c449d251240e2098f4b29e4cfa28ab7b45b77f045589312d"
),
bytes.fromhex(
"f1d002004f92099262dbedc059237e3aff412204131dad9cbad98147322b00ed"
"988cd7f7b2ea2f34b0388b3efa1246477d058e4d94773a38355bc2e7"
),
bytes.fromhex(
"f1d00200ac93867d1bfbe6a6be75d943354f280e32fafce204bcee65db097666"
"e805b80d38f4f3094f334fb310d4f5cc80ccef603fdd6ba320b4eb73"
),
bytes.fromhex(
"f1d002006d5d6efbe81fe81927029727409d0f242a4da827947ec55e118cd65c"
"e6f0d1ae4c7ac578f3682806b5e0e5bfaaf7d0416960ece3fc219516"
),
bytes.fromhex(
"f1d00200e231eba4d9875231644ff1e38c83be7ce3508401b6184320a2ea3dc2"
"6092f807aba192c6fc5e7286dfc0e5ccc4738d6d8c8a1a440140b47a"
),
bytes.fromhex(
"f1d002008841311e477753cbfa4b21779d4c04e7c5532f956f2c6995b99e1392"
"1143b64b4099c98b4b1c012ef06c1bfa673f192fec193f05cf26c0cc"
),
]
RK_CAPACITY = 100
@pytest.mark.skip_t1
@ -155,7 +73,7 @@ class TestMsgWebAuthn:
with pytest.raises(Cancelled):
webauthn.add_credential(client, CRED1[:-2])
# Check that the credential was not added.
# Check that the invalid credential was not added.
creds = webauthn.list_credentials(client)
assert len(creds) == 1
@ -166,28 +84,28 @@ class TestMsgWebAuthn:
creds = webauthn.list_credentials(client)
assert len(creds) == 2
# Fill up with 14 more valid credentials.
for cred in CREDS[:14]:
# Fill up the credential storage to maximum capacity.
for cred in CREDS[: RK_CAPACITY - 2]:
webauthn.add_credential(client, cred)
# Adding one more valid credential to full storage should fail.
with pytest.raises(TrezorFailure):
webauthn.add_credential(client, CREDS[14])
webauthn.add_credential(client, CREDS[-1])
# Remove index 16 should fail.
# Removing the index, which is one past the end, should fail.
with pytest.raises(TrezorFailure):
webauthn.remove_credential(client, 16)
webauthn.remove_credential(client, RK_CAPACITY)
# Remove index 2.
webauthn.remove_credential(client, 2)
# Check that the credential was removed.
creds = webauthn.list_credentials(client)
assert len(creds) == 15
assert len(creds) == RK_CAPACITY - 1
# Adding another valid credential should succeed now.
webauthn.add_credential(client, CREDS[14])
webauthn.add_credential(client, CREDS[-1])
# Check that the credential was added.
creds = webauthn.list_credentials(client)
assert len(creds) == 16
assert len(creds) == RK_CAPACITY

@ -1 +1 @@
Subproject commit cb4560f3ea569093d0a2be414a4d01a94082d839
Subproject commit f414dd2bc1094f148b217ed58516ccbf4cf43690
Loading…
Cancel
Save