async def done_splash2(): # Boot up code; after splash screen is done. # MAYBE: check if we're a brick and die again? Or show msg? if version.is_factory_mode: # in factory mode, turn on USB early to allow debug/setup from usb import enable_usb enable_usb(loop, True) # always start the self test. if not settings.get('tested', False): from actions import start_selftest await start_selftest() else: # force them to accept terms (unless marked as already done) from actions import accept_terms await accept_terms() # Prompt for PIN and then pick appropriate top-level menu, # based on contents of secure chip (ie. is there # a wallet defined) from actions import start_login_sequence await start_login_sequence() loop.create_task(mainline())
async def initial_pin_setup(*a): # First time they select a PIN of any type. from login import LoginUX lll = LoginUX() pin = await lll.get_new_pin( 'Choose PIN', '''\ Pick the main wallet's PIN code now. Be more clever, but an example: 123-4567 It has two parts: prefix (123-) and suffix (-4567). \ Each part must between 2 to 6 digits long. Total length \ can be as long as 12 digits. The prefix part determines the anti-phishing words you will \ see each time you login. Your new PIN protects access to \ this Coldcard device and is not a factor in the wallet's \ seed words or private keys. THERE IS ABSOLUTELY NO WAY TO RECOVER A FORGOTTEN PIN! Write it down. ''') del lll if pin is None: return # A new pin is to be set! from main import pa, dis, settings, loop dis.fullscreen("Saving...") try: assert pa.is_blank() pa.change(new_pin=pin) # check it? kinda, but also get object into normal "logged in" state pa.setup(pin) ok = pa.login() assert ok # must re-read settings after login, because they are encrypted # with a key derived from the main secret. settings.set_key() settings.load() except Exception as e: print("Exception: %s" % e) # Allow USB protocol, now that we are auth'ed from usb import enable_usb enable_usb(loop, False) from menu import MenuSystem from flow import EmptyWallet return MenuSystem(EmptyWallet)
def set_it(idx, text): settings.set('du', idx) import pyb from usb import enable_usb, disable_usb cur = pyb.usb_mode() if cur and idx: # usb enabled, but should not be now disable_usb() elif not cur and not idx: # USB disabled, but now should be enable_usb()
async def dev_enable_protocol(*a): # Turn off disk emulation. Keep VCP enabled, since they are still devs. from main import loop cur = pyb.usb_mode() if cur and 'HID' in cur: await ux_show_story('Coldcard USB protocol is already enabled (HID mode)') return # might need to reset stuff? from usb import enable_usb # reset / re-enable pyb.usb_mode(None) enable_usb(loop, True) await ux_show_story('Back to normal USB mode.')
async def more_setup(): # Boot up code; splash screen is being shown # MAYBE: check if we're a brick and die again? Or show msg? try: # Some background "tasks" # from dev_helper import monitor_usb IMPT.start_task('vcp', monitor_usb()) from files import CardSlot CardSlot.setup() # This "pa" object holds some state shared w/ bootloader about the PIN try: from pincodes import pa pa.setup(b'') # just to see where we stand. except RuntimeError as e: print("Problem: %r" % e) if version.is_factory_mode: # in factory mode, turn on USB early to allow debug/setup from usb import enable_usb enable_usb() # always start the self test. if not settings.get('tested', False): from actions import start_selftest await start_selftest() else: # force them to accept terms (unless marked as already done) from actions import accept_terms await accept_terms() # Prompt for PIN and then pick appropriate top-level menu, # based on contents of secure chip (ie. is there # a wallet defined) from actions import start_login_sequence await start_login_sequence() except BaseException as exc: die_with_debug(exc) IMPT.start_task('mainline', mainline())
# (c) Copyright 2018 by Coinkite Inc. This file is covered by license found in COPYING-CC. # # This is my personal /lib/boot2.py which enables easier USB access. For v4+ firmware. # print("/lib/boot2: runs") # start the REPL very early from usb import enable_usb # very slow, noticable in boot sequence enable_usb(True) import uasyncio from dev_helper import usb_keypad_emu uasyncio.create_task(usb_keypad_emu()) print("/lib/boot2: done")
async def start_login_sequence(): # Boot up login sequence here. # from main import pa, settings, dis, loop, numpad import version if pa.is_blank(): # Blank devices, with no PIN set all, can continue w/o login # Do green-light set immediately after firmware upgrade if version.is_fresh_version(): pa.greenlight_firmware() dis.show() goto_top_menu() return # Allow impatient devs and crazy people to skip the PIN guess = settings.get('_skip_pin', None) if guess is not None: try: dis.fullscreen("(Skip PIN)") pa.setup(guess) pa.login() except: pass # if that didn't work, or no skip defined, force # them to login succefully. while not pa.is_successful(): # always get a PIN and login first await block_until_login() # Must read settings after login settings.set_key() settings.load() # Restore a login preference or two numpad.sensitivity = settings.get('sens', numpad.sensitivity) # Do green-light set immediately after firmware upgrade if not pa.is_secondary: if version.is_fresh_version(): pa.greenlight_firmware() dis.show() # Populate xfp/xpub values, if missing. # - can happen for first-time login of duress wallet # - may indicate lost settings, which we can easily recover from # - these values are important to USB protocol if not (settings.get('xfp', 0) and settings.get('xpub', 0)) and not pa.is_secret_blank(): try: import stash # Recalculate xfp/xpub values (depends both on secret and chain) with stash.SensitiveValues() as sv: sv.capture_xpub() except Exception as exc: # just in case, keep going; we're not useless and this # is early in boot process print("XFP save failed: %s" % exc) # Allow USB protocol, now that we are auth'ed from usb import enable_usb enable_usb(loop, False) goto_top_menu()
async def initial_pin_setup(*a): # First time they select a PIN of any type. from login import LoginUX lll = LoginUX() title = 'Choose PIN' ch = await ux_show_story('''\ Pick the main wallet's PIN code now. Be more clever, but an example: 123-4567 It has two parts: prefix (123-) and suffix (-4567). \ Each part must between 2 to 6 digits long. Total length \ can be as long as 12 digits. The prefix part determines the anti-phishing words you will \ see each time you login. Your new PIN protects access to \ this Coldcard device and is not a factor in the wallet's \ seed words or private keys. THERE IS ABSOLUTELY NO WAY TO RECOVER A FORGOTTEN PIN! Write it down. ''', title=title) if ch != 'y': return while 1: ch = await ux_show_story('''\ There is ABSOLUTELY NO WAY to 'reset the PIN' or 'factory reset' the Coldcard if you forget the PIN. DO NOT FORGET THE PIN CODE. Press 6 to prove you read to the end of this message.''', title='WARNING', escape='6') if ch == 'x': return if ch == '6': break # do the actual picking pin = await lll.get_new_pin(title) del lll if pin is None: return # A new pin is to be set! from main import pa, dis, settings, loop dis.fullscreen("Saving...") try: dis.busy_bar(True) assert pa.is_blank() pa.change(new_pin=pin) # check it? kinda, but also get object into normal "logged in" state pa.setup(pin) ok = pa.login() assert ok # must re-read settings after login, because they are encrypted # with a key derived from the main secret. settings.set_key() settings.load() except Exception as e: print("Exception: %s" % e) finally: dis.busy_bar(False) # Allow USB protocol, now that we are auth'ed from usb import enable_usb enable_usb(loop, False) from menu import MenuSystem from flow import EmptyWallet return MenuSystem(EmptyWallet)
async def start_login_sequence(): # Boot up login sequence here. # from main import pa, settings, dis, loop, numpad from ux import idle_logout if pa.is_blank(): # Blank devices, with no PIN set all, can continue w/o login # Do green-light set immediately after firmware upgrade if version.is_fresh_version(): pa.greenlight_firmware() dis.show() goto_top_menu() return # maybe show a nickname before we do anything nickname = settings.get('nick', None) if nickname: try: await show_nickname(nickname) except: pass # Allow impatient devs and crazy people to skip the PIN guess = settings.get('_skip_pin', None) if guess is not None: try: dis.fullscreen("(Skip PIN)") pa.setup(guess) pa.login() except: pass # if that didn't work, or no skip defined, force # them to login succefully. while not pa.is_successful(): # always get a PIN and login first await block_until_login() # Must re-read settings after login settings.set_key() settings.load() # implement "login countdown" feature delay = settings.get('lgto', 0) if delay: pa.reset() await login_countdown(delay) await block_until_login() # implement idle timeout now that we are logged-in loop.create_task(idle_logout()) # Do green-light set immediately after firmware upgrade if not pa.is_secondary: if version.is_fresh_version(): pa.greenlight_firmware() dis.show() # Populate xfp/xpub values, if missing. # - can happen for first-time login of duress wallet # - may indicate lost settings, which we can easily recover from # - these values are important to USB protocol if not (settings.get('xfp', 0) and settings.get('xpub', 0)) and not pa.is_secret_blank(): try: import stash # Recalculate xfp/xpub values (depends both on secret and chain) with stash.SensitiveValues() as sv: sv.capture_xpub() except Exception as exc: # just in case, keep going; we're not useless and this # is early in boot process print("XFP save failed: %s" % exc) # If HSM policy file is available, offer to start that, # **before** the USB is even enabled. if version.has_fatram: try: import hsm, hsm_ux if hsm.hsm_policy_available(): ar = await hsm_ux.start_hsm_approval(usb_mode=False, startup_mode=True) if ar: await ar.interact() except: pass # Allow USB protocol, now that we are auth'ed from usb import enable_usb enable_usb(loop, False) goto_top_menu()
# (c) Copyright 2018 by Coinkite Inc. This file is part of Coldcard <coldcardwallet.com> # and is covered by GPLv3 license found in COPYING. # # This is my personal /lib/boot2.py which enables easier USB access. # print("/lib/boot2: runs") # start the REPL very early import uasyncio.core as asyncio from usb import enable_usb loop = asyncio.get_event_loop() enable_usb(loop, True) from dev_helper import usb_keypad_emu loop.create_task(usb_keypad_emu()) print("/lib/boot2: done")
# - cannot be changed by /flash/lib overrides, because already imported before that. # # see RAM_HEADER_BASE, and coldcardFirmwareHeader_t in sigheader.h import pyb, sys, version, gc # this makes the GC run when larger objects are free in an attempt to reduce fragmentation. gc.threshold(4096) # what firmware signing key did we boot with? are we in dev mode? is_devmode = version.is_devmode() if 0: # useful for debug: keep this stub from usb import enable_usb enable_usb(None, True) raise SystemExit if is_devmode: # For devs only: allow code in this directory to overide compiled-in stuff. Dangerous! # - using relative paths here so works better on simulator # - you must boot w/ non-production-signed firmware to get here sys.path.insert(0, 'flash/lib') # Give external devs a way to start stuff early try: import boot2 except: pass import ckcc