Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure dependency between PIN and wipe code #4447

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
chore(core): ensure dependency between PIN and wipe code
  • Loading branch information
bieleluk committed Dec 19, 2024
commit c919ce1d565e4b7d1f5ebfeaaf9412b04d69e1fe
1 change: 1 addition & 0 deletions core/.changelog.d/4446.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add dependency check between PIN and wipe code.
3 changes: 3 additions & 0 deletions core/embed/rust/librust_qstr.h
Original file line number Diff line number Diff line change
@@ -389,6 +389,8 @@ static void _librust_qstrs(void) {
MP_QSTR_pin__tries_left;
MP_QSTR_pin__turn_off;
MP_QSTR_pin__turn_on;
MP_QSTR_pin__wipe_code_exists_description;
MP_QSTR_pin__wipe_code_exists_title;
MP_QSTR_pin__wrong_pin;
MP_QSTR_plurals__contains_x_keys;
MP_QSTR_plurals__lock_after_x_hours;
@@ -739,6 +741,7 @@ static void _librust_qstrs(void) {
MP_QSTR_wipe_code__info;
MP_QSTR_wipe_code__invalid;
MP_QSTR_wipe_code__mismatch;
MP_QSTR_wipe_code__pin_not_set_description;
MP_QSTR_wipe_code__reenter;
MP_QSTR_wipe_code__reenter_to_confirm;
MP_QSTR_wipe_code__title_check;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions core/mocks/trezortranslate_keys.pyi
Original file line number Diff line number Diff line change
@@ -541,6 +541,8 @@ class TR:
pin__tries_left: str = "tries left"
pin__turn_off: str = "Are you sure you want to turn off PIN protection?"
pin__turn_on: str = "Turn on PIN protection?"
pin__wipe_code_exists_description: str = "Wipe code must be turned off before turnig off PIN protection."
pin__wipe_code_exists_title: str = "Wipe code set"
pin__wrong_pin: str = "Wrong PIN"
plurals__contains_x_keys: str = "key|keys"
plurals__lock_after_x_hours: str = "hour|hours"
@@ -908,6 +910,7 @@ class TR:
wipe_code__info: str = "Wipe code can be used to erase all data from this device."
wipe_code__invalid: str = "Invalid wipe code"
wipe_code__mismatch: str = "The wipe codes you entered do not match."
wipe_code__pin_not_set_description: str = "PIN must be set before enabling wipe code."
wipe_code__reenter: str = "Re-enter wipe code"
wipe_code__reenter_to_confirm: str = "Please re-enter wipe code to confirm."
wipe_code__title_check: str = "Check wipe code"
20 changes: 20 additions & 0 deletions core/src/apps/common/request_pin.py
Original file line number Diff line number Diff line change
@@ -147,3 +147,23 @@ async def error_pin_matches_wipe_code() -> NoReturn:
exc=wire.PinInvalid,
)
assert False


async def error_pin_not_set() -> NoReturn:
await show_error_and_raise(
"warning_pin_not_set",
TR.wipe_code__pin_not_set_description,
TR.homescreen__title_pin_not_set,
exc=wire.ActionCancelled,
)
assert False


async def error_wipe_code_exists() -> NoReturn:
await show_error_and_raise(
"wipe_code_exists",
TR.pin__wipe_code_exists_description,
TR.pin__wipe_code_exists_title,
exc=wire.ActionCancelled,
)
assert False
5 changes: 5 additions & 0 deletions core/src/apps/management/change_pin.py
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ async def change_pin(msg: ChangePin) -> Success:
from apps.common.request_pin import (
error_pin_invalid,
error_pin_matches_wipe_code,
error_wipe_code_exists,
request_pin_and_sd_salt,
request_pin_confirm,
)
@@ -26,6 +27,10 @@ async def change_pin(msg: ChangePin) -> Success:
# confirm that user wants to change the pin
await _require_confirm_change_pin(msg)

# Do not allow to remove the PIN if the wipe code is set.
if msg.remove and config.has_wipe_code():
await error_wipe_code_exists()

# get old pin
curpin, salt = await request_pin_and_sd_salt(TR.pin__enter)

16 changes: 12 additions & 4 deletions core/src/apps/management/change_wipe_code.py
Original file line number Diff line number Diff line change
@@ -15,7 +15,11 @@ async def change_wipe_code(msg: ChangeWipeCode) -> Success:
from trezor.ui.layouts import show_success
from trezor.wire import NotInitialized

from apps.common.request_pin import error_pin_invalid, request_pin_and_sd_salt
from apps.common.request_pin import (
error_pin_invalid,
error_pin_not_set,
request_pin_and_sd_salt,
)

if not is_initialized():
raise NotInitialized("Device is not initialized")
@@ -24,6 +28,10 @@ async def change_wipe_code(msg: ChangeWipeCode) -> Success:
has_wipe_code = config.has_wipe_code()
await _require_confirm_action(msg, has_wipe_code)

# Do not allow to set the wipe code if the PIN is not set.
if not config.has_pin():
await error_pin_not_set()

# Get the unlocking PIN.
pin, salt = await request_pin_and_sd_salt(TR.pin__enter)

@@ -62,7 +70,7 @@ def _require_confirm_action(
from trezor.ui.layouts import confirm_action, confirm_set_new_pin
from trezor.wire import ProcessError

if msg.remove and has_wipe_code:
if msg.remove and has_wipe_code: # removing wipe code
return confirm_action(
"disable_wipe_code",
TR.wipe_code__title_settings,
@@ -71,15 +79,15 @@ def _require_confirm_action(
prompt_screen=True,
)

if not msg.remove and has_wipe_code:
if not msg.remove and has_wipe_code: # changing wipe code
return confirm_action(
"change_wipe_code",
TR.wipe_code__title_settings,
description=TR.wipe_code__change,
verb=TR.buttons__change,
)

if not msg.remove and not has_wipe_code:
if not msg.remove and not has_wipe_code: # setting new wipe code
return confirm_set_new_pin(
"set_wipe_code",
TR.wipe_code__title_settings,
3 changes: 3 additions & 0 deletions core/translations/cs.json
Original file line number Diff line number Diff line change
@@ -586,6 +586,8 @@
"pin__turn_off": "Opravdu chcete vypnout ochranu PIN kódem?",
"pin__turn_on": "Zapnout ochranu PIN kódem?",
"pin__wrong_pin": "Nesprávný PIN",
"pin__wipe_code_exists_title": "Aktivní kód pro vymazání",
"pin__wipe_code_exists_description": "Pro vypnutí ochrany PIN kódem musí být vypnut kód pro vymazání.",
"plurals__contains_x_keys": "klíč|klíčů",
"plurals__lock_after_x_hours": "hod.|hod.",
"plurals__lock_after_x_milliseconds": "ms|ms",
@@ -960,6 +962,7 @@
"wipe_code__turn_off": "Vypnout ochranu kódem pro vymazání?",
"wipe_code__turn_on": "Zapnout ochranu kódem pro vymazání?",
"wipe_code__wipe_code_mismatch": "Neshoda kódu vymazání",
"wipe_code__pin_not_set_description": "Pro nastavení kódu pro vymazání musí být aktivní PIN",
"word_count__title": "Počet slov",
"words__account": "Účet",
"words__account_colon": "Účet:",
3 changes: 3 additions & 0 deletions core/translations/de.json
Original file line number Diff line number Diff line change
@@ -586,6 +586,8 @@
"pin__turn_off": "Möchtest du den PIN-Schutz wirklich deaktivieren?",
"pin__turn_on": "PIN-Schutz aktivieren?",
"pin__wrong_pin": "Falsche PIN",
"pin__wipe_code_exists_title": "Aktiver Löschcode",
"pin__wipe_code_exists_description": "Zum Deaktivieren des PIN-Schutzes muss der Löschcode deaktiviert sein.",
"plurals__contains_x_keys": "Key|Keys",
"plurals__lock_after_x_hours": "Stunde|Stunden",
"plurals__lock_after_x_milliseconds": "Millisekunde|Millisekunden",
@@ -960,6 +962,7 @@
"wipe_code__turn_off": "Löschcode-Schutz deaktivieren?",
"wipe_code__turn_on": "Löschcode-Schutz aktivieren?",
"wipe_code__wipe_code_mismatch": "Löschcode-Konflikt",
"wipe_code__pin_not_set_description": "Um den Löschcode einzurichten, muss eine PIN aktiviert sein.",
"word_count__title": "Anzahl der wörter",
"words__account": "Konto",
"words__account_colon": "Konto:",
3 changes: 3 additions & 0 deletions core/translations/en.json
Original file line number Diff line number Diff line change
@@ -544,6 +544,8 @@
"pin__turn_off": "Are you sure you want to turn off PIN protection?",
"pin__turn_on": "Turn on PIN protection?",
"pin__wrong_pin": "Wrong PIN",
"pin__wipe_code_exists_title": "Wipe code set",
"pin__wipe_code_exists_description": "Wipe code must be turned off before turnig off PIN protection.",
"plurals__contains_x_keys": "key|keys",
"plurals__lock_after_x_hours": "hour|hours",
"plurals__lock_after_x_milliseconds": "millisecond|milliseconds",
@@ -918,6 +920,7 @@
"wipe_code__turn_off": "Turn off wipe code protection?",
"wipe_code__turn_on": "Turn on wipe code protection?",
"wipe_code__wipe_code_mismatch": "Wipe code mismatch",
"wipe_code__pin_not_set_description": "PIN must be set before enabling wipe code.",
"word_count__title": "Number of words",
"words__account": "Account",
"words__account_colon": "Account:",
3 changes: 3 additions & 0 deletions core/translations/es.json
Original file line number Diff line number Diff line change
@@ -586,6 +586,8 @@
"pin__turn_off": "¿Quieres desactivar la protección con PIN?",
"pin__turn_on": "¿Activar la protección con PIN?",
"pin__wrong_pin": "PIN incorrecto",
"pin__wipe_code_exists_title": "Código de borrar activo",
"pin__wipe_code_exists_description": "Para desactivar la protección con PIN, el código de borrar debe estar desactivado.",
"plurals__contains_x_keys": "clave|claves",
"plurals__lock_after_x_hours": "hora|horas",
"plurals__lock_after_x_milliseconds": "milisegundo|milisegundos",
@@ -960,6 +962,7 @@
"wipe_code__turn_off": "¿Desactivar protección del código de borrar?",
"wipe_code__turn_on": "¿Activar la protección del código de borrar?",
"wipe_code__wipe_code_mismatch": "Cód.borrar no coincide.",
"wipe_code__pin_not_set_description": "Para configurar el código de borrar, debe haber un PIN activo.",
"word_count__title": "Nro.palabras",
"words__account": "Cuenta",
"words__account_colon": "Cuenta:",
3 changes: 3 additions & 0 deletions core/translations/fr.json
Original file line number Diff line number Diff line change
@@ -586,6 +586,8 @@
"pin__turn_off": "Voulez-vous vraiment désactiver la prot. par PIN ?",
"pin__turn_on": "Activer la prot. par PIN ?",
"pin__wrong_pin": "Mauvais PIN",
"pin__wipe_code_exists_title": "Code d'eff. actif",
"pin__wipe_code_exists_description": "Pour désactiver la protection par code PIN, le code d'eff. doit être désactivé.",
"plurals__contains_x_keys": "touche|touches",
"plurals__lock_after_x_hours": "heure|heures",
"plurals__lock_after_x_milliseconds": "milliseconde|millisecondes",
@@ -960,6 +962,7 @@
"wipe_code__turn_off": "Désactiver la prot. par code d'eff. ?",
"wipe_code__turn_on": "Activer la prot. par code d'eff. ?",
"wipe_code__wipe_code_mismatch": "Erreur de code d'eff.",
"wipe_code__pin_not_set_description": "Pour configurer le code d'eff., un code PIN doit être actif.",
"word_count__title": "Nbr de mots",
"words__account": "Compte",
"words__account_colon": "Compte:",
3 changes: 3 additions & 0 deletions core/translations/it.json
Original file line number Diff line number Diff line change
@@ -586,6 +586,8 @@
"pin__turn_off": "Disattivare la protezione con PIN?",
"pin__turn_on": "Attivare la protez. con PIN?",
"pin__wrong_pin": "PIN errato",
"pin__wipe_code_exists_title": "Codice elim. attivo",
"pin__wipe_code_exists_description": "Per disattivare la protezione con PIN, il codice elim. deve essere disattivato.",
"plurals__contains_x_keys": "chiave|chiavi",
"plurals__lock_after_x_hours": "ora|ore",
"plurals__lock_after_x_milliseconds": "millisecondo|millisecondi",
@@ -960,6 +962,7 @@
"wipe_code__turn_off": "Disattivare protez. con codice elim.?",
"wipe_code__turn_on": "Attivare protez. con codice elim.?",
"wipe_code__wipe_code_mismatch": "Codice elim. non corr.",
"wipe_code__pin_not_set_description": "Per configurare il codice elim., un PIN deve essere attivo.",
"word_count__title": "Numero di parole",
"words__account": "Conto",
"words__account_colon": "Conto:",
5 changes: 4 additions & 1 deletion core/translations/order.json
Original file line number Diff line number Diff line change
@@ -973,5 +973,8 @@
"971": "instructions__view_all_data",
"972": "ethereum__interaction_contract",
"973": "misc__enable_labeling",
"974": "ethereum__unknown_contract_address_short"
"974": "ethereum__unknown_contract_address_short",
"975": "wipe_code__pin_not_set_description",
"976": "pin__wipe_code_exists_description",
"977": "pin__wipe_code_exists_title"
}
3 changes: 3 additions & 0 deletions core/translations/pt.json
Original file line number Diff line number Diff line change
@@ -585,6 +585,8 @@
"pin__turn_off": "Deseja desligar a proteção por PIN?",
"pin__turn_on": "Ligar proteção por PIN?",
"pin__wrong_pin": "PIN incorreto",
"pin__wipe_code_exists_title": "Código de limpeza ativo",
"pin__wipe_code_exists_description": "Para desativar a proteção por PIN, o código de limpeza deve estar desativado.",
"plurals__contains_x_keys": "tecla|teclas",
"plurals__lock_after_x_hours": "hora|horas",
"plurals__lock_after_x_milliseconds": "milissegundo|milissegundos",
@@ -959,6 +961,7 @@
"wipe_code__turn_off": "Desativar a proteção do código de limpeza?",
"wipe_code__turn_on": "Ativar a proteção do código de limpeza?",
"wipe_code__wipe_code_mismatch": "Cód. limp. não coincide",
"wipe_code__pin_not_set_description": "Para configurar o código de limpeza, é necessário ter um PIN ativo.",
"word_count__title": "Número de palavras",
"words__account": "Conta",
"words__account_colon": "Conta:",
6 changes: 3 additions & 3 deletions core/translations/signatures.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"current": {
"merkle_root": "53515eead12df806f139761eddc91f2aa2d3de3b9e0eb831552167ee25897f4a",
"datetime": "2024-12-16T11:26:54.578708",
"commit": "76301b1e97ea5ce0a2e17967f44a9db2a2e905e4"
"merkle_root": "b4a9f4626da2b0a07d43bd807db2da01335069525ba692b4a094331d8bf62539",
"datetime": "2024-12-16T13:26:07.096128",
"commit": "78cce0ba04436b2ec8a72d00d157a1dd37055572"
},
"history": [
{
3 changes: 3 additions & 0 deletions core/translations/tr.json
Original file line number Diff line number Diff line change
@@ -539,6 +539,8 @@
"pin__turn_off": "PIN korumayı kapatmak istediğinizden emin misiniz?",
"pin__turn_on": "PIN kodu koruması açılsın mı?",
"pin__wrong_pin": "Yanlış PIN kodu",
"pin__wipe_code_exists_title": "Aktif silme kodu",
"pin__wipe_code_exists_description": "PIN korumasını devre dışı bırakmak için silme kodu kapatılmalıdır.",
"plurals__contains_x_keys": "anahtar|anahtarlar",
"plurals__lock_after_x_hours": "saat|saatler",
"plurals__lock_after_x_milliseconds": "milisaniye|milisaniyeler",
@@ -881,6 +883,7 @@
"wipe_code__turn_off": "Silme kodu koruması kapatılsın mı?",
"wipe_code__turn_on": "Silme kodu koruması açılsın mı?",
"wipe_code__wipe_code_mismatch": "Silme kod. uyumsuzluğu",
"wipe_code__pin_not_set_description": "Silme kodunu ayarlamak için bir PIN etkin olmalıdır.",
"word_count__title": "Keli̇me sayisi",
"words__account": "Hesap",
"words__account_colon": "Hesap:",
35 changes: 34 additions & 1 deletion tests/device_tests/test_msg_change_wipe_code_t2.py
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
from trezorlib.client import MAX_PIN_LENGTH, PASSPHRASE_TEST_PATH
from trezorlib.debuglink import LayoutType
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.exceptions import TrezorFailure
from trezorlib.exceptions import Cancelled, TrezorFailure

from ..input_flows import InputFlowNewCodeMismatch

@@ -167,3 +167,36 @@ def test_set_pin_to_wipe_code(client: Client):
)
client.use_pin_sequence([WIPE_CODE4, WIPE_CODE4])
device.change_pin(client)


def test_set_wipe_code_without_pin(client: Client):
# Make sure that both PIN and wipe code are not set.
assert client.features.pin_protection is False
assert client.features.wipe_code_protection is False
# Expect an error when trying to set the wipe code without a PIN being turned on.
with pytest.raises(Cancelled):
device.change_wipe_code(client)


@pytest.mark.setup_client(pin=PIN4)
def test_set_remove_pin_without_removing_wipe_code(client: Client):
_ensure_unlocked(client, PIN4)
# Make sure the PIN is set.
assert client.features.pin_protection is True
# Make sure the wipe code is not set.
assert client.features.wipe_code_protection is False

# Set wipe code
with client:
client.use_pin_sequence([PIN4, WIPE_CODE4, WIPE_CODE4])
device.change_wipe_code(client)

client.init_device()
# Make sure the wipe code is set.
assert client.features.wipe_code_protection is True

# Remove PIN without wipe code being turned off.
with client:
# Expect an error when trying to remove PIN with enabled wipe code.
with pytest.raises(Cancelled):
device.change_pin(client, remove=True)