#!/bin/sh # There is no concurrency control here. We are relying on the fact that # the runner on the host is set to a max capacity of 1 if [ "${INPUT_UHUB_CONTROL}" != "false" ]; then if [ -z "${UHUB_LOCATION}" ] || [ -z "${UHUB_PORT}" ]; then echo "error: UHUB control requested, but runner has not been configured with UHUB_LOCATION and UHUB_PORT environment variables" exit 255 fi uhubctl -a off -p "${UHUB_PORT}" -l "${UHUB_LOCATION}" # Off seems to be reflected immediately # Capture the number of hidraw devices with the port off # The way docker works, we can't seem to monitor /dev directory # But a USB device should show up in dmesg log when this happens #devs="$(find /dev -maxdepth 1 -name 'hi*' |wc -l)" devs=$(dmesg |grep "usb ${UHUB_LOCATION}.${UHUB_PORT}" |grep -c "New USB device found") uhubctl -a on -p "${UHUB_PORT}" -l "${UHUB_LOCATION}" retries=0 while [ "$(dmesg |grep "usb ${UHUB_LOCATION}.${UHUB_PORT}" |grep -c "New USB device found")" = "$devs" ] && [ $retries -lt 10 ]; do # Generally takes a few seconds to settle in echo "waiting for device connection ($((retries+1)) / 10)" sleep 1 retries=$((retries+1)) done if [ $retries -ge 10 ]; then echo "device is not available. Aborting" exit 1 fi fi dir="$(dirname "${INPUT_FILES}")" glob="$(basename "${INPUT_FILES}")" # Pass these through sort so we can have deterministic output indexing if [ "${glob}" = "**" ]; then all_files="$(find "$dir" -type f |sort)" else all_files="$(find "$dir" -maxdepth 1 -name "${glob}" -type f |sort)" fi i=0 while IFS= read -r f; do sign_dir="$(dirname "$f")" sign_file="$(basename "$f")" dest_sig="${sign_dir}/${sign_file}.sig" echo "Signing file $f. Signature file destination: ${dest_sig}" # We can't use a volume mount because it will use the host volume, and we're # not on the host, but in a container. So we'll create a container, copy # the file to sign in place, get the signature and copy that back container="$(docker create \ -v /run/pcscd/pcscd.comm:/run/pcscd/pcscd.comm:ro \ -e INPUT_PIN \ git.lerch.org/lobo/pkcs11:1 \ -s --id "${INPUT_SLOT}" -m SHA256-RSA-PKCS -i artifact -o signature --pin env:INPUT_PIN)" docker cp "$f" "${container}":/home/user/artifact docker start -a "$container" # let container run, pick up the exit code ec=$? if [ $ec -ne 0 ]; then docker rm "$container" exit $ec fi # We are clear. Copy signature back into the workspace and remove the container docker cp "${container}":/home/user/signature "${dest_sig}" docker rm "${container}" if [ -n "${INPUT_PUBLIC_KEY}" ]; then echo "Public key url specified. Uploading to sigstore public transparency log" echo "Fetching key from ${INPUT_PUBLIC_KEY}" curl -sLo /tmp/public_key "${INPUT_PUBLIC_KEY}" ec=$?; if [ $ec -ne 0 ]; then exit $ec; fi output=$(rekor upload --artifact "$f" --signature "${dest_sig}" --pki-format x509 --public-key /tmp/public_key) ec=$?; echo "$output"; if [ $ec -ne 0 ]; then exit $ec; fi # Index will not be there if the entry already exists # echo "INDEX_${i}=$(echo "$output"|cut -d, -f1|cut -d\ -f5)" >> "${GITHUB_OUTPUT}" # The parsing, though, is identical echo "URL_${i}=$(echo "$output"|cut -d: -f2-|cut -d\ -f2)" >> "${GITHUB_OUTPUT}" fi echo "SOURCE_${i}=${f}" >> "${GITHUB_OUTPUT}" echo "SIG_${i}=${dest_sig}" >> "${GITHUB_OUTPUT}" i=$((i+1)) done <