Add testsuite infrastructure for checking use of timestamp database
authorJacob Bachmeyer <jcb@gnu.org>
Fri, 28 Apr 2023 23:18:01 +0000 (18:18 -0500)
committerJacob Bachmeyer <jcb@gnu.org>
Fri, 28 Apr 2023 23:18:01 +0000 (18:18 -0500)
testsuite/lib/serials.exp [new file with mode: 0644]

diff --git a/testsuite/lib/serials.exp b/testsuite/lib/serials.exp
new file mode 100644 (file)
index 0000000..0d5fd7d
--- /dev/null
@@ -0,0 +1,87 @@
+# DejaGnu library file for timestamp ratchet handling
+
+# Copyright (C) 2023 Jacob Bachmeyer
+#
+# This file is part of a testsuite for the GNU Secure Software Gatekeeper.
+#
+# 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/>.
+
+# The timestamp ratchet, also known as the "serials" file, enables the
+# gatekeeper to detect and reject replay attacks.  The actual file is a
+# flat text file, but a format change to an indexed text-based database is
+# planned.
+
+# allow a few seconds difference from expected values to accommodate delays
+# while running the testsuite
+set SERIALS_TOLERANCE 5
+
+# entry:
+#  { <filename> <timestamp> ... }
+#  FILENAME is the full filename relative to the zone root
+#  TIMESTAMP is a timestamp acceptable for [clock scan ...]
+#  Addtional fields to be added to support later formats.
+
+proc write_serials_v0 { filename contents } {
+    set chan [open $filename w]
+
+    foreach cell $contents {
+       puts $chan [format "%s:%d" \
+                       [lindex $cell 0] \
+                       [clock scan [lindex $cell 1]]]
+    }
+
+    close $chan
+}
+
+proc check_serials_v0 { testname filename contents } {
+    global SERIALS_TOLERANCE
+
+    array set want {}
+    foreach cell $contents {
+       set want([lindex $cell 0]) [clock scan [lindex $cell 1]]
+    }
+
+    set result pass
+    verbose -log "Reading legacy format serials file $filename..."
+    spawn -open [open $filename r]
+    expect {
+       -re {^([^:]+):([^\r\n]+)[\r\n]+} {
+           regsub -all {[[:space:]]+} $expect_out(1,string) "" fname
+           regsub -all {[[:space:]]+} $expect_out(2,string) "" tstamp
+           if { [info exists want($fname)] } {
+               if { [expr { abs($want($fname) - $tstamp) }]
+                    < $SERIALS_TOLERANCE } {
+                   unset want($fname)
+               } else {
+                   verbose -log "unexpected timestamp for $fname:"
+                   verbose -log "  want: $want($fname)"
+                   verbose -log "  have: $tstamp"
+                   set result fail
+               }
+           }
+           exp_continue
+       }
+       eof { catch close }
+    }
+
+    if { [llength [array get want]] > 0 } {
+       verbose -log "expected record(s) not found:"
+       verbose -log "  want: [array names want]"
+       set result fail
+    }
+
+    $result "$testname: directive timestamp ratchet"
+}
+
+#EOF