From 8e4c7c159418b399a91a69e2ecefbc418b5c13b4 Mon Sep 17 00:00:00 2001 From: "Kieran R. Prasch" Date: Mon, 12 Jul 2021 16:13:19 -0700 Subject: [PATCH] Renames secret_key -> key_material for CLI BYOK. --- nucypher/cli/commands/ursula.py | 10 +++++----- nucypher/config/base.py | 18 ++++++++++-------- nucypher/crypto/keystore.py | 4 ++-- tests/unit/crypto/test_keystore.py | 4 ++-- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/nucypher/cli/commands/ursula.py b/nucypher/cli/commands/ursula.py index 715d9a277..26870f3a7 100644 --- a/nucypher/cli/commands/ursula.py +++ b/nucypher/cli/commands/ursula.py @@ -161,7 +161,7 @@ class UrsulaConfigOptions: # TODO: Exit codes (not only for this, but for other exceptions) return click.get_current_context().exit(1) - def generate_config(self, emitter, config_root, force, secret_key): + def generate_config(self, emitter, config_root, force, key_material): if self.dev: raise RuntimeError('Persistent configurations cannot be created in development mode.') @@ -180,7 +180,7 @@ class UrsulaConfigOptions: self.rest_host = collect_worker_ip_address(emitter, network=self.domain, force=force) return UrsulaConfiguration.generate(password=get_nucypher_password(emitter=emitter, confirm=True), - secret_key=bytes.fromhex(secret_key), + key_material=bytes.fromhex(key_material) if key_material else None, config_root=config_root, rest_host=self.rest_host, rest_port=self.rest_port, @@ -296,8 +296,8 @@ def ursula(): @option_force @option_config_root @group_general_config -@click.option('--secret-key', help="An custom pre-secured secret hex blob to use for key derivations", type=click.STRING) -def init(general_config, config_options, force, config_root, secret_key): +@click.option('--key-material', help="An custom pre-secured secret hex blob to use for key derivations", type=click.STRING) +def init(general_config, config_options, force, config_root, key_material): """Create a new Ursula node configuration.""" emitter = setup_emitter(general_config, config_options.worker_address) _pre_launch_warnings(emitter, dev=None, force=force) @@ -307,7 +307,7 @@ def init(general_config, config_options, force, config_root, secret_key): raise click.BadOptionUsage('--provider', message="--provider is required to initialize a new ursula.") if not config_options.federated_only and not config_options.domain: config_options.domain = select_network(emitter) - ursula_config = config_options.generate_config(emitter, config_root, force, secret_key) + ursula_config = config_options.generate_config(emitter, config_root, force, key_material) filepath = ursula_config.to_configuration_file() paint_new_installation_help(emitter, new_configuration=ursula_config, filepath=filepath) diff --git a/nucypher/config/base.py b/nucypher/config/base.py index 6180e362f..0b14dfe37 100644 --- a/nucypher/config/base.py +++ b/nucypher/config/base.py @@ -579,10 +579,10 @@ class CharacterConfiguration(BaseConfiguration): return super().update(filepath=self.config_file_location, **kwargs) @classmethod - def generate(cls, password: str, secret_key: bytes, *args, **kwargs): + def generate(cls, password: str, key_material: Optional[bytes] = None, *args, **kwargs): """Shortcut: Hook-up a new initial installation and configuration.""" node_config = cls(dev_mode=False, *args, **kwargs) - node_config.initialize(secret_key=secret_key, password=password) + node_config.initialize(key_material=key_material, password=password) return node_config def cleanup(self) -> None: @@ -769,7 +769,7 @@ class CharacterConfiguration(BaseConfiguration): power_ups.append(power_up) return power_ups - def initialize(self, password: str, secret_key: Optional[bytes] = None) -> Path: + def initialize(self, password: str, key_material: Optional[bytes] = None) -> str: """Initialize a new configuration and write installation files to disk.""" # Development @@ -780,7 +780,9 @@ class CharacterConfiguration(BaseConfiguration): # Persistent else: self._ensure_config_root_exists() - self.write_keystore(secret_key=secret_key, password=password, interactive=self.MNEMONIC_KEYSTORE) + self.write_keystore(key_material=key_material, + password=password, + interactive=self.MNEMONIC_KEYSTORE) self._cache_runtime_filepaths() self.node_storage.initialize() @@ -792,11 +794,11 @@ class CharacterConfiguration(BaseConfiguration): # Success message = "Created nucypher installation files at {}".format(self.config_root) self.log.debug(message) - return self.config_root + return Path(self.config_root) - def write_keystore(self, password: str, secret_key: Optional[bytes] = None, interactive: bool = True) -> Keystore: - if secret_key: - self.__keystore = Keystore.import_secure(secret=secret_key, + def write_keystore(self, password: str, key_material: Optional[bytes] = None, interactive: bool = True) -> Keystore: + if key_material: + self.__keystore = Keystore.import_secure(key_material=key_material, password=password, keystore_dir=self.keystore_dir) else: diff --git a/nucypher/crypto/keystore.py b/nucypher/crypto/keystore.py index f68f425ac..e3f78e9c7 100644 --- a/nucypher/crypto/keystore.py +++ b/nucypher/crypto/keystore.py @@ -321,13 +321,13 @@ class Keystore: return instance @classmethod - def import_secure(cls, secret: bytes, password: str, keystore_dir: Optional[Path] = None) -> 'Keystore': + def import_secure(cls, key_material: bytes, password: str, keystore_dir: Optional[Path] = None) -> 'Keystore': """ Generate a Keystore using a a custom pre-secured entropy blob. This method of keystore creation does not generate a mnemonic phrase - it is assumed that the provided blob is recoverable and secure. """ - path = Keystore.__save(secret=secret, password=password, keystore_dir=keystore_dir) + path = Keystore.__save(secret=key_material, password=password, keystore_dir=keystore_dir) keystore = cls(keystore_path=path) return keystore diff --git a/tests/unit/crypto/test_keystore.py b/tests/unit/crypto/test_keystore.py index 698094d79..ec9483b9a 100644 --- a/tests/unit/crypto/test_keystore.py +++ b/tests/unit/crypto/test_keystore.py @@ -246,13 +246,13 @@ def test_import_custom_keystore(tmpdir): # Too short - 32 bytes is required custom_secret = b'tooshort' with pytest.raises(ValueError, match="Entropy must be at least 32 bytes."): - _keystore = Keystore.import_secure(secret=custom_secret, + _keystore = Keystore.import_secure(key_material=custom_secret, password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir) # Import private key custom_secret = os.urandom(32) # not secure but works - keystore = Keystore.import_secure(secret=custom_secret, + keystore = Keystore.import_secure(key_material=custom_secret, password=INSECURE_DEVELOPMENT_PASSWORD, keystore_dir=tmpdir) keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)