def is_key_saved(self): flash_exists = platform.file_exists(self.flashpath) if not platform.is_sd_present(): return flash_exists platform.mount_sdcard() sd_exists = platform.file_exists(self.sdpath) platform.unmount_sdcard() return sd_exists or flash_exists
def load_mnemonic(self): if self.is_locked: raise KeyStoreError("Keystore is locked") if not platform.file_exists(self.path + "/reckless"): raise KeyStoreError("Key is not saved") _, data = self.load_aead(self.path + "/reckless", self.pin_secret) self.set_mnemonic(data.decode(), "")
async def select_keystore(self, path): # if we have fixed keystore - just use it if len(self.keystores) == 1: self.keystore = self.keystores[0]() return # otherwise check if the file exists # that determines what class to use if file_exists(path): with open(path) as f: name = f.read() for k in self.keystores: if k.__name__ == name: self.keystore = k() return raise SpecterError("Didn't find a matching keystore class") # if not -> ask the user buttons = [(None, " ")] for k in self.keystores: buttons.extend([(k, k.NAME), (None, " ")]) # wait for menu selection keystore_cls = await self.gui.menu( buttons, title="Select key storage type", note="\n\nWhere do you want to store your key?\n\n" "By default Specter-DIY is amnesic and doesn't save the key.\n" "But you can use one of the options below if you don't want " "to remember your recovery phrase.\n\n" "Note: Smartcard requires a special extension board.", ) self.keystore = keystore_cls()
def delete_mnemonic(self): if not platform.file_exists(self.path + "/reckless"): raise KeyStoreError( "Secret is not saved. No need to delete anything.") try: os.remove(self.path + "/reckless") except: raise KeyStoreError("Failed to delete from memory")
async def load_mnemonic(self): if self.is_locked: raise KeyStoreError("Keystore is locked") if not platform.file_exists(self.flashpath): raise KeyStoreError("Key is not saved") _, data = self.load_aead(self.flashpath, self.enc_secret) self.set_mnemonic(data.decode(), "") return True
def load_enc_secret(self): fpath = self.path + "/enc_secret" if platform.file_exists(fpath): _, secret = self.load_aead(fpath, self.pin_secret) else: # create new key if it doesn't exist secret = get_random_bytes(32) self.save_aead(fpath, plaintext=secret, key=self.pin_secret) self.enc_secret = secret
async def get_keypath(self, title="Select media", only_if_exist=True, **kwargs): # enable / disable buttons enable_flash = (not only_if_exist) or platform.file_exists( self.flashpath) enable_sd = False if platform.is_sd_present(): platform.mount_sdcard() enable_sd = (not only_if_exist) or platform.file_exists( self.sdpath) platform.unmount_sdcard() buttons = [ (None, "Make your choice"), (self.flashpath, "Internal flash", enable_flash), (self.sdpath, "SD card", enable_sd), ] scr = Menu(buttons, title=title, last=(None, ), **kwargs) res = await self.show(scr) return res
async def save_mnemonic(self): if self.is_locked: raise KeyStoreError("Keystore is locked") if self.mnemonic is None: raise KeyStoreError("Recovery phrase is not loaded") path = await self.get_keypath(title="Where to save?", only_if_exist=False, note="Select media") if path is None: return filename = await self.get_input(suggestion=self.mnemonic.split()[0]) if filename is None: return fullpath = "%s/%s.%s" % (path, self.fileprefix(path), filename) if fullpath.startswith(self.sdpath): if not platform.is_sd_present(): raise KeyStoreError("SD card is not present") platform.mount_sdcard() if platform.file_exists(fullpath): scr = Prompt( "\n\nFile already exists: %s\n" % filename, "Would you like to overwrite this file?", ) res = await self.show(scr) if res is False: if fullpath.startswith(self.sdpath): platform.unmount_sdcard() return self.save_aead(fullpath, plaintext=self.mnemonic.encode(), key=self.enc_secret) if fullpath.startswith(self.sdpath): platform.unmount_sdcard() # check it's ok await self.load_mnemonic(fullpath) # return the full file name incl. prefix if saved to SD card, just the name if on flash return fullpath.split("/")[-1] if fullpath.startswith( self.sdpath) else filename
async def delete_mnemonic(self): file = await self.select_file() if file is None: return False # mount sd before check if platform.is_sd_present() and file.startswith(self.sdpath): platform.mount_sdcard() if not platform.file_exists(file): raise KeyStoreError("File not found.") try: os.remove(file) except Exception as e: print(e) raise KeyStoreError("Failed to delete file '%s'" % file) finally: if platform.is_sd_present() and file.startswith(self.sdpath): platform.unmount_sdcard() return True
async def load_mnemonic(self, file=None): if self.is_locked: raise KeyStoreError("Keystore is locked") if file is None: file = await self.select_file() if file is None: return False if file.startswith(self.sdpath) and platform.is_sd_present(): platform.mount_sdcard() if not platform.file_exists(file): raise KeyStoreError("Key is not saved") _, data = self.load_aead(file, self.enc_secret) if file.startswith(self.sdpath) and platform.is_sd_present(): platform.unmount_sdcard() self.set_mnemonic(data.decode(), "") return True
def load_state(self): """Verify file and load PIN state from it""" # If PIN file doesn't exist - create it # This can happen if the device was initialized with the smartcard if not platform.file_exists(self.path + "/pin"): self.create_empty_pin_file() return try: # verify that the pin file is ok _, data = self.load_aead(self.path + "/pin", self.secret) # load pin object data = json.loads(data.decode()) self.pin = unhexlify( data["pin"]) if data["pin"] is not None else None self._pin_attempts_max = data["pin_attempts_max"] self._pin_attempts_left = data["pin_attempts_left"] except Exception as e: # this happens if someone tries to change PIN file self.wipe(self.path) raise CriticalErrorWipeImmediately( "Something went terribly wrong!\nDevice is wiped!\n%s" % e)
async def load_mnemonic(self, path=None): if self.is_locked: raise KeyStoreError("Keystore is locked") if path is None: path = await self.get_keypath(title="From where to load?", note="Select media") if path is None: return False if path == self.sdpath: if not platform.is_sd_present(): raise KeyStoreError("SD card is not present") platform.mount_sdcard() if not platform.file_exists(path): raise KeyStoreError("Key is not saved") _, data = self.load_aead(path, self.enc_secret) if path == self.sdpath: platform.unmount_sdcard() self.set_mnemonic(data.decode(), "") return True
async def delete_mnemonic(self, path=None): if path is None: path = await self.get_keypath(title="From where to delete?") if path is None: return False if path == self.sdpath: if not platform.is_sd_present(): raise KeyStoreError("SD card is not present") platform.mount_sdcard() if not platform.file_exists(path): raise KeyStoreError( "Secret is not saved. No need to delete anything.") try: os.remove(path) except Exception as e: print(e) raise KeyStoreError("Failed to delete file at " + path) finally: if path == self.sdpath: platform.unmount_sdcard() return True
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()
def is_key_saved(self): return platform.file_exists(self.flashpath)
def is_key_saved(self): return platform.file_exists(self.path + "/reckless")