You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
5.2 KiB
152 lines
5.2 KiB
#!/bin/bash
|
|
#
|
|
# kmodgenca - Helper script to create CA/Keypair to sign modules.
|
|
# Copyright (c) 2017 Stanislas Leduc <stanislas.leduc@balinor.net>
|
|
# Copyright (c) 2018-2019 Nicolas Viéville <nicolas.vieville@uphf.fr>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining
|
|
# a copy of this software and associated documentation files (the
|
|
# "Software"), to deal in the Software without restriction, including
|
|
# without limitation the rights to use, copy, modify, merge, publish,
|
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
# permit persons to whom the Software is furnished to do so, subject to
|
|
# the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be
|
|
# included in all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#
|
|
MYPROG="kmodgenca"
|
|
MYVER="0.5.7"
|
|
FORCE_BUILD=0
|
|
AUTOMATIC_BUILD=0
|
|
AUTOMATIC_BUILD_OPTION=""
|
|
|
|
myprog_help ()
|
|
{
|
|
echo "Build CA/Keypair to sign modules"
|
|
echo $'\n'"Usage: ${MYPROG} [OPTIONS]"
|
|
echo $'\n'"Options:"
|
|
echo " -a, --auto -- generate default values for cacert.config file without prompt"
|
|
echo " -f, --force -- build CA/Keypair even if there is already ones"
|
|
echo " -h, --help -- print usage"
|
|
echo " -V, --version -- show version"
|
|
}
|
|
|
|
|
|
# Parse command line options.
|
|
#
|
|
while [ "${1}" ] ; do
|
|
case "${1}" in
|
|
-a|--auto)
|
|
AUTOMATIC_BUILD=1
|
|
shift
|
|
;;
|
|
-f|--force)
|
|
FORCE_BUILD=1
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
myprog_help
|
|
exit 0
|
|
;;
|
|
-V|--version)
|
|
echo "${MYPROG} ${MYVER}"
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Error: Unknown option '${1}'." >&2
|
|
myprog_help >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Exit early if cert and private key already exist and if FORCE_BUILD
|
|
# is not equal to 1.
|
|
#
|
|
if $(readlink -e /etc/pki/akmods/certs/public_key.der &>/dev/null) && \
|
|
$(readlink -e /etc/pki/akmods/private/private_key.priv &>/dev/null) && \
|
|
[ ${FORCE_BUILD} -eq 0 ] ; then
|
|
exit 0
|
|
fi
|
|
|
|
CACERT_CONFIG="/etc/pki/akmods/cacert.config"
|
|
KEYNAME="$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')"
|
|
|
|
# Create cacert.config file with local values if AUTOMATIC_BUILD is set
|
|
# or ask for values manually.
|
|
#
|
|
echo "Update cacert.config..."
|
|
if [ ${AUTOMATIC_BUILD} -eq 1 ] ; then
|
|
# Set OpenSSL fields values, comment default values and min/max ones.
|
|
sed -e "s#\(0.organizationName *= \).*#\1$(hostname)#" \
|
|
-e "s#\(organizationalUnitName *= \).*#\1$(hostname)#" \
|
|
-e "s#\(emailAddress *= \).*#\1akmods@$(hostname)#" \
|
|
-e "s#\(localityName *= \).*#\1None#" \
|
|
-e "s#\(stateOrProvinceName *= \).*#\1None#" \
|
|
-e "s#\(countryName *= \).*#\1$(locale country_ab2)#" \
|
|
-e "s#\(commonName *= \).*#\1$(hostname)"-"$(od -vAn -N4 -tu4 < /dev/urandom | awk '{print $1}')#" \
|
|
-e "s/^[^#]*_default *= /#&/" \
|
|
-e "s/^[^#]*_min/#&/" \
|
|
-e "s/^[^#]*_max/#&/" ${CACERT_CONFIG}.in > ${CACERT_CONFIG}
|
|
AUTOMATIC_BUILD_OPTION=" -batch"
|
|
else
|
|
# Activate prompt directive.
|
|
sed -e "s#\(prompt *= \).*#\1yes#" ${CACERT_CONFIG}.in > ${CACERT_CONFIG}
|
|
fi
|
|
KEY_SUFF="$(date "+%F_%T_%N")"
|
|
# If cert and private key files names already exists, do not overwrite
|
|
# them but save them.
|
|
#
|
|
if [[ -e /etc/pki/akmods/certs/${KEYNAME}.der ]] ; then
|
|
# If the cert has already been loaded in MOK, add "already_enrolled"
|
|
# to the suffix of the backup file.
|
|
# `mokutil --help` fails if EFI variables are not supported on the
|
|
# system. It is therefore impossible to test the presence of the key
|
|
# in MOK, and then do not add special suffix to the backup file.
|
|
#
|
|
if $(which mokutil &> /dev/null) && $(mokutil --help &> /dev/null) && $(mokutil --test-key /etc/pki/akmods/certs/${KEYNAME}.der &> /dev/null) ; then
|
|
KEY_SUFF="${KEY_SUFF}_already_enrolled"
|
|
fi
|
|
mv /etc/pki/akmods/certs/${KEYNAME}.der /etc/pki/akmods/certs/${KEYNAME}.der.${KEY_SUFF}.bak
|
|
if [[ -e /etc/pki/akmods/private/${KEYNAME}.priv ]] ; then
|
|
mv /etc/pki/akmods/private/${KEYNAME}.priv /etc/pki/akmods/private/${KEYNAME}.priv.${KEY_SUFF}.bak
|
|
fi
|
|
fi
|
|
|
|
echo "Generate new keypair..."
|
|
sg akmods -c "
|
|
umask 037
|
|
openssl req -x509 -new -nodes -utf8 -sha256 -days 3650${AUTOMATIC_BUILD_OPTION} \
|
|
-config ${CACERT_CONFIG} -outform DER \
|
|
-out /etc/pki/akmods/certs/${KEYNAME}.der \
|
|
-keyout /etc/pki/akmods/private/${KEYNAME}.priv
|
|
"
|
|
|
|
# Ensure that akmods group can read keys.
|
|
#
|
|
chmod g+r /etc/pki/akmods/certs/${KEYNAME}.*
|
|
chmod g+r /etc/pki/akmods/private/${KEYNAME}.*
|
|
|
|
# Sanitize permissions.
|
|
#
|
|
if [[ -x /usr/sbin/restorecon ]] ; then
|
|
/usr/sbin/restorecon /etc/pki/akmods/certs/${KEYNAME}.der
|
|
/usr/sbin/restorecon /etc/pki/akmods/private/${KEYNAME}.priv
|
|
fi
|
|
|
|
# Update symlink to use new keypair.
|
|
#
|
|
ln -nsf /etc/pki/akmods/certs/${KEYNAME}.der /etc/pki/akmods/certs/public_key.der
|
|
ln -nsf /etc/pki/akmods/private/${KEYNAME}.priv /etc/pki/akmods/private/private_key.priv
|
|
|
|
exit 0
|