def test_save_key_file(): # If the params are of the right type, the key is saved no matter if the dir exists or not. key_name = "test_key" key_dir = "test_key_dir" assert not os.path.exists(key_dir) assert not os.path.exists(os.path.join(key_dir, key_name)) Cryptographer.save_key_file(bytes(33), key_name, key_dir) assert os.path.exists(key_dir) assert os.path.exists(os.path.join(key_dir, key_name + ".der")) rmtree(key_dir)
def main(config): setup_data_folder(config.get("DATA_DIR")) logging_server_ready = multiprocessing.Event() stop_logging_server = multiprocessing.Event() logging_port = multiprocessing.Value("i") logging_process = multiprocessing.Process( target=serve_logging, daemon=True, args=(config.get("LOG_FILE"), logging_port, config.get("DAEMON"), logging_server_ready, stop_logging_server), ) logging_process.start() logging_server_ready.wait() setup_logging(logging_port.value) logger = get_logger(component="Daemon") if not os.path.exists( config.get("TEOS_SECRET_KEY")) or config.get("OVERWRITE_KEY"): logger.info("Generating a new key pair") sk = Cryptographer.generate_key() Cryptographer.save_key_file(sk.to_der(), "teos_sk", config.get("DATA_DIR")) else: logger.info("Tower identity found. Loading keys") secret_key_der = Cryptographer.load_key_file( config.get("TEOS_SECRET_KEY")) if not secret_key_der: raise IOError("TEOS private key cannot be loaded") sk = Cryptographer.load_private_key_der(secret_key_der) # Windows cannot run gunicorn if os.name == "nt" and config.get("WSGI") == "gunicorn": logger.warning( "Windows cannot run gunicorn as WSGI. Changing to waitress") config["WSGI"] = "waitress" try: TeosDaemon(config, sk, logger, logging_port.value, stop_logging_server, logging_process).start() except Exception as e: logger.error("An error occurred: {}. Shutting down".format(e)) stop_logging_server.set() logging_process.join() exit(1)
def run_teosd(): sk_file_path = os.path.join(config.get("DATA_DIR"), "teos_sk.der") if not os.path.exists(sk_file_path): # Generating teos sk so we can return the teos_id teos_sk = Cryptographer.generate_key() Cryptographer.save_key_file(teos_sk.to_der(), "teos_sk", config.get("DATA_DIR")) else: teos_sk = Cryptographer.load_private_key_der(Cryptographer.load_key_file(sk_file_path)) teos_id = Cryptographer.get_compressed_pk(teos_sk.public_key) # Change the default WSGI for Windows if os.name == "nt": config["WSGI"] = "waitress" teosd_process = Process(target=main, kwargs={"config": config}) teosd_process.start() # Give it some time to bootstrap # TODO: we should do better synchronization using an Event sleep(3) return teosd_process, teos_id
def test_save_key_file_wrong_params(): # Function fails if the args are not of the proper type no_str_nor_byte = [None, 1, 1.5, object, {}, Exception()] for wrong_val in no_str_nor_byte: with pytest.raises(InvalidParameter, match="Key must be bytes"): Cryptographer.save_key_file(wrong_val, "name", "dir") for wrong_val in no_str_nor_byte: with pytest.raises(InvalidParameter, match="Key name must be str"): Cryptographer.save_key_file(bytes(33), wrong_val, "dir") for wrong_val in no_str_nor_byte: with pytest.raises(InvalidParameter, match="Data dir must be str"): Cryptographer.save_key_file(bytes(33), "name", wrong_val)
def main(command, args, config): setup_data_folder(config.get("DATA_DIR")) # Set the teos url teos_url = "{}:{}".format(config.get("API_CONNECT"), config.get("API_PORT")) # If an http or https prefix if found, leaves the server as is. Otherwise defaults to http. if not teos_url.startswith("http"): teos_url = "http://" + teos_url try: if os.path.exists(config.get("USER_PRIVATE_KEY")): logger.debug("Client id found. Loading keys") user_sk, user_id = load_keys(config.get("USER_PRIVATE_KEY")) else: logger.info("Client id not found. Generating new keys") user_sk = Cryptographer.generate_key() Cryptographer.save_key_file(user_sk.to_der(), "user_sk", config.get("DATA_DIR")) user_id = Cryptographer.get_compressed_pk(user_sk.public_key) if command == "register": if not args: raise InvalidParameter( "Cannot register. No tower id was given") else: teos_id = args.pop(0) if not is_compressed_pk(teos_id): raise InvalidParameter( "Cannot register. Tower id has invalid format") available_slots, subscription_expiry = register( user_id, teos_id, teos_url) logger.info( "Registration succeeded. Available slots: {}".format( available_slots)) logger.info("Subscription expires at block {}".format( subscription_expiry)) teos_id_file = os.path.join(config.get("DATA_DIR"), "teos_pk") Cryptographer.save_key_file(bytes.fromhex(teos_id), teos_id_file, config.get("DATA_DIR")) if command == "add_appointment": teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY")) appointment_data = parse_add_appointment_args(args) appointment = create_appointment(appointment_data) start_block, signature = add_appointment(appointment, user_sk, teos_id, teos_url) save_appointment_receipt(appointment.to_dict(), start_block, signature, config.get("APPOINTMENTS_FOLDER_NAME")) elif command == "get_appointment": if not args: logger.error("No arguments were given") else: arg_opt = args.pop(0) if arg_opt in ["-h", "--help"]: sys.exit(help_get_appointment()) teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY")) appointment_data = get_appointment(arg_opt, user_sk, teos_id, teos_url) if appointment_data: logger.info(json.dumps(appointment_data, indent=4)) elif command == "get_subscription_info": if args: arg_opt = args.pop(0) if arg_opt in ["-h", "--help"]: sys.exit(help_get_subscription_info()) teos_id = load_teos_id(config.get("TEOS_PUBLIC_KEY")) subscription_info = get_subscription_info(user_sk, teos_id, teos_url) if subscription_info: logger.info(json.dumps(subscription_info, indent=4)) elif command == "help": if args: command = args.pop(0) if command == "register": sys.exit(help_register()) if command == "add_appointment": sys.exit(help_add_appointment()) if command == "get_subscription_info": sys.exit(help_get_subscription_info()) elif command == "get_appointment": sys.exit(help_get_appointment()) else: logger.error( "Unknown command. Use help to check the list of available commands" ) else: sys.exit(show_usage()) except ( FileNotFoundError, IOError, ConnectionError, ValueError, BasicException, ) as e: logger.error(str(e)) except Exception as e: logger.error("Unknown error occurred", error=str(e))