0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-09 10:43:19 -05:00

Rewrite guix-{attest,verify} for new hier

This commit is contained in:
Carl Dong 2021-06-07 15:05:33 -04:00
parent 28a9c9b839
commit 4cc35daed5
2 changed files with 143 additions and 121 deletions

View file

@ -99,24 +99,34 @@ fi
# We should be able to find at least one output # 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 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 shopt -u nullglob
noncodesigned_fragments=()
codesigned_fragments=()
if (( ${#OUTDIRS[@]} )); then if (( ${#OUTDIRS[@]} )); then
echo "Found build output directories:" echo "Found build output SHA256SUMS fragments:"
for outdir in "${OUTDIRS[@]}"; do for outdir in "${OUTDIRS[@]}"; do
echo " '$outdir'" echo " '$outdir'"
case "$outdir" in
"$OUTDIR_BASE"/*-codesigned/SHA256SUMS.part)
codesigned_fragments+=("$outdir")
;;
*)
noncodesigned_fragments+=("$outdir")
;;
esac
done done
echo echo
else 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 exit 1
fi fi
############## ##############
## Attest ## ## Attest ##
############## ##############
@ -126,82 +136,65 @@ fi
# HOST: The output directory being attested # HOST: The output directory being attested
# #
out_name() { 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 "Attesting to build outputs for version: '${VERSION}'"
echo "" echo ""
# MAIN LOGIC: Loop through each output for VERSION and attest to output in outsigdir="$GUIX_SIGS_REPO/$VERSION/$signer_name"
# GUIX_SIGS_REPO as SIGNER, if attestation does not exist mkdir -p "$outsigdir"
for outdir in "${OUTDIRS[@]}"; do (
if [ -e "${outdir}/SKIPATTEST.TAG" ]; then cd "$outsigdir"
echo "${outname}: SKIPPING: Output directory marked with SKIPATTEST.TAG file"
continue if [ -e "noncodesigned.SHA256SUMS" ]; then
fi echo "noncodesigned.SHA256SUMS already exists, using..."
outname="$(out_name "$outdir")" elif (( ${#noncodesigned_fragments[@]} )); then
outsigdir="$(out_sig_dir "$outdir")" cat "${noncodesigned_fragments[@]}" \
if [ -e "$outsigdir" ]; then | sort -u \
echo "${outname}: SKIPPING: Signature directory already exists in the specified guix.sigs repository" | sort -k2 \
outdirs_already_attested_to+=("$outdir") > noncodesigned.SHA256SUMS
else else
# Clean up incomplete sigdir if something fails (likely gpg) echo "no noncodesigned outputs found"
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
fi fi
done
if (( ${#outdirs_already_attested_to[@]} )); then if [ -e noncodesigned.SHA256SUMS ]; then
# ...so that we can print them out nicely in a warning message # noncodesigned.SHA256SUMS already exists, or was produced, let's sanity
cat << EOF # check it.
( cd "$OUTDIR_BASE"; sha256sum -c "$outsigdir"/noncodesigned.SHA256SUMS )
WARN: Signature directories from '$signer_name' already exist in the specified # Now produce all.SHA256SUMS manifest
guix.sigs repository for the following output directories and were if [ -e "all.SHA256SUMS" ]; then
skipped: 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 if [ -e all.SHA256SUMS ]; then
for outdir in "${outdirs_already_attested_to[@]}"; do ( cd "$OUTDIR_BASE"; sha256sum -c "$outsigdir"/all.SHA256SUMS )
echo " '${outdir}'" fi
echo " Corresponds to: '$(out_sig_dir "$outdir")'" 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 "" echo ""
done )
fi

View file

@ -56,58 +56,87 @@ cmd_usage
exit 1 exit 1
fi 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 ## ## Verify ##
############## ##############
# MAIN LOGIC: Loop through each output for VERSION and check that the SHA256SUMS OUTSIGDIR_BASE="${GUIX_SIGS_REPO}/${VERSION}"
# and SHA256SUMS.asc file match between signers, using the first echo "Looking for signature directories in '${OUTSIGDIR_BASE}'"
# available signer as the arbitrary comparison base. echo ""
for outsigdir in "${OUTSIGDIRS[@]}"; do
echo "BEGIN: Checking output signatures for $(basename "$outsigdir")" # Usage: verify compare_manifest current_manifest
echo "" verify() {
signer_dirs=( "$outsigdir"/* ) # This expands to an array of directories... local compare_manifest="$1"
compare_signer_dir="${signer_dirs[0]}" # ...we just want the first one local current_manifest="$2"
for current_signer_dir in "${signer_dirs[@]}"; do if ! gpg --quiet --batch --verify "$current_manifest".asc "$current_manifest" 1>&2; then
if ! gpg --quiet --batch --verify "$current_signer_dir"/SHA256SUMS.asc "$current_signer_dir"/SHA256SUMS; then echo "ERR: Failed to verify GPG signature in '${current_manifest}'"
echo "ERR: Failed to verify GPG signature in '${current_signer_dir}/SHA256SUMS.asc'" echo ""
echo "" echo "Hint: Either the signature is invalid or the public key is missing"
echo "Hint: Either the signature is invalid or the public key is missing" echo ""
echo "" elif ! diff --report-identical "$compare_manifest" "$current_manifest" 1>&2; then
elif ! diff --report-identical "$compare_signer_dir"/SHA256SUMS "$current_signer_dir"/SHA256SUMS; then echo "ERR: The SHA256SUMS attestation in these two directories differ:"
echo "ERR: The SHA256SUMS attestation in these two directories differ:" echo " '${compare_manifest}'"
echo " '${compare_signer_dir}'" echo " '${current_manifest}'"
echo " '${current_signer_dir}'" echo ""
echo "" else
else echo "Verified: '${current_manifest}'"
echo "Verified: '${current_signer_dir}'" echo ""
echo "" fi
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 done
echo "DONE: Checking output signatures for $(basename "$outsigdir")"
echo "DONE: Checking output signatures for noncodesigned.SHA256SUMS"
echo "" echo ""
else
echo "WARN: No signature directories with noncodesigned.SHA256SUMS found"
echo "" 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