1818# pylint: disable=too-many-lines
1919
2020import argparse
21+ import socket
2122import pprint
2223import sys
2324from typing import List , Any , Optional , Callable , Union , Tuple , Sequence
4142 FirmwareVersionOutdatedException ,
4243 u2fhid ,
4344 bitbox_api_protocol ,
45+ PhysicalLayer ,
4446)
4547
4648import u2f
@@ -1556,6 +1558,65 @@ def run(self) -> int:
15561558 return 0
15571559
15581560
1561+ def connect_to_simulator_bitbox (debug : bool ) -> int :
1562+ """
1563+ Connects and runs the main menu on host computer,
1564+ simulating a BitBox02 connected over USB.
1565+ """
1566+
1567+ class Simulator (PhysicalLayer ):
1568+ """
1569+ Simulator class handles the communication
1570+ with the firmware simulator
1571+ """
1572+
1573+ def __init__ (self ) -> None :
1574+ self .client_socket = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
1575+ port = 15423
1576+ self .client_socket .bind (("" , port ))
1577+ self .client_socket .listen (50 )
1578+ print (f"Waiting for connection on port { port } " )
1579+ self .connection , addr = self .client_socket .accept ()
1580+ print (f"Connected to { addr } " )
1581+
1582+ def write (self , data : bytes ) -> None :
1583+ self .connection .send (data [1 :])
1584+ if debug :
1585+ print (f"Written to the simulator:\n { data .hex ()[2 :]} " )
1586+
1587+ def read (self , size : int , timeout_ms : int ) -> bytes :
1588+ res = self .connection .recv (64 )
1589+ if debug :
1590+ print (f"Read from the simulator:\n { res .hex ()} " )
1591+ return res
1592+
1593+ def __del__ (self ) -> None :
1594+ print ("Simulator quit" )
1595+ if self .connection :
1596+ self .connection .shutdown (socket .SHUT_RDWR )
1597+ self .connection .close ()
1598+
1599+ simulator = Simulator ()
1600+
1601+ device_info : devices .DeviceInfo = {
1602+ "serial_number" : "v9.16.0" ,
1603+ "path" : b"" ,
1604+ "product_string" : "BitBox02BTC" ,
1605+ }
1606+ noise_config = bitbox_api_protocol .BitBoxNoiseConfig ()
1607+ bitbox_connection = bitbox02 .BitBox02 (
1608+ transport = u2fhid .U2FHid (simulator ),
1609+ device_info = device_info ,
1610+ noise_config = noise_config ,
1611+ )
1612+ try :
1613+ bitbox_connection .check_min_version ()
1614+ except FirmwareVersionOutdatedException as exc :
1615+ print ("WARNING: " , exc )
1616+
1617+ return SendMessage (bitbox_connection , debug ).run ()
1618+
1619+
15591620def connect_to_usb_bitbox (debug : bool , use_cache : bool ) -> int :
15601621 """
15611622 Connects and runs the main menu on a BitBox02 connected
@@ -1643,6 +1704,11 @@ def main() -> int:
16431704 parser = argparse .ArgumentParser (description = "Tool for communicating with bitbox device" )
16441705 parser .add_argument ("--debug" , action = "store_true" , help = "Print messages sent and received" )
16451706 parser .add_argument ("--u2f" , action = "store_true" , help = "Use u2f menu instead" )
1707+ parser .add_argument (
1708+ "--simulator" ,
1709+ action = "store_true" ,
1710+ help = "Connect to the BitBox02 simulator instead of a real BitBox02" ,
1711+ )
16461712 parser .add_argument (
16471713 "--no-cache" , action = "store_true" , help = "Don't use cached or store noise keys"
16481714 )
@@ -1663,6 +1729,9 @@ def main() -> int:
16631729 return u2fapp .run ()
16641730 return 1
16651731
1732+ if args .simulator :
1733+ return connect_to_simulator_bitbox (args .debug )
1734+
16661735 return connect_to_usb_bitbox (args .debug , not args .no_cache )
16671736
16681737
0 commit comments