#!/bin/bash # # \brief Signature verification tool # \author Stephan Müller # \date 2013-05-24 # # Script to be invoked as # $0 # # The source pubkey(s) is some ID that can be handled by gpg --search-keys # or --recv-keys # The special keyword of GNU as source pubkey implies the downloading of the GNU # key ring. # # Script returns 0 on success. Any other value is a failure. FILE=$1 SIGFILE=$2 shift;shift; PUBKEYSRC=$@ # # Probe if a default keyserver is configured by the user. If not, fall back to # a predefined key server. # KEYSERVER="" if ! $(cat $HOME/.gnupg/gpg.conf | grep -v '^#.*' | grep -q keyserver); then KEYSERVER="--keyserver hkp://keys.gnupg.net" fi # Get a particular key # \param key fingerprint to obtain get_gpg_key() { key=$1 # check if key is present gpg --list-key $key > /dev/null 2>&1 if [ $? -eq 0 ];then return fi size=$(echo -n $key |wc -m) if [ "$size" -eq 40 ] then # we have a full fingerprint gpg $KEYSERVER --recv-keys $key else # we have some other ID gpg $KEYSERVER --search-keys $key fi } GNUURL="ftp://ftp.gnu.org/gnu/gnu-keyring.gpg" get_gnu_keys() { sigfile=$1 sigdir=$(dirname $sigfile) if [ ! -d "$sigdir" ] then echo "Directory $sigdir does not exist" exit 1 fi targetfile=$(basename $GNUURL) if [ ! -f "$sigdir/$targetfile" ] then wget -c -P $sigdir $GNUURL fi } # Get all keys handed in # \param array of keys to be searched get_all_keys() { keys=$@ for i in $keys do get_gpg_key $i done } # Verify the file # \param file to be verified # \param signature file # # function causes script to exit: # return 0 implies all passed # any other return code implies failure verify_file() { file=$1 sigfile=$2 gpgargs="" targetfile=$(basename $GNUURL) sigdir=$(dirname $sigfile) if [ -f "$sigdir/$targetfile" ] then gpgargs="--keyring $sigdir/$targetfile" fi if [ -z "$file" -o ! -f "$file" ] then echo "File $file not found" exit 1 fi if [ -z "$sigfile" -o ! -f "$sigfile" ] then echo "Signature file $sigfile not found" exit 1 fi gpg --verify $gpgargs $sigfile $file if [ $? -ne 0 ] then echo "Signature check of file $file failed" exit 1 fi echo "Signature check of file $file passed" exit 0 } if [ "$PUBKEYSRC" = "GNU" ] then get_gnu_keys $SIGFILE else get_all_keys "$PUBKEYSRC" fi verify_file $FILE $SIGFILE