#!/bin/sh # abuild-keygen - generate signing keys # Copyright (c) 2009 Natanael Copa # # Distributed under GPL-2.0-only # program_version=@VERSION@ sharedir=${ABUILD_SHAREDIR:-@sharedir@} SUDO="${SUDO-$(command -v doas || command -v sudo || echo doas)}" if ! [ -f "$sharedir/functions.sh" ]; then echo "$sharedir/functions.sh: not found" >&2 exit 1 fi . "$sharedir/functions.sh" set -e # ask for privkey unless non-interactive mode # returns value in global $privkey get_privkey_file() { local emailaddr default_name emailaddr=${PACKAGER##*<} emailaddr=${emailaddr%%>*} # if PACKAGER does not contain a valid email address, then ask git if [ -z "$emailaddr" ] || [ "${emailaddr##*@}" = "$emailaddr" ]; then emailaddr=$(${GIT:-git} config --get user.email 2>/dev/null || true) fi default_name="${emailaddr:-$USER}-$(printf "%x" $(date +%s))" privkey="$ABUILD_USERDIR/$default_name.rsa" if [ -z "$interactive" ]; then return 0 fi msg "Generating public/private rsa key pair for abuild" echo -n "Enter file in which to save the key [$privkey]: " read line if [ -n "$line" ]; then privkey="$line" fi } do_keygen() { mkdir -p "$ABUILD_USERDIR" get_privkey_file pubkey="$privkey.pub" # generate the private key in a subshell with stricter umask ( umask 0007 openssl genrsa -out "$privkey" "$numbits" ) openssl rsa -in "$privkey" -pubout -out "$pubkey" if [ -n "$install_pubkey" ]; then msg "Installing $pubkey to /etc/apk/keys..." $SUDO mkdir -p "${abuild_keygen_install_root}"/etc/apk/keys $SUDO cp ${interactive:+-i} "$pubkey" "${abuild_keygen_install_root}"/etc/apk/keys/ else msg "" msg "You'll need to install $pubkey into " msg "/etc/apk/keys to be able to install packages and repositories signed with" msg "$privkey" fi if [ -n "$append_config" ]; then if [ -f "$ABUILD_USERCONF" ]; then # comment out the existing values sed -i -e 's/^PACKAGER_PRIVKEY=/\#&/' "$ABUILD_USERCONF" fi echo "PACKAGER_PRIVKEY=\"$privkey\"" >> "$ABUILD_USERCONF" else msg "" msg "You might want add following line to $ABUILD_USERCONF:" msg "" msg "PACKAGER_PRIVKEY=\"$privkey\"" msg "" fi msg "" msg "Please remember to make a safe backup of your private key:" msg "$privkey" msg "" } do_kernel_key() { mkdir -p "$ABUILD_USERDIR" pem="$ABUILD_USERDIR"/kernel_signing_key.pem ( umask 0007 # https://www.kernel.org/doc/html/v6.1/admin-guide/module-signing.html#generating-signing-keys openssl req -verbose -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \ -outform PEM -out "$pem" \ -keyout "$pem" -config - <<-EOF [ req ] default_bits = 4096 distinguished_name = req_distinguished_name prompt = no string_mask = utf8only x509_extensions = myexts [ req_distinguished_name ] O = alpinelinux.org CN = Alpine Linux kernel key #emailAddress = unspecified.user@unspecified.company [ myexts ] basicConstraints=critical,CA:FALSE keyUsage=digitalSignature subjectKeyIdentifier=hash authorityKeyIdentifier=keyid EOF ) msg "Kernel signing key was created: $pem" if ! grep -q "^KERNEL_SIGNING_KEY=" "$ABUILD_USERCONF" 2>/dev/null; then echo "KERNEL_SIGNING_KEY='$pem'" >> "$ABUILD_USERCONF" fi msg "KERNEL_SIGNING_KEY='$pem' was added to $ABUILD_USERCONF" } usage() { cat <<-__EOF__ $program $program_version - generate signing keys Usage: $program [-a|--append] [-i|--install] [-n] Options: -a, --append Set PACKAGER_PRIVKEY= in $ABUILD_USERCONF -i, --install Install public key into /etc/apk/keys using doas -n Non-interactive. Use defaults --kernel Generate a key for kernel modules -b, --numbits [BITS] The size of the private key to generate in bits. -q, --quiet -h, --help Show this help The SUDO variable can be set to pick which tool can be used to elevate privileges, if it is not set it defaults to doas or sudo if doas is not found. __EOF__ } append_config= install_pubkey= interactive=1 numbits=4096 quiet= kernel_key= args=$(getopt -o ab:inqh --long append,numbits:,install,quiet,help,kernel -n "$program" -- "$@") if [ $? -ne 0 ]; then usage exit 2 fi eval set -- "$args" while true; do case $1 in -a|--append) append_config=1;; -i|--install) install_pubkey=1;; --kernel) kernel_key=1;; -n) unset interactive ;; -b|--numbits) numbits="$2"; shift 1;; -q|--quiet) quiet=1;; # suppresses msg -h|--help) usage; exit;; --) shift; break;; *) usage >&2; exit 1;; # getopt error esac shift done if [ $# -ne 0 ]; then usage >&2 exit 2 fi if [ -n "$kernel_key" ]; then do_kernel_key exit fi do_keygen