109 lines
3.6 KiB
Bash
Executable file
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 |