From e87d413948b328251f8497f9eeb692c9023f2437 Mon Sep 17 00:00:00 2001 From: Shohei KAMON Date: Tue, 29 Apr 2025 17:30:54 +0800 Subject: [PATCH 1/3] update configure gen-keys Signed-off-by: Shohei KAMON --- fireblocks_cli/commands/configure.py | 34 ++++++++++++++++++++++------ fireblocks_cli/crypto.py | 23 +++++++++++++++---- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/fireblocks_cli/commands/configure.py b/fireblocks_cli/commands/configure.py index 80c1262..36bf509 100644 --- a/fireblocks_cli/commands/configure.py +++ b/fireblocks_cli/commands/configure.py @@ -65,16 +65,36 @@ def init(): @configure_app.command("gen-keys") -def gen_keys(): - """秘密鍵とCSRを api_key_dir に生成します""" - org = typer.prompt("🔐 組織名を入力してください(例: MyCompany)").strip() +def gen_keys( + org_name: str = typer.Option(None, help="Organization Name (CN/O)"), + key_type: str = typer.Option( + None, "--key-type", help="Key type: rsa:2048, rsa:4096, ed25519" + ), +): + """Generate a pair of secret key and the CSR key""" + org = typer.prompt("🔐 Organization Name:").strip() if not org: - typer.secho("❌ 組織名は必須です。処理を中止します。", fg=typer.colors.RED) + typer.secho("❌ Organisztion Name is required.", fg=typer.colors.RED) raise typer.Exit(code=1) + if not key_type: + typer.echo("Select Key Type:") + typer.echo("[1] rsa:2048") + typer.echo("[2] rsa:4096 (default)") + typer.echo("[3] ed25519") + choice = typer.prompt("Enter number (or 'y' for default)").strip().lower() + if choice in ("", "y", "2"): + key_type = "rsa:4096" + elif choice == "1": + key_type = "rsa:2048" + elif choice == "3": + key_type = "ed25519" + else: + typer.secho("❌ Invalid choice.", fg=typer.colors.RED) + raise typer.Exit(code=1) - key_path, csr_path = generate_key_and_csr(org) - typer.secho(f"✅ 秘密鍵: {key_path}", fg=typer.colors.GREEN) - typer.secho(f"✅ CSR : {csr_path}", fg=typer.colors.GREEN) + key_path, csr_path = generate_key_and_csr(org_name, key_type) + typer.secho(f"✅ Private Key: {key_path}", fg=typer.colors.GREEN) + typer.secho(f"✅ CSR Key: {csr_path}", fg=typer.colors.GREEN) @configure_app.command("validate") diff --git a/fireblocks_cli/crypto.py b/fireblocks_cli/crypto.py index 470249f..3b30052 100644 --- a/fireblocks_cli/crypto.py +++ b/fireblocks_cli/crypto.py @@ -23,20 +23,33 @@ def generate_unique_basename(base_dir: Path) -> tuple[str, Path, Path]: return basename, key_path, csr_path -def generate_key_and_csr(org_name: str) -> tuple[Path, Path]: +def generate_key_and_csr( + org_name: str, key_type: str = "rsa:4096" +) -> tuple[Path, Path]: api_key_dir = get_api_key_dir() api_key_dir.mkdir(parents=True, exist_ok=True) basename, key_path, csr_path = generate_unique_basename(api_key_dir) subj = f"/O={org_name}" + # key_type: "rsa:2048", "rsa:4096", "ed25519" + if key_type.startswith("rsa:"): + bits = key_type.split(":")[1] + key_alg = "rsa" + key_args = ["-newkey", f"rsa:{bits}"] + elif key_type == "ed25519": + key_alg = "ed25519" + key_args = ["-newkey", "ed25519"] + else: + typer.secho(f"❌ Unsupported key type: {key_type}", fg=typer.colors.RED) + raise typer.Exit(code=1) + result = subprocess.run( [ "openssl", "req", "-new", - "-newkey", - "ed25519", + *key_args, "-nodes", "-keyout", str(key_path), @@ -51,10 +64,10 @@ def generate_key_and_csr(org_name: str) -> tuple[Path, Path]: ) if result.returncode != 0: - typer.secho("❌ OpenSSLエラー:", fg=typer.colors.RED) + typer.secho("❌ OpenSSL error:", fg=typer.colors.RED) typer.echo(result.stderr) raise typer.Exit(code=1) + key_path.chmod(0o600) csr_path.chmod(0o600) - return key_path, csr_path From 97c4db523fb44546d52436571ac66548a817de08 Mon Sep 17 00:00:00 2001 From: Shohei KAMON Date: Tue, 29 Apr 2025 17:39:03 +0800 Subject: [PATCH 2/3] fix: disable unexpected blank line insert Signed-off-by: Shohei KAMON --- scripts/sync_init_with_pyproject.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/sync_init_with_pyproject.py b/scripts/sync_init_with_pyproject.py index 28db3b5..6ecb7cc 100644 --- a/scripts/sync_init_with_pyproject.py +++ b/scripts/sync_init_with_pyproject.py @@ -50,7 +50,6 @@ def update_version( # 6. ファイルを書き直す with open(init_path, "w") as f: f.writelines(header) - f.write("\n") f.write(f'__version__ = "{pyproject_version}"\n') print(f"Updated {init_path}: {current_version} → {pyproject_version}") From 40b5a64951a422a282f7b746f50d55df3f88dfd6 Mon Sep 17 00:00:00 2001 From: Shohei KAMON Date: Tue, 29 Apr 2025 17:58:23 +0800 Subject: [PATCH 3/3] Update fireblocks-cli v0.1.10 Signed-off-by: Shohei KAMON --- .pre-commit-config.yaml | 2 +- fireblocks_cli/__init__.py | 2 +- pyproject.toml | 2 +- scripts/sync_init_with_pyproject.py | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0847841..cf2f7ad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: hooks: - id: update-__init__.py name: Sync __init__.py with pyproject.toml - entry: python ./scripts/sync_init_with_pyproject.py + entry: poetry run python ./scripts/sync_init_with_pyproject.py language: python files: pyproject.toml - repo: local diff --git a/fireblocks_cli/__init__.py b/fireblocks_cli/__init__.py index c4046af..ebc1de9 100644 --- a/fireblocks_cli/__init__.py +++ b/fireblocks_cli/__init__.py @@ -5,4 +5,4 @@ # Author: Shohei KAMON -__version__ = "0.1.9" +__version__ = "0.1.10" diff --git a/pyproject.toml b/pyproject.toml index ed321db..ef28247 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ [project] name = "fireblocks-cli" -version = "0.1.9" +version = "0.1.10" description = "An unofficial CLI for managing Fireblocks services." authors = [{ name = "Kamon Shohei", email = "cameong@stir.network" }] readme = "README.md" diff --git a/scripts/sync_init_with_pyproject.py b/scripts/sync_init_with_pyproject.py index 6ecb7cc..59e7d8b 100644 --- a/scripts/sync_init_with_pyproject.py +++ b/scripts/sync_init_with_pyproject.py @@ -5,8 +5,9 @@ # SPDX-License-Identifier: MPL-2.0 # Author: Shohei KAMON -import toml import re +import sys +import tomllib as toml def update_version( @@ -16,7 +17,7 @@ def update_version( """pyproject.tomlのversionと__init__.pyのversionを同期する""" # 1. pyproject.toml を読み込む - with open(pyproject_path, "r") as f: + with open(pyproject_path, "rb") as f: pyproject = toml.load(f) pyproject_version = pyproject["project"]["version"] @@ -37,7 +38,7 @@ def update_version( print( f"No update needed: {init_path} version {current_version} matches pyproject.toml version {pyproject_version}" ) - return + return False # 5. SPDXヘッダーのみ残して、後続を書き直す header = [] @@ -56,4 +57,5 @@ def update_version( if __name__ == "__main__": - update_version() + changed = update_version() + sys.exit(1 if changed else 0)