aboutsummaryrefslogtreecommitdiff
path: root/contrib/guix/guix-verify
blob: 629050956cb5a6bd3c7c0b701a430437fdf21d36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/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> ./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

################
# We should be able to find at least one output
################

OUTSIGDIR_BASE="${GUIX_SIGS_REPO}/${VERSION}"
echo "Looking for output signature directories in '${OUTSIGDIR_BASE}'"

shopt -s nullglob
OUTSIGDIRS=( "$OUTSIGDIR_BASE"/* ) # This expands to an array of directories...
shopt -u nullglob

if (( ${#OUTSIGDIRS[@]} )); then
    echo "Found output signature directories:"
    for outsigdir in "${OUTSIGDIRS[@]}"; do
        echo "    '$outsigdir'"
    done
    echo
else
    echo "ERR: Could not find any output signature directories in ${OUTSIGDIR_BASE}"
    exit 1
fi


##############
##  Verify  ##
##############

# MAIN LOGIC: Loop through each output for VERSION and check that the SHA256SUMS
#             and SHA256SUMS.asc file match between signers, using the first
#             available signer as the arbitrary comparison base.
for outsigdir in "${OUTSIGDIRS[@]}"; do
    echo "BEGIN: Checking output signatures for $(basename "$outsigdir")"
    echo ""
    signer_dirs=( "$outsigdir"/* ) # This expands to an array of directories...
    compare_signer_dir="${signer_dirs[0]}" # ...we just want the first one
    for current_signer_dir in "${signer_dirs[@]}"; do
        if ! gpg --quiet --batch --verify "$current_signer_dir"/SHA256SUMS.asc "$current_signer_dir"/SHA256SUMS; then
            echo "ERR: Failed to verify GPG signature in '${current_signer_dir}/SHA256SUMS.asc'"
            echo ""
            echo "Hint: Either the signature is invalid or the public key is missing"
            echo ""
        elif ! diff --report-identical "$compare_signer_dir"/SHA256SUMS "$current_signer_dir"/SHA256SUMS; then
            echo "ERR: The SHA256SUMS attestation in these two directories differ:"
            echo "    '${compare_signer_dir}'"
            echo "    '${current_signer_dir}'"
            echo ""
        else
            echo "Verified: '${current_signer_dir}'"
            echo ""
        fi
    done
    echo "DONE: Checking output signatures for $(basename "$outsigdir")"
    echo ""
    echo ""
done