From ea1ed90ecd996494e8bd2994b141dde54d402ff9 Mon Sep 17 00:00:00 2001 From: Jacob Bachmeyer Date: Tue, 9 Mar 2021 23:48:12 -0600 Subject: [PATCH] Add mock gpgv signature verification tool and mock tool testsuite --- testsuite/lib/exec/mockgpgv | 239 +++++++++++ testsuite/lib/mock.exp | 40 ++ testsuite/lib/mockgpg.exp | 111 ++++++ testsuite/mock.gpgv/sign.exp | 741 +++++++++++++++++++++++++++++++++++ 4 files changed, 1131 insertions(+) create mode 100755 testsuite/lib/exec/mockgpgv create mode 100644 testsuite/lib/mock.exp create mode 100644 testsuite/lib/mockgpg.exp create mode 100644 testsuite/mock.gpgv/sign.exp diff --git a/testsuite/lib/exec/mockgpgv b/testsuite/lib/exec/mockgpgv new file mode 100755 index 0000000..c4ccfd2 --- /dev/null +++ b/testsuite/lib/exec/mockgpgv @@ -0,0 +1,239 @@ +#!/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 . + +: ${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: +# :::: +# The field is 16 hex digits. +# The is 'V' for a valid key or 'R' for a revoked key. +# The field may be omitted if same as key ID. +# The field is free-form text. +# The 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 "" \ + # "" + 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 diff --git a/testsuite/lib/mock.exp b/testsuite/lib/mock.exp new file mode 100644 index 0000000..da21208 --- /dev/null +++ b/testsuite/lib/mock.exp @@ -0,0 +1,40 @@ +# DejaGnu tool init file for testing gpgv mock tests + +# 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 . + +set MINLOGD [testsuite file -source -top lib exec minlogd.pl] +set MINSMTPD [testsuite file -source -top lib exec minsmtpd.tcl] + +set MOCKGPGV [testsuite file -source -top lib exec mockgpgv] +set ::env(GNUPGHOME) [file join \ + [file dirname [testsuite file -object -top]] \ + test.tmp gpgv] + +load_lib mockgpg.exp + +proc put_file { file string } { + set chan [open $file w] + puts -nonewline $chan $string + close $chan +} + +proc mock_exit {} {} +proc mock_version {} {} +# The mock tools do not have independent versions. + +#EOF diff --git a/testsuite/lib/mockgpg.exp b/testsuite/lib/mockgpg.exp new file mode 100644 index 0000000..a2f702e --- /dev/null +++ b/testsuite/lib/mockgpg.exp @@ -0,0 +1,111 @@ +# DejaGnu library file for mockGPG support procedures + +# 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 . + +# Wrap value in double quotes if it contains spaces. +proc _mockGPG_quote_value { val } { + if { [regexp {[[:space:]]} $val] } { + return "\"$val\"" + } else { + return $val + } +} + +# Prepare a keyring file suitable for the GPG mock tools. +# Call as: +# write_test_keyring /some/file/some/where { +# { id name [is ] +# [subkey-of ] +# [expires ] }... +# } +proc write_test_keyring { file keylist } { + set keys [list] + foreach keyrec $keylist { + set keyfields [list {} V {} {} {}] + foreach { fld val } $keyrec { + switch -- $fld { + id { + lset keyfields 0 [format "%016s" $val] + } + name { + lset keyfields 3 $val + } + is { + switch -- $val { + valid { lset keyfields 1 V } + revoked { lset keyfields 1 R } + } + } + subkey-of { + lset keyfields 2 [format "%016s" $val] + } + expired - + expires { + lset keyfields 4 $val + } + default { error "invalid key record: $keyrec" } + } + } + lappend keys [join $keyfields ":"] + } + set chan [open $file w] + foreach key $keys { puts $chan $key } + close $chan +} + +# Return a signature suitable for the GPG mock tools. +# Call as: +# make_test_signature [] \ +# [expires ] +proc make_test_signature { validity sigID keyID + {timestamp {5 minutes ago}} args } { + set sig "SIGNED" + + if { $validity eq "good" } { + lappend sig V + } elseif { $validity eq "bad" } { + lappend sig B + } else { error "bad call to make_test_signature" } + + lappend sig [_mockGPG_quote_value $sigID] + lappend sig [_mockGPG_quote_value [format "%016s" $keyID]] + lappend sig [_mockGPG_quote_value $timestamp] + + if { [llength $args] > 1 && [regexp {expire[ds]} [lindex $args 0]] } { + lappend sig [_mockGPG_quote_value [lindex $args 1]] + } + + return [join $sig " "] +} + +# Combine a message and a signature (from [make_test_signature ...]) +proc sign_test_message { message signature } { + set msg "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\n" + append msg $message + append msg "\n-----BEGIN PGP SIGNATURE-----\n" + append msg $signature + append msg "\n-----END PGP SIGNATURE-----\n" + return $msg +} + +# Return a detached signature +proc sign_test_file { filename signature } { + return "DETACHED SIGNATURE\nSIGNED_FILE ${filename}\n$signature\n" +} + +#EOF diff --git a/testsuite/mock.gpgv/sign.exp b/testsuite/mock.gpgv/sign.exp new file mode 100644 index 0000000..5f8208f --- /dev/null +++ b/testsuite/mock.gpgv/sign.exp @@ -0,0 +1,741 @@ +# 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 . + +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 + } + } -- 2.25.1