#!/usr/bin/env bash export LC_ALL=C set -e -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin Core repository # 2. Defines a few common functions and variables # # shellcheck source=libexec/prelude.bash source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash" ################### ## Sanity Checks ## ################### ################ # Required non-builtin commands should be invokable ################ check_tools cat env basename mkdir xargs find if [ -z "$NO_SIGN" ]; then check_tools gpg fi ################ # Required env vars should be non-empty ################ cmd_usage() { cat < \\ SIGNER=GPG_KEY_NAME[=SIGNER_NAME] \\ [ NO_SIGN=1 ] ./contrib/guix/guix-attest Example w/o overriding signing name: env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\ SIGNER=achow101 \\ ./contrib/guix/guix-attest Example overriding signing name: env GUIX_SIGS_REPO=/home/dongcarl/guix.sigs \\ SIGNER=0x96AB007F1A7ED999=dongcarl \\ ./contrib/guix/guix-attest Example w/o signing, just creating SHA256SUMS: env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\ SIGNER=achow101 \\ NO_SIGN=1 \\ ./contrib/guix/guix-attest EOF } if [ -z "$GUIX_SIGS_REPO" ] || [ -z "$SIGNER" ]; then cmd_usage exit 1 fi ################ # GUIX_SIGS_REPO should exist as a directory ################ if [ ! -d "$GUIX_SIGS_REPO" ]; then cat << EOF ERR: The specified GUIX_SIGS_REPO is not an existent directory: '$GUIX_SIGS_REPO' Hint: Please clone the guix.sigs repository and point to it with the GUIX_SIGS_REPO environment variable. EOF cmd_usage exit 1 fi ################ # The key specified in SIGNER should be usable ################ IFS='=' read -r gpg_key_name signer_name <<< "$SIGNER" if [ -z "${signer_name}" ]; then signer_name="$gpg_key_name" fi if [ -z "$NO_SIGN" ] && ! gpg --dry-run --list-secret-keys "${gpg_key_name}" >/dev/null 2>&1; then echo "ERR: GPG can't seem to find any key named '${gpg_key_name}'" exit 1 fi ################ # We should be able to find at least one output ################ echo "Looking for build output SHA256SUMS fragments in ${OUTDIR_BASE}" shopt -s nullglob OUTDIRS=( "$OUTDIR_BASE"/*/SHA256SUMS.part ) # This expands to an array of directories... shopt -u nullglob noncodesigned_fragments=() codesigned_fragments=() if (( ${#OUTDIRS[@]} )); then echo "Found build output SHA256SUMS fragments:" for outdir in "${OUTDIRS[@]}"; do echo " '$outdir'" case "$outdir" in "$OUTDIR_BASE"/*-codesigned/SHA256SUMS.part) codesigned_fragments+=("$outdir") ;; *) noncodesigned_fragments+=("$outdir") ;; esac done echo else echo "ERR: Could not find any build output SHA256SUMS fragments in ${OUTDIR_BASE}" exit 1 fi ############## ## Attest ## ############## # Usage: out_name $outdir # # HOST: The output directory being attested # out_name() { basename "$(dirname "$1")" } echo "Attesting to build outputs for version: '${VERSION}'" echo "" outsigdir="$GUIX_SIGS_REPO/$VERSION/$signer_name" mkdir -p "$outsigdir" ( cd "$outsigdir" if [ -e "noncodesigned.SHA256SUMS" ]; then echo "noncodesigned.SHA256SUMS already exists, using..." elif (( ${#noncodesigned_fragments[@]} )); then cat "${noncodesigned_fragments[@]}" \ | sort -u \ | sort -k2 \ > noncodesigned.SHA256SUMS else echo "no noncodesigned outputs found" fi if [ -e noncodesigned.SHA256SUMS ]; then # noncodesigned.SHA256SUMS already exists, or was produced, let's sanity # check it. ( cd "$OUTDIR_BASE"; sha256sum -c "$outsigdir"/noncodesigned.SHA256SUMS ) # Now produce all.SHA256SUMS manifest if [ -e "all.SHA256SUMS" ]; then echo "all.SHA256SUMS already there!" elif (( ${#codesigned_fragments[@]} )); then cat "${OUTDIRS[@]}" \ | sort -u \ | sort -k2 \ > all.SHA256SUMS else echo "no codesigned outputs found" fi if [ -e all.SHA256SUMS ]; then ( cd "$OUTDIR_BASE"; sha256sum -c "$outsigdir"/all.SHA256SUMS ) fi fi if [ -z "$NO_SIGN" ]; then echo "Signing SHA256SUMS to produce SHA256SUMS.asc" for i in *.SHA256SUMS; do if [ ! -e "$i".asc ]; then gpg --detach-sign \ --local-user "$gpg_key_name" \ --armor \ --output "$i".asc "$i" else echo "Signature already there" fi done else echo "Not signing SHA256SUMS as \$NO_SIGN is not empty" fi echo "" )