mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-17 21:22:10 +00:00
feat(core): Support 50 digit PIN and wipe code.
This commit is contained in:
parent
c68e91c12a
commit
3084d1196d
@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Allow decreasing the output value in RBF transactions. [#1491]
|
||||
- Cardano: Allow stake pool registrations with zero margin. [#1502]
|
||||
- Cardano: Assets are now shown as CIP-0014. [#1510]
|
||||
- Support PIN of unlimited length. [#1167]
|
||||
|
||||
### Deprecated
|
||||
|
||||
@ -358,6 +359,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
[#1139]: https://github.com/trezor/trezor-firmware/issues/1139
|
||||
[#1159]: https://github.com/trezor/trezor-firmware/issues/1159
|
||||
[#1165]: https://github.com/trezor/trezor-firmware/pull/1165
|
||||
[#1167]: https://github.com/trezor/trezor-firmware/issues/1167
|
||||
[#1173]: https://github.com/trezor/trezor-firmware/pull/1173
|
||||
[#1184]: https://github.com/trezor/trezor-firmware/issues/1184
|
||||
[#1188]: https://github.com/trezor/trezor-firmware/issues/1188
|
||||
|
@ -66,13 +66,15 @@ STATIC mp_obj_t mod_trezorconfig_init(size_t n_args, const mp_obj_t *args) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_init_obj, 0, 1,
|
||||
mod_trezorconfig_init);
|
||||
|
||||
/// def unlock(pin: int, ext_salt: Optional[bytes]) -> bool:
|
||||
/// def unlock(pin: str, ext_salt: Optional[bytes]) -> bool:
|
||||
/// """
|
||||
/// Attempts to unlock the storage with the given PIN and external salt.
|
||||
/// Returns True on success, False on failure.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorconfig_unlock(mp_obj_t pin, mp_obj_t ext_salt) {
|
||||
uint32_t pin_i = trezor_obj_get_uint(pin);
|
||||
mp_buffer_info_t pin_b = {0};
|
||||
mp_get_buffer_raise(pin, &pin_b, MP_BUFFER_READ);
|
||||
|
||||
mp_buffer_info_t ext_salt_b = {0};
|
||||
ext_salt_b.buf = NULL;
|
||||
if (ext_salt != mp_const_none) {
|
||||
@ -81,7 +83,7 @@ STATIC mp_obj_t mod_trezorconfig_unlock(mp_obj_t pin, mp_obj_t ext_salt) {
|
||||
mp_raise_msg(&mp_type_ValueError, "Invalid length of external salt.");
|
||||
}
|
||||
|
||||
if (sectrue != storage_unlock(pin_i, ext_salt_b.buf)) {
|
||||
if (sectrue != storage_unlock(pin_b.buf, pin_b.len, ext_salt_b.buf)) {
|
||||
return mp_const_false;
|
||||
}
|
||||
return mp_const_true;
|
||||
@ -89,7 +91,7 @@ STATIC mp_obj_t mod_trezorconfig_unlock(mp_obj_t pin, mp_obj_t ext_salt) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorconfig_unlock_obj,
|
||||
mod_trezorconfig_unlock);
|
||||
|
||||
/// def check_pin(pin: int, ext_salt: Optional[bytes]) -> bool:
|
||||
/// def check_pin(pin: str, ext_salt: Optional[bytes]) -> bool:
|
||||
/// """
|
||||
/// Check the given PIN with the given external salt.
|
||||
/// Returns True on success, False on failure.
|
||||
@ -148,8 +150,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_get_pin_rem_obj,
|
||||
mod_trezorconfig_get_pin_rem);
|
||||
|
||||
/// def change_pin(
|
||||
/// oldpin: int,
|
||||
/// newpin: int,
|
||||
/// oldpin: str,
|
||||
/// newpin: str,
|
||||
/// old_ext_salt: Optional[bytes],
|
||||
/// new_ext_salt: Optional[bytes],
|
||||
/// ) -> bool:
|
||||
@ -158,8 +160,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_get_pin_rem_obj,
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorconfig_change_pin(size_t n_args,
|
||||
const mp_obj_t *args) {
|
||||
uint32_t oldpin = trezor_obj_get_uint(args[0]);
|
||||
uint32_t newpin = trezor_obj_get_uint(args[1]);
|
||||
mp_buffer_info_t oldpin = {0};
|
||||
mp_get_buffer_raise(args[0], &oldpin, MP_BUFFER_READ);
|
||||
|
||||
mp_buffer_info_t newpin = {0};
|
||||
mp_get_buffer_raise(args[1], &newpin, MP_BUFFER_READ);
|
||||
|
||||
mp_buffer_info_t ext_salt_b = {0};
|
||||
const uint8_t *old_ext_salt = NULL;
|
||||
if (args[2] != mp_const_none) {
|
||||
@ -176,8 +182,8 @@ STATIC mp_obj_t mod_trezorconfig_change_pin(size_t n_args,
|
||||
new_ext_salt = ext_salt_b.buf;
|
||||
}
|
||||
|
||||
if (sectrue !=
|
||||
storage_change_pin(oldpin, newpin, old_ext_salt, new_ext_salt)) {
|
||||
if (sectrue != storage_change_pin(oldpin.buf, oldpin.len, newpin.buf,
|
||||
newpin.len, old_ext_salt, new_ext_salt)) {
|
||||
return mp_const_false;
|
||||
}
|
||||
return mp_const_true;
|
||||
@ -185,13 +191,14 @@ STATIC mp_obj_t mod_trezorconfig_change_pin(size_t n_args,
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_change_pin_obj, 4,
|
||||
4, mod_trezorconfig_change_pin);
|
||||
|
||||
/// def ensure_not_wipe_code(pin: int) -> None:
|
||||
/// def ensure_not_wipe_code(pin: str) -> None:
|
||||
/// """
|
||||
/// Wipes the device if the entered PIN is the wipe code.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorconfig_ensure_not_wipe_code(mp_obj_t pin) {
|
||||
uint32_t pin_i = trezor_obj_get_uint(pin);
|
||||
storage_ensure_not_wipe_code(pin_i);
|
||||
mp_buffer_info_t pin_b = {0};
|
||||
mp_get_buffer_raise(pin, &pin_b, MP_BUFFER_READ);
|
||||
storage_ensure_not_wipe_code(pin_b.buf, pin_b.len);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorconfig_ensure_not_wipe_code_obj,
|
||||
@ -211,17 +218,21 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_has_wipe_code_obj,
|
||||
mod_trezorconfig_has_wipe_code);
|
||||
|
||||
/// def change_wipe_code(
|
||||
/// pin: int,
|
||||
/// pin: str,
|
||||
/// ext_salt: Optional[bytes],
|
||||
/// wipe_code: int,
|
||||
/// wipe_code: str,
|
||||
/// ) -> bool:
|
||||
/// """
|
||||
/// Change wipe code. Returns True on success, False on failure.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorconfig_change_wipe_code(size_t n_args,
|
||||
const mp_obj_t *args) {
|
||||
uint32_t pin = trezor_obj_get_uint(args[0]);
|
||||
uint32_t wipe_code = trezor_obj_get_uint(args[2]);
|
||||
mp_buffer_info_t pin_b = {0};
|
||||
mp_get_buffer_raise(args[0], &pin_b, MP_BUFFER_READ);
|
||||
|
||||
mp_buffer_info_t wipe_code_b = {0};
|
||||
mp_get_buffer_raise(args[2], &wipe_code_b, MP_BUFFER_READ);
|
||||
|
||||
mp_buffer_info_t ext_salt_b = {0};
|
||||
const uint8_t *ext_salt = NULL;
|
||||
if (args[1] != mp_const_none) {
|
||||
@ -231,7 +242,8 @@ STATIC mp_obj_t mod_trezorconfig_change_wipe_code(size_t n_args,
|
||||
ext_salt = ext_salt_b.buf;
|
||||
}
|
||||
|
||||
if (sectrue != storage_change_wipe_code(pin, ext_salt, wipe_code)) {
|
||||
if (sectrue != storage_change_wipe_code(pin_b.buf, pin_b.len, ext_salt,
|
||||
wipe_code_b.buf, wipe_code_b.len)) {
|
||||
return mp_const_false;
|
||||
}
|
||||
return mp_const_true;
|
||||
|
@ -39,6 +39,6 @@
|
||||
/*
|
||||
* Current storage version.
|
||||
*/
|
||||
#define NORCOW_VERSION ((uint32_t)0x00000002)
|
||||
#define NORCOW_VERSION ((uint32_t)0x00000003)
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@ def init(
|
||||
|
||||
|
||||
# extmod/modtrezorconfig/modtrezorconfig.c
|
||||
def unlock(pin: int, ext_salt: Optional[bytes]) -> bool:
|
||||
def unlock(pin: str, ext_salt: Optional[bytes]) -> bool:
|
||||
"""
|
||||
Attempts to unlock the storage with the given PIN and external salt.
|
||||
Returns True on success, False on failure.
|
||||
@ -20,7 +20,7 @@ def unlock(pin: int, ext_salt: Optional[bytes]) -> bool:
|
||||
|
||||
|
||||
# extmod/modtrezorconfig/modtrezorconfig.c
|
||||
def check_pin(pin: int, ext_salt: Optional[bytes]) -> bool:
|
||||
def check_pin(pin: str, ext_salt: Optional[bytes]) -> bool:
|
||||
"""
|
||||
Check the given PIN with the given external salt.
|
||||
Returns True on success, False on failure.
|
||||
@ -57,8 +57,8 @@ def get_pin_rem() -> int:
|
||||
|
||||
# extmod/modtrezorconfig/modtrezorconfig.c
|
||||
def change_pin(
|
||||
oldpin: int,
|
||||
newpin: int,
|
||||
oldpin: str,
|
||||
newpin: str,
|
||||
old_ext_salt: Optional[bytes],
|
||||
new_ext_salt: Optional[bytes],
|
||||
) -> bool:
|
||||
@ -68,7 +68,7 @@ def change_pin(
|
||||
|
||||
|
||||
# extmod/modtrezorconfig/modtrezorconfig.c
|
||||
def ensure_not_wipe_code(pin: int) -> None:
|
||||
def ensure_not_wipe_code(pin: str) -> None:
|
||||
"""
|
||||
Wipes the device if the entered PIN is the wipe code.
|
||||
"""
|
||||
@ -83,9 +83,9 @@ def has_wipe_code() -> bool:
|
||||
|
||||
# extmod/modtrezorconfig/modtrezorconfig.c
|
||||
def change_wipe_code(
|
||||
pin: int,
|
||||
pin: str,
|
||||
ext_salt: Optional[bytes],
|
||||
wipe_code: int,
|
||||
wipe_code: str,
|
||||
) -> bool:
|
||||
"""
|
||||
Change wipe code. Returns True on success, False on failure.
|
||||
|
@ -3,7 +3,6 @@ import utime
|
||||
import storage.sd_salt
|
||||
from trezor import config, ui, wire
|
||||
from trezor.messages import ButtonRequestType
|
||||
from trezor.pin import pin_to_int
|
||||
from trezor.ui.components.tt.pin import CANCELLED, PinDialog
|
||||
from trezor.ui.components.tt.text import Text
|
||||
from trezor.ui.popup import Popup
|
||||
@ -71,7 +70,7 @@ async def request_pin_and_sd_salt(
|
||||
) -> Tuple[str, Optional[bytearray]]:
|
||||
if config.has_pin():
|
||||
pin = await request_pin(ctx, prompt, config.get_pin_rem(), allow_cancel)
|
||||
config.ensure_not_wipe_code(pin_to_int(pin))
|
||||
config.ensure_not_wipe_code(pin)
|
||||
else:
|
||||
pin = ""
|
||||
|
||||
@ -98,7 +97,7 @@ async def verify_user_pin(
|
||||
|
||||
if config.has_pin():
|
||||
pin = await request_pin(ctx, prompt, config.get_pin_rem(), allow_cancel)
|
||||
config.ensure_not_wipe_code(pin_to_int(pin))
|
||||
config.ensure_not_wipe_code(pin)
|
||||
else:
|
||||
pin = ""
|
||||
|
||||
@ -106,7 +105,7 @@ async def verify_user_pin(
|
||||
salt = await request_sd_salt(ctx)
|
||||
except SdCardUnavailable:
|
||||
raise wire.PinCancelled("SD salt is unavailable")
|
||||
if config.unlock(pin_to_int(pin), salt):
|
||||
if config.unlock(pin, salt):
|
||||
_last_successful_unlock = utime.ticks_ms()
|
||||
return
|
||||
elif not config.has_pin():
|
||||
@ -116,7 +115,7 @@ async def verify_user_pin(
|
||||
pin = await request_pin(
|
||||
ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel
|
||||
)
|
||||
if config.unlock(pin_to_int(pin), salt):
|
||||
if config.unlock(pin, salt):
|
||||
_last_successful_unlock = utime.ticks_ms()
|
||||
return
|
||||
|
||||
|
@ -4,7 +4,6 @@ from trezor import config, wire
|
||||
from trezor.crypto import bip39, slip39
|
||||
from trezor.messages import BackupType
|
||||
from trezor.messages.Success import Success
|
||||
from trezor.pin import pin_to_int
|
||||
from trezor.ui.layouts import confirm_action, require
|
||||
|
||||
from apps.management import backup_types
|
||||
@ -46,7 +45,7 @@ async def load_device(ctx, msg):
|
||||
storage.device.set_passphrase_enabled(msg.passphrase_protection)
|
||||
storage.device.set_label(msg.label or "")
|
||||
if msg.pin:
|
||||
config.change_pin(pin_to_int(""), pin_to_int(msg.pin), None, None)
|
||||
config.change_pin("", msg.pin, None, None)
|
||||
|
||||
return Success(message="Device loaded")
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
from storage.device import is_initialized
|
||||
from trezor import config, ui, wire
|
||||
from trezor.messages.Success import Success
|
||||
from trezor.pin import pin_to_int
|
||||
from trezor.ui.components.tt.text import Text
|
||||
from trezor.ui.layouts import require, show_success
|
||||
|
||||
@ -29,7 +28,7 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success:
|
||||
|
||||
# if changing pin, pre-check the entered pin before getting new pin
|
||||
if curpin and not msg.remove:
|
||||
if not config.check_pin(pin_to_int(curpin), salt):
|
||||
if not config.check_pin(curpin, salt):
|
||||
await error_pin_invalid(ctx)
|
||||
|
||||
# get new pin
|
||||
@ -39,7 +38,7 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success:
|
||||
newpin = ""
|
||||
|
||||
# write into storage
|
||||
if not config.change_pin(pin_to_int(curpin), pin_to_int(newpin), salt, salt):
|
||||
if not config.change_pin(curpin, newpin, salt, salt):
|
||||
if newpin:
|
||||
await error_pin_matches_wipe_code(ctx)
|
||||
else:
|
||||
|
@ -1,7 +1,6 @@
|
||||
from storage.device import is_initialized
|
||||
from trezor import config, ui, wire
|
||||
from trezor.messages.Success import Success
|
||||
from trezor.pin import pin_to_int
|
||||
from trezor.ui.components.tt.text import Text
|
||||
from trezor.ui.layouts import require, show_success
|
||||
from trezor.ui.popup import Popup
|
||||
@ -30,7 +29,7 @@ async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success:
|
||||
|
||||
if not msg.remove:
|
||||
# Pre-check the entered PIN.
|
||||
if config.has_pin() and not config.check_pin(pin_to_int(pin), salt):
|
||||
if config.has_pin() and not config.check_pin(pin, salt):
|
||||
await error_pin_invalid(ctx)
|
||||
|
||||
# Get new wipe code.
|
||||
@ -39,7 +38,7 @@ async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success:
|
||||
wipe_code = ""
|
||||
|
||||
# Write into storage.
|
||||
if not config.change_wipe_code(pin_to_int(pin), salt, pin_to_int(wipe_code)):
|
||||
if not config.change_wipe_code(pin, salt, wipe_code):
|
||||
await error_pin_invalid(ctx)
|
||||
|
||||
if wipe_code:
|
||||
|
@ -4,7 +4,6 @@ import storage.recovery
|
||||
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
|
||||
from trezor.ui.components.tt.text import Text
|
||||
|
||||
from apps.common.confirm import require_confirm
|
||||
@ -47,14 +46,14 @@ async def recovery_device(ctx: wire.Context, msg: RecoveryDevice) -> Success:
|
||||
# for dry run pin needs to be entered
|
||||
if msg.dry_run:
|
||||
curpin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN")
|
||||
if not config.check_pin(pin_to_int(curpin), salt):
|
||||
if not config.check_pin(curpin, salt):
|
||||
await error_pin_invalid(ctx)
|
||||
|
||||
if not msg.dry_run:
|
||||
# set up pin if requested
|
||||
if msg.pin_protection:
|
||||
newpin = await request_pin_confirm(ctx, allow_cancel=False)
|
||||
config.change_pin(pin_to_int(""), pin_to_int(newpin), None, None)
|
||||
config.change_pin("", newpin, None, None)
|
||||
|
||||
storage.device.set_passphrase_enabled(bool(msg.passphrase_protection))
|
||||
if msg.u2f_counter is not None:
|
||||
|
@ -6,7 +6,6 @@ from trezor.messages import BackupType
|
||||
from trezor.messages.EntropyAck import EntropyAck
|
||||
from trezor.messages.EntropyRequest import EntropyRequest
|
||||
from trezor.messages.Success import Success
|
||||
from trezor.pin import pin_to_int
|
||||
from trezor.ui.layouts import confirm_backup, confirm_reset_device, require
|
||||
from trezor.ui.loader import LoadingAnimation
|
||||
|
||||
@ -43,7 +42,7 @@ async def reset_device(ctx: wire.Context, msg: ResetDevice) -> Success:
|
||||
# request and set new PIN
|
||||
if msg.pin_protection:
|
||||
newpin = await request_pin_confirm(ctx)
|
||||
if not config.change_pin(pin_to_int(""), pin_to_int(newpin), None, None):
|
||||
if not config.change_pin("", newpin, None, None):
|
||||
raise wire.ProcessError("Failed to set PIN")
|
||||
|
||||
# generate and display internal entropy
|
||||
|
@ -4,7 +4,6 @@ from trezor import config, ui, wire
|
||||
from trezor.crypto import random
|
||||
from trezor.messages import SdProtectOperationType
|
||||
from trezor.messages.Success import Success
|
||||
from trezor.pin import pin_to_int
|
||||
from trezor.ui.components.tt.text import Text
|
||||
from trezor.ui.layouts import require, show_success
|
||||
|
||||
@ -66,9 +65,9 @@ async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success:
|
||||
|
||||
# Get the current PIN.
|
||||
if config.has_pin():
|
||||
pin = pin_to_int(await request_pin(ctx, "Enter PIN", config.get_pin_rem()))
|
||||
pin = await request_pin(ctx, "Enter PIN", config.get_pin_rem())
|
||||
else:
|
||||
pin = pin_to_int("")
|
||||
pin = ""
|
||||
|
||||
# Check PIN and prepare salt file.
|
||||
salt, salt_auth_key, salt_tag = _make_salt()
|
||||
@ -107,7 +106,7 @@ async def sd_protect_disable(ctx: wire.Context, msg: SdProtect) -> Success:
|
||||
pin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN")
|
||||
|
||||
# Check PIN and remove salt.
|
||||
if not config.change_pin(pin_to_int(pin), pin_to_int(pin), salt, None):
|
||||
if not config.change_pin(pin, pin, salt, None):
|
||||
await error_pin_invalid(ctx)
|
||||
|
||||
storage.device.set_sd_salt_auth_key(None)
|
||||
@ -144,7 +143,7 @@ async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success:
|
||||
new_salt, new_auth_key, new_salt_tag = _make_salt()
|
||||
await _set_salt(ctx, new_salt, new_salt_tag, stage=True)
|
||||
|
||||
if not config.change_pin(pin_to_int(pin), pin_to_int(pin), old_salt, new_salt):
|
||||
if not config.change_pin(pin, pin, old_salt, new_salt):
|
||||
await error_pin_invalid(ctx)
|
||||
|
||||
storage.device.set_sd_salt_auth_key(new_auth_key)
|
||||
|
@ -4,10 +4,6 @@ if False:
|
||||
from typing import Any, Optional
|
||||
|
||||
|
||||
def pin_to_int(pin: str) -> int:
|
||||
return int("1" + pin)
|
||||
|
||||
|
||||
_previous_progress: Optional[int] = None
|
||||
_previous_seconds: Optional[int] = None
|
||||
keepalive_callback: Any = None
|
||||
|
@ -41,16 +41,40 @@ class PinInput(ui.Component):
|
||||
self.repaint = False
|
||||
|
||||
def render_pin(self) -> None:
|
||||
display.bar(0, 0, ui.WIDTH, 50, ui.BG)
|
||||
count = len(self.pin)
|
||||
MAX_LENGTH = const(14) # maximum length of displayed PIN
|
||||
CONTD_MARK = "<"
|
||||
BOX_WIDTH = const(240)
|
||||
DOT_SIZE = const(10)
|
||||
PADDING = const(14)
|
||||
PADDING = const(4)
|
||||
RENDER_Y = const(20)
|
||||
render_x = (BOX_WIDTH - count * PADDING) // 2
|
||||
TWITCH = const(3)
|
||||
|
||||
display.bar(0, 0, ui.WIDTH, 50, ui.BG)
|
||||
|
||||
if len(self.pin) > MAX_LENGTH:
|
||||
contd_width = display.text_width(CONTD_MARK, ui.BOLD) + PADDING
|
||||
twitch = TWITCH * (len(self.pin) % 2)
|
||||
else:
|
||||
contd_width = 0
|
||||
twitch = 0
|
||||
|
||||
count = min(len(self.pin), MAX_LENGTH)
|
||||
render_x = (BOX_WIDTH - count * (DOT_SIZE + PADDING) - contd_width) // 2
|
||||
|
||||
if contd_width:
|
||||
display.text(
|
||||
render_x, RENDER_Y + DOT_SIZE, CONTD_MARK, ui.BOLD, ui.GREY, ui.BG
|
||||
)
|
||||
|
||||
for i in range(0, count):
|
||||
display.bar_radius(
|
||||
render_x + i * PADDING, RENDER_Y, DOT_SIZE, DOT_SIZE, ui.GREY, ui.BG, 4
|
||||
render_x + contd_width + twitch + i * (DOT_SIZE + PADDING),
|
||||
RENDER_Y,
|
||||
DOT_SIZE,
|
||||
DOT_SIZE,
|
||||
ui.GREY,
|
||||
ui.BG,
|
||||
4,
|
||||
)
|
||||
|
||||
def render_prompt(self) -> None:
|
||||
@ -82,7 +106,7 @@ class PinDialog(ui.Layout):
|
||||
prompt: str,
|
||||
subprompt: Optional[str],
|
||||
allow_cancel: bool = True,
|
||||
maxlength: int = 9,
|
||||
maxlength: int = 50,
|
||||
) -> None:
|
||||
self.maxlength = maxlength
|
||||
self.input = PinInput(prompt, subprompt, "")
|
||||
|
@ -1,5 +1,4 @@
|
||||
from common import *
|
||||
from trezor.pin import pin_to_int
|
||||
from trezor import config
|
||||
from storage import device
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
from common import *
|
||||
|
||||
from trezor.crypto import random
|
||||
from trezor.pin import pin_to_int
|
||||
|
||||
from trezor import config
|
||||
|
||||
@ -27,7 +26,7 @@ class TestConfig(unittest.TestCase):
|
||||
def test_wipe(self):
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
self.assertEqual(config.unlock('', None), True)
|
||||
config.set(1, 1, b'hello')
|
||||
config.set(1, 2, b'world')
|
||||
v0 = config.get(1, 1)
|
||||
@ -44,7 +43,7 @@ class TestConfig(unittest.TestCase):
|
||||
for _ in range(128):
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
self.assertEqual(config.unlock('', None), True)
|
||||
appid, key = random_entry()
|
||||
value = random.bytes(16)
|
||||
config.set(appid, key, value)
|
||||
@ -58,7 +57,7 @@ class TestConfig(unittest.TestCase):
|
||||
def test_public(self):
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
self.assertEqual(config.unlock('', None), True)
|
||||
|
||||
appid, key = random_entry()
|
||||
|
||||
@ -84,20 +83,46 @@ class TestConfig(unittest.TestCase):
|
||||
def test_change_pin(self):
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
with self.assertRaises(RuntimeError):
|
||||
config.set(PINAPP, PINKEY, b'value')
|
||||
self.assertEqual(config.change_pin(pin_to_int('000'), pin_to_int('666'), None, None), False)
|
||||
self.assertEqual(config.change_pin(pin_to_int(''), pin_to_int('000'), None, None), True)
|
||||
self.assertEqual(config.get(PINAPP, PINKEY), None)
|
||||
self.assertTrue(config.unlock('', None))
|
||||
config.set(1, 1, b'value')
|
||||
config.init()
|
||||
self.assertEqual(config.unlock(pin_to_int('000'), None), True)
|
||||
config.change_pin(pin_to_int('000'), pin_to_int(''), None, None)
|
||||
config.init()
|
||||
self.assertEqual(config.unlock(pin_to_int('000'), None), False)
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
self.assertEqual(config.get(1, 1), b'value')
|
||||
PINS = ('123', '123', 'Trezor T', '3141592653589793238462643383279502884197', '')
|
||||
old_pin = ''
|
||||
for new_pin in PINS:
|
||||
self.assertTrue(config.unlock(old_pin, None))
|
||||
|
||||
# The APP namespace which is reserved for storage related values is inaccessible even
|
||||
# when unlocked.
|
||||
with self.assertRaises(RuntimeError):
|
||||
config.set(PINAPP, PINKEY, b'value')
|
||||
|
||||
self.assertTrue(config.change_pin(old_pin, new_pin, None, None))
|
||||
|
||||
# Old PIN cannot be used to change the current PIN.
|
||||
if old_pin != new_pin:
|
||||
self.assertFalse(config.change_pin(old_pin, '666', None, None))
|
||||
|
||||
# Storage remains unlocked.
|
||||
self.assertEqual(config.get(1, 1), b'value')
|
||||
|
||||
# The APP namespace which is reserved for storage related values is inaccessible even
|
||||
# when unlocked.
|
||||
self.assertEqual(config.get(PINAPP, PINKEY), None)
|
||||
|
||||
# Old PIN cannot be used to unlock storage.
|
||||
if old_pin != new_pin:
|
||||
config.init()
|
||||
self.assertFalse(config.unlock(old_pin, None))
|
||||
self.assertEqual(config.get(1, 1), None)
|
||||
with self.assertRaises(RuntimeError):
|
||||
config.set(1, 1, b'new value')
|
||||
|
||||
# New PIN unlocks the storage.
|
||||
self.assertTrue(config.unlock(new_pin, None))
|
||||
self.assertEqual(config.get(1, 1), b'value')
|
||||
|
||||
# Lock the storage.
|
||||
config.init()
|
||||
old_pin = new_pin
|
||||
|
||||
def test_change_sd_salt(self):
|
||||
salt1 = b"0123456789abcdef0123456789abcdef"
|
||||
@ -106,37 +131,37 @@ class TestConfig(unittest.TestCase):
|
||||
# Enable PIN and SD salt.
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertTrue(config.unlock(pin_to_int(''), None))
|
||||
self.assertTrue(config.unlock('', None))
|
||||
config.set(1, 1, b'value')
|
||||
self.assertFalse(config.change_pin(pin_to_int(''), pin_to_int(''), salt1, None))
|
||||
self.assertTrue(config.change_pin(pin_to_int(''), pin_to_int('000'), None, salt1))
|
||||
self.assertFalse(config.change_pin('', '', salt1, None))
|
||||
self.assertTrue(config.change_pin('', '000', None, salt1))
|
||||
self.assertEqual(config.get(1, 1), b'value')
|
||||
|
||||
# Disable PIN and change SD salt.
|
||||
config.init()
|
||||
self.assertFalse(config.unlock(pin_to_int('000'), None))
|
||||
self.assertFalse(config.unlock('000', None))
|
||||
self.assertIsNone(config.get(1, 1))
|
||||
self.assertTrue(config.unlock(pin_to_int('000'), salt1))
|
||||
self.assertTrue(config.change_pin(pin_to_int('000'), pin_to_int(''), salt1, salt2))
|
||||
self.assertTrue(config.unlock('000', salt1))
|
||||
self.assertTrue(config.change_pin('000', '', salt1, salt2))
|
||||
self.assertEqual(config.get(1, 1), b'value')
|
||||
|
||||
# Disable SD salt.
|
||||
config.init()
|
||||
self.assertFalse(config.unlock(pin_to_int('000'), salt2))
|
||||
self.assertFalse(config.unlock('000', salt2))
|
||||
self.assertIsNone(config.get(1, 1))
|
||||
self.assertTrue(config.unlock(pin_to_int(''), salt2))
|
||||
self.assertTrue(config.change_pin(pin_to_int(''), pin_to_int(''), salt2, None))
|
||||
self.assertTrue(config.unlock('', salt2))
|
||||
self.assertTrue(config.change_pin('', '', salt2, None))
|
||||
self.assertEqual(config.get(1, 1), b'value')
|
||||
|
||||
# Check that PIN and SD salt are disabled.
|
||||
config.init()
|
||||
self.assertTrue(config.unlock(pin_to_int(''), None))
|
||||
self.assertTrue(config.unlock('', None))
|
||||
self.assertEqual(config.get(1, 1), b'value')
|
||||
|
||||
def test_set_get(self):
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
self.assertEqual(config.unlock('', None), True)
|
||||
for _ in range(32):
|
||||
appid, key = random_entry()
|
||||
value = random.bytes(128)
|
||||
@ -147,7 +172,7 @@ class TestConfig(unittest.TestCase):
|
||||
def test_compact(self):
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
self.assertEqual(config.unlock('', None), True)
|
||||
appid, key = 1, 1
|
||||
for _ in range(259):
|
||||
value = random.bytes(259)
|
||||
@ -158,7 +183,7 @@ class TestConfig(unittest.TestCase):
|
||||
def test_get_default(self):
|
||||
config.init()
|
||||
config.wipe()
|
||||
self.assertEqual(config.unlock(pin_to_int(''), None), True)
|
||||
self.assertEqual(config.unlock('', None), True)
|
||||
for _ in range(128):
|
||||
appid, key = random_entry()
|
||||
value = config.get(appid, key)
|
||||
|
Loading…
Reference in New Issue
Block a user