diff --git a/coreos-init-build-env b/coreos-init-build-env index f7dac82..fa54294 100755 --- a/coreos-init-build-env +++ b/coreos-init-build-env @@ -89,4 +89,8 @@ coreos-bblayers-envsub COREOS_EXTLAYERSDIR "${COREOS_ROOT}/external-layers" # Generate the ${BUILDDIR}/key directory. The scripts doesn't generate anything it # the directory already exist, so it's safe to call it everytime -coreos-keygen > /dev/null 2> /dev/null +# stdout is redirected to reduce the amount of output but not stderr +coreos-keygen > /dev/null || { + echo "The coreos-keygen script has failed" >&2 + return 1 +} \ No newline at end of file diff --git a/scripts/coreos-keygen b/scripts/coreos-keygen index b269e3f..e270634 100755 --- a/scripts/coreos-keygen +++ b/scripts/coreos-keygen @@ -1,53 +1,110 @@ #!/usr/bin/env bash +# This script will generate key needed by the UEFI secure boot implementation +# under $BUILDDIR/keys +# db.auth db.der db.key KEK.crt KEK.esl PK.auth PK.der PK.key +# db.crt db.esl KEK.auth KEK.der KEK.key PK.crt PK.esl + +# This script is used every time the build environment of CoreOS is sourced +# Note: in the build environment stdout is redirected to /dev/null but not +# stderr. + +set -e + +# Logging helper +RED='\033[0;31m' +GREEN='\033[0;32m' +BOLD='\033[1m' +RESET='\033[0m' + +# Ensure that BUILDDIR is defined +# ============================================================================== +# This is usually done inside the coreos-init-build-env script + + if [ -z "$BUILDDIR" ]; then - echo "BUILDDIR is not defined" + echo -e "${RED}BUILDDIR is not defined${RESET}" 2>&1 + echo -e "Have you run the coreos-init-buildenv script?" 2>&1 exit 1 fi +# We need the KEYDIR directory to exist +# ============================================================================== + KEYDIR="${BUILDDIR}/keys" - -if [ -d "${KEYDIR}" ]; then - echo "${KEYDIR} directory already is exist" - echo "Skipping generating keys" - exit 1 -fi - -mkdir "${KEYDIR}" +mkdir -p "${KEYDIR}" cd "${KEYDIR}" +# we need openssl, cert-to-efi-sig-list and sign-efi-sig-list +# ============================================================================== + +assert_command_in_path() { + if command -v "$1" >/dev/null 2>&1; then + echo -e "✓ Command ${GREEN}${1}${RESET} was found" + else + echo -e "✗ ${RED}Command ${BOLD}${1}${RESET}${RED} was not found in your path${RESET}" >&2 + echo -e "Please check the coreos-documentation for the list of required packages" >&2 + exit 1 + fi +} + +assert_command_in_path openssl +assert_command_in_path cert-to-efi-sig-list +assert_command_in_path sign-efi-sig-list + +# Generate all they keys, as needed +# ============================================================================== +# Only generate the file if it's missing and don't fail if the file already +# exist + +check_files_exist() { + for file in "$@"; do + echo -e "✓ File ${GREEN}${file}${RESET} already exist" + if [ ! -e "$file" ]; then + return 1 + fi + done + return 0 +} + echo "Generating private/public keys in .key/.crt format for PK, KEK et db" +check_files_exist PK.key PK.crt || \ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ \ -keyout PK.key -out PK.crt -nodes -days 365 +check_files_exist KEK.key KEK.crt || \ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ \ -keyout KEK.key -out KEK.crt -nodes -days 365 +check_files_exist db.key db.crt || \ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ \ -keyout db.key -out db.crt -nodes -days 365 echo "Generatic EFI signature list file with PK, KEK et db public key" +check_files_exist PK.esl || \ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \ PK.crt PK.esl; +check_files_exist KEK.esl || \ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \ KEK.crt KEK.esl +check_files_exist db.esl || \ cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc \ db.crt db.esl echo "Generatic EFI AUTH file with PK, KEK et db public key" -sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth -sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth -sign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth +check_files_exist PK.auth || sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth +check_files_exist KEK.auth || sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth +check_files_exist db.auth || sign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth echo "Generatic DER files with PK, KEK et db public key" # der certificate are need for OVMF based firmware (virtual machine) -openssl x509 -in PK.crt -outform der -out PK.der -openssl x509 -in KEK.crt -outform der -out KEK.der -openssl x509 -in db.crt -outform der -out db.der +check_files_exist PK.der || openssl x509 -in PK.crt -outform der -out PK.der +check_files_exist KEK.der || openssl x509 -in KEK.crt -outform der -out KEK.der +check_files_exist db.der || openssl x509 -in db.crt -outform der -out db.der