187 lines
4.6 KiB
Bash
187 lines
4.6 KiB
Bash
#!/bin/sh
|
|
|
|
# abuild-keygen - generate signing keys
|
|
# Copyright (c) 2009 Natanael Copa <ncopa@alpinelinux.org>
|
|
#
|
|
# 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=<generated key> 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
|