From e79859b0a091c9d9254c4f1596bde0e47a3805c0 Mon Sep 17 00:00:00 2001 From: InsanePrawn Date: Mon, 1 Apr 2024 21:46:22 +0200 Subject: [PATCH] distro/gpg: add helpers for generating secret keys --- distro/gpg.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 distro/gpg.py diff --git a/distro/gpg.py b/distro/gpg.py new file mode 100644 index 0000000..4fe15df --- /dev/null +++ b/distro/gpg.py @@ -0,0 +1,50 @@ +import logging +import os + +from exec.cmd import run_cmd +from exec.file import get_temp_dir, makedir, write_file + +GPG_ARGS = ["--batch", "--no-tty"] + + +def get_gpg_creation_script( + key_name: str = "Kupfer Local Signing", + email: str = "local@kupfer.mobi", + comment: str = "Generated by kupferbootstrap", +): + return f""" +%echo Generating a new ed25519 GPG key for "{key_name} <{email}> # {comment}" + +%no-protection + +Key-Type: eddsa +Key-Curve: Ed25519 +Key-Usage: cert,sign +Subkey-Type: ecdh +Subkey-Curve: Curve25519 +Subkey-Usage: encrypt + +Name-Real: {key_name} +Name-Comment: {comment} +Name-Email: {email} +Expire-Date: 0 +# Do a commit here, so that we can later print "done" +%commit +%echo done +""" + + +def create_secret_key(location: str, *, gpg_binary: str = "gpg", **creation_args): + makedir(os.path.dirname(location)) + temp_dir = get_temp_dir() + script_file = os.path.join(temp_dir, "__gpg_creation_script") + write_file(script_file, content=get_gpg_creation_script(**creation_args)) + logging.info(f"Creating new GPG key for {location!r}") + run_cmd([gpg_binary, *GPG_ARGS, "--homedir", temp_dir, "--generate-key", script_file]).check_returncode() + res = run_cmd( + [gpg_binary, *GPG_ARGS, "--homedir", temp_dir, "--armor", "--export-secret-keys"], capture_output=True + ) + if not (res.stdout and res.stdout.strip()): + raise Exception(f"Failed to get secret GPG key from stdout: {res.stdout=}\n{res.stderr=}") + logging.debug(f"Writing GPG private key to {location}") + write_file(location, content=res.stdout, mode="600")