50 lines
1.5 KiB
Python
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")
|