#!/bin/bash set -u set -e set -o pipefail if [ $# -lt 5 ]; then echo "Usage: $0 filename version arch changes_file suite" exit 1 fi IN_TARBALL="$1" # Tarball to read, compressed with xz VERSION="$2" ARCH="$3" CHANGES="$4" # Changes file for the upload SUITE="$5" error() { echo >&2 "E: $*" exit 1 } export OPENSSL_CONF=/dev/null # Read dak configuration for security or main archive. # Also determine subdirectory for the suite. case "$0" in /srv/security-master.debian.org/*) configdir="/srv/security-master.debian.org/dak/config/debian-security" suitedir="$SUITE/updates" ;; /srv/ftp-master.debian.org/*) configdir="/srv/ftp-master.debian.org/dak/config/debian" suitedir="$SUITE" ;; *) error "$0: Can't tell if security or not" ;; esac . "$configdir/vars" # Read and trivially validate our configuration . "$configdir/byhand-code-sign.conf" for var in EFI_BINARY_PRIVKEY EFI_BINARY_CERT \ LINUX_SIGNFILE LINUX_MODULE_PRIVKEY LINUX_MODULE_CERT; do test -v $var || error "$var is not defined in configuration" test -n "${!var}" || error "$var is empty in configuration" done TARGET="$ftpdir/dists/$suitedir/main/code-sign/" OUT_TARBALL="$TARGET/${IN_TARBALL##*/}" OUT_TARBALL="${OUT_TARBALL%.tar.xz}_sigs.tar.xz" # Check that this source/arch/version hasn't already been signed if [ -e "$OUT_TARBALL" ]; then error "Signature tarball already exists: $OUT_TARBALL" fi # If we fail somewhere, cleanup the temporary directories IN_DIR= OUT_DIR= CERT_DIR= cleanup() { for dir in "$IN_DIR" "$OUT_DIR" "$CERT_DIR"; do test -z "$dir" || rm -rf "$dir" done } trap cleanup EXIT # Extract the data into the input directory IN_DIR="$(mktemp -td byhand-code-sign-in.XXXXXX)" tar xaf "$IN_TARBALL" --directory="$IN_DIR" case "$EFI_BINARY_PRIVKEY" in pkcs11:*) # Translate from OpenSSL PKCS#11 enigne syntax to pesign parameters # See: https://sources.debian.net/src/engine-pkcs11/0.2.2-1/src/engine_pkcs11.c pkcs11_pin_value= old_IFS="$IFS" IFS=';' for kv in ${EFI_BINARY_PRIVKEY#pkcs11:}; do case "$kv" in token=*) pkcs11_token="${kv#*=}" ;; object=*) pkcs11_object="${kv#*=}" ;; pin-value=*) pkcs11_pin_value="${kv#*=}" ;; esac done IFS="$old_IFS" unset old_IFS # TODO: unlock it PESIGN_PARAMS=(-t "$pkcs11_token" -c "$pkcs11_object") ;; *) # Create certificate store for pesign CERT_DIR="$(mktemp -td byhand-code-sign-cert.XXXXXX)" chmod 700 "$CERT_DIR" mkdir "$CERT_DIR/store" certutil -N --empty-password -d "$CERT_DIR/store" openssl pkcs12 -export \ -inkey "$EFI_BINARY_PRIVKEY" -in "$EFI_BINARY_CERT" \ -out "$CERT_DIR/efi-image.p12" -passout pass: \ -name efi-image pk12util -i "$CERT_DIR/efi-image.p12" -d "$CERT_DIR/store" -K '' -W '' PESIGN_PARAMS=(-n "$CERT_DIR/store" -c efi-image) ;; esac # Create hierarchy of detached signatures in parallel to the uploaded files OUT_DIR="$(mktemp -td byhand-code-sign-out.XXXXXX)" while read filename; do mkdir -p "$OUT_DIR/${filename%/*}" case "${filename##*/}" in *.efi | vmlinuz-*) pesign -i "$IN_DIR/$filename" \ --export-signature "$OUT_DIR/$filename.sig" --sign \ -d sha256 "${PESIGN_PARAMS[@]}" ;; *.ko) "$LINUX_SIGNFILE" -d sha256 "$LINUX_MODULE_PRIVKEY" \ "$LINUX_MODULE_CERT" "$IN_DIR/$filename" mv "$IN_DIR/$filename.p7s" "$OUT_DIR/$filename.sig" ;; *) echo >&2 "W: Not signing unrecognised file: $filename" continue ;; esac if [ ${#filename} -gt 60 ]; then filename_trunc="...${filename:$((${#filename} - 57)):57}" else filename_trunc="$filename" fi printf 'I: Signed %-60s\r' "$filename_trunc" done < <(find "$IN_DIR" -type f -printf '%P\n') # Clear last progress message printf '%-70s\r' '' # Build tarball of signatures chmod -R a+rX "$OUT_DIR" mkdir -p "$TARGET" tar caf "$OUT_TARBALL" --directory="$OUT_DIR" . echo "I: Created $OUT_TARBALL" trap - EXIT cleanup exit 0