parchbootstrap/distro/gpg.py

50 lines
1.5 KiB
Python

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")