Пример #1
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()
Пример #2
0
def _find_and_open_usart_bitbox(serial_port: usart.SerialPort,
                                use_cache: bool) -> devices.DeviceInfo:
    """
    Connects to a BitBoxBase bootloader over UART.
    If the BitBoxBase is currently running a firmware, it will
    be rebooted and this function will connect to the bootloader
    when it shows up.
    """
    print("Connecting to BitBox bootloader over UART.")
    bootloader_device: devices.DeviceInfo = get_bitboxbase_default_device(
        serial_port.port)
    # First, try to connect to the bootloader directly.
    bootloader_status = _try_usart_bootloader_connection(
        serial_port, bootloader_device)
    if bootloader_status == UsartBootloaderProbeResult.SUCCESS:
        return bootloader_device
    if bootloader_status == UsartBootloaderProbeResult.TIMEOUT:
        print("No reponse from BitBox. Maybe it's not connected properly?")
        sys.exit(1)

    # The bootloader wasn't valid, try to connect to the firmware instead.
    print("BitBox bootloader not available.")
    print("Trying to connect to BitBox firmware instead...")

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

    try:
        transport = usart.U2FUsart(serial_port)
        bitbox_attempt = BitBoxBase(transport,
                                    bootloader_device,
                                    noise_config=config)
        print("Connected. Rebooting.")
        bitbox_attempt.reboot()
    except usart.U2FUsartTimeoutError:
        pass
    finally:
        bitbox_attempt.close()
    print("Reboot completed.")

    # wait for it to reboot
    while True:
        bootloader_status = _try_usart_bootloader_connection(
            serial_port, bootloader_device)
        if bootloader_status == UsartBootloaderProbeResult.SUCCESS:
            return bootloader_device
        if bootloader_status == UsartBootloaderProbeResult.TIMEOUT:
            print("Waiting for the BitBox bootloader to show up...")
            sleep(1)
        else:
            print("Stuck in bitbox mode -  didn't reboot properly!")