mirror of
https://github.com/flatcar/scripts.git
synced 2026-05-04 11:51:14 +02:00
coreos-base/coreos-sb-keys: Add GPG keys, generation scripts, new README
We want to sign and verify kernel load scripts with GRUB, but it only supports GPG signatures for plain text files. To avoid needing to manage another key in Azure Key Vault for official builds, the existing key has been converted, keeping the start and end dates from the existing certificate. For unofficial builds, it is awkward to convert plain PEM files into GPG keys, but there is no need to use the same key in this case anyway, so a new key has been created. Being publicly visible, it has no expiry date. Two new scripts have been added to generate official and unofficial keys and certificates. The README has been rewritten with details on how to use these scripts and what each file is actually for. Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
This commit is contained in:
parent
010962f6d6
commit
bdb87aea6b
@ -10,9 +10,10 @@ else
|
||||
SBSIGN_CERT="/usr/share/sb_keys/official/signing.pem"
|
||||
fi
|
||||
|
||||
PKCS11_MODULE_PATH="/usr/$(get_sdk_libdir)/pkcs11/azure-keyvault-pkcs11.so"
|
||||
PKCS11_MODULE_PATH="$(pkg-config p11-kit-1 --variable p11_module_path)/azure-keyvault-pkcs11.so"
|
||||
|
||||
PKCS11_ENV=(
|
||||
AZURE_CORE_COLLECT_TELEMETRY=no
|
||||
AZURE_KEYVAULT_URL="https://flatcar-sb-dev-kv.vault.azure.net/"
|
||||
PKCS11_MODULE_PATH="${PKCS11_MODULE_PATH}"
|
||||
AZURE_KEYVAULT_PKCS11_DEBUG=1
|
||||
@ -31,3 +32,25 @@ do_sbsign() {
|
||||
--cert "${SBSIGN_CERT}" \
|
||||
"${@}"
|
||||
}
|
||||
|
||||
setup_gnupghome() {
|
||||
export GNUPGHOME
|
||||
GNUPGHOME=$(mktemp -d)
|
||||
trap 'gpgconf --kill gpg-agent; rm -r -- "${GNUPGHOME}"' EXIT
|
||||
|
||||
# Unofficial builds simply use a local private key.
|
||||
[[ ${COREOS_OFFICIAL:-0} -ne 1 ]] && return
|
||||
|
||||
cat <<EOF > "${GNUPGHOME}"/gpg-agent.conf
|
||||
scdaemon-program $(type -P gnupg-pkcs11-scd)
|
||||
EOF
|
||||
|
||||
cat <<EOF > "${GNUPGHOME}"/gnupg-pkcs11-scd.conf
|
||||
providers kms
|
||||
provider-kms-library ${PKCS11_MODULE_PATH}
|
||||
log-file /dev/null
|
||||
EOF
|
||||
|
||||
# This fetches the private keys from AKV.
|
||||
gpg --card-status
|
||||
}
|
||||
|
||||
@ -1,15 +1,31 @@
|
||||
## Keys & Certificates
|
||||
|
||||
- DB (Signature Database): The signature database is used to validate signed EFI binaries.
|
||||
- Shim Certificates: Our set of certificates
|
||||
### X.509 signature database - DB.key, DB.pem
|
||||
|
||||
The signature database is used by the UEFI firmware to validate signed EFI binaries (e.g. the shim). In this case, `DB.key` and `DB.pem` are only used for testing with QEMU. Real deployments use the database provided by the bare metal host or hypervisor.
|
||||
|
||||
### X.509 shim vendor certificates - shim.key, shim-*.pem
|
||||
|
||||
Unofficial builds: `shim-*.pem` are the current and historical self-signed signing certificates used to sign the bootloader and kernel. `shim.key` is the private key for the current certificate.
|
||||
|
||||
Official builds: `shim-*.pem` are the current and historical CA certificates that issue the signing certificates. The private key is only needed to issue new signing certificates so is kept offline.
|
||||
|
||||
### X.509 signing certificate - signing.pem
|
||||
|
||||
Unofficial builds: The current signing certificate is also the current shim vendor certificate above, so there is no separate `signing.pem`.
|
||||
|
||||
Official builds: `signing.pem` is the current signing certificate used to sign the bootloader and kernel. It is copied from Azure Key Vault, where the private key is also stored.
|
||||
|
||||
### GPG signing keys - signing*.gpg
|
||||
|
||||
Unofficial builds: `signing.gpg` is the current private key used to sign the kernel load script. `signing-*.gpg` are the historical public keys used to verify them. They have no expiry date.
|
||||
|
||||
Official builds: `signing.gpg` is the current public key used to sign the kernel load script. `signing-*.gpg` are the historical public keys used to verify them. These keys are created from their respective X.509 signing certificates. As such, the private keys are only stored in Azure Key Vault. The start and end dates of the keys also match the certificates.
|
||||
|
||||
## Generation of Keys & Certificates
|
||||
|
||||
Unofficial builds: Delete any of `DB.key`, `shim.key`, or `signing.gpg` to force recreation.
|
||||
|
||||
Generate the our shim certificates:
|
||||
Official builds: Delete `signing.gpg` to force recreation. `shim-*.pem` must be updated manually. `signing.pem` is refreshed from Azure Key Vault using the details stored in `build_library/sbsign_util.sh`. Ensure [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) is in your `PATH`.
|
||||
|
||||
```
|
||||
openssl genrsa -out "shim.key" 2048
|
||||
openssl req -new -x509 -sha256 -subj "/CN=shim/" -key "shim.key" -out "shim.pem" -days 7300
|
||||
```
|
||||
Run the `refresh_keys` script without any arguments. Bump the coreos-sb-keys package with the changes.
|
||||
|
||||
@ -56,5 +56,14 @@ src_install() {
|
||||
doins -r unofficial official
|
||||
|
||||
insinto /usr/share/sb_keys/unofficial
|
||||
doins "${FILESDIR}"/unofficial/{DB.{key,pem},shim.key}
|
||||
doins "${FILESDIR}"/unofficial/{DB.{key,pem},shim.key,signing*.gpg}
|
||||
|
||||
insinto /usr/share/sb_keys/official
|
||||
doins "${FILESDIR}"/official/signing-*.gpg
|
||||
|
||||
# For unofficial builds, we install the GPG private key as signing.gpg to
|
||||
# sign with. For official builds, we create a symlink to the newest public
|
||||
# key instead because the private key is in Azure Key Vault.
|
||||
local FILES=( "${FILESDIR}"/official/signing-*.gpg )
|
||||
dosym "${FILES[-1]##*/}" /usr/share/sb_keys/official/signing.gpg
|
||||
}
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
# azure-cli creates this, seemingly due to a bug.
|
||||
/None/
|
||||
67
sdk_container/src/third_party/coreos-overlay/coreos-base/coreos-sb-keys/files/official/refresh_keys
vendored
Executable file
67
sdk_container/src/third_party/coreos-overlay/coreos-base/coreos-sb-keys/files/official/refresh_keys
vendored
Executable file
@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
cd "${0%/*}"
|
||||
|
||||
COREOS_OFFICIAL=1
|
||||
. ../../../../../../../../build_library/sbsign_util.sh
|
||||
export "${PKCS11_ENV[@]}"
|
||||
|
||||
echo "Fetching ${SBSIGN_KEY} from Azure"
|
||||
CERT=$(p11-kit export-object --provider "${PKCS11_MODULE_PATH}" "${SBSIGN_KEY};type=cert")
|
||||
|
||||
if [[ -f signing.pem && ${CERT} = "$(< signing.pem)" ]]; then
|
||||
echo "signing.pem: Unchanged"
|
||||
else
|
||||
echo "signing.pem: Updating"
|
||||
cat > signing.pem <<< "${CERT}"
|
||||
fi
|
||||
|
||||
CERT=signing.pem
|
||||
|
||||
# Copy the X.509 dates to the GPG key. This isn't required, but it helps to
|
||||
# identify the key, and not setting an expiry date is bad practise.
|
||||
START=$(openssl x509 -noout -in "${CERT}" -startdate)
|
||||
START=$(date -d "${START#*=}" -u +%Y%m%dT%H%M%S)
|
||||
#
|
||||
END=$(openssl x509 -noout -in "${CERT}" -enddate)
|
||||
END=$(date -d "${END#*=}" -u +%Y%m%dT%H%M%S)
|
||||
|
||||
# We also use the start date to name the GPG key.
|
||||
OUTPUT=signing-${START%%T*}.gpg
|
||||
|
||||
if [[ -f ${OUTPUT} ]]; then
|
||||
echo "${OUTPUT}: Exists (remove to recreate)"
|
||||
exit
|
||||
fi
|
||||
|
||||
setup_gnupghome
|
||||
|
||||
# This isn't a great way to find the matching key from AKV, and it only works
|
||||
# with RSA keys, but keygrips are internal to GPG, so there isn't much choice.
|
||||
MODULUS=$(openssl x509 -in "${CERT}" -noout -modulus)
|
||||
MODULUS=${MODULUS#*=}
|
||||
#
|
||||
for KEYGRIP in "${GNUPGHOME}"/private-keys-v1.d/*.key; do
|
||||
if tr -d "\n " < "${KEYGRIP}" | grep -qF "${MODULUS}"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
#
|
||||
KEYGRIP=${KEYGRIP##*/}
|
||||
KEYGRIP=${KEYGRIP%.key}
|
||||
|
||||
echo "${OUTPUT}: Creating"
|
||||
gpg --batch --generate-key <<-EOF
|
||||
Key-Type: RSA
|
||||
Key-Grip: ${KEYGRIP}
|
||||
Key-Usage: sign
|
||||
Name-Real: Flatcar Secure Boot official
|
||||
Name-Email: maintainers@flatcar-linux.org
|
||||
Creation-Date: ${START}
|
||||
Expire-Date: ${END}
|
||||
%commit
|
||||
EOF
|
||||
|
||||
# Only write the public key to a file. The private key remains in AKV.
|
||||
gpg --export --output "${OUTPUT}"
|
||||
Binary file not shown.
56
sdk_container/src/third_party/coreos-overlay/coreos-base/coreos-sb-keys/files/unofficial/refresh_keys
vendored
Executable file
56
sdk_container/src/third_party/coreos-overlay/coreos-base/coreos-sb-keys/files/unofficial/refresh_keys
vendored
Executable file
@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
cd "${0%/*}"
|
||||
|
||||
COREOS_OFFICIAL=0
|
||||
. ../../../../../../../../build_library/sbsign_util.sh
|
||||
|
||||
BITS=2048
|
||||
DAYS=7300
|
||||
DATE=$(date +%Y%m%d)
|
||||
|
||||
if [[ -f DB.key ]]; then
|
||||
echo "DB.key: Exists (remove to recreate)"
|
||||
else
|
||||
echo "DB.key: Creating"
|
||||
openssl genrsa -out DB.key "${BITS}"
|
||||
echo "DB.pem: Creating"
|
||||
openssl req -new -x509 -sha256 -days "${DAYS}" -subj "/CN=CoreOS test DB/" -key DB.key -out DB.pem
|
||||
fi
|
||||
|
||||
if [[ -f shim.key ]]; then
|
||||
echo "shim.key: Exists (remove to recreate)"
|
||||
else
|
||||
echo "shim.key: Creating"
|
||||
openssl genrsa -out shim.key "${BITS}"
|
||||
echo "shim-${DATE}.pem: Creating"
|
||||
openssl req -new -x509 -sha256 -days "${DAYS}" -subj "/CN=shim/" -key shim.key -out shim-"${DATE}".pem
|
||||
fi
|
||||
|
||||
if [[ -f signing.gpg ]]; then
|
||||
echo "signing.gpg: Exists (remove to recreate)"
|
||||
exit
|
||||
fi
|
||||
|
||||
setup_gnupghome
|
||||
|
||||
echo "signing.gpg: Creating"
|
||||
gpg --batch --generate-key <<-EOF
|
||||
%no-protection
|
||||
Key-Type: RSA
|
||||
Key-Length: ${BITS}
|
||||
Key-Usage: sign
|
||||
Name-Real: Flatcar Secure Boot development
|
||||
Name-Email: maintainers@flatcar-linux.org
|
||||
Expire-Date: 0
|
||||
%commit
|
||||
EOF
|
||||
|
||||
# Write the private key to a file for signing.
|
||||
gpg --export-secret-keys --output signing.gpg
|
||||
|
||||
# Write the public key to a file for verification.
|
||||
echo "signing-${DATE}.gpg: Creating"
|
||||
rm -f signing-"${DATE}".gpg
|
||||
gpg --export --output signing-"${DATE}".gpg
|
||||
Binary file not shown.
BIN
sdk_container/src/third_party/coreos-overlay/coreos-base/coreos-sb-keys/files/unofficial/signing.gpg
vendored
Normal file
BIN
sdk_container/src/third_party/coreos-overlay/coreos-base/coreos-sb-keys/files/unofficial/signing.gpg
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user