# Package Signing Key Generation and Handling
Last updated 2024-07-10.
# Owernship
Certificate and key generation and handling is overseen by ALESCo.
# Key Generation
This is a slow and tedious process. It is important that no corners are cut and the utmost care is taken validating security through every step of the process.
# Prepare a Secure Environment
Download latest AlmaLinux live ISO from https://repo.almalinux.org/
. Using default Gnome mini for this guide as to not have any 3rd-party binaries present (EPEL).
In the folder where you download the ISO, look at the CHECKSUM
and CHECKSUM.asc
files. First let's verify that it is properly signed and that its contents can be authenticated.
wget https://repo.almalinux.org/almalinux/9/live/x86_64/CHECKSUM
wget https://repo.almalinux.org/almalinux/9/live/x86_64/CHECKSUM.asc
wget https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-9
gpg --import RPM-GPG-KEY-AlmaLinux-9
gpg --verify CHECKSUM.asc CHECKSUM
Now verify the downloaded ISO's sha256 checksum against that contained in the CHECKSUM
file.
Copy the ISO file to a flash drive.
dd if=almalinux.iso of=/dev/sdX
Boot the image. Connect to the internet temporarily to run a single command:
sudo dnf install pcsc-lite
# Download GPG Public Keys of Recipients
If you are doing key exports as part of this, grab the public keys of all recipients.
These keys are accurate at the time of this writing. Verify them prior to use, of course.
curl <key> | gpg --import
It may also be helpful to open a copy of this guide in the browser before disconnecting from the internet.
Disconnect from the internet and do not connect again. Everything from here on out has to be done fully air-gapped and the generated private keys can never be connected to a machine with network access.
# Generate Keys and Certificates
Prepare GPG Environment:
mkdir ~/.gnupg/ cat << 'EOF' > ~/.gnupg/gpg.conf personal-cipher-preferences AES256 AES192 AES personal-digest-preferences SHA512 SHA384 SHA256 personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed cert-digest-algo SHA512 s2k-digest-algo SHA512 s2k-cipher-algo AES256 charset utf-8 no-comments no-emit-version no-greeting keyid-format 0xlong list-options show-uid-validity verify-options show-uid-validity with-fingerprint require-cross-certification no-symkey-cache armor use-agent throw-keyids EOF
Generate the key:
export IDENTITY="AlmaLinux OS 10 <packager@almalinux.org>" export KEY_TYPE=rsa4096 CERTIFY_PASS=$(LC_ALL=C tr -dc 'A-Z1-9' < /dev/urandom | \ tr -d "1IOS5U" | fold -w 30 | sed "-es/./ /"{1..26..5} | \ cut -c2- | tr " " "-" | head -1) ; echo "$CERTIFY_PASS" gpg --batch --passphrase "$CERTIFY_PASS" --quick-generate-key "$IDENTITY" "$KEY_TYPE" sign never KEYID=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^pub:/ { print $5; exit }') KEYFP=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^fpr:/ { print $10; exit }') printf "\nKey ID: %40s\nKey FP: %40s\n\n" "$KEYID" "$KEYFP"
Make sure to securely store the passphrase in Vaultwarden.
Export Public and Private Keys
gpg --armor --export $KEYID > almalinux10.asc gpg --batch --armor --passphrase "$CERTIFY_PASS" --pinentry-mode=loopback --export-secret-keys $KEYID > almalinux10-privkey.asc
Configure (new) Yubikey
Generate Pins
# generate pins ADMIN_PIN=$(LC_ALL=C tr -dc '0-9' < /dev/urandom | fold -w8 | head -1) USER_PIN=$(LC_ALL=C tr -dc '0-9' < /dev/urandom | fold -w6 | head -1) printf "\nAdmin PIN: %12s\nUser PIN: %13s\n\n" "$ADMIN_PIN" "$USER_PIN"
Make sure to securely store the admin and user pins in Vaultwarden.
Set pins
# set admin pin gpg --command-fd=0 --pinentry-mode=loopback --change-pin <<EOF 3 12345678 $ADMIN_PIN $ADMIN_PIN q EOF # set user pin gpg --command-fd=0 --pinentry-mode=loopback --change-pin <<EOF 1 123456 $USER_PIN $USER_PIN q EOF
Set basic info on the Yubikey
gpg --command-fd=0 --pinentry-mode=loopback --edit-card <<EOF admin login $IDENTITY $ADMIN_PIN forcesig url https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-10 quit EOF
Copy private key to Yubikey. This is a destructive proces so we need to make a backup of the private keys before we proceed and use that to write to the Yubikey. If we're only writing to a single Yubikey the backup is not necessary as we have already exported the key into armored format which will not be impacted.
cp -r ~/.gnupg ~/.gnupg.keytocard GNUPGHOME=~/.gnupg.keytocard gpg --command-fd=0 --pinentry-mode=loopback --edit-key $KEYID <<EOF keytocard y 1 $CERTIFY_PASS $ADMIN_PIN save EOF
# Copy Keys and Certificates
DO NOT DO NOT DO NOT connect to the internet to copy the files.
# Public Certificates
Copy the public key (almalinux10.asc
if copy/pasting commands from this guide) to a flash drive. This drive can then be connected to a machine with networking and distributed as necessary - there is nothing secret about them.
# Private Keys
Encrypt the private keys using GPG. The GPG-encrypted files are the only ones that can be distributed to key holders via offline methods. It's recommended that they keys remain encrypted at rest.
gpg -r <recipient-gpg-email> -r <recipient-gpg-email> -e almalinux10-privkey.asc
Copy the .asc (public/private) keys and GPG-encrypted version of the private key to a blank flash drive. The drive must never be connected to a networked or untrusted system. It should only ever be connected to an air-gapped blank OS install.
# Removal of Custodianship
We need to define how we handle if a keyholder leaves AlmaLinux.
# Distribution of Keys to Key Holders
Keys will be distributed to key holders only via physical medium - never via the internet. Our SOP is for the key generator to encrypt the keys with GPG and place them on a hardware-encrypted (FIPS-140 certified), self-destructing (if brute force or disassembly are attempted) USB key. These may then be mailed to the key holder or delivered in person at, for example, a conference.
The unlock code for the flash drive will be provided by the key generator to the key holder upon their recipient of the flash drive, and confirmation of that receipt via a GPG-signed email.
The hardware unlock code may be provided via the internet using encrypted means - either AlmaLinux's internal password manager (Vaultwarden) or GPG-encrypted email.
# Storage of Keys by Key Holders
Keys should be stored offline and encrypted at rest via GPG and the hardware encryption of the flash drive. It should be stored in a fire resistant lock box/safe or bank safety deposit box.
# Key Generation Log
# AlmaLinux 10
Package signing keys generated on 2024-07-10 using policy dated 2024-07-03. These keys and certs will be used for package signing in AlmaLinux 10, including testing/beta builds.
# Changelog
# 2024-07-03
Initial ratification