#!/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 Feather Wallet 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 diff gpg ################ # Required env vars should be non-empty ################ cmd_usage() { cat < [ SIGNER= ] ./contrib/guix/guix-verify Example overriding signer's manifest to use as base env GUIX_SIGS_REPO=/home/user/feather-sigs SIGNER=achow101 ./contrib/guix/guix-verify EOF } if [ -z "${GUIX_SIGS_REPO}" ]; then printf "Enter path to 'feather-sigs' repo: " read -r GUIX_SIGS_REPO if [ ! -d "${GUIX_SIGS_REPO}" ]; then echo "Directory does not exist" exit 1 fi echo "" echo "Next time, invoke this command as:" echo "env GUIX_SIGS_REPO=${GUIX_SIGS_REPO} make verify" echo "" 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 feather-sigs repository and point to it with the GUIX_SIGS_REPO environment variable. EOF cmd_usage exit 1 fi ############## ## Verify ## ############## OUTSIGDIR_BASE="${GUIX_SIGS_REPO}/${VERSION}" echo "Looking for signature directories in '${OUTSIGDIR_BASE}'" echo "" # Usage: verify compare_manifest current_manifest verify() { local compare_manifest="$1" local current_manifest="$2" if ! gpg --quiet --batch --verify "$current_manifest".asc "$current_manifest" 1>&2; then echo "ERR: Failed to verify GPG signature in '${current_manifest}'" echo "" echo "Hint: Either the signature is invalid or the public key is missing" echo "" failure=1 elif ! diff --report-identical "$compare_manifest" "$current_manifest" 1>&2; then echo "ERR: The SHA256SUMS attestation in these two directories differ:" echo " '${compare_manifest}'" echo " '${current_manifest}'" echo "" failure=1 else echo "Verified: '${current_manifest}'" echo "" fi } shopt -s nullglob all_noncodesigned=( "$OUTSIGDIR_BASE"/*/noncodesigned.SHA256SUMS ) shopt -u nullglob echo "--------------------" echo "" if (( ${#all_noncodesigned[@]} )); then compare_noncodesigned="${all_noncodesigned[0]}" if [[ -n "$SIGNER" ]]; then signer_noncodesigned="$OUTSIGDIR_BASE/$SIGNER/noncodesigned.SHA256SUMS" if [[ -f "$signer_noncodesigned" ]]; then echo "Using $SIGNER's manifest as the base to compare against" compare_noncodesigned="$signer_noncodesigned" else echo "Unable to find $SIGNER's manifest, using the first one found" fi else echo "No SIGNER provided, using the first manifest found" fi for current_manifest in "${all_noncodesigned[@]}"; do verify "$compare_noncodesigned" "$current_manifest" done echo "DONE: Checking output signatures for noncodesigned.SHA256SUMS" echo "" else echo "WARN: No signature directories with noncodesigned.SHA256SUMS found" echo "" fi shopt -s nullglob all_all=( "$OUTSIGDIR_BASE"/*/all.SHA256SUMS ) shopt -u nullglob echo "--------------------" echo "" if (( ${#all_all[@]} )); then compare_all="${all_all[0]}" if [[ -n "$SIGNER" ]]; then signer_all="$OUTSIGDIR_BASE/$SIGNER/all.SHA256SUMS" if [[ -f "$signer_all" ]]; then echo "Using $SIGNER's manifest as the base to compare against" compare_all="$signer_all" else echo "Unable to find $SIGNER's manifest, using the first one found" fi else echo "No SIGNER provided, using the first manifest found" fi for current_manifest in "${all_all[@]}"; do verify "$compare_all" "$current_manifest" done # Sanity check: there should be no entries that exist in # noncodesigned.SHA256SUMS that doesn't exist in all.SHA256SUMS if [[ "$(comm -23 <(sort "$compare_noncodesigned") <(sort "$compare_all") | wc -c)" -ne 0 ]]; then echo "ERR: There are unique lines in noncodesigned.SHA256SUMS which" echo " do not exist in all.SHA256SUMS, something went very wrong." exit 1 fi echo "DONE: Checking output signatures for all.SHA256SUMS" echo "" else echo "WARN: No signature directories with all.SHA256SUMS found" echo "" fi echo "====================" echo "" if (( ${#all_noncodesigned[@]} + ${#all_all[@]} == 0 )); then echo "ERR: Unable to perform any verifications as no signature directories" echo " were found" echo "" exit 1 fi if [ -n "$failure" ]; then exit 1 fi