mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-19 13:08:14 +00:00
WIP - using obj_module!, is_initialized rust binding
This commit is contained in:
parent
bcf837694b
commit
1c87e57570
@ -23,41 +23,6 @@
|
|||||||
|
|
||||||
#include "librust.h"
|
#include "librust.h"
|
||||||
|
|
||||||
/// def is_version_stored() -> bool:
|
|
||||||
/// """Whether version is in storage."""
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(
|
|
||||||
mod_trezorutils_storagedevice_is_version_stored_obj,
|
|
||||||
storagedevice_is_version_stored);
|
|
||||||
|
|
||||||
/// def get_version() -> bytes:
|
|
||||||
/// """Get from storage."""
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_storagedevice_get_version_obj,
|
|
||||||
storagedevice_get_version);
|
|
||||||
|
|
||||||
/// def set_version(version: bytes) -> bool:
|
|
||||||
/// """Save to storage."""
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorutils_storagedevice_set_version_obj,
|
|
||||||
storagedevice_set_version);
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t mp_module_trezorstoragedevice_globals_table[] = {
|
|
||||||
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorstoragedevice)},
|
|
||||||
|
|
||||||
{MP_ROM_QSTR(MP_QSTR_is_version_stored),
|
|
||||||
MP_ROM_PTR(&mod_trezorutils_storagedevice_is_version_stored_obj)},
|
|
||||||
{MP_ROM_QSTR(MP_QSTR_get_version),
|
|
||||||
MP_ROM_PTR(&mod_trezorutils_storagedevice_get_version_obj)},
|
|
||||||
{MP_ROM_QSTR(MP_QSTR_set_version),
|
|
||||||
MP_ROM_PTR(&mod_trezorutils_storagedevice_set_version_obj)},
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorstoragedevice_globals,
|
|
||||||
mp_module_trezorstoragedevice_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_trezorstoragedevice = {
|
|
||||||
.base = {&mp_type_module},
|
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_trezorstoragedevice_globals,
|
|
||||||
};
|
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_trezorstoragedevice, mp_module_trezorstoragedevice,
|
MP_REGISTER_MODULE(MP_QSTR_trezorstoragedevice, mp_module_trezorstoragedevice,
|
||||||
MICROPY_PY_TREZORSTORAGEDEVICE);
|
MICROPY_PY_TREZORSTORAGEDEVICE);
|
||||||
|
|
||||||
|
@ -143,6 +143,7 @@ fn generate_micropython_bindings() {
|
|||||||
.allowlist_var("mp_type_dict")
|
.allowlist_var("mp_type_dict")
|
||||||
// fun
|
// fun
|
||||||
.allowlist_type("mp_obj_fun_builtin_fixed_t")
|
.allowlist_type("mp_obj_fun_builtin_fixed_t")
|
||||||
|
.allowlist_var("mp_type_fun_builtin_0")
|
||||||
.allowlist_var("mp_type_fun_builtin_1")
|
.allowlist_var("mp_type_fun_builtin_1")
|
||||||
.allowlist_var("mp_type_fun_builtin_2")
|
.allowlist_var("mp_type_fun_builtin_2")
|
||||||
.allowlist_var("mp_type_fun_builtin_3")
|
.allowlist_var("mp_type_fun_builtin_3")
|
||||||
|
@ -9,16 +9,13 @@ mp_obj_t protobuf_decode(mp_obj_t buf, mp_obj_t def,
|
|||||||
mp_obj_t protobuf_len(mp_obj_t obj);
|
mp_obj_t protobuf_len(mp_obj_t obj);
|
||||||
mp_obj_t protobuf_encode(mp_obj_t buf, mp_obj_t obj);
|
mp_obj_t protobuf_encode(mp_obj_t buf, mp_obj_t obj);
|
||||||
|
|
||||||
mp_obj_t storagedevice_is_version_stored();
|
|
||||||
mp_obj_t storagedevice_get_version();
|
|
||||||
mp_obj_t storagedevice_set_version(mp_obj_t key);
|
|
||||||
|
|
||||||
#ifdef TREZOR_EMULATOR
|
#ifdef TREZOR_EMULATOR
|
||||||
mp_obj_t protobuf_debug_msg_type();
|
mp_obj_t protobuf_debug_msg_type();
|
||||||
mp_obj_t protobuf_debug_msg_def_type();
|
mp_obj_t protobuf_debug_msg_def_type();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern mp_obj_module_t mp_module_trezorui2;
|
extern mp_obj_module_t mp_module_trezorui2;
|
||||||
|
extern mp_obj_module_t mp_module_trezorstoragedevice;
|
||||||
|
|
||||||
#ifdef TREZOR_EMULATOR
|
#ifdef TREZOR_EMULATOR
|
||||||
mp_obj_t ui_debug_layout_type();
|
mp_obj_t ui_debug_layout_type();
|
||||||
|
@ -19,6 +19,13 @@ static void _librust_qstrs(void) {
|
|||||||
MP_QSTR_confirm_text;
|
MP_QSTR_confirm_text;
|
||||||
MP_QSTR_request_pin;
|
MP_QSTR_request_pin;
|
||||||
|
|
||||||
|
// storagedevice
|
||||||
|
MP_QSTR___name_storage__;
|
||||||
|
MP_QSTR_is_version_stored;
|
||||||
|
MP_QSTR_is_initialized;
|
||||||
|
MP_QSTR_get_version;
|
||||||
|
MP_QSTR_set_version;
|
||||||
|
|
||||||
MP_QSTR_set_timer_fn;
|
MP_QSTR_set_timer_fn;
|
||||||
MP_QSTR_touch_event;
|
MP_QSTR_touch_event;
|
||||||
MP_QSTR_button_event;
|
MP_QSTR_button_event;
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod storagedevice;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod micropython;
|
mod micropython;
|
||||||
mod protobuf;
|
mod protobuf;
|
||||||
|
mod storagedevice;
|
||||||
mod time;
|
mod time;
|
||||||
#[cfg(feature = "ui_debug")]
|
#[cfg(feature = "ui_debug")]
|
||||||
mod trace;
|
mod trace;
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
/// Create an object for an exported function taking 0 args.
|
||||||
|
macro_rules! obj_fn_0 {
|
||||||
|
($f:expr) => {{
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
|
unsafe {
|
||||||
|
use $crate::micropython::ffi;
|
||||||
|
|
||||||
|
ffi::mp_obj_fun_builtin_fixed_t {
|
||||||
|
base: ffi::mp_obj_base_t {
|
||||||
|
type_: &ffi::mp_type_fun_builtin_0,
|
||||||
|
},
|
||||||
|
fun: ffi::_mp_obj_fun_builtin_fixed_t__bindgen_ty_1 { _0: Some($f) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
/// Create an object for an exported function taking 1 arg.
|
/// Create an object for an exported function taking 1 arg.
|
||||||
macro_rules! obj_fn_1 {
|
macro_rules! obj_fn_1 {
|
||||||
($f:expr) => {{
|
($f:expr) => {{
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
#[macro_use]
|
||||||
mod storagedevice;
|
mod storagedevice;
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
micropython::{buffer::Buffer, obj::Obj},
|
micropython::{buffer::Buffer, map::Map, module::Module, obj::Obj, qstr::Qstr},
|
||||||
trezorhal::secbool,
|
trezorhal::secbool,
|
||||||
util,
|
util,
|
||||||
};
|
};
|
||||||
|
|
||||||
use core::convert::{TryFrom, TryInto};
|
use core::convert::{TryFrom, TryInto};
|
||||||
|
|
||||||
// TODO: transfer this into a struct with field specifying data type and
|
const FLAG_PUBLIC: u8 = 0x80;
|
||||||
// max_length
|
|
||||||
const APP_DEVICE: u8 = 0x01;
|
const APP_DEVICE: u8 = 0x01;
|
||||||
|
|
||||||
|
// TODO: transfer this into a struct with field specifying data type and
|
||||||
|
// `max_length`, possibly even `is_public`
|
||||||
|
|
||||||
const DEVICE_ID: u8 = 0x01;
|
const DEVICE_ID: u8 = 0x01;
|
||||||
const _VERSION: u8 = 0x02;
|
const _VERSION: u8 = 0x02;
|
||||||
const _MNEMONIC_SECRET: u8 = 0x03;
|
const _MNEMONIC_SECRET: u8 = 0x03;
|
||||||
@ -50,20 +53,18 @@ extern "C" {
|
|||||||
fn storage_set(key: u16, val: Buffer, len: u16) -> secbool::Secbool;
|
fn storage_set(key: u16, val: Buffer, len: u16) -> secbool::Secbool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
extern "C" fn storagedevice_is_version_stored() -> Obj {
|
||||||
pub extern "C" fn storagedevice_is_version_stored() -> Obj {
|
|
||||||
let block = || {
|
let block = || {
|
||||||
let key = _get_appkey(_VERSION);
|
let key = _get_appkey(_VERSION, false);
|
||||||
let result = storagedevice_storage_has(key);
|
let result = storagedevice_storage_has(key);
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
};
|
};
|
||||||
unsafe { util::try_or_raise(block) }
|
unsafe { util::try_or_raise(block) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
extern "C" fn storagedevice_get_version() -> Obj {
|
||||||
pub extern "C" fn storagedevice_get_version() -> Obj {
|
|
||||||
let block = || {
|
let block = || {
|
||||||
let key = _get_appkey(_VERSION);
|
let key = _get_appkey(_VERSION, false);
|
||||||
let (buf, len) = storagedevice_storage_get(key);
|
let (buf, len) = storagedevice_storage_get(key);
|
||||||
let result = &buf[..len as usize];
|
let result = &buf[..len as usize];
|
||||||
// let result = storagedevice_storage_get(key);
|
// let result = storagedevice_storage_get(key);
|
||||||
@ -72,18 +73,27 @@ pub extern "C" fn storagedevice_get_version() -> Obj {
|
|||||||
unsafe { util::try_or_raise(block) }
|
unsafe { util::try_or_raise(block) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
extern "C" fn storagedevice_set_version(version: Obj) -> Obj {
|
||||||
pub extern "C" fn storagedevice_set_version(version: Obj) -> Obj {
|
|
||||||
let block = || {
|
let block = || {
|
||||||
let value = Buffer::try_from(version)?;
|
let value = Buffer::try_from(version)?;
|
||||||
|
|
||||||
let key = _get_appkey(_VERSION);
|
let key = _get_appkey(_VERSION, false);
|
||||||
let result = storagedevice_storage_set(key, value);
|
let result = storagedevice_storage_set(key, value);
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
};
|
};
|
||||||
unsafe { util::try_or_raise(block) }
|
unsafe { util::try_or_raise(block) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn storagedevice_is_initialized() -> Obj {
|
||||||
|
let block = || {
|
||||||
|
let key = _get_appkey(INITIALIZED, true);
|
||||||
|
let (_, len) = storagedevice_storage_get(key);
|
||||||
|
let result = if len > 0 { true } else { false };
|
||||||
|
Ok(result.into())
|
||||||
|
};
|
||||||
|
unsafe { util::try_or_raise(block) }
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: find out how to return the real result
|
// TODO: find out how to return the real result
|
||||||
// pub fn storagedevice_storage_get(key: u16) -> &'static [u8] {
|
// pub fn storagedevice_storage_get(key: u16) -> &'static [u8] {
|
||||||
// pub fn storagedevice_storage_get(key: u16) -> [u8] {
|
// pub fn storagedevice_storage_get(key: u16) -> [u8] {
|
||||||
@ -123,17 +133,51 @@ pub fn storagedevice_storage_delete(key: u16) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _get_appkey(key: u8) -> u16 {
|
// TODO: we could include `is_public` bool into each key's struct item
|
||||||
((APP_DEVICE as u16) << 8) | key as u16
|
|
||||||
|
fn _get_appkey(key: u8, is_public: bool) -> u16 {
|
||||||
|
let app = if is_public {
|
||||||
|
APP_DEVICE | FLAG_PUBLIC
|
||||||
|
} else {
|
||||||
|
APP_DEVICE
|
||||||
|
};
|
||||||
|
((app as u16) << 8) | key as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub static mp_module_trezorstoragedevice: Module = obj_module! {
|
||||||
|
Qstr::MP_QSTR___name_storage__ => Qstr::MP_QSTR_trezorstoragedevice.to_obj(),
|
||||||
|
|
||||||
|
/// def is_version_stored() -> bool:
|
||||||
|
/// """Whether version is in storage."""
|
||||||
|
Qstr::MP_QSTR_is_version_stored => obj_fn_0!(storagedevice_is_version_stored).as_obj(),
|
||||||
|
|
||||||
|
/// def is_initialized() -> bool:
|
||||||
|
/// """Whether device is initialized."""
|
||||||
|
Qstr::MP_QSTR_is_initialized => obj_fn_0!(storagedevice_is_initialized).as_obj(),
|
||||||
|
|
||||||
|
/// def get_version() -> bytes:
|
||||||
|
/// """Get from storage."""
|
||||||
|
Qstr::MP_QSTR_get_version => obj_fn_0!(storagedevice_get_version).as_obj(),
|
||||||
|
|
||||||
|
/// def set_version(version: bytes) -> bool:
|
||||||
|
/// """Save to storage."""
|
||||||
|
Qstr::MP_QSTR_set_version => obj_fn_1!(storagedevice_set_version).as_obj(),
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_appkey() {
|
fn get_appkey() {
|
||||||
let result = _get_appkey(0x11);
|
let result = _get_appkey(0x11, false);
|
||||||
assert_eq!(result, 0x0111);
|
assert_eq!(result, 0x0111);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_appkey_public() {
|
||||||
|
let result = _get_appkey(0x11, true);
|
||||||
|
assert_eq!(result, 0x8111);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
from typing import *
|
from typing import *
|
||||||
|
|
||||||
|
|
||||||
# extmod/rustmods/modtrezorstoragedevice.c
|
# rust/src/storagedevice/storagedevice.rs
|
||||||
def is_version_stored() -> bool:
|
def is_version_stored() -> bool:
|
||||||
"""Whether version is in storage."""
|
"""Whether version is in storage."""
|
||||||
|
|
||||||
|
|
||||||
# extmod/rustmods/modtrezorstoragedevice.c
|
# rust/src/storagedevice/storagedevice.rs
|
||||||
|
def is_initialized() -> bool:
|
||||||
|
"""Whether device is initialized."""
|
||||||
|
|
||||||
|
|
||||||
|
# rust/src/storagedevice/storagedevice.rs
|
||||||
def get_version() -> bytes:
|
def get_version() -> bytes:
|
||||||
"""Get from storage."""
|
"""Get from storage."""
|
||||||
|
|
||||||
|
|
||||||
# extmod/rustmods/modtrezorstoragedevice.c
|
# rust/src/storagedevice/storagedevice.rs
|
||||||
def set_version(version: bytes) -> bool:
|
def set_version(version: bytes) -> bool:
|
||||||
"""Save to storage."""
|
"""Save to storage."""
|
||||||
|
@ -2,6 +2,7 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
import storage.cache
|
import storage.cache
|
||||||
import storage.device
|
import storage.device
|
||||||
|
from storage import trezorstoragedevice
|
||||||
from trezor import config, utils, wire, workflow
|
from trezor import config, utils, wire, workflow
|
||||||
from trezor.enums import MessageType
|
from trezor.enums import MessageType
|
||||||
from trezor.messages import Success
|
from trezor.messages import Success
|
||||||
@ -76,7 +77,7 @@ def get_features() -> Features:
|
|||||||
Capability.PassphraseEntry,
|
Capability.PassphraseEntry,
|
||||||
]
|
]
|
||||||
f.sd_card_present = sdcard.is_present()
|
f.sd_card_present = sdcard.is_present()
|
||||||
f.initialized = storage.device.is_initialized()
|
f.initialized = trezorstoragedevice.is_initialized()
|
||||||
|
|
||||||
# private fields:
|
# private fields:
|
||||||
if config.is_unlocked():
|
if config.is_unlocked():
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from storage import cache, device
|
from storage import cache, trezorstoragedevice
|
||||||
from trezor import wire
|
from trezor import wire
|
||||||
from trezor.crypto import bip32, cardano
|
from trezor.crypto import bip32, cardano
|
||||||
from trezor.enums import CardanoDerivationType
|
from trezor.enums import CardanoDerivationType
|
||||||
@ -115,7 +115,7 @@ def is_minting_path(path: Bip32Path) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def derive_and_store_secrets(passphrase: str) -> None:
|
def derive_and_store_secrets(passphrase: str) -> None:
|
||||||
assert device.is_initialized()
|
assert trezorstoragedevice.is_initialized()
|
||||||
assert cache.get(cache.APP_COMMON_DERIVE_CARDANO)
|
assert cache.get(cache.APP_COMMON_DERIVE_CARDANO)
|
||||||
|
|
||||||
if not mnemonic.is_bip39():
|
if not mnemonic.is_bip39():
|
||||||
@ -152,7 +152,7 @@ async def _get_secret(ctx: wire.Context, cache_entry: int) -> bytes:
|
|||||||
async def _get_keychain_bip39(
|
async def _get_keychain_bip39(
|
||||||
ctx: wire.Context, derivation_type: CardanoDerivationType
|
ctx: wire.Context, derivation_type: CardanoDerivationType
|
||||||
) -> Keychain:
|
) -> Keychain:
|
||||||
if not device.is_initialized():
|
if not trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
|
|
||||||
if derivation_type == CardanoDerivationType.LEDGER:
|
if derivation_type == CardanoDerivationType.LEDGER:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from storage import cache, device
|
from storage import cache, device, trezorstoragedevice
|
||||||
from trezor import utils, wire
|
from trezor import utils, wire
|
||||||
from trezor.crypto import bip32, hmac
|
from trezor.crypto import bip32, hmac
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ if not utils.BITCOIN_ONLY:
|
|||||||
# expose a method for Cardano to do the same
|
# expose a method for Cardano to do the same
|
||||||
|
|
||||||
async def derive_and_store_roots(ctx: wire.Context) -> None:
|
async def derive_and_store_roots(ctx: wire.Context) -> None:
|
||||||
if not device.is_initialized():
|
if not trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
|
|
||||||
need_seed = not cache.is_set(cache.APP_COMMON_SEED)
|
need_seed = not cache.is_set(cache.APP_COMMON_SEED)
|
||||||
@ -89,7 +89,7 @@ else:
|
|||||||
|
|
||||||
@cache.stored(cache.APP_COMMON_SEED_WITHOUT_PASSPHRASE)
|
@cache.stored(cache.APP_COMMON_SEED_WITHOUT_PASSPHRASE)
|
||||||
def _get_seed_without_passphrase() -> bytes:
|
def _get_seed_without_passphrase() -> bytes:
|
||||||
if not device.is_initialized():
|
if not trezorstoragedevice.is_initialized():
|
||||||
raise Exception("Device is not initialized")
|
raise Exception("Device is not initialized")
|
||||||
return mnemonic.get_seed(progress_bar=False)
|
return mnemonic.get_seed(progress_bar=False)
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ async def load_device(ctx: wire.Context, msg: LoadDevice) -> Success:
|
|||||||
|
|
||||||
|
|
||||||
def _validate(msg: LoadDevice) -> int:
|
def _validate(msg: LoadDevice) -> int:
|
||||||
if storage.device.is_initialized():
|
if storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.UnexpectedMessage("Already initialized")
|
raise wire.UnexpectedMessage("Already initialized")
|
||||||
|
|
||||||
if not msg.mnemonics:
|
if not msg.mnemonics:
|
||||||
|
@ -25,7 +25,7 @@ class Homescreen(HomescreenBase):
|
|||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
self.label = "Go to trezor.io/start"
|
self.label = "Go to trezor.io/start"
|
||||||
|
|
||||||
self.loader = Loader(
|
self.loader = Loader(
|
||||||
@ -38,13 +38,19 @@ class Homescreen(HomescreenBase):
|
|||||||
|
|
||||||
def do_render(self) -> None:
|
def do_render(self) -> None:
|
||||||
# warning bar on top
|
# warning bar on top
|
||||||
if storage.device.is_initialized() and storage.device.no_backup():
|
if storage.trezorstoragedevice.is_initialized() and storage.device.no_backup():
|
||||||
ui.header_error("SEEDLESS")
|
ui.header_error("SEEDLESS")
|
||||||
elif storage.device.is_initialized() and storage.device.unfinished_backup():
|
elif (
|
||||||
|
storage.trezorstoragedevice.is_initialized()
|
||||||
|
and storage.device.unfinished_backup()
|
||||||
|
):
|
||||||
ui.header_error("BACKUP FAILED!")
|
ui.header_error("BACKUP FAILED!")
|
||||||
elif storage.device.is_initialized() and storage.device.needs_backup():
|
elif (
|
||||||
|
storage.trezorstoragedevice.is_initialized()
|
||||||
|
and storage.device.needs_backup()
|
||||||
|
):
|
||||||
ui.header_warning("NEEDS BACKUP!")
|
ui.header_warning("NEEDS BACKUP!")
|
||||||
elif storage.device.is_initialized() and not config.has_pin():
|
elif storage.trezorstoragedevice.is_initialized() and not config.has_pin():
|
||||||
ui.header_warning("PIN NOT SET!")
|
ui.header_warning("PIN NOT SET!")
|
||||||
elif storage.device.get_experimental_features():
|
elif storage.device.get_experimental_features():
|
||||||
ui.header_warning("EXPERIMENTAL MODE!")
|
ui.header_warning("EXPERIMENTAL MODE!")
|
||||||
|
@ -10,7 +10,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
async def apply_flags(ctx: wire.GenericContext, msg: ApplyFlags) -> Success:
|
async def apply_flags(ctx: wire.GenericContext, msg: ApplyFlags) -> Success:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
set_flags(msg.flags)
|
set_flags(msg.flags)
|
||||||
return Success(message="Flags applied")
|
return Success(message="Flags applied")
|
||||||
|
@ -34,7 +34,7 @@ def validate_homescreen(homescreen: bytes) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def apply_settings(ctx: wire.Context, msg: ApplySettings) -> Success:
|
async def apply_settings(ctx: wire.Context, msg: ApplySettings) -> Success:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
if (
|
if (
|
||||||
msg.homescreen is None
|
msg.homescreen is None
|
||||||
|
@ -14,7 +14,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
async def backup_device(ctx: wire.Context, msg: BackupDevice) -> Success:
|
async def backup_device(ctx: wire.Context, msg: BackupDevice) -> Success:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
if not storage.device.needs_backup():
|
if not storage.device.needs_backup():
|
||||||
raise wire.ProcessError("Seed already backed up")
|
raise wire.ProcessError("Seed already backed up")
|
||||||
|
@ -8,7 +8,7 @@ from trezor.ui.layouts import confirm_action
|
|||||||
async def get_next_u2f_counter(
|
async def get_next_u2f_counter(
|
||||||
ctx: wire.Context, msg: GetNextU2FCounter
|
ctx: wire.Context, msg: GetNextU2FCounter
|
||||||
) -> NextU2FCounter:
|
) -> NextU2FCounter:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
|
|
||||||
await confirm_action(
|
await confirm_action(
|
||||||
|
@ -70,9 +70,9 @@ async def recovery_device(ctx: wire.Context, msg: RecoveryDevice) -> Success:
|
|||||||
|
|
||||||
|
|
||||||
def _validate(msg: RecoveryDevice) -> None:
|
def _validate(msg: RecoveryDevice) -> None:
|
||||||
if not msg.dry_run and storage.device.is_initialized():
|
if not msg.dry_run and storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.UnexpectedMessage("Already initialized")
|
raise wire.UnexpectedMessage("Already initialized")
|
||||||
if msg.dry_run and not storage.device.is_initialized():
|
if msg.dry_run and not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
|
|
||||||
if msg.enforce_wordlist is False:
|
if msg.enforce_wordlist is False:
|
||||||
|
@ -185,7 +185,7 @@ def _validate_reset_device(msg: ResetDevice) -> None:
|
|||||||
raise wire.ProcessError("Invalid strength (has to be 128, 192 or 256 bits)")
|
raise wire.ProcessError("Invalid strength (has to be 128, 192 or 256 bits)")
|
||||||
if msg.display_random and (msg.skip_backup or msg.no_backup):
|
if msg.display_random and (msg.skip_backup or msg.no_backup):
|
||||||
raise wire.ProcessError("Can't show internal entropy when backup is skipped")
|
raise wire.ProcessError("Can't show internal entropy when backup is skipped")
|
||||||
if storage.device.is_initialized():
|
if storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.UnexpectedMessage("Already initialized")
|
raise wire.UnexpectedMessage("Already initialized")
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ async def _set_salt(
|
|||||||
|
|
||||||
|
|
||||||
async def sd_protect(ctx: wire.Context, msg: SdProtect) -> Success:
|
async def sd_protect(ctx: wire.Context, msg: SdProtect) -> Success:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
|
|
||||||
if msg.operation == SdProtectOperationType.ENABLE:
|
if msg.operation == SdProtectOperationType.ENABLE:
|
||||||
|
@ -6,7 +6,7 @@ from trezor.ui.layouts import confirm_action
|
|||||||
|
|
||||||
|
|
||||||
async def set_u2f_counter(ctx: wire.Context, msg: SetU2FCounter) -> Success:
|
async def set_u2f_counter(ctx: wire.Context, msg: SetU2FCounter) -> Success:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
if msg.u2f_counter is None:
|
if msg.u2f_counter is None:
|
||||||
raise wire.ProcessError("No value provided")
|
raise wire.ProcessError("No value provided")
|
||||||
|
@ -28,7 +28,7 @@ class ConfirmAddCredential(ConfirmInfo):
|
|||||||
async def add_resident_credential(
|
async def add_resident_credential(
|
||||||
ctx: wire.Context, msg: WebAuthnAddResidentCredential
|
ctx: wire.Context, msg: WebAuthnAddResidentCredential
|
||||||
) -> Success:
|
) -> Success:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
if not msg.credential_id:
|
if not msg.credential_id:
|
||||||
raise wire.ProcessError("Missing credential ID parameter.")
|
raise wire.ProcessError("Missing credential ID parameter.")
|
||||||
|
@ -1190,7 +1190,7 @@ def msg_register(req: Msg, dialog_mgr: DialogManager) -> Cmd:
|
|||||||
dialog_mgr.set_state(new_state)
|
dialog_mgr.set_state(new_state)
|
||||||
return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED)
|
return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED)
|
||||||
|
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.warning(__name__, "not initialized")
|
log.warning(__name__, "not initialized")
|
||||||
# There is no standard way to decline a U2F request, but responding with ERR_CHANNEL_BUSY
|
# There is no standard way to decline a U2F request, but responding with ERR_CHANNEL_BUSY
|
||||||
@ -1271,7 +1271,7 @@ def msg_authenticate(req: Msg, dialog_mgr: DialogManager) -> Cmd:
|
|||||||
dialog_mgr.set_state(new_state)
|
dialog_mgr.set_state(new_state)
|
||||||
return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED)
|
return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED)
|
||||||
|
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.warning(__name__, "not initialized")
|
log.warning(__name__, "not initialized")
|
||||||
# Device is not registered with the RP.
|
# Device is not registered with the RP.
|
||||||
@ -1450,7 +1450,7 @@ def cbor_make_credential(req: Cmd, dialog_mgr: DialogManager) -> Cmd | None:
|
|||||||
def cbor_make_credential_process(req: Cmd, dialog_mgr: DialogManager) -> State | Cmd:
|
def cbor_make_credential_process(req: Cmd, dialog_mgr: DialogManager) -> State | Cmd:
|
||||||
from . import knownapps
|
from . import knownapps
|
||||||
|
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.warning(__name__, "not initialized")
|
log.warning(__name__, "not initialized")
|
||||||
return cbor_error(req.cid, _ERR_OTHER)
|
return cbor_error(req.cid, _ERR_OTHER)
|
||||||
@ -1628,7 +1628,7 @@ def cbor_get_assertion(req: Cmd, dialog_mgr: DialogManager) -> Cmd | None:
|
|||||||
|
|
||||||
|
|
||||||
def cbor_get_assertion_process(req: Cmd, dialog_mgr: DialogManager) -> State | Cmd:
|
def cbor_get_assertion_process(req: Cmd, dialog_mgr: DialogManager) -> State | Cmd:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.warning(__name__, "not initialized")
|
log.warning(__name__, "not initialized")
|
||||||
return cbor_error(req.cid, _ERR_OTHER)
|
return cbor_error(req.cid, _ERR_OTHER)
|
||||||
@ -1888,7 +1888,7 @@ def cbor_client_pin(req: Cmd) -> Cmd:
|
|||||||
|
|
||||||
|
|
||||||
def cbor_reset(req: Cmd, dialog_mgr: DialogManager) -> Cmd | None:
|
def cbor_reset(req: Cmd, dialog_mgr: DialogManager) -> Cmd | None:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
if __debug__:
|
if __debug__:
|
||||||
log.warning(__name__, "not initialized")
|
log.warning(__name__, "not initialized")
|
||||||
# Return success, because the authenticator is already in factory default state.
|
# Return success, because the authenticator is already in factory default state.
|
||||||
|
@ -28,7 +28,7 @@ class ConfirmRemoveCredential(ConfirmInfo):
|
|||||||
async def remove_resident_credential(
|
async def remove_resident_credential(
|
||||||
ctx: wire.Context, msg: WebAuthnRemoveResidentCredential
|
ctx: wire.Context, msg: WebAuthnRemoveResidentCredential
|
||||||
) -> Success:
|
) -> Success:
|
||||||
if not storage.device.is_initialized():
|
if not storage.trezorstoragedevice.is_initialized():
|
||||||
raise wire.NotInitialized("Device is not initialized")
|
raise wire.NotInitialized("Device is not initialized")
|
||||||
if msg.index is None:
|
if msg.index is None:
|
||||||
raise wire.ProcessError("Missing credential index parameter.")
|
raise wire.ProcessError("Missing credential index parameter.")
|
||||||
|
@ -21,7 +21,10 @@ def init_unlocked() -> None:
|
|||||||
|
|
||||||
# In FWs <= 2.3.1 'version' denoted whether the device is initialized or not.
|
# In FWs <= 2.3.1 'version' denoted whether the device is initialized or not.
|
||||||
# In 2.3.2 we have introduced a new field 'initialized' for that.
|
# In 2.3.2 we have introduced a new field 'initialized' for that.
|
||||||
if trezorstoragedevice.is_version_stored() and not device.is_initialized():
|
if (
|
||||||
|
trezorstoragedevice.is_version_stored()
|
||||||
|
and not trezorstoragedevice.is_initialized()
|
||||||
|
):
|
||||||
common.set_bool(common.APP_DEVICE, device.INITIALIZED, True, public=True)
|
common.set_bool(common.APP_DEVICE, device.INITIALIZED, True, public=True)
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ class TestCredential(unittest.TestCase):
|
|||||||
def test_fido2_credential_decode(self):
|
def test_fido2_credential_decode(self):
|
||||||
mnemonic_secret = b"all all all all all all all all all all all all"
|
mnemonic_secret = b"all all all all all all all all all all all all"
|
||||||
mnemonic.get_secret = lambda: mnemonic_secret
|
mnemonic.get_secret = lambda: mnemonic_secret
|
||||||
storage.device.is_initialized = lambda: True
|
storage.trezorstoragedevice.is_initialized = lambda: True
|
||||||
|
|
||||||
cred_id = (
|
cred_id = (
|
||||||
b"f1d0020013e65c865634ad8abddf7a66df56ae7d8c3afd356f76426801508b2e"
|
b"f1d0020013e65c865634ad8abddf7a66df56ae7d8c3afd356f76426801508b2e"
|
||||||
@ -24,9 +24,7 @@ class TestCredential(unittest.TestCase):
|
|||||||
rp_id = "example.com"
|
rp_id = "example.com"
|
||||||
rp_id_hash = sha256(rp_id).digest()
|
rp_id_hash = sha256(rp_id).digest()
|
||||||
|
|
||||||
user_id = (
|
user_id = b"3082019330820138a0030201023082019330820138a003020102308201933082"
|
||||||
b"3082019330820138a0030201023082019330820138a003020102308201933082"
|
|
||||||
)
|
|
||||||
|
|
||||||
user_name = "johnpsmith@example.com"
|
user_name = "johnpsmith@example.com"
|
||||||
|
|
||||||
@ -108,18 +106,32 @@ class TestCredential(unittest.TestCase):
|
|||||||
|
|
||||||
c2 = U2fCredential()
|
c2 = U2fCredential()
|
||||||
|
|
||||||
self.assertEqual(sorted(distinguishable_cred_list([a1, a2, a3, b1, b2, c1, c2])), [b2, a3, a1, c1])
|
self.assertEqual(
|
||||||
self.assertEqual(sorted(distinguishable_cred_list([c2, c1, b2, b1, a3, a2, a1])), [b2, a3, a1, c2])
|
sorted(distinguishable_cred_list([a1, a2, a3, b1, b2, c1, c2])),
|
||||||
|
[b2, a3, a1, c1],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sorted(distinguishable_cred_list([c2, c1, b2, b1, a3, a2, a1])),
|
||||||
|
[b2, a3, a1, c2],
|
||||||
|
)
|
||||||
|
|
||||||
# Test input by creation time.
|
# Test input by creation time.
|
||||||
self.assertEqual(sorted(distinguishable_cred_list([b2, a3, c1, a2, b1, a1, c2])), [b2, a3, a1, c1])
|
self.assertEqual(
|
||||||
self.assertEqual(sorted(distinguishable_cred_list([c2, a1, b1, a2, c1, a3, b2])), [b2, a3, a1, c2])
|
sorted(distinguishable_cred_list([b2, a3, c1, a2, b1, a1, c2])),
|
||||||
|
[b2, a3, a1, c1],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
sorted(distinguishable_cred_list([c2, a1, b1, a2, c1, a3, b2])),
|
||||||
|
[b2, a3, a1, c2],
|
||||||
|
)
|
||||||
|
|
||||||
# Test duplicities.
|
# Test duplicities.
|
||||||
self.assertEqual(sorted(distinguishable_cred_list([c1, a1, a1, c2, c1])), [a1, c1])
|
self.assertEqual(
|
||||||
|
sorted(distinguishable_cred_list([c1, a1, a1, c2, c1])), [a1, c1]
|
||||||
|
)
|
||||||
self.assertEqual(sorted(distinguishable_cred_list([b2, b3])), [b2])
|
self.assertEqual(sorted(distinguishable_cred_list([b2, b3])), [b2])
|
||||||
self.assertEqual(sorted(distinguishable_cred_list([b3, b2])), [b3])
|
self.assertEqual(sorted(distinguishable_cred_list([b3, b2])), [b3])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user