--- /dev/null
+#!/bin/bash
+# -*- bash -*-
+
+# Copyright (C) 2021 Jacob Bachmeyer
+#
+# This file is part of a testsuite for the GNU FTP upload system.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+: ${GNUPGHOME:=~/.gnupg}
+
+# parse command line
+while :; do
+ case "$1" in
+ --version)
+ echo 'gpgv (Testing mock)'
+ exit 0
+ ;;
+ --keyring)
+ case "$2" in
+ */*)
+ Keyrings="$Keyrings \"$2\""
+ ;;
+ *)
+ Keyrings="$Keyrings \"${GNUPGHOME}/$2\""
+ ;;
+ esac
+ shift 2
+ ;;
+ --homedir)
+ GNUPGHOME=$2
+ shift 2
+ ;;
+ --status-fd)
+ StatusFd=$2
+ shift 2
+ ;;
+ --logger-fd)
+ LogFd=$2
+ shift 2
+ ;;
+ --*)
+ echo bogus option $1
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+### Output helpers
+function status {
+ if [ x$StatusFd != x ]; then
+ echo '[GNUPG:]' "$@" >&${StatusFd}
+ fi
+}
+function log {
+ echo gpgv: "$@" >&${LogFd-2}
+}
+
+### Keyring handling
+
+# Mock keyrings consist of line-oriented records, in the format:
+# <long key ID>:<status>:<primary long key ID>:<user ID>:<expiration timestamp>
+# The <long key ID> field is 16 hex digits.
+# The <status> is 'V' for a valid key or 'R' for a revoked key.
+# The <primary long key ID> field may be omitted if same as key ID.
+# The <user ID> field is free-form text.
+# The <expiration timestamp> is empty for no expiration.
+
+# search keyrings for the given long key ID
+# return success and load global KeyRec if found
+function search_keyrings {
+ KeyRec=$(eval grep -he \"^$1:\" $Keyrings | head -1; \
+ return ${PIPESTATUS[0]})
+ return $?
+}
+# access fields from global KeyRec
+function keyrec_id() (IFS=: ; set -- $KeyRec ; echo $1)
+function keyrec_status()(IFS=: ; set -- $KeyRec ; echo $2)
+function keyrec_pri() (IFS=: ; set -- $KeyRec ; echo ${3:-$1})
+function keyrec_user() (IFS=: ; set -- $KeyRec ; echo $4)
+function keyrec_exp() (IFS=: ; set -- $KeyRec ; echo $5)
+
+function keyrec_expired() {
+ [ -n "$(keyrec_exp)" \
+ -a $(date -d "$(keyrec_exp)" +%s) -lt $(date -d now +%s) ]
+}
+function keyrec_revoked() { [ "$(keyrec_status)" = R ]; }
+
+### Signature handling
+
+ExitCode=0
+
+# handle SIGNED record in mock data
+function handle_SIGNED {
+ # SIGNED <status> <sigID> <keyID> "<timestamp>" \
+ # "<expiration timestamp>"
+ local status="$1" sigID="$2" keyID="$3" tstamp="$4"
+ if [ "x$5" = x ]; then local exptstamp=0
+ else local exptstamp=$(date -d "$5" +%s) exptstamp_raw="$5"
+ fi
+
+ log Signature made $(date -d "$tstamp" +'%a %b %e %T %Y %Z') \
+ using RSA key ID ${keyID:8}
+ if search_keyrings $keyID; then
+ # key was found in the keyrings
+
+ # handle caveats (expired signature, expired key, revoked key)
+ local chktype=GOOD desctype=Good
+ keyrec_revoked && chktype=REVKEY
+ keyrec_expired && chktype=EXPKEY
+ # Note that signatures from expired and revoked keys are still
+ # considered "Good" apparently ...
+ [ $exptstamp -gt 0 \
+ -a $exptstamp -lt $(date -d now +%s) ] \
+ && chktype=EXP desctype=Expired
+ # ... but a signature that has *itself* expired is reported.
+
+ case "$status" in
+ V) # valid signature
+ if keyrec_expired; then
+ status KEYEXPIRED $(date -d "$(keyrec_exp)" +%s)
+ fi
+ status SIG_ID testmock/sig/"$sigID"/id \
+ $(date -d "$tstamp" +'%Y-%m-%d %s')
+ status ${chktype}SIG $keyID $(keyrec_user)
+ log ${desctype} signature from \"$(keyrec_user)\"
+ status VALIDSIG 000000000000000000000000$keyID \
+ $(date -d "$tstamp" +'%Y-%m-%d %s') \
+ $exptstamp 3 0 1 2 01 \
+ 000000000000000000000000$(keyrec_pri)
+ if [ $chktype = EXP ]; then
+ log Signature expired \
+ $(date -d "$exptstamp_raw" +'%a %b %e %T %Y %Z')
+ elif [ $exptstamp -gt 0 ]; then
+ log Signature expires \
+ $(date -d "$exptstamp_raw" +'%a %b %e %T %Y %Z')
+ fi
+ ;;
+ B) # bogus signature
+ status BADSIG $keyID $(keyrec_user)
+ log BAD signature from \"$(keyrec_user)\"
+ ExitCode=1
+ ;;
+ esac
+
+ else
+ # key not found
+ status ERRSIG $keyID 1 2 01 $(date -d "$tstamp" +%s) 9
+ status NO_PUBKEY $keyID
+ log "Can't check signature:" public key not found
+ ExitCode=2
+ fi
+}
+
+# process a "signature" file for a testing run
+function process_sig_file {
+ while read line; do
+ case "$line" in
+ -----BEGIN?PGP?SIGNATURE-----)
+ break
+ ;;
+ DETACHED?SIGNATURE)
+ DataFile="$1"
+ shift
+ break
+ esac
+ done
+ while read token rest; do
+ case "$token" in
+ -----END)
+ break
+ ;;
+ Version:)
+ # this looks like a GPG signature instead of mock data...
+ # complain... loudly
+ echo mockgpgv: looks like someone fed a real signature \
+ to the mock tool
+ log mock: real GPG signature detected instead of mock test data
+ status NODATA 3
+ exit 120
+ ;;
+ SIGNED_FILE)
+ if [ x"$DataFile" = x ]; then
+ log no signed data
+ log "can't hash datafile:" file open error
+ ExitCode=2
+ break
+ elif [ ! -f "$DataFile" ]; then
+ log "can't open signed data" $DataFile
+ log "can't hash datafile:" file open error
+ ExitCode=2
+ break
+ fi
+ ;;
+ SIGNED)
+ eval handle_SIGNED $rest
+ ;;
+ *)
+ echo $token $rest
+ ;;
+ esac
+ done
+} <"$SigFile"
+
+# check that we were actually given a file to process
+if [ x"$*" = x ]; then
+ status NODATA 2
+ log verify signatures failed: eof
+ exit 2
+fi
+
+# check that the file is readable and process it
+SigFile="$1"
+shift
+if [ -r "$SigFile" ] ; then
+ process_sig_file "$@"
+else
+ log "can't" open '`'"$SigFile'"
+ log verify signatures failed: file open error
+ exit 2
+fi
+
+exit $ExitCode
+
+#EOF
--- /dev/null
+# Signature "verification" tests for GPG mock
+
+# Copyright (C) 2021 Jacob Bachmeyer
+#
+# This file is part of a testsuite for the GNU FTP upload system.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+file mkdir $::env(GNUPGHOME)
+
+write_test_keyring [file join $::env(GNUPGHOME) dg1.gpg] {
+ { id 1001 name {test 1-1} }
+ { id 1002 name {test 1-2} }
+ { id 1003 name {test 1-3} expires {+5 minutes} }
+ { id 1004 name {test 1-4 (expired)} expired {5 minutes ago} }
+ { id 1005 name {test 1-5 (revoked)} is revoked }
+ { id 1006 name {test 1-6 (revoked expired)}
+ is revoked expired {5 minutes ago} }
+}
+
+write_test_keyring [file join $::env(GNUPGHOME) dg2.gpg] {
+ { id 1011 name {test 2-1 (primary)} }
+ { id 1012 name {test 2-2 (subkey)} subkey-of 1011 }
+ { id 1013 name {test 2-3 (subkey)} subkey-of 1011 expires {+5 minutes} }
+ { id 1014 name {test 2-4 (expired subkey)}
+ subkey-of 1011 expired {5 minutes ago} }
+ { id 1015 name {test 2-5 (revoked subkey)}
+ subkey-of 1011 is revoked }
+ { id 1016 name {test 2-6 (revoked expired subkey)}
+ subkey-of 1011 is revoked expired {5 minutes ago} }
+}
+
+#
+
+proc prepare_test_group { stem message signature } {
+ put_file $stem $message
+ put_file "${stem}.asc" [sign_test_message $message $signature]
+ put_file "${stem}.sig" [sign_test_file $stem $signature]
+}
+
+proc spawn_gpgv { keyrings args } {
+ global MOCKGPGV
+ upvar 1 spawn_id spawn_id
+ set cmd [list spawn $MOCKGPGV --logger-fd 2 --status-fd 2]
+ foreach ring $keyrings { lappend cmd --keyring $ring }
+ verbose -log "$cmd $args"
+ eval $cmd $args
+}
+
+# InitialCapital variable names may be used in the $expect block.
+# The "test_dir" variable is also set for the $init block.
+proc run_gpgv_test { Name stem keyrings exitCode init phases assess expect } {
+ set test_dir [file join \
+ [file dirname [testsuite file -object -top]] test.tmp]
+ file mkdir $test_dir
+
+ eval $init
+
+ array set A {}
+ append expect {
+ -re {^[\r\n]+} { exp_continue }
+ -re .+ {
+ warning "$Name (${Phase}): unexpected output from mockgpgv"
+ exp_continue
+ }
+ eof { set waited [wait] }
+ }
+
+ foreach Phase $phases {
+ foreach {key desc} $assess { set A($Phase,$key) 0 }
+ switch -- $Phase {
+ inline {
+ spawn_gpgv $keyrings \
+ [file join $test_dir "${stem}.asc"]
+ }
+ detached {
+ spawn_gpgv $keyrings \
+ [file join $test_dir "${stem}.sig"] \
+ [file join $test_dir "${stem}"]
+ }
+ file_missing {
+ spawn_gpgv $keyrings \
+ [file join $test_dir "${stem}.sig"]
+ }
+ }
+ expect $expect
+ if { [lindex $waited 2] != 0 } {
+ perror "OS error in child process: $waited"
+ } else {
+ if { [lindex $waited 3] == $exitCode } {
+ pass "$Name (${Phase}): expected exit code"
+ } else {
+ fail "$Name (${Phase}): expected exit code"
+ verbose -log [format "%s (%s): expected exit code %d got %d" \
+ $Name $Phase $exitCode [lindex $waited 3]]
+ }
+ }
+ foreach {key desc} $assess {
+ if { $A($Phase,$key) } {
+ pass "$Name (${Phase}): $desc"
+ } else {
+ fail "$Name (${Phase}): $desc"
+ }
+ }
+ }
+}
+proc do_gpgv_test { Name stem keyrings exitCode signature assess expect } {
+ run_gpgv_test $Name $stem $keyrings $exitCode \
+ "prepare_test_group \[file join \$test_dir {$stem}\] {$Name} {$signature}"\
+ {inline detached} $assess $expect
+}
+
+#
+
+do_gpgv_test "unknown key used for signature" t0a {dg1.gpg dg2.gpg} 2 \
+ [make_test_signature good 00 8765 "5 minutes ago"] {
+ sighdr "signature header" ERRSIG "ERRSIG status"
+ NO_PUBKEY "NO_PUBKEY status" keynotfound "key not found message"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00008765[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Can't check signature: public key not found[\r\n]+} {
+ set A($Phase,keynotfound) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] ERRSIG 0{12}8765 1 2 01 [0-9]+ 9[\r\n]+} {
+ set A($Phase,ERRSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] NO_PUBKEY 0{12}8765[\r\n]+} {
+ set A($Phase,NO_PUBKEY) 1
+ exp_continue
+ }
+ }
+run_gpgv_test "detached signature without signed file" t0b {dg1.gpg dg2.gpg} 2 \
+ { put_file [file join $test_dir t0b.sig] \
+ [sign_test_file t0b \
+ [make_test_signature good 00 1001 "5 minutes ago"]]
+ } {file_missing} {
+ nodata "missing data message" canthash "file open error message"
+ } {
+ -re {^gpgv: no signed data[\r\n]+} {
+ set A($Phase,nodata) 1
+ exp_continue
+ }
+ -re {^gpgv: can't hash datafile: file open error[\r\n]+} {
+ set A($Phase,canthash) 1
+ exp_continue
+ }
+ }
+run_gpgv_test "detached signature with missing signed file" t0c {dg1.gpg} 2 \
+ { put_file [file join $test_dir t0c.sig] \
+ [sign_test_file t0c \
+ [make_test_signature good 00 1001 "5 minutes ago"]]
+ } {detached} {
+ cantopen "missing file message" canthash "file open error message"
+ } {
+ -re {^gpgv: can't open signed data [^\r\n]+[\r\n]+} {
+ set A($Phase,cantopen) 1
+ exp_continue
+ }
+ -re {^gpgv: can't hash datafile: file open error[\r\n]+} {
+ set A($Phase,canthash) 1
+ exp_continue
+ }
+ }
+run_gpgv_test "all signed files missing" t0d {dg1.gpg} 2 \
+ { put_file [file join $test_dir t0d] $Name } {inline detached} {
+ cantopen "missing file message" failuremsg "verify failure message"
+ } {
+ -re {^gpgv: can't open [^\r\n]+[\r\n]+} {
+ set A($Phase,cantopen) 1
+ exp_continue
+ }
+ -re {^gpgv: verify signatures failed: file open error[\r\n]+} {
+ set A($Phase,failuremsg) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "valid signature" t1a {dg1.gpg} 0 \
+ [make_test_signature good 00 1001 "5 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ SIG_ID "SIG_ID status"
+ GOODSIG "GOODSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001001[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 1-1"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/00/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] GOODSIG 0{12}1001 test 1-1[\r\n]+} {
+ set A($Phase,GOODSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1001 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1001[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "valid signature from subkey" t1b {dg2.gpg} 0 \
+ [make_test_signature good 80 1012 "5 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ SIG_ID "SIG_ID status"
+ GOODSIG "GOODSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001012[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 2-2 \(subkey\)"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/80/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] GOODSIG 0{12}1012 test 2-2 \(subkey\)[\r\n]+} {
+ set A($Phase,GOODSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1012 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "bad signature" t2a {dg1.gpg} 1 \
+ [make_test_signature bad 01 1002 "5 minutes ago"] {
+ sighdr "signature header" badsigmsg "bad signature message"
+ BADSIG "BADSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001002[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: BAD signature from "test 1-2"[\r\n]+} {
+ set A($Phase,badsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] BADSIG 0{12}1002 test 1-2[\r\n]+} {
+ set A($Phase,BADSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "bad signature from subkey" t2b {dg2.gpg} 1 \
+ [make_test_signature bad 01 1012 "5 minutes ago"] {
+ sighdr "signature header" badsigmsg "bad signature message"
+ BADSIG "BADSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001012[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: BAD signature from "test 2-2 \(subkey\)"[\r\n]+} {
+ set A($Phase,badsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] BADSIG 0{12}1012 test 2-2 \(subkey\)[\r\n]+} {
+ set A($Phase,BADSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "expired signature" t3a {dg1.gpg} 0 \
+ [make_test_signature good 02 1001 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001001[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 1-1"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/02/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1001 test 1-1[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1001 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1001[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "expired signature from subkey" t3b {dg2.gpg} 0 \
+ [make_test_signature good 82 1012 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001012[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 2-2 \(subkey\)"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/82/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1012 test 2-2 \(subkey\)[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1012 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "good signature from expired key" t4a {dg1.gpg} 0 \
+ [make_test_signature good 03 1004 "6 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPKEYSIG "EXPKEYSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001004[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 1-4 \(expired\)"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/03/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPKEYSIG 0{12}1004 test 1-4 \(expired\)[\r\n]+} {
+ set A($Phase,EXPKEYSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1004 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1004[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "good signature from expired subkey" t4b {dg2.gpg} 0 \
+ [make_test_signature good 83 1014 "6 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPKEYSIG "EXPKEYSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001014[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 2-4 \(expired subkey\)"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/83/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPKEYSIG 0{12}1014 test 2-4 \(expired subkey\)[\r\n]+} {
+ set A($Phase,EXPKEYSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1014 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "expired signature from expired key" t5a {dg1.gpg} 0 \
+ [make_test_signature good 04 1004 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001004[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 1-4 \(expired\)"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/04/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1004 test 1-4 \(expired\)[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1004 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1004[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "expired signature from expired subkey" t5b {dg2.gpg} 0 \
+ [make_test_signature good 84 1014 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001014[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 2-4 \(expired subkey\)"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/84/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1014 test 2-4 \(expired subkey\)[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1014 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "signature from revoked key" t6a {dg1.gpg} 0 \
+ [make_test_signature good 05 1005 "5 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ SIG_ID "SIG_ID status"
+ REVKEYSIG "REVKEYSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001005[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 1-5 \(revoked\)"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/05/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] REVKEYSIG 0{12}1005 test 1-5 \(revoked\)[\r\n]+} {
+ set A($Phase,REVKEYSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1005 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1005[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "signature from revoked subkey" t6b {dg2.gpg} 0 \
+ [make_test_signature good 85 1015 "5 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ SIG_ID "SIG_ID status"
+ REVKEYSIG "REVKEYSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001015[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 2-5 \(revoked subkey\)"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/85/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] REVKEYSIG 0{12}1015 test 2-5 \(revoked subkey\)[\r\n]+} {
+ set A($Phase,REVKEYSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1015 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "expired signature from revoked key" t7a {dg1.gpg} 0 \
+ [make_test_signature good 06 1005 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001005[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 1-5 \(revoked\)"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/06/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1005 test 1-5 \(revoked\)[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1005 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1005[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "expired signature from revoked subkey" t7b {dg2.gpg} 0 \
+ [make_test_signature good 86 1015 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001015[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 2-5 \(revoked subkey\)"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/86/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1015 test 2-5 \(revoked subkey\)[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1015 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "signature from revoked expired key" t8a {dg1.gpg} 0 \
+ [make_test_signature good 07 1006 "6 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPKEYSIG "EXPKEYSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001006[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 1-6 \(revoked expired\)"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/07/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPKEYSIG 0{12}1006 test 1-6 \(revoked expired\)[\r\n]+} {
+ set A($Phase,EXPKEYSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1006 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1006[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "signature from revoked expired subkey" t8b {dg2.gpg} 0 \
+ [make_test_signature good 87 1016 "6 minutes ago"] {
+ sighdr "signature header" goodsigmsg "good signature message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPKEYSIG "EXPKEYSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001016[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Good signature from "test 2-6 \(revoked expired subkey\)"[\r\n]+} {
+ set A($Phase,goodsigmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/87/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPKEYSIG 0{12}1016 test 2-6 \(revoked expired subkey\)[\r\n]+} {
+ set A($Phase,EXPKEYSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1016 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+
+do_gpgv_test "expired signature from revoked key" t9a {dg1.gpg} 0 \
+ [make_test_signature good 08 1006 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001006[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 1-6 \(revoked expired\)"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/08/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1006 test 1-6 \(revoked expired\)[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1006 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1006[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }
+do_gpgv_test "expired signature from expired subkey" t9b {dg2.gpg} 0 \
+ [make_test_signature good 88 1016 "10 minutes ago" expired "5 minutes ago"] {
+ sighdr "signature header" expsigmsg "expired signature message"
+ sigexpmsg "signature expiration message"
+ KEYEXPIRED "KEYEXPIRED status" SIG_ID "SIG_ID status"
+ EXPSIG "EXPSIG status" VALIDSIG "VALIDSIG status"
+ } {
+ -re {^gpgv: Signature made [^:]+:..:[^k]+key ID 00001016[\r\n]+} {
+ set A($Phase,sighdr) 1
+ exp_continue
+ }
+ -re {^gpgv: Expired signature from "test 2-6 \(revoked expired subkey\)"[\r\n]+} {
+ set A($Phase,expsigmsg) 1
+ exp_continue
+ }
+ -re {^gpgv: Signature expired [^:]+:..:[^\r\n]+[\r\n]+} {
+ set A($Phase,sigexpmsg) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] KEYEXPIRED [0-9]+[\r\n]+} {
+ set A($Phase,KEYEXPIRED) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] SIG_ID testmock/sig/88/id ....-..-.. [0-9]+[\r\n]+} {
+ set A($Phase,SIG_ID) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] EXPSIG 0{12}1016 test 2-6 \(revoked expired subkey\)[\r\n]+} {
+ set A($Phase,EXPSIG) 1
+ exp_continue
+ }
+ -re {^\[GNUPG:\] VALIDSIG 0{36}1016 [-0-9]+ [0-9]+ [0-9]+ 3 0 1 2 01 0{36}1011[\r\n]+} {
+ set A($Phase,VALIDSIG) 1
+ exp_continue
+ }
+ }