def set_identity(identity): """set given identity (one of: 0, 1, 2)""" if not identity.isdigit(): print("identity number must be a digit") sys.exit(1) identity = int(identity) if identity < 0 or identity > 2: print("identity must be 0, 1 or 2") sys.exit(1) print(f"Trying to set identity to {identity}") for x in range(3): try: gnuk = get_gnuk_device() gnuk.cmd_select_openpgp() try: gnuk.cmd_set_identity(identity) except USBError: print("device has reset, and should now have the new identity") sys.exit(0) except ValueError as e: if 'No ICC present' in str(e): print("Could not connect to device, trying to close scdaemon") result = check_output( ["gpg-connect-agent", "SCD KILLSCD", "SCD BYE", "/bye"]) # gpgconf --kill all might be better? sleep(3) else: print('*** Found error: {}'.format(str(e)))
def set_identity(identity): """set given identity (one of: 0, 1, 2)""" if not identity.isdigit(): local_critical("identity number must be a digit") identity = int(identity) if identity < 0 or identity > 2: local_print("identity must be 0, 1 or 2") local_print(f"Setting identity to {identity}") for x in range(3): try: gnuk = get_gnuk_device() gnuk.cmd_select_openpgp() try: gnuk.cmd_set_identity(identity) except USBError: local_print(f"reset done - now active identity: {identity}") break except ValueError as e: if "No ICC present" in str(e): local_print("Could not connect to device, trying to close scdaemon") result = check_output(["gpg-connect-agent", "SCD KILLSCD", "SCD BYE", "/bye"]) # gpgconf --kill all might be better? sleep(3) else: local_critical(e) except Exception as e: local_critical(e)
def show_kdf_details(passwd): gnuk = None try: gnuk = get_gnuk_device(logger=logger, verbose=True) except ValueError as e: local_print("Connection error", e) if "No ICC present" in str(e): print("Cannot connect to device. Closing other open connections.") kill_smartcard_services() return else: raise gnuk.cmd_select_openpgp() # Compute passwd data try: kdf_data = gnuk.cmd_get_data(0x00, 0xF9).tobytes() except: kdf_data = b"" if kdf_data == b"": print("KDF not set") # passwd_data = passwd.encode('UTF-8') else: ( algo, subalgo, iters, salt_user, salt_reset, salt_admin, hash_user, hash_admin, ) = parse_kdf_data(kdf_data) if salt_admin: salt = salt_admin else: salt = salt_user d = { "algo": algo, "subalgo": subalgo, "iters": iters, "salt_user": binascii.b2a_hex(salt_user), "salt_reset": binascii.b2a_hex(salt_reset), "salt_admin": binascii.b2a_hex(salt_admin), "hash_user": binascii.b2a_hex(hash_user), "hash_admin": binascii.b2a_hex(hash_admin), } pprint(d, width=100) if passwd: try: passwd_data = kdf_calc(passwd, salt, iters) print(f"passwd_data: {binascii.b2a_hex(passwd_data)}") except ValueError as e: local_print("Error getting KDF", e) else: print("Provide password to calculate final hash")
def show_kdf_details(passwd): gnuk = None try: gnuk = get_gnuk_device(logger=logger, verbose=True) except ValueError as e: if "No ICC present" in str(e): print("Cannot connect to device. Closing other open connections.") kill_smartcard_services() return else: raise gnuk.cmd_select_openpgp() # Compute passwd data try: kdf_data = gnuk.cmd_get_data(0x00, 0xf9).tobytes() except: kdf_data = b"" if kdf_data == b"": print('KDF not set') # passwd_data = passwd.encode('UTF-8') else: algo, subalgo, iters, salt_user, salt_reset, salt_admin, \ hash_user, hash_admin = parse_kdf_data(kdf_data) if salt_admin: salt = salt_admin else: salt = salt_user d = { 'algo': algo, 'subalgo': subalgo, 'iters': iters, 'salt_user': binascii.b2a_hex(salt_user), 'salt_reset': binascii.b2a_hex(salt_reset), 'salt_admin': binascii.b2a_hex(salt_admin), 'hash_user': binascii.b2a_hex(hash_user), 'hash_admin': binascii.b2a_hex(hash_admin), } pprint(d, width=100) if passwd: try: passwd_data = kdf_calc(passwd, salt, iters) print(f'passwd_data: {binascii.b2a_hex(passwd_data)}') except ValueError as e: print(str(e)) else: print('Provide password to calculate final hash')
def main(wait_e, keyno, passwd, data_regnual, data_upgrade, skip_bootloader, verbosity=0): reg = None # @todo: this is constantly used: how about a consistent/generic solution? conn_retries = 3 for i in range(conn_retries): if reg is not None: break local_print(".", end="", flush=True) time.sleep(1) for dev in gnuk_devices_by_vidpid(): try: reg = regnual(dev) if dev.filename: local_print(f"Device: {dev.filename}") reg.set_logger(logger) break except Exception as e: if str(e) != "Wrong interface class": local_print(e) if reg is None and not skip_bootloader: local_print("", "Starting bootloader upload procedure") _l = len(data_regnual) if (_l & 0x03) != 0: data_regnual = data_regnual.ljust(_l + 4 - (_l & 0x03), chr(0)) crc32code = crc32(data_regnual) # @todo: use global verbosity if verbosity: local_print("CRC32: %04x\n" % crc32code) data_regnual += pack("<I", crc32code) rsa_key = rsa.read_key_from_list(rsa_key_data) rsa_raw_pubkey = rsa.get_raw_pubkey(rsa_key) gnuk = get_gnuk_device(logger=logger) gnuk.cmd_select_openpgp() local_print("Connected to the device") # Compute passwd data try: kdf_data = gnuk.cmd_get_data(0x00, 0xF9).tobytes() except Exception as e: local_print("Note: KDF DO not found", e) kdf_data = b"" if kdf_data == b"": passwd_data = passwd.encode("UTF-8") else: ( algo, subalgo, iters, salt_user, salt_reset, salt_admin, hash_user, hash_admin, ) = parse_kdf_data(kdf_data) salt = salt_admin if salt_admin else salt_user passwd_data = kdf_calc(passwd, salt, iters) # And authenticate with the passwd data gnuk.cmd_verify(BY_ADMIN, passwd_data) gnuk.cmd_write_binary(1 + keyno, rsa_raw_pubkey, False) gnuk.cmd_select_openpgp() challenge = gnuk.cmd_get_challenge().tobytes() digestinfo = binascii.unhexlify(SHA256_OID_PREFIX) + challenge signed = rsa.compute_signature(rsa_key, digestinfo) signed_bytes = rsa.integer_to_bytes_256(signed) gnuk.cmd_external_authenticate(keyno, signed_bytes) gnuk.stop_gnuk() mem_info = gnuk.mem_info() # @todo: use global verbosity if verbosity: local_print("%08x:%08x" % mem_info) local_print( "Running update!", "Do NOT remove the device from the USB slot, until further notice", "Downloading flash upgrade program...", ) gnuk.download( mem_info[0], data_regnual, progress_func=progress_func, verbose=verbosity == 2, ) local_print("Executing flash upgrade...") for i in range(conn_retries): time.sleep(1.5 * (i + 1)) try: gnuk.execute(mem_info[0] + len(data_regnual) - 4) break except Exception as e: local_print(f"failed - trying again - retry: {i+1}", e) if i == conn_retries - 1: raise e continue time.sleep(3) gnuk.reset_device() del gnuk gnuk = None if reg is None: local_print("Waiting for device to appear:") local_print(f" Wait {wait_e} second{'s' if wait_e > 1 else ''}...", end="") for i in range(wait_e): if reg is not None: break local_print(".", end="", flush=True) time.sleep(1) for dev in gnuk_devices_by_vidpid(): try: reg = regnual(dev) if dev.filename: local_print("Device: {dev.filename}") break except Exception as e: local_print(f"failed - trying again - retry: {i+1}", e) # @todo: log exception to file: e local_print("", "") if reg is None: # @todo: replace with proper Exception raise RuntimeWarning("device not found - exiting") # Then, send upgrade program... mem_info = reg.mem_info() # @todo: use global verbosity if verbosity: local_print("%08x:%08x" % mem_info) local_print("Downloading the program") reg.download(mem_info[0], data_upgrade, progress_func=progress_func, verbose=verbosity == 2) local_print("Protecting device") reg.protect() local_print("Finish flashing") reg.finish() local_print("Resetting device") reg.reset_device() local_print( "Update procedure finished. Device could be removed from USB slot.", "") return 0