112 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| # Copyright 2018 B. Persson, Bjorn@Rombobeorn.se
 | |
| #
 | |
| # This material is provided as is, with absolutely no warranty expressed
 | |
| # or implied. Any use is at your own risk.
 | |
| #
 | |
| # Permission is hereby granted to use or copy this shellscript
 | |
| # for any purpose, provided the above notices are retained on all copies.
 | |
| # Permission to modify the code and to distribute modified code is granted,
 | |
| # provided the above notices are retained, and a notice that the code was
 | |
| # modified is included with the above copyright notice.
 | |
| 
 | |
| 
 | |
| function print_help {
 | |
|     cat <<'EOF'
 | |
| Usage: gpgverify --keyring=<pathname> --signature=<pathname> --data=<pathname>
 | |
| 
 | |
| gpgverify is a wrapper around gpgv designed for easy and safe scripting. It
 | |
| verifies a file against a detached OpenPGP signature and a keyring. The keyring
 | |
| shall contain all the keys that are trusted to certify the authenticity of the
 | |
| file, and must not contain any untrusted keys.
 | |
| 
 | |
| The differences, compared to invoking gpgv directly, are that gpgverify accepts
 | |
| the keyring in either ASCII-armored or unarmored form, and that it will not
 | |
| accidentally use a default keyring in addition to the specified one.
 | |
| 
 | |
| Parameters:
 | |
|   --keyring=<pathname>    keyring with all the trusted keys and no others
 | |
|   --signature=<pathname>  detached signature to verify
 | |
|   --data=<pathname>       file to verify against the signature
 | |
| EOF
 | |
| }
 | |
| 
 | |
| 
 | |
| fatal_error() {
 | |
|     message="$1"  # an error message
 | |
|     status=$2     # a number to use as the exit code
 | |
|     echo "gpgverify: $message" >&2
 | |
|     exit $status
 | |
| }
 | |
| 
 | |
| 
 | |
| require_parameter() {
 | |
|     term="$1"   # a term for a required parameter
 | |
|     value="$2"  # Complain and terminate if this value is empty.
 | |
|     if test -z "${value}" ; then
 | |
|         fatal_error "No ${term} was provided." 2
 | |
|     fi
 | |
| }
 | |
| 
 | |
| 
 | |
| check_status() {
 | |
|     action="$1"  # a string that describes the action that was attempted
 | |
|     status=$2    # the exit code of the command
 | |
|     if test $status -ne 0 ; then
 | |
|         fatal_error "$action failed." $status
 | |
|     fi
 | |
| }
 | |
| 
 | |
| 
 | |
| # Parse the command line.
 | |
| keyring=
 | |
| signature=
 | |
| data=
 | |
| for parameter in "$@" ; do
 | |
|     case "${parameter}" in
 | |
|         (--help)
 | |
|             print_help
 | |
|             exit
 | |
|             ;;
 | |
|         (--keyring=*)
 | |
|             keyring="${parameter#*=}"
 | |
|             ;;
 | |
|         (--signature=*)
 | |
|             signature="${parameter#*=}"
 | |
|             ;;
 | |
|         (--data=*)
 | |
|             data="${parameter#*=}"
 | |
|             ;;
 | |
|         (*)
 | |
|             fatal_error "Unknown parameter: \"${parameter}\"" 2
 | |
|             ;;
 | |
|     esac
 | |
| done
 | |
| require_parameter 'keyring' "${keyring}"
 | |
| require_parameter 'signature' "${signature}"
 | |
| require_parameter 'data file' "${data}"
 | |
| 
 | |
| # Make a temporary working directory.
 | |
| workdir="$(mktemp --directory)"
 | |
| check_status 'Making a temporary directory' $?
 | |
| workring="${workdir}/keyring.gpg"
 | |
| 
 | |
| # Decode any ASCII armor on the keyring. This is harmless if the keyring isn't
 | |
| # ASCII-armored.
 | |
| gpg2 --homedir="${workdir}" --yes --output="${workring}" --dearmor "${keyring}"
 | |
| check_status 'Decoding the keyring' $?
 | |
| 
 | |
| # Verify the signature using the decoded keyring.
 | |
| gpgv2 --homedir="${workdir}" --keyring="${workring}" "${signature}" "${data}"
 | |
| check_status 'Signature verification' $?
 | |
| 
 | |
| # (--homedir isn't actually necessary. --dearmor processes only the input file,
 | |
| # and if --keyring is used and contains a slash, then gpgv2 uses only that
 | |
| # keyring. Thus neither command will look for a default keyring, but --homedir
 | |
| # makes extra double sure that no default keyring will be touched in case
 | |
| # another version of GPG works differently.)
 | |
| 
 | |
| # Clean up. (This is not done in case of an error that may need inspection.)
 | |
| rm --recursive --force ${workdir}
 |