Exemple #1
0
def main(apps=None, network="main", keystore_cls=None):
    """
    apps: list of apps to load
    network: default network to operate
    keystores: list of KeyStore classes that can be used
    """
    # create virtual file system /sdram
    # for temp untrusted data storage
    rampath = platform.mount_sdram()
    # define hosts - USB, QR, SDCard
    # each hosts gets it's own RAM folder for data
    hosts = [
        QRHost(rampath + "/qr"),
        USBHost(rampath + "/usb"),
        # SDHost(rampath+"/sd"), # not implemented yet
    ]
    # temp storage in RAM for host commands processing
    BaseApp.TEMPDIR = rampath+"/tmp"
    # define GUI
    gui = SpecterGUI()

    # inject the folder where keystore stores it's data
    KeyStore.path = platform.fpath("/flash/keystore")
    # detect keystore to use
    if keystore_cls is not None:
        keystores = [keystore_cls]
    else:
        keystores = [
            MemoryCard,
            SDKeyStore,
        ]

    # loading apps
    if apps is None:
        apps = load_apps()

    # make Specter instance
    settings_path = platform.fpath("/flash")
    specter = Specter(
        gui=gui,
        keystores=keystores,
        hosts=hosts,
        apps=apps,
        settings_path=settings_path,
        network=network,
    )
    specter.start()
Exemple #2
0
def load_apps(module='apps', whitelist=None, blacklist=None):
    mod = __import__(module)
    mods = mod.__all__
    apps = []
    if blacklist is not None:
        mods = [mod for mod in mods if mod not in blacklist]
    if whitelist is not None:
        mods = [mod for mod in mods if mod in whitelist]
    for modname in mods:
        appmod = __import__('%s.%s' % (module, modname))
        mod = getattr(appmod, modname)
        if hasattr(mod, 'App'):
            app = mod.App(platform.fpath("/qspi/%s" % modname))
            apps.append(app)
        else:
            print("Failed loading app:", modname)
    return apps
Exemple #3
0
 async def export_menu(self, show_screen):
     while True:
         buttons = [
             (None, "Export options"),
             (1, "Show QR code"),
             (2, "Save to SD card", platform.is_sd_present()),
         ]
         menuitem = await show_screen(
             Menu(buttons,
                  last=(255, None),
                  title="Export wallet %s" % self.name))
         desc = add_checksum(str(self.descriptor.branch(0)))
         obj = {
             "descriptor": desc,
             "label": self.name,
         }
         if self.descriptor.num_branches > 2:
             obj["branches"] = [
                 add_checksum(str(self.descriptor.branch(i)))
                 for i in range(self.descriptor.num_branches)
             ]
         if menuitem == 1:
             await show_screen(
                 QRAlert(
                     title="Export wallet %s" % self.name,
                     qr_width=450,
                     message=
                     "Scan this QR code with compatible software wallet",
                     qr_message=json.dumps(obj)))
         elif menuitem == 2:
             if not platform.is_sd_present():
                 raise WalletError("SD card is not present")
             platform.mount_sdcard()
             fname = "/sd/%s.json" % self.name
             with open(platform.fpath(fname), "w") as f:
                 json.dump(obj, f)
             platform.unmount_sdcard()
             await show_screen(
                 Alert("Success!",
                       "Wallet descriptor is written to\n\n%s" % fname))
         else:
             return
Exemple #4
0
    async def setup(self):
        try:
            path = fpath("/flash/KEYSTORECLS")
            # check if the user already selected the keystore class
            if self.keystore is None:
                await self.select_keystore(path)

            if self.keystore is not None:
                self.load_network(self.path, self.network)

            # load secrets
            await self.keystore.init(self.gui.show_screen())
            if not file_exists(path):
                # save selected keystore
                with open(path, "w") as f:
                    f.write(self.keystore.__class__.__name__)
            # unlock with PIN or set up the PIN code
            await self.unlock()
        except Exception as e:
            next_fn = await self.handle_exception(e, self.setup)
            await next_fn()

        await self.main()
Exemple #5
0
 def load_config(self):
     try:
         config, _ = self.keystore.load_aead(self.path+"/settings",
                                             self.keystore.enc_secret)
         config = json.loads(config.decode())
     except Exception as e:
         print(e)
         config = {"dev": self.dev, "usb": self.usb}
         self.keystore.save_aead(self.path+"/settings",
                                 adata=json.dumps(config).encode(),
                                 key=self.keystore.enc_secret)
     self.dev = config["dev"]
     self.usb = config["usb"]
     # add apps in dev mode
     if self.dev:
         try:
             qspi = fpath("/qspi/extensions")
             maybe_mkdir(qspi)
             maybe_mkdir(qspi+"/extra_apps")
             if qspi not in sys.path:
                 sys.path.append(qspi)
                 self.apps += load_apps('extra_apps')
         except Exception as e:
             print(e)
Exemple #6
0
 def wipe(self):
     # TODO: wipe the smartcard as well?
     delete_recursively(fpath("/flash"))
     delete_recursively(fpath("/qspi"))
Exemple #7
0
 def __init__(self, path, sdpath=fpath("/sd")):
     super().__init__(path)
     self.sdpath = sdpath
     self.f = None
     self.fram = self.path + "/data"
     self.sd_file = self.sdpath + "/signed.psbt"
Exemple #8
0
 def sdpath(self):
     hexid = hexlify(tagged_hash("sdid", self.secret)[:4]).decode()
     return platform.fpath("/sd/specterdiy%s" % hexid)
Exemple #9
0
 def sdpath(self):
     return platform.fpath("/sd")
Exemple #10
0
 def __init__(self, path, sdpath=fpath("/sd")):
     super().__init__(path)
     self.sdpath = sdpath
Exemple #11
0
def main(apps=None, network="main", keystore_cls=None):
    """
    apps: list of apps to load
    network: default network to operate
    keystores: list of KeyStore classes that can be used
    """
    # Init display first as it also inits the SDRAM
    display.init(False)
    # create virtual file system /sdram
    # for temp untrusted data storage
    rampath = platform.mount_sdram()

    # set working path to empty folder in sdram
    if not platform.simulator:
        cwd = rampath + "/cwd"
        platform.maybe_mkdir(cwd)
        os.chdir(cwd)

    # define hosts - USB, QR, SDCard
    # each hosts gets it's own RAM folder for data
    Host.SETTINGS_DIR = platform.fpath("/qspi/hosts")
    Specter.SETTINGS_DIR = platform.fpath("/qspi/global")
    hosts = [
        USBHost(rampath + "/usb"),
        QRHost(rampath + "/qr"),
        SDHost(rampath + "/sd"),
    ]
    # temp storage in RAM for host commands processing
    BaseApp.TEMPDIR = rampath + "/tmp"

    # define GUI
    if not platform.simulator:
        gui = SpecterGUI()
    else:
        # this GUI can simulate user actions for automated testing
        from gui.tcp_gui import TCPGUI
        gui = TCPGUI()

    # inject the folder where keystore stores it's data
    KeyStore.path = platform.fpath("/flash/keystore")
    # detect keystore to use
    if keystore_cls is not None:
        keystores = [keystore_cls]
    else:
        keystores = [
            MemoryCard,
            SDKeyStore,
        ]

    # loading apps
    if apps is None:
        apps = load_apps()

    # make Specter instance
    settings_path = platform.fpath("/flash")
    specter = Specter(
        gui=gui,
        keystores=keystores,
        hosts=hosts,
        apps=apps,
        settings_path=settings_path,
        network=network,
    )
    specter.start()