def _find_and_open_usb_bitbox02( use_cache: bool) -> Tuple[devices.DeviceInfo, TransportLayer]: """ Connects to a BitBox02 bootloader over USB. If the BitBox02 is currently running a firmware, it will be rebooted and this function will connect to the bootloader when it shows up. """ bootloader_device = None try: bootloader_device = devices.get_any_bitbox02_bootloader() except TooManyFoundException: eprint( "Found multiple bb02 bootloader standard editions. Only one supported." ) sys.exit(1) except NoneFoundException: pass if bootloader_device is None: try: bootloader_device = _get_bitbox_and_reboot(use_cache) except TooManyFoundException: eprint("Found multiple bitboxes. Only one supported.") sys.exit(1) except NoneFoundException: eprint("Neither bootloader nor bitbox found.") sys.exit(1) pprint.pprint(bootloader_device) hid_device = hid.device() hid_device.open_path(bootloader_device["path"]) return bootloader_device, u2fhid.U2FHid(hid_device)
def _get_bitbox_and_reboot(use_cache: bool) -> devices.DeviceInfo: """Search for a bitbox and then reboot it into bootloader""" device = devices.get_any_bitbox02() class NoiseConfig(util.NoiseConfigUserCache): """NoiseConfig extends NoiseConfigUserCache""" def __init__(self) -> None: super().__init__("shift/load_firmware") def show_pairing(self, code: str, device_response: Callable[[], bool]) -> bool: print( "Please compare and confirm the pairing code on your BitBox02:" ) print(code) return device_response() class NoiseConfigNoCache(bitbox_api_protocol.BitBoxNoiseConfig): """NoiseConfig extends BitBoxNoiseConfig""" def show_pairing(self, code: str, device_response: Callable[[], bool]) -> bool: print( "Please compare and confirm the pairing code on your BitBox02:" ) print(code) return device_response() if use_cache: config: bitbox_api_protocol.BitBoxNoiseConfig = NoiseConfig() else: config = NoiseConfigNoCache() hid_device = hid.device() hid_device.open_path(device["path"]) bitbox = BitBox02(transport=u2fhid.U2FHid(hid_device), device_info=device, noise_config=config) if not bitbox.reboot(): raise RuntimeError("User aborted") # wait for it to reboot while True: try: bootloader_device = devices.get_any_bitbox02_bootloader() except NoneFoundException: sys.stdout.write(".") sys.stdout.flush() sleep(1) continue return bootloader_device
def connect_to_usb_bitbox(debug: bool, use_cache: bool) -> int: """ Connects and runs the main menu on a BitBox02 connected over USB. """ try: bitbox = devices.get_any_bitbox02() except devices.TooManyFoundException: print("Multiple bitboxes detected. Only one supported") return 1 except devices.NoneFoundException: try: bootloader = devices.get_any_bitbox02_bootloader() except devices.TooManyFoundException: print("Multiple bitbox bootloaders detected. Only one supported") return 1 except devices.NoneFoundException: print("Neither bitbox nor bootloader found.") return 1 else: hid_device = hid.device() hid_device.open_path(bootloader["path"]) bootloader_connection = bitbox02.Bootloader( u2fhid.U2FHid(hid_device), bootloader) boot_app = SendMessageBootloader(bootloader_connection) return boot_app.run() else: def show_pairing(code: str, device_response: Callable[[], bool]) -> bool: print( "Please compare and confirm the pairing code on your BitBox02:" ) print(code) if not device_response(): return False return input("Accept pairing? [y]/n: ").strip() != "n" class NoiseConfig(util.NoiseConfigUserCache): """NoiseConfig extends NoiseConfigUserCache""" def __init__(self) -> None: super().__init__("shift/send_message") def show_pairing(self, code: str, device_response: Callable[[], bool]) -> bool: return show_pairing(code, device_response) def attestation_check(self, result: bool) -> None: if result: print("Device attestation PASSED") else: print("Device attestation FAILED") class NoiseConfigNoCache(bitbox_api_protocol.BitBoxNoiseConfig): """NoiseConfig extends BitBoxNoiseConfig""" def show_pairing(self, code: str, device_response: Callable[[], bool]) -> bool: return show_pairing(code, device_response) def attestation_check(self, result: bool) -> None: if result: print("Device attestation PASSED") else: print("Device attestation FAILED") if use_cache: config: bitbox_api_protocol.BitBoxNoiseConfig = NoiseConfig() else: config = NoiseConfigNoCache() hid_device = hid.device() hid_device.open_path(bitbox["path"]) bitbox_connection = bitbox02.BitBox02( transport=u2fhid.U2FHid(hid_device), device_info=bitbox, noise_config=config) try: bitbox_connection.check_min_version() except FirmwareVersionOutdatedException as exc: print("WARNING: ", exc) if debug: print("Device Info:") pprint.pprint(bitbox) return SendMessage(bitbox_connection, debug).run()