mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-28 22:15:42 +00:00
core/webauthn: Cache user verification for 3 minutes.
This commit is contained in:
parent
b867ac1d01
commit
5469acfabf
@ -1,3 +1,5 @@
|
|||||||
|
import utime
|
||||||
|
|
||||||
import storage.sd_salt
|
import storage.sd_salt
|
||||||
from trezor import config, ui, wire
|
from trezor import config, ui, wire
|
||||||
from trezor.messages import ButtonRequestType
|
from trezor.messages import ButtonRequestType
|
||||||
@ -14,6 +16,9 @@ if False:
|
|||||||
from typing import Any, NoReturn, Optional, Tuple
|
from typing import Any, NoReturn, Optional, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
_last_successful_unlock = 0
|
||||||
|
|
||||||
|
|
||||||
def can_lock_device() -> bool:
|
def can_lock_device() -> bool:
|
||||||
"""Return True if the device has a PIN set or SD-protect enabled."""
|
"""Return True if the device has a PIN set or SD-protect enabled."""
|
||||||
return config.has_pin() or storage.sd_salt.is_enabled()
|
return config.has_pin() or storage.sd_salt.is_enabled()
|
||||||
@ -81,7 +86,17 @@ async def verify_user_pin(
|
|||||||
prompt: str = "Enter your PIN",
|
prompt: str = "Enter your PIN",
|
||||||
allow_cancel: bool = True,
|
allow_cancel: bool = True,
|
||||||
retry: bool = True,
|
retry: bool = True,
|
||||||
|
cache_time_ms: int = 0,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
global _last_successful_unlock
|
||||||
|
if (
|
||||||
|
cache_time_ms
|
||||||
|
and _last_successful_unlock
|
||||||
|
and utime.ticks_ms() - _last_successful_unlock <= cache_time_ms
|
||||||
|
and config.is_unlocked()
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
if config.has_pin():
|
if config.has_pin():
|
||||||
pin = await request_pin(ctx, prompt, config.get_pin_rem(), allow_cancel)
|
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_to_int(pin))
|
||||||
@ -93,6 +108,7 @@ async def verify_user_pin(
|
|||||||
except SdCardUnavailable:
|
except SdCardUnavailable:
|
||||||
raise wire.PinCancelled("SD salt is unavailable")
|
raise wire.PinCancelled("SD salt is unavailable")
|
||||||
if config.unlock(pin_to_int(pin), salt):
|
if config.unlock(pin_to_int(pin), salt):
|
||||||
|
_last_successful_unlock = utime.ticks_ms()
|
||||||
return
|
return
|
||||||
elif not config.has_pin():
|
elif not config.has_pin():
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
@ -102,6 +118,7 @@ async def verify_user_pin(
|
|||||||
ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel
|
ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel
|
||||||
)
|
)
|
||||||
if config.unlock(pin_to_int(pin), salt):
|
if config.unlock(pin_to_int(pin), salt):
|
||||||
|
_last_successful_unlock = utime.ticks_ms()
|
||||||
return
|
return
|
||||||
|
|
||||||
raise wire.PinInvalid
|
raise wire.PinInvalid
|
||||||
|
@ -141,6 +141,7 @@ _U2F_CONFIRM_TIMEOUT_MS = const(
|
|||||||
) # maximum U2F pollling interval, Chrome uses 200 ms
|
) # maximum U2F pollling interval, Chrome uses 200 ms
|
||||||
_FIDO2_CONFIRM_TIMEOUT_MS = const(60 * 1000)
|
_FIDO2_CONFIRM_TIMEOUT_MS = const(60 * 1000)
|
||||||
_POPUP_TIMEOUT_MS = const(4 * 1000)
|
_POPUP_TIMEOUT_MS = const(4 * 1000)
|
||||||
|
_UV_CACHE_TIME_MS = const(3 * 60 * 1000) # user verification cache time
|
||||||
|
|
||||||
# hid error codes
|
# hid error codes
|
||||||
_ERR_NONE = const(0x00) # no error
|
_ERR_NONE = const(0x00) # no error
|
||||||
@ -593,7 +594,7 @@ async def verify_user(keepalive_callback: KeepaliveCallback) -> bool:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
trezor.pin.keepalive_callback = keepalive_callback
|
trezor.pin.keepalive_callback = keepalive_callback
|
||||||
await verify_user_pin()
|
await verify_user_pin(cache_time_ms=_UV_CACHE_TIME_MS)
|
||||||
ret = True
|
ret = True
|
||||||
except (PinCancelled, PinInvalid):
|
except (PinCancelled, PinInvalid):
|
||||||
ret = False
|
ret = False
|
||||||
|
Loading…
Reference in New Issue
Block a user