block some USB command in hobble mode
This commit is contained in:
parent
4bd8d12d9d
commit
54d58d4b43
@ -19,10 +19,10 @@ class CCBusyError(RuntimeError):
|
||||
# HSM is blocking your action
|
||||
class HSMDenied(RuntimeError):
|
||||
pass
|
||||
|
||||
class HSMCMDDisabled(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
# PSBT / transaction related
|
||||
class FatalPSBTIssue(RuntimeError):
|
||||
pass
|
||||
@ -51,7 +51,7 @@ class QRDecodeExplained(ValueError):
|
||||
class UnknownAddressExplained(ValueError):
|
||||
pass
|
||||
|
||||
# We're not going to co-sign using CCC feature
|
||||
# We're not going to co-sign using spending policy features
|
||||
class SpendPolicyViolation(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
@ -11,7 +11,8 @@ from ustruct import pack, unpack_from
|
||||
from ckcc import watchpoint, is_simulator
|
||||
from utils import problem_file_line, call_later_ms
|
||||
from version import supports_hsm, is_devmode, MAX_TXN_LEN, MAX_UPLOAD_LEN
|
||||
from exceptions import FramingError, CCBusyError, HSMDenied, HSMCMDDisabled
|
||||
from exceptions import FramingError, CCBusyError, HSMDenied, HSMCMDDisabled, SpendPolicyViolation
|
||||
from pincodes import pa
|
||||
|
||||
# Unofficial, unpermissioned... numbers
|
||||
COINKITE_VID = 0xd13e
|
||||
@ -68,6 +69,21 @@ HSM_DISABLE_CMDS = frozenset({
|
||||
"hsms",
|
||||
})
|
||||
|
||||
# spending policy active: blacklist some commands
|
||||
# - 'pass' may be allowed if 'okeys' is enabled
|
||||
HOBBLED_CMDS = frozenset({
|
||||
'enrl', # no new multisigs during policy enforcement
|
||||
'back', # no backups
|
||||
'bagi', 'dfu_', # just in case
|
||||
|
||||
"user", # same as HSM_DISABLE_CMDS
|
||||
"rmur",
|
||||
"nwur",
|
||||
"gslr",
|
||||
"hsts",
|
||||
"hsms",
|
||||
})
|
||||
|
||||
# singleton instance of USBHandler()
|
||||
handler = None
|
||||
|
||||
@ -217,6 +233,8 @@ class USBHandler:
|
||||
except CCBusyError:
|
||||
# auth UX is doing something else
|
||||
resp = b'busy'
|
||||
except SpendPolicyViolation:
|
||||
resp = b'err_Spending policy in effect'
|
||||
except HSMDenied:
|
||||
resp = b'err_Not allowed in HSM mode'
|
||||
except HSMCMDDisabled:
|
||||
@ -345,7 +363,7 @@ class USBHandler:
|
||||
except:
|
||||
raise FramingError('decode')
|
||||
|
||||
if cmd[0].isupper() and is_devmode:
|
||||
if is_devmode and cmd[0].isupper():
|
||||
# special hacky commands to support testing w/ the simulator
|
||||
try:
|
||||
from usb_test_commands import do_usb_command
|
||||
@ -358,7 +376,18 @@ class USBHandler:
|
||||
if cmd not in HSM_WHITELIST:
|
||||
raise HSMDenied
|
||||
|
||||
if not settings.get('hsmcmd', False):
|
||||
if pa.hobbled_mode:
|
||||
# block some commands when we are hobbled.
|
||||
if cmd in HOBBLED_CMDS:
|
||||
raise SpendPolicyViolation
|
||||
|
||||
if cmd in {'pwok', 'pass'}:
|
||||
from ccc import sssp_spending_policy
|
||||
if not sssp_spending_policy('okeys'):
|
||||
raise SpendPolicyViolation
|
||||
|
||||
elif not settings.get('hsmcmd', False):
|
||||
# block these HSM-related command if not using feature
|
||||
if cmd in HSM_DISABLE_CMDS:
|
||||
raise HSMCMDDisabled
|
||||
|
||||
@ -741,7 +770,6 @@ class USBHandler:
|
||||
from glob import dis, hsm_active
|
||||
from utils import check_firmware_hdr
|
||||
from sigheader import FW_HEADER_OFFSET, FW_HEADER_SIZE, FW_HEADER_MAGIC
|
||||
from pincodes import pa
|
||||
|
||||
# maintain a running SHA256 over what's received
|
||||
if offset == 0:
|
||||
@ -754,8 +782,8 @@ class USBHandler:
|
||||
assert offset % 256 == 0, 'alignment'
|
||||
assert offset+len(data) <= total_size <= MAX_UPLOAD_LEN, 'long'
|
||||
|
||||
if hsm_active:
|
||||
# additional restrictions in HSM mode
|
||||
if hsm_active or pa.hobbled_mode:
|
||||
# additional restriction in HSM mode or hobbled: must be PSBT
|
||||
assert offset+len(data) <= total_size <= MAX_TXN_LEN, 'psbt'
|
||||
if offset == 0:
|
||||
assert data[0:5] == b'psbt\xff', 'psbt'
|
||||
@ -834,7 +862,6 @@ class USBHandler:
|
||||
def handle_bag_number(self, bag_num):
|
||||
import version, callgate
|
||||
from glob import dis, settings
|
||||
from pincodes import pa
|
||||
|
||||
if bag_num and version.is_factory_mode and not version.has_qr:
|
||||
# check state first
|
||||
|
||||
@ -12,26 +12,6 @@ from test_ephemeral import SEEDVAULT_TEST_DATA, WORDLISTS
|
||||
from test_ephemeral import confirm_tmp_seed, verify_ephemeral_secret_ui
|
||||
from test_ux import word_menu_entry
|
||||
|
||||
'''
|
||||
TODO -- When hobbled...
|
||||
|
||||
- login sequence
|
||||
1) system has lgto value: should get bypass pin, main pin, delay, then main pin again
|
||||
2) using a trick PIN with delay, after bypass pin should delay
|
||||
3) bypass pin + duress wallet PIN => should work => but not a useful trick combo
|
||||
|
||||
- word entry during login
|
||||
- q1 vs mk4 style
|
||||
- wrong values given, etc
|
||||
|
||||
- verify whitelist of QR types is correct when in hobbled mode
|
||||
- no private key material, no teleport starting, unless "okeys" is set
|
||||
|
||||
- TODO: update menu tree w/ hobble mode view
|
||||
|
||||
- verify that PSBT can be "signed" when SP enabled and delta-mode pin is active. seed not wiped.
|
||||
|
||||
'''
|
||||
|
||||
# NOTE: these are unit tests of the effects of hobble mode, not how it is enabled/disabled:
|
||||
#
|
||||
@ -386,6 +366,46 @@ def test_h_tempseeds(mode, set_hobble, pick_menu_item, cap_menu, settings_set, i
|
||||
pick_menu_item("Restore Master")
|
||||
press_select()
|
||||
|
||||
# TODO: test usb commands are blocked
|
||||
|
||||
@pytest.mark.parametrize('en_okeys', [ True, False])
|
||||
def test_h_usbcmds(en_okeys, set_hobble, dev):
|
||||
# test various usb commands are blocked during hobble
|
||||
|
||||
from ckcc_protocol.protocol import CCProtoError
|
||||
|
||||
set_hobble(True, {'okeys'} if en_okeys else {})
|
||||
|
||||
block_list = [
|
||||
'back', 'enrl', 'bagi', 'hsms', 'user', 'nwur', 'rmur',
|
||||
]
|
||||
|
||||
if not en_okeys:
|
||||
block_list.insert(0, 'pass')
|
||||
|
||||
for cmd in block_list:
|
||||
with pytest.raises(CCProtoError) as ee:
|
||||
got = dev.send_recv(cmd)
|
||||
assert 'Spending policy in effect' in str(ee)
|
||||
|
||||
# TODO: verify that PSBT can be "signed" when SP enabled and delta-mode pin is active. seed not wiped.
|
||||
|
||||
|
||||
# TODO verify whitelist of QR types is correct when in hobbled mode
|
||||
# - no private key material, no teleport starting, unless "okeys" is set
|
||||
|
||||
|
||||
# TODO Special Login Sequence
|
||||
|
||||
'''
|
||||
- login sequence
|
||||
1) system has lgto value: should get bypass pin, main pin, delay, then main pin again
|
||||
2) using a trick PIN with delay, after bypass pin should delay
|
||||
3) bypass pin + duress wallet PIN => should work => but not a useful trick combo
|
||||
|
||||
- word entry during login
|
||||
- q1 vs mk4 style
|
||||
- wrong values given, etc
|
||||
|
||||
'''
|
||||
|
||||
# EOF
|
||||
|
||||
Loading…
Reference in New Issue
Block a user