Example #1
0
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()
Example #2
0
def connect_to_usart_bitboxbase(debug: bool, serial_port: usart.SerialPort,
                                use_cache: bool) -> int:
    """
    Connects and runs the main menu over a BitBoxBase connected
    over UART.
    """
    print("Trying to connect to BitBoxBase firmware...")
    bootloader_device: devices.DeviceInfo = get_bitboxbase_default_device(
        serial_port.port)

    def show_pairing(code: str, device_response: Callable[[], bool]) -> bool:
        print("(Pairing should be automatic) Pairing code:")
        print(code)
        return device_response()

    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()

    try:
        transport = usart.U2FUsart(serial_port)
        base_dev = BitBoxBase(transport, bootloader_device, config)
        if debug:
            print("Device Info:")
            pprint.pprint(base_dev)
        return SendMessageBitBoxBase(base_dev, debug).run()
    except usart.U2FUsartErrorResponse as err:
        if err.error_code != usart.U2FUsartErrorResponse.ENDPOINT_UNAVAILABLE:
            raise
    except usart.U2FUsartTimeoutError:
        print("Timed out. Maybe the device is not connected?", file=sys.stderr)
        return 1

    print("BitBox unavailable. Starting bootloader connection.")
    transport = usart.U2FUsart(serial_port)
    bootloader = bitbox02.Bootloader(transport, bootloader_device)
    return SendMessageBootloader(bootloader).run()