Re: Bug#821051: [PATCH v2] byhand-code-sign: sign using another user
---
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
Reply to: