You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.7 KiB
174 lines
4.7 KiB
#!/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 diff gpg |
|
|
|
################ |
|
# Required env vars should be non-empty |
|
################ |
|
|
|
cmd_usage() { |
|
cat <<EOF |
|
Synopsis: |
|
|
|
env GUIX_SIGS_REPO=<path/to/guix.sigs> [ SIGNER=<signer> ] ./contrib/guix/guix-verify |
|
|
|
Example overriding signer's manifest to use as base |
|
|
|
env GUIX_SIGS_REPO=/home/dongcarl/guix.sigs SIGNER=achow101 ./contrib/guix/guix-verify |
|
|
|
EOF |
|
} |
|
|
|
if [ -z "$GUIX_SIGS_REPO" ]; 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 |
|
|
|
############## |
|
## 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
|
|
|