mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
Rewrite guix-{attest,verify} for new hier
This commit is contained in:
parent
28a9c9b839
commit
4cc35daed5
2 changed files with 143 additions and 121 deletions
|
@ -99,24 +99,34 @@ fi
|
|||
# We should be able to find at least one output
|
||||
################
|
||||
|
||||
echo "Looking for build output directories in ${OUTDIR_BASE}"
|
||||
echo "Looking for build output SHA256SUMS fragments in ${OUTDIR_BASE}"
|
||||
|
||||
shopt -s nullglob
|
||||
OUTDIRS=( "${OUTDIR_BASE}"/* ) # This expands to an array of directories...
|
||||
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 directories:"
|
||||
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 directories in ${OUTDIR_BASE}"
|
||||
echo "ERR: Could not find any build output SHA256SUMS fragments in ${OUTDIR_BASE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
##############
|
||||
## Attest ##
|
||||
##############
|
||||
|
@ -126,82 +136,65 @@ fi
|
|||
# HOST: The output directory being attested
|
||||
#
|
||||
out_name() {
|
||||
basename "$1"
|
||||
basename "$(dirname "$1")"
|
||||
}
|
||||
|
||||
# Usage: out_sig_dir $outdir
|
||||
#
|
||||
# outdir: The output directory being attested
|
||||
#
|
||||
out_sig_dir() {
|
||||
echo "$GUIX_SIGS_REPO/$VERSION/$(out_name "$1")/$signer_name"
|
||||
}
|
||||
|
||||
# Accumulate a list of signature directories that already exist...
|
||||
outdirs_already_attested_to=()
|
||||
|
||||
echo "Attesting to build outputs for version: '${VERSION}'"
|
||||
echo ""
|
||||
|
||||
# MAIN LOGIC: Loop through each output for VERSION and attest to output in
|
||||
# GUIX_SIGS_REPO as SIGNER, if attestation does not exist
|
||||
for outdir in "${OUTDIRS[@]}"; do
|
||||
if [ -e "${outdir}/SKIPATTEST.TAG" ]; then
|
||||
echo "${outname}: SKIPPING: Output directory marked with SKIPATTEST.TAG file"
|
||||
continue
|
||||
fi
|
||||
outname="$(out_name "$outdir")"
|
||||
outsigdir="$(out_sig_dir "$outdir")"
|
||||
if [ -e "$outsigdir" ]; then
|
||||
echo "${outname}: SKIPPING: Signature directory already exists in the specified guix.sigs repository"
|
||||
outdirs_already_attested_to+=("$outdir")
|
||||
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
|
||||
# Clean up incomplete sigdir if something fails (likely gpg)
|
||||
trap 'rm -rf "$outsigdir"' ERR
|
||||
|
||||
mkdir -p "$outsigdir"
|
||||
|
||||
(
|
||||
cd "$outdir"
|
||||
|
||||
if [ -e inputs.SHA256SUMS ]; then
|
||||
echo "${outname}: Including existent input SHA256SUMS"
|
||||
cat inputs.SHA256SUMS >> "$outsigdir"/SHA256SUMS
|
||||
fi
|
||||
|
||||
echo "${outname}: Hashing build outputs to produce SHA256SUMS"
|
||||
files="$(find -L . -type f ! -iname '*.SHA256SUMS')"
|
||||
if [ -n "$files" ]; then
|
||||
cut -c3- <<< "$files" | env LC_ALL=C sort | xargs sha256sum >> "$outsigdir"/SHA256SUMS
|
||||
else
|
||||
echo "ERR: ${outname}: No outputs found in '${outdir}'"
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
if [ -z "$NO_SIGN" ]; then
|
||||
echo "${outname}: Signing SHA256SUMS to produce SHA256SUMS.asc"
|
||||
gpg --detach-sign --local-user "$gpg_key_name" --armor --output "$outsigdir"/SHA256SUMS.asc "$outsigdir"/SHA256SUMS
|
||||
else
|
||||
echo "${outname}: Not signing SHA256SUMS as \$NO_SIGN is not empty"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
trap - ERR # Reset ERR trap
|
||||
echo "no noncodesigned outputs found"
|
||||
fi
|
||||
done
|
||||
|
||||
if (( ${#outdirs_already_attested_to[@]} )); then
|
||||
# ...so that we can print them out nicely in a warning message
|
||||
cat << EOF
|
||||
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 )
|
||||
|
||||
WARN: Signature directories from '$signer_name' already exist in the specified
|
||||
guix.sigs repository for the following output directories and were
|
||||
skipped:
|
||||
# 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
|
||||
|
||||
EOF
|
||||
for outdir in "${outdirs_already_attested_to[@]}"; do
|
||||
echo " '${outdir}'"
|
||||
echo " Corresponds to: '$(out_sig_dir "$outdir")'"
|
||||
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 ""
|
||||
done
|
||||
fi
|
||||
)
|
||||
|
|
|
@ -56,58 +56,87 @@ 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
|
||||
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 ""
|
||||
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 ""
|
||||
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]}"
|
||||
|
||||
for current_manifest in "${all_noncodesigned[@]}"; do
|
||||
verify "$compare_noncodesigned" "$current_manifest"
|
||||
done
|
||||
echo "DONE: Checking output signatures for $(basename "$outsigdir")"
|
||||
|
||||
echo "DONE: Checking output signatures for noncodesigned.SHA256SUMS"
|
||||
echo ""
|
||||
else
|
||||
echo "WARN: No signature directories with noncodesigned.SHA256SUMS found"
|
||||
echo ""
|
||||
done
|
||||
fi
|
||||
|
||||
shopt -s nullglob
|
||||
all_all=( "$OUTSIGDIR_BASE"/*/all.SHA256SUMS )
|
||||
shopt -u nullglob
|
||||
|
||||
echo "--------------------"
|
||||
echo ""
|
||||
if (( ${#all_all[@]} )); then
|
||||
compare_all="${all_all[0]}"
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue