]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add duplicate signature test
authorMark Andrews <marka@isc.org>
Thu, 3 May 2018 06:50:32 +0000 (16:50 +1000)
committerMark Andrews <marka@isc.org>
Wed, 6 Jun 2018 07:45:23 +0000 (17:45 +1000)
(cherry picked from commit 0db5b087ed2d5bedfe5ef09ad9ea0fa347eeb18b)
(cherry picked from commit 1783fa5aba2b22bda9a22edfd7d2b1953b2b61b3)
(cherry picked from commit 1710e5cfca255b687f41143a9fcbf1c273578e69)

12 files changed:
bin/tests/system/conf.sh.in
bin/tests/system/conf.sh.win32
bin/tests/system/dupsigs/check_journal.pl [new file with mode: 0644]
bin/tests/system/dupsigs/clean.sh [new file with mode: 0644]
bin/tests/system/dupsigs/ns1/named.args [new file with mode: 0644]
bin/tests/system/dupsigs/ns1/named.conf.in [new file with mode: 0644]
bin/tests/system/dupsigs/ns1/reset_keys.sh [new file with mode: 0644]
bin/tests/system/dupsigs/ns1/signing.test.db.in [new file with mode: 0644]
bin/tests/system/dupsigs/prereq.sh [new file with mode: 0644]
bin/tests/system/dupsigs/setup.sh [new file with mode: 0644]
bin/tests/system/dupsigs/tests.sh [new file with mode: 0644]
util/copyrights

index 876b6edddf4b06b09cb95def12eec1a92bfcee66..78ab7e981dd9428dfb89ca02d4dde29408d54f32 100644 (file)
@@ -74,8 +74,8 @@ KRB5_CONFIG=/dev/null
 
 # The "stress" test is not run by default since it creates enough
 # load on the machine to make it unusable to other users.
-# The "dialup" and "delzone" tests are also not run by default because
-# they take a very long time to complete.
+# The "dialup", "delzone", and "dupsigs" tests are also not run by
+# default because they take a very long time to complete.
 #
 # List of tests hard-coded to use ports 5300 and 9953. For this
 # reason, these must be run sequentially.
index ee491025c8d04a1a10e27246160b58e2d8cd4dab..0d7be96f7e11a771ed3c543415c5f98b8527cd8e 100644 (file)
@@ -87,7 +87,8 @@ KRB5_CONFIG=NUL
 
 # The "stress" test is not run by default since it creates enough
 # load on the machine to make it unusable to other users.
-# v6synth
+# The "dialup", "delzone", and "dupsigs" tests are also not run by
+# default because they take a very long time to complete.
 #
 # List of tests that use ports 5300 and 9953.  For this reason, these must
 # be run sequentially.
diff --git a/bin/tests/system/dupsigs/check_journal.pl b/bin/tests/system/dupsigs/check_journal.pl
new file mode 100644 (file)
index 0000000..972ea8b
--- /dev/null
@@ -0,0 +1,209 @@
+#!/usr/bin/env perl
+#
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+use strict;
+use warnings;
+
+sub process_changeset;
+
+my @changeset;
+
+while( my $line = <> ) {
+    chomp $line;
+
+    if( $line =~ /^(?<op>add|del) (?<label>\S+)\s+(?<ttl>\d+)\s+IN\s+(?<rrtype>\S+)\s+(?<rdata>.*)/ ) {
+        my $change = {
+            op     => $+{op},
+            label  => $+{label},
+            ttl    => $+{ttl},
+            rrtype => $+{rrtype},
+            rdata  => $+{rdata},
+        };
+
+        if( $change->{op} eq 'del' and $change->{rrtype} eq 'SOA' ) {
+            if( @changeset ) {
+                process_changeset( @changeset );
+                @changeset = ();
+            }
+        }
+
+        push @changeset, $change;
+    }
+    else {
+        die "error parsing journal data";
+    }
+}
+
+if( @changeset ) {
+    process_changeset( @changeset );
+}
+
+{
+    my %rrsig_db;
+    my %keys;
+    my $apex;
+
+    sub process_changeset {
+        my @changeset = @_;
+
+        if( not $apex ) {
+            # the first record of the first changeset is guaranteed to be the apex
+            $apex = $changeset[0]{label};
+        }
+
+        my $newserial;
+        my %touched_rrsigs;
+        my %touched_keys;
+
+        foreach my $change( @changeset ) {
+            if( $change->{rrtype} eq 'SOA' ) {
+                if( $change->{op} eq 'add' ) {
+                    if( $change->{rdata} !~ /^\S+ \S+ (?<serial>\d+)/ ) {
+                        die "unable to parse SOA";
+                    }
+
+                    $newserial = $+{serial};
+                }
+            }
+            elsif( $change->{rrtype} eq 'NSEC' ) {
+                ; # do nothing
+            }
+            elsif( $change->{rrtype} eq 'DNSKEY' ) {
+                ; # ignore for now
+            }
+            elsif( $change->{rrtype} eq 'TYPE65534' and $change->{label} eq $apex ) {
+                # key status
+                if( $change->{rdata} !~ /^\\# (?<datasize>\d+) (?<data>[0-9A-F]+)$/ ) {
+                    die "unable to parse key status record";
+                }
+
+                my $datasize = $+{datasize};
+                my $data = $+{data};
+
+                if( $datasize == 5 ) {
+                    my( $alg, $id, $flag_del, $flag_done ) = unpack 'CnCC', pack( 'H10', $data );
+
+                    if( $change->{op} eq 'add' ) {
+                        if( not exists $keys{$id} ) {
+                            $touched_keys{$id} //= 1;
+
+                            $keys{$id} = {
+                                $data        => 1,
+                                rrs          => 1,
+                                done_signing => $flag_done,
+                                deleting     => $flag_del,
+                            };
+                        }
+                        else {
+                            if( not exists $keys{$id}{$data} ) {
+                                my $keydata = $keys{$id};
+                                $touched_keys{$id} = { %$keydata };
+
+                                $keydata->{rrs}++;
+                                $keydata->{$data} = 1;
+                                $keydata->{done_signing} += $flag_done;
+                                $keydata->{deleting} += $flag_del;
+                            }
+                        }
+                    }
+                    else {
+                        # this logic relies upon the convention that there won't
+                        # ever be multiple records with the same flag set
+                        if( exists $keys{$id} ) {
+                            my $keydata = $keys{$id};
+
+                            if( exists $keydata->{$data} ) {
+                                $touched_keys{$id} = { %$keydata };
+
+                                $keydata->{rrs}--;
+                                delete $keydata->{$data};
+                                $keydata->{done_signing} -= $flag_done;
+                                $keydata->{deleting} -= $flag_del;
+
+                                if( $keydata->{rrs} == 0 ) {
+                                    delete $keys{$id};
+                                }
+                            }
+                        }
+                    }
+                }
+                else {
+                    die "unexpected key status record content";
+                }
+            }
+            elsif( $change->{rrtype} eq 'RRSIG' ) {
+                if( $change->{rdata} !~ /^(?<covers>\S+) \d+ \d+ \d+ (?<validity_end>\d+) (?<validity_start>\d+) (?<signing_key>\d+)/ ) {
+                    die "unable to parse RRSIG rdata";
+                }
+
+                $change->{covers} = $+{covers};
+                $change->{validity_end} = $+{validity_end};
+                $change->{validity_start} = $+{validity_start};
+                $change->{signing_key} = $+{signing_key};
+
+                my $db_key = $change->{label} . ':' . $change->{covers};
+
+                $rrsig_db{$db_key} //= {};
+                $touched_rrsigs{$db_key} = 1;
+
+                if( $change->{op} eq 'add' ) {
+                    $rrsig_db{$db_key}{ $change->{signing_key} } = 1;
+                }
+                else {
+                    # del
+                    delete $rrsig_db{$db_key}{ $change->{signing_key} };
+                }
+            }
+        }
+
+        foreach my $key_id( sort keys %touched_keys ) {
+            my $old_data;
+            my $new_data;
+
+            if( ref $touched_keys{$key_id} ) {
+                $old_data = $touched_keys{$key_id};
+            }
+
+            if( exists $keys{$key_id} ) {
+                $new_data = $keys{$key_id};
+            }
+
+            if( $old_data ) {
+                if( $new_data ) {
+                    print "at serial $newserial key $key_id status changed from ($old_data->{deleting},$old_data->{done_signing}) to ($new_data->{deleting},$new_data->{done_signing})\n";
+                }
+                else {
+                    print "at serial $newserial key $key_id status removed from zone\n";
+                }
+            }
+            else {
+                print "at serial $newserial key $key_id status added with flags ($new_data->{deleting},$new_data->{done_signing})\n";
+            }
+        }
+
+        foreach my $rrsig_id( sort keys %touched_rrsigs ) {
+            my $n_signing_keys = keys %{ $rrsig_db{$rrsig_id} };
+
+            if( $n_signing_keys == 0 ) {
+                print "at serial $newserial $rrsig_id went unsigned\n";
+            }
+            elsif( $rrsig_id =~ /:DNSKEY$/ ) {
+                if( $n_signing_keys != 2 ) {
+                    print "at serial $newserial $rrsig_id was signed $n_signing_keys time(s) when it should have been signed twice\n";
+                }
+            }
+            elsif( $n_signing_keys > 1 ) {
+                my @signing_keys = sort { $a <=> $b } keys %{ $rrsig_db{$rrsig_id} };
+                print "at serial $newserial $rrsig_id was signed too many times, keys (@signing_keys)\n";
+            }
+        }
+    }
+}
diff --git a/bin/tests/system/dupsigs/clean.sh b/bin/tests/system/dupsigs/clean.sh
new file mode 100644 (file)
index 0000000..7a6d78e
--- /dev/null
@@ -0,0 +1,19 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+rm -f ns1/named.conf
+rm -f ns1/named.lock
+rm -f ns1/named.memstats
+rm -f ns1/named.run
+rm -f ns1/signing.test.db
+rm -f ns1/signing.test.db.jbk
+rm -f ns1/signing.test.db.signed
+rm -f ns1/signing.test.db.signed.jnl
+rm -f ns1/keys/signing.test/K*
+rm -f ns1/managed-keys.bind*
diff --git a/bin/tests/system/dupsigs/ns1/named.args b/bin/tests/system/dupsigs/ns1/named.args
new file mode 100644 (file)
index 0000000..bd68942
--- /dev/null
@@ -0,0 +1 @@
+-D dupsigs-ns1 -m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T sigvalinsecs
diff --git a/bin/tests/system/dupsigs/ns1/named.conf.in b/bin/tests/system/dupsigs/ns1/named.conf.in
new file mode 100644 (file)
index 0000000..296ad0e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+       recursion no;
+       max-journal-size unlimited;
+       port @PORT@;
+       listen-on { 10.53.0.1; };
+       listen-on-v6 { none; };
+       pid-file "named.pid";
+};
+
+zone "signing.test" {
+       type master;
+       masterfile-format text;
+       allow-update { any; };
+       file "signing.test.db";
+       update-check-ksk yes;
+       key-directory "keys/signing.test";
+       inline-signing yes;
+       auto-dnssec maintain;
+       sig-validity-interval 120 30;
+};
diff --git a/bin/tests/system/dupsigs/ns1/reset_keys.sh b/bin/tests/system/dupsigs/ns1/reset_keys.sh
new file mode 100644 (file)
index 0000000..f03503f
--- /dev/null
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+SYSTEMTESTTOP=../..
+. $SYSTEMTESTTOP/conf.sh
+
+zone=signing.test
+rm -rf keys/signing.test
+mkdir -p keys/signing.test
+
+timetodnssec() {
+    $PERL -e 'my ($S,$M,$H,$d,$m,$y,$x) = gmtime(@ARGV[0]);
+             printf("%04u%02u%02u%02u%02u%02u\n", $y+1900,$m+1,$d,$H,$M,$S);' ${1}
+}
+
+KEYDIR=keys/signing.test
+KSK=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q -f KSK $zone`
+
+ZSK0=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK1=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK2=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK3=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK4=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK5=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK6=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK7=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK8=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+ZSK9=`$KEYGEN -a RSASHA256 -b 1024 -K $KEYDIR -q $zone`
+
+# clear all times on all keys
+for FILEN in keys/signing.test/*.key
+do
+    $SETTIME -P none -A none -R none -I none -D none $FILEN
+done
+
+BASE=`date +%s`
+BASET=`timetodnssec $BASE`
+
+# reset the publish and activation time on the KSK
+$SETTIME -P $BASET -A $BASET $KEYDIR/$KSK
+
+# reset the publish and activation time on the first ZSK
+$SETTIME -P $BASET -A $BASET $KEYDIR/$ZSK0
+
+# schedule the first roll
+R1=`expr $BASE + 300`
+R1T=`timetodnssec $R1`
+
+$SETTIME -I $R1T $KEYDIR/$ZSK0
+$SETTIME -P $BASET -A $R1T $KEYDIR/$ZSK1
+
+# schedule the second roll (which includes the delete of the first key)
+R2=`expr $R1 + 300`
+R2T=`timetodnssec $R2`
+DT=$R2
+DTT=`timetodnssec $DT`
+
+$SETTIME -D $DTT $KEYDIR/$ZSK0
+$SETTIME -I $R2T $KEYDIR/$ZSK1
+$SETTIME -P $R1T -A $R2T $KEYDIR/$ZSK2
+
+# schedule the third roll
+# this isn't long enough for the signing to complete
+R3=`expr $R2 + 60`
+R3T=`timetodnssec $R3`
+
+$SETTIME -D $R3T $KEYDIR/$ZSK1
+$SETTIME -I $R3T $KEYDIR/$ZSK2
+$SETTIME -P $R2T -A $R3T $KEYDIR/$ZSK3
+
+$SETTIME -P $R3T $KEYDIR/$ZSK4
+
+echo KSK=$KSK
+echo ZSK0=$ZSK0
+echo ZSK1=$ZSK1
+echo ZSK2=$ZSK2
+echo ZSK3=$ZSK3
+echo ZSK4=$ZSK4
+
+exit
+
+# schedule the fourth roll
+# this isn't long enough for the signing to complete
+R4=`expr $R3 + 30`
+R4T=`timetodnssec $R4`
+
+$SETTIME -D $R4T $KEYDIR/$ZSK2
+$SETTIME -I $R4T $KEYDIR/$ZSK3
+$SETTIME -P $R3T -A $R4T $KEYDIR/$ZSK4
diff --git a/bin/tests/system/dupsigs/ns1/signing.test.db.in b/bin/tests/system/dupsigs/ns1/signing.test.db.in
new file mode 100644 (file)
index 0000000..072efe1
--- /dev/null
@@ -0,0 +1,16 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 3600
+@ IN SOA  ns root.ns 1996072700 3600 1800 86400 60
+@    NS   ns
+ns   A    127.0.0.1
+ns   AAAA ::1
+
+$GENERATE 0-1999 a${0,4,d} AAAA ::$
diff --git a/bin/tests/system/dupsigs/prereq.sh b/bin/tests/system/dupsigs/prereq.sh
new file mode 100644 (file)
index 0000000..a0d4e9c
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+exec $SHELL ../testcrypto.sh
diff --git a/bin/tests/system/dupsigs/setup.sh b/bin/tests/system/dupsigs/setup.sh
new file mode 100644 (file)
index 0000000..0c37928
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+test -f clean.sh && $SHELL clean.sh
+
+test -r $RANDFILE || $GENRANDOM 800 $RANDFILE
+
+copy_setports ns1/named.conf.in ns1/named.conf
+
+cp -f ns1/signing.test.db.in ns1/signing.test.db
+(cd ns1; $SHELL ./reset_keys.sh)
diff --git a/bin/tests/system/dupsigs/tests.sh b/bin/tests/system/dupsigs/tests.sh
new file mode 100644 (file)
index 0000000..80ddaea
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+status=0
+start=`date +%s`
+end=`expr $start + 1200`
+now=$start
+while test $now -lt $end
+do
+       et=`expr $now - $start`
+       echo "=============== $et ============"
+       $JOURNALPRINT ns1/signing.test.db.signed.jnl | $PERL check_journal.pl
+       $DIG axfr signing.test -p 5300 @10.53.0.1 > dig.out.at$et
+       awk '$4 == "RRSIG" { print $11 }' dig.out.at$et | sort | uniq -c
+       lines=`awk '$4 == "RRSIG" { print}' dig.out.at$et | wc -l`
+       if [ ${et} -ne 0 -a ${lines} -ne 4009 ]
+       then
+               echo_i "failed"
+               status=`expr $status + 1`
+       fi
+       sleep 20
+       now=`date +%s`
+done
+
+echo_i "exit status: $status"
+[ $status -eq 0 ] || exit 1
index dc770cf7472ef3edd127c4981e11f7fcb74f7cb6..fb69024a1f6a1be4caf5faf5b8336f01ae9c62b1 100644 (file)
 ./bin/tests/system/dsdigest/prereq.sh          SH      2012,2014,2018
 ./bin/tests/system/dsdigest/setup.sh           SH      2012,2014,2018
 ./bin/tests/system/dsdigest/tests.sh           SH      2012,2016,2018
+./bin/tests/system/dupsigs/check_journal.pl    PERL    2018
+./bin/tests/system/dupsigs/clean.sh            SH      2018
+./bin/tests/system/dupsigs/ns1/named.args      X       2018
+./bin/tests/system/dupsigs/ns1/named.conf.in   CONF-C  2018
+./bin/tests/system/dupsigs/ns1/reset_keys.sh   SH      2018
+./bin/tests/system/dupsigs/ns1/signing.test.db.in      ZONE    2018
+./bin/tests/system/dupsigs/prereq.sh           SH      2018
+./bin/tests/system/dupsigs/setup.sh            SH      2018
+./bin/tests/system/dupsigs/tests.sh            SH      2018
 ./bin/tests/system/ecdsa/clean.sh              SH      2012,2014,2018
 ./bin/tests/system/ecdsa/ns1/named.conf                CONF-C  2012,2018
 ./bin/tests/system/ecdsa/ns1/root.db.in                ZONE    2012,2018