rafeOS/signing-keys/genkeys.sh
2024-03-12 15:11:00 +01:00

109 lines
3.6 KiB
Bash
Executable file

#!/bin/sh
# Automates the generation of keys in the context of Secure Boot.
# The script utilizes the elliptic curve algorithm with the NIST
# P-384 curve (prime384v1) for key generation.
#
# UEFI Specification: https://uefi.org/specs/UEFI/2.10/32_Secure_Boot_and_Driver_Signing.html#firmware-os-crypto-algorithm-exchange
#
# Tip: View certificate content with "openssl x509 -noout -text -in *secureboot.crt"
set -eu
IMAGE_ID="rafeOS"
generate_key_pair() {
# Parameters
FILENAME_PREFIX="$1"
SUBJECT="$2"
KEY_ALG="$3"
# Check if parameters are provided
if [ -z "$FILENAME_PREFIX" ] || [ -z "$SUBJECT" ] || [ -z "$KEY_ALG" ]; then
echo "Usage: generate_key_pair <filename_prefix> <subject> <rsa|ec>"
exit 2
fi
# Default filenames
PRIVATE_KEY_FILE="${IMAGE_ID}.${FILENAME_PREFIX}.key"
CERTIFICATE_FILE="${IMAGE_ID}.${FILENAME_PREFIX}.crt"
# Period of validity (in days) for the created certificate.
# Defaults to 3650, i.e. 10 years.
CERT_VALIDITY_DAYS=3650
# Check if both private key and certificate files exist
if [ -e "$PRIVATE_KEY_FILE" ] && [ -e "$CERTIFICATE_FILE" ]; then
echo "$FILENAME_PREFIX: Both private key and certificate files exist."
elif [ -e "$PRIVATE_KEY_FILE" ]; then
# Only private key exists, generate certificate
openssl req -new -key "$PRIVATE_KEY_FILE" -out "$CERTIFICATE_FILE" \
-subj "$SUBJECT" -sha256 -days "$CERT_VALIDITY_DAYS"
echo "$FILENAME_PREFIX: Certificate generated for $PRIVATE_KEY_FILE."
# Set permissions for the new files
chmod 0400 "$PRIVATE_KEY_FILE" "$CERTIFICATE_FILE"
else
# Neither private key nor certificate exists, generate both
case "$KEY_ALG" in
"rsa")
# Legacy RSA 2048, i.e. for wide compatibility UEFI Secure Boot keys
openssl req -newkey rsa:2048 \
-noenc -keyout "$PRIVATE_KEY_FILE" \
-new -x509 -sha256 \
-days "$CERT_VALIDITY_DAYS" \
-subj "$SUBJECT" \
-out "$CERTIFICATE_FILE"
;;
"ec")
# Modern P-348 EC Key
openssl req -newkey ec \
-pkeyopt ec_paramgen_curve:P-384 -pkeyopt ec_param_enc:named_curve \
-noenc -keyout "$PRIVATE_KEY_FILE" \
-new -x509 -sha256 \
-days "$CERT_VALIDITY_DAYS" \
-subj "$SUBJECT" \
-out "$CERTIFICATE_FILE"
;;
*)
echo "Error: Invalid value for <secureboot|verity|all>."
exit 1
;;
esac
echo "$FILENAME_PREFIX: Private key and certificate generated with filenames: $PRIVATE_KEY_FILE, $CERTIFICATE_FILE."
# Set permissions for the new files
chmod 0400 "$PRIVATE_KEY_FILE" "$CERTIFICATE_FILE"
# Protect files from modifications
chattr +i "$PRIVATE_KEY_FILE" "$CERTIFICATE_FILE"
fi
}
generate_secureboot_keys() {
generate_key_pair "secure-boot" "/CN=$IMAGE_ID UEFI CA $(date +%Y)" "rsa"
}
generate_verity_keys() {
generate_key_pair "verity" "/CN=$IMAGE_ID Verity CA $(date +%Y)" "ec"
}
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <secureboot|verity|all>"
exit 1
fi
case "$1" in
"secureboot")
generate_secureboot_keys
;;
"verity")
generate_verity_keys
;;
"all")
generate_secureboot_keys
generate_verity_keys
;;
*)
echo "Error: Invalid value for <secureboot|verity|all>."
exit 1
;;
esac