It actually takes a fair bit of effort. I made this script to make it bit easier.
It could be lots better, it assumes you already imported the release keys:
Code: Select all
gpg --import /usr/share/openpgp-keys/gentoo-release.ascRelies on "Good signature from" to indicate a valid signature.
Ignores trust warnings.
Currently only handles SHA512 and BLAKE2B - easy to modify to add more.
Code: Select all
#!/bin/bash
# Check if DIGESTS file is provided as a parameter
if [ $# -ne 1 ]; then
echo "Usage: $0 <DIGESTS_file>"
exit 1
fi
DIGESTS_FILE="$1"
# Check if DIGESTS file exists
if [ ! -f "$DIGESTS_FILE" ]; then
echo "Error: DIGESTS file $DIGESTS_FILE not found!"
exit 1
fi
# Function to verify PGP signature
verify_pgp_signature() {
local file="$1"
local gpg_output
local signature_line
# Run gpg --verify and capture output
gpg_output=$(gpg --verify "$file" 2>&1)
# Check for "Good signature from" in the output
signature_line=$(echo "$gpg_output" | grep "Good signature from" || true)
echo "Testing \"$file\" for Good PGP signature:"
if [ -n "$signature_line" ]; then
echo "$signature_line"
else
echo "FAILURE!"
fi
echo
}
# Function to calculate hash
calculate_hash() {
local file="$1"
local hash_type="$2"
case "$hash_type" in
"SHA512")
openssl dgst -r -sha512 "$file" | awk '{print $1}'
;;
"BLAKE2B")
openssl dgst -r -blake2b512 "$file" | awk '{print $1}'
;;
*)
echo "Error: Unsupported hash type $hash_type"
return 1
;;
esac
}
# Function to verify hash
verify_hash() {
local file="$1"
local hash_type="$2"
local stored_hash="$3"
local calculated_hash
calculated_hash=$(calculate_hash "$file" "$hash_type")
if [ $? -ne 0 ]; then
echo "Testing: \"$file\" with $hash_type against DIGEST:"
echo "$stored_hash"
echo "Failed to calculate hash"
echo " FAILED!"
echo
return
fi
echo "Testing: \"$file\" with $hash_type against DIGEST:"
echo "$stored_hash"
echo "$calculated_hash"
if [ "$stored_hash" = "$calculated_hash" ]; then
echo " VERIFIED!"
else
echo " FAILED!"
fi
echo
}
# Verify PGP signature of the DIGESTS file
verify_pgp_signature "$DIGESTS_FILE"
# Process DIGESTS file line by line
current_hash_type=""
while IFS= read -r line; do
# Check for hash type header
if [[ "$line" =~ ^#[[:space:]]+([A-Z0-9]+)[[:space:]]+HASH$ ]]; then
current_hash_type="${BASH_REMATCH[1]}"
continue
fi
# Check for hash and filename line
if [ -n "$current_hash_type" ] && [[ "$line" =~ ^([0-9a-f]+)[[:space:]]+(.+)$ ]]; then
stored_hash="${BASH_REMATCH[1]}"
file="${BASH_REMATCH[2]}"
# Verify file exists
if [ ! -f "$file" ]; then
echo "Error: File $file not found!"
echo
continue
fi
# Verify PGP signature for the file (if .asc exists)
if [ -f "$file.asc" ]; then
verify_pgp_signature "$file.asc"
else
echo "Testing \"$file\" for Good PGP signature:"
echo "No signature file ($file.asc) found!"
echo
fi
# Verify hash
verify_hash "$file" "$current_hash_type" "$stored_hash"
fi
done < <(grep -v '^-' "$DIGESTS_FILE" | grep -v '^Hash:')
exit 0