list, export and remove RPM GPG keys.

This is a small script to list, display and optionally export and remove gpg public keys.
I was inspired by this thread new repository key - how to verify?, had actually the same problem with the same repo (and still have it). But I needed such a tool for a long time already. Here is it.

#!/bin/bash

#: Title	: lskeys
#: Date Created : Thu Oct 27 22:44:20 PDT 2011
#: Last Edit	: Thu Oct 27 23:56:46 PDT 2011 
#: Author	: Agnelo de la Crotche (please_try_again)
#: Version	: 1.0
#: Description	: lists, exports, deletes RPM GPG keys
#: Syntax	: lskeys [option]
#: Options      : -e --export : exports selected key
#:              : -d --delete : ereases selected key 

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 "x$1" == "x-e" -o "x$1" == "x--export" ] && EXPORT=1
 "x$1" == "x-d" -o "x$1" == "x--delete" ] && DELETE=1
i=0
for k in $(rpm -qa gpg-pubkey*) ; do
	let i++	
	K$i]=$k ; K=${k/gpg-pubkey-/}
	eval $(LC_ALL=C rpm -qi $k | awk '/Summary|Build Date/ {sub(/.*Build Date:/, "Date :", $0 ) ; sub(/gpg\(/, "", $0) ; if ( $1 == "Date" ) printf "D=\"%2i-%s-%s\";
",$5, $4, $7 ; else { gsub(/Summary *: */,"", $0) ; sub(/\)$/,"",$0) ; printf "T=\"%s\";
", $0 }}' | sed 's|" |"0|')
	N$i]=$(echo $T | sed 's|<.*||;s|(.*||;s| Signing Key||;s|OBS Project|OBS|;s|\(.*\) OBS|OBS:\1|;s|,;.]||g;s| *$||;s| |_|g;s|^|RPM-GPG-KEY-|;s|$|.key|')
	printf "%2s]  %s%-22s%s%-15s%s%s%s
" $i $(tput bold) $K $(tput sgr0) $D $(tput setaf 2) "$T" $(tput sgr0)
done

j=0

declare -u j
while  $j -lt 1 -o $j -gt $i ] ; do
	read -p "view key [1-$i or Q to quit]: " j
	 "$j" == "Q" ] && break
	j=$(($j*1))
	echo
	 "${K$j]}" ] && rpm -qi ${K$j]}
	if  "$EXPORT" ] ; then
		rpm -qi ${K$j]} | sed -n '/BEGIN/,/END/p' > ${N$j]} && printf "
Key %s%s%s%s successfully written in %s%s/%s%s
" $(tput bold) $(tput setaf 3) ${K$j]} $(tput sgr0) $(tput bold) $(pwd) ${N$j]} $(tput sgr0)
	elif  "$DELETE" ] ; then
		declare -u YN
		YN=""
		while  "x$YN" != "xY" -a "x$YN" != "xN" ] ; do
			read -p "Delete key ${K$j]}? [y/n] " YN
			 "$YN" == "Y" ] && rpm -e ${K$j]} && printf "
Key %s%s%s%s successfully deleted.
" $(tput bold) $(tput setaf 3) ${K$j]} $(tput sgr0)
		done
	fi
done

Usage:

Type lskeys and select the key you want to display.
To export a key in a file in the current directory, type lskeys -e and select the key you want to export.
To erase a key, type lskeys -d and select the key you want to remove.

Now, this one is simple, isn’t it?

The version in the post above works in openSUSE and Mandriva. The following version 1.1 also works in Fedora.

#!/bin/bash

#: Title	: lskeys
#: Date Created : Thu Oct 27 22:44:20 PDT 2011
#: Last Edit	: Fri Oct 28 05:48:44 PDT 2011
#: Author	: Agnelo de la Crotche (please_try_again)
#: Version	: 1.1
#: Description	: lists, exports, deletes RPM GPG keys
#: Syntax	: lskeys [option]
#: Options      : -e --export : exports selected key
#:              : -d --delete : ereases selected key 

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 "x$1" == "x-e" -o "x$1" == "x--export" ] && EXPORT=1
 "x$1" == "x-d" -o "x$1" == "x--delete" ] && DELETE=1
i=0
for k in $(rpm -qa gpg-pubkey*) ; do
	let i++	
	K$i]=$k ; K=${k/gpg-pubkey-/}
	eval $(LC_ALL=C rpm -qi $k | sed 's|[0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}||;s/ 	]\+\(Build Date\):/
\1 :/;s/Date 	]*: .\{3\} /Date  : /;s/.*gpg(/T="/;s/)$/";/;s/Build Date.*: *\(^ ]*\) *\(^ ]*\) *\([0-9]\{4\}\).*/D="\2-\1-\3";/;s/="\([0-9]\)-/="0\1-/' | awk '/^D=|^T=/{ print}')
	N$i]=$(echo $T | sed 's|<.*||;s|(.*||;s| Signing Key||;s|OBS Project|OBS|;s|\(.*\) OBS|OBS:\1|;s|,;.]||g;s| *$||;s| |_|g;s|^|RPM-GPG-KEY-|;s|$|.key|')
	printf "%2s]  %s%-22s%s%-15s%s%s%s
" $i $(tput bold) $K $(tput sgr0) $D $(tput setaf 2) "$T" $(tput sgr0)
done

j=0

declare -u j
while  $j -lt 1 -o $j -gt $i ] ; do
	read -p "view key [1-$i or Q to quit]: " j
	 "$j" == "Q" ] && break
	j=$(($j*1))
	echo
	 "${K$j]}" ] && rpm -qi ${K$j]}
	if  "$EXPORT" ] ; then
		rpm -qi ${K$j]} | sed -n '/BEGIN/,/END/p' > ${N$j]} && printf "
Key %s%s%s%s successfully written in %s%s/%s%s
" $(tput bold) $(tput setaf 3) ${K$j]} $(tput sgr0) $(tput bold) $(pwd) ${N$j]} $(tput sgr0)
	elif  "$DELETE" ] ; then
		declare -u YN
		YN=""
		while  "x$YN" != "xY" -a "x$YN" != "xN" ] ; do
			read -p "Delete key ${K$j]}? [y/n] " YN
			 "$YN" == "Y" ] && rpm -e ${K$j]} && printf "
Key %s%s%s%s successfully deleted.
" $(tput bold) $(tput setaf 3) ${K$j]} $(tput sgr0)
		done
	fi
done

I wrote this version a while ago but wanted to post it before I modify the script to add support for Ubuntu apt-key.

lskeys v 2.0

This new version supports Ubuntu/Debian apt-key, displays creation (instead of installation) date, expiration date if any and highlights keys that have expired in red. I tested it under openSUSE (11.4), Fedora (15), Mandriva (2001) and Ubuntu (11.10). It should work under Mint and Debian as well. Other LSB compliant distros storing packages signing keys in the rpm database or using debian apt-key can be added. Just add the ouput of **lsb_release -si **(after removing the spaces within the string if there are any) in the *case $linux *statement (in red in the code below).


#!/bin/bash
#: Title	: lskeys
#: Date Created : Thu Oct 27 22:44:20 PDT 2011
#: Last Edit	: Fri Nov 18 23:17:02 PST 2011
#: Author	: Agnelo de la Crotche (please_try_again)
#: Version	: 2.0
#: Description	: lists, exports, deletes RPM GPG keys
#: Syntax	: lskeys [option]
#: Options      : -e --export : exports selected key
#:              : -d --delete : ereases selected key 

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

declare -l linux dist
declare -a K E N T S

if ( which lsb_release &>/dev/null ) ; then
	linux=$(lsb_release -si | tr -d " ")
else
	linux=$(sudo find /etc ! -name "meta*" ! -name "lsb*" ! -name "system*" ! -name "jpackage*" -name "*-release" -exec basename "{}" -release ";" 2>/dev/null | sort | head -1)
fi

case $linux in
fedora|suse|suselinux|mandrivalinux) dist=rpm ;;
ubuntu|linuxmint|debian) dist=apt ;;
*) exec echo "unsupported distro" ;;
esac

 "x$1" == "x-e" -o "x$1" == "x--export" ] && EXPORT=1
 "x$1" == "x-d" -o "x$1" == "x--delete" ] && DELETE=1

i=0

function listkeys {
	case $dist in
	rpm)
		for k in $(rpm -qa gpg-pubkey*) ; do
			let i++	; K$i]=$k ; N$i]=${k/gpg-pubkey-/}
			eval $(LC_ALL=C rpm -qi $k | gpg --with-key-data 2>/dev/null | awk -F ":" '/^pub/ { gsub(/\\x3/,":", $10) ; if ($6 ~ /-/ ) printf "%s;%s;", $6, $10 ; else printf "%s;%s;", strftime("%Y-%m-%d", $6), $10 ; if ( $7 ~ /-/ ) printf "%s" , $7 ; else if ( $7 ) printf "%s", strftime("%Y-%m-%d", $7) ; printf "
" }' | sed "s|\(.*\);\(.*\);\(.*\)|T$i]=\"\1\";S$i]=\"\2\";E$i]=\"\3\";|")
		done
	;;
	apt)
		eval $(LC_ALL=C apt-key list | sed -e '/^sub/d' | sed -e :a -e '$!N;s/
uid */; /;ta' -e 'P;D' | sed -n 's/pub *//p' | sed 's/>;.*//;s| |;|;s|\(.*\) \[expires: \([0-9-]*\)\]; *\(.*\)|\1;\3;\2|;s|; *|;|g' | awk -F ";" '{ K=$1 ; sub(/.*\//, "", K) ; N=$1 ; sub(/\//, "-", N) ; printf "K%i]=\"%s\";N%i]=\"%s\";T%i]=\"%s\";S%i]=\"%s\";
", NR, K, NR, N, NR, $2, NR, $3 ; if ($4) printf "E%i]=\"\%s\";", NR, $4 }'  2>/dev/null)
	;;
	*) return 1 ;;
	esac
}

function viewkey {
	case $dist in
		rpm) rpm -qi $1 ;;
		apt) apt-key export $1 ;;
		*) return 1 ;;
	esac
}

function deletekey {
	case $dist in
		rpm) rpm -e $1 ;;
		apt) apt-key del $1 ;;
		*) return 1 ;;
	esac
}

function isExpired {
	keyTime=$(echo "${@//-/ } 00 00 00" | awk ' { print mktime($0) }')
	sysTime=$(awk 'BEGIN { print systime()}')
	 $keyTime -lt $sysTime ] && return 0 || return 1
}

listkeys

i=1
while  $i -le ${#N@]} ] ; do
	KCL=$(tput setaf 7) ; TCL=$(tput sgr0) ; SCL=$(tput setaf 2)
	 "${E$i]}" ] && isExpired ${E$i]} && { KCL=$(tput setaf 1); TCL=$(tput setaf 1) ; SCL=$(tput setaf 1); }
	printf "%2s] %s%s%-20s%s%-13s%s%-13s%s%s%s
" $i $(tput bold) $KCL ${N$i]} $TCL "${T$i]}" $(tput setaf 1) "${E$i]}" $SCL "${S$i]}" $(tput sgr0)
	let i++
done
let i--

declare -u j=0

while  $j -lt 1 -o $j -gt $i ] ; do
	read -p "view key [1-$i or Q to quit]: " j
	 "$j" == "Q" ] && break
	j=$(($j*1))
	echo
	 "${K$j]}" ] && viewkey ${K$j]}
	if  "$EXPORT" ] ; then
		GPG="$(echo $dist | tr ":lower:]" ":upper:]")GPG-${N$j]}.key"
		echo $GPG		
		viewkey ${K$j]} | sed -n '/BEGIN/,/END/p' > $GPG && printf "
Key %s%s%s%s successfully written in %s%s/%s%s
" $(tput bold) $(tput setaf 3) ${N$j]} $(tput sgr0) $(tput bold) $(pwd) $GPG $(tput sgr0)
	elif  "$DELETE" ] ; then
		declare -u YN
		YN=""
		while  "x$YN" != "xY" -a "x$YN" != "xN" ] ; do
			read -p "Delete key ${K$j]}? [y/n] " YN
			 "$YN" == "Y" ] && deletekey ${K$j]} && printf "
Key %s%s%s%s successfully deleted.
" $(tput bold) $(tput setaf 3) ${K$j]} $(tput sgr0)
		done
	fi
done

http://img17.imageshack.us/img17/2001/lskeys.th.png](http://img17.imageshack.us/img17/2001/lskeys.png)