--- Hi,
Thanks Jakub for your review. I modified the script to read the .tar.xz from stdin and output the -sign.tar.xz to stdout. It is also available here: https://github.com/helen-fornazier/dak Changes since last version: - add quotes around variables - remove unnecessary chmod 700 - receive tar.xz from stdin in byhand-code-sign-user script - generate the -sign.tar.xz to stdout in byhand-code-sign-user script I would appreciate if someone could review this version Thank you Helen scripts/debian/byhand-code-sign | 104 +----------------------- scripts/debian/byhand-code-sign-user | 135 +++++++++++++++++++++++++++++++ scripts/debian/byhand-code-sign-user-exp | 17 ++++ 3 files changed, 154 insertions(+), 102 deletions(-) create mode 100755 scripts/debian/byhand-code-sign-user create mode 100755 scripts/debian/byhand-code-sign-user-exp diff --git a/scripts/debian/byhand-code-sign b/scripts/debian/byhand-code-sign index fbd6855..18bd09e 100755 --- a/scripts/debian/byhand-code-sign +++ b/scripts/debian/byhand-code-sign @@ -20,8 +20,6 @@ error() { exit 1 } -export OPENSSL_CONF=/dev/null - # Read dak configuration for security or main archive. # Also determine subdirectory for the suite. case "$0" in @@ -39,14 +37,6 @@ case "$0" in 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" @@ -56,99 +46,9 @@ 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' '' +mkdir -p "${OUT_TARBALL%/*}" -# Build tarball of signatures -chmod -R a+rX "$OUT_DIR" -mkdir -p "$TARGET" -tar caf "$OUT_TARBALL" --directory="$OUT_DIR" . +sudo -u codesign "${0%/*}/byhand-code-sign-user" "$configdir/byhand-code-sign.conf" < "$IN_TARBALL" > "$OUT_TARBALL" echo "I: Created $OUT_TARBALL" -trap - EXIT -cleanup - exit 0 diff --git a/scripts/debian/byhand-code-sign-user b/scripts/debian/byhand-code-sign-user new file mode 100755 index 0000000..e0c5446 --- /dev/null +++ b/scripts/debian/byhand-code-sign-user @@ -0,0 +1,135 @@ +#!/bin/bash + +set -u +set -e +set -o pipefail + +if [ $# -lt 1 ]; then + echo "Usage: $0 config_file" + exit 1 +fi + +# This script receives a .tar.xz file from stdin and generates a .tar.xz in stdout +# Prevent any possible output to stdout, recirect them to stderr instead +# Save STDOUT in FD 3 +exec 3>&1 +# Redirect STDOUT to STDERR +exec 1>&2 + +CONFIG_FILE="$1" + +error() { + echo >&2 "E: $*" + exit 1 +} + +export OPENSSL_CONF=/dev/null + +# Read and trivially validate our configuration +. "$CONFIG_FILE" +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 + +# 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 from stdin into the input directory +IN_DIR="$(mktemp -td byhand-code-sign-in.XXXXXX)" +tar xJ --directory="$IN_DIR" <&0 + +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)" + 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-*) + if [ -v pkcs11_pin_value ]; then + "${0%/*}/byhand-code-sign-user-exp" "$IN_DIR/$filename" "$OUT_DIR/$filename.sig" "$pkcs11_pin_value" ${PESIGN_PARAMS[@]} + else + pesign -i "$IN_DIR/$filename" \ + --export-signature "$OUT_DIR/$filename.sig" --sign \ + -d sha256 "${PESIGN_PARAMS[@]}" + fi + ;; + *.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' '' + +# Restore STDOUT from FD 3 +exec 1>&3 + +# Build tarball of signatures +chmod -R a+rX "$OUT_DIR" +tar -cJf - --directory="$OUT_DIR" . + +trap - EXIT +cleanup + +exit 0 diff --git a/scripts/debian/byhand-code-sign-user-exp b/scripts/debian/byhand-code-sign-user-exp new file mode 100755 index 0000000..836e7d0 --- /dev/null +++ b/scripts/debian/byhand-code-sign-user-exp @@ -0,0 +1,17 @@ +#!/usr/bin/expect + +if {[llength $argv] < 3} { + puts stderr "Usage: $argv0 in_file out_file pin [pesign params]" + exit 2 +} + +log_user 0 +lassign $argv in_file out_file pin +spawn pesign -i $in_file \ + --export-signature $out_file --sign \ + -d sha256 {*}[lrange $argv 3 end] +expect "Enter Password *:" {send $pin} timeout {exit 1} +expect "Enter passphrase *:" {send $pin} timeout {exit 1} +lassign [wait] wait_pid spawn_id exec_rc wait_code +if {$exec_rc != 0} {exit 1} +exit $wait_code -- 2.9.3