]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] allow CDS/CDNSKEY records to be signed with only KSK
authorEvan Hunt <each@isc.org>
Wed, 13 Sep 2017 06:09:48 +0000 (23:09 -0700)
committerEvan Hunt <each@isc.org>
Wed, 13 Sep 2017 06:09:48 +0000 (23:09 -0700)
4721. [func] 'dnssec-signzone -x' and 'dnssec-dnskey-kskonly'
options now apply to CDNSKEY and DS records as well
as DNSKEY. Thanks to Tony Finch. [RT #45689]

15 files changed:
CHANGES
bin/dnssec/dnssec-signzone.c
bin/dnssec/dnssec-signzone.docbook
bin/tests/system/autosign/clean.sh
bin/tests/system/autosign/ns3/keygen.sh
bin/tests/system/autosign/ns3/kskonly.example.db.in [new file with mode: 0644]
bin/tests/system/autosign/ns3/named.conf
bin/tests/system/autosign/tests.sh
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/ns2/named.conf
bin/tests/system/dnssec/ns2/sign.sh
bin/tests/system/dnssec/tests.sh
doc/arm/Bv9ARM-book.xml
doc/arm/notes.xml
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index a27f2fab3a9519b21134cafe87ca5a0e8ea73725..b00baff4d92fec6deb4f923afb7f53c336ce8407 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+4721.  [func]          'dnssec-signzone -x' and 'dnssec-dnskey-kskonly'
+                       options now apply to CDNSKEY and DS records as well
+                       as DNSKEY. Thanks to Tony Finch. [RT #45689]
+
 4720.  [func]          Added a statistics counter to track prefetch
                        queries. [RT #45847]
 
index 47759558e5dfe0469b7662cd16b289a2cd15bb8b..5d278a18a88963e74c885a67f679a8e1715c9b94 100644 (file)
@@ -659,7 +659,9 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                if (!issigningkey(key))
                        continue;
 
-               if (set->type == dns_rdatatype_dnskey &&
+               if ((set->type == dns_rdatatype_cds ||
+                    set->type == dns_rdatatype_cdnskey ||
+                    set->type == dns_rdatatype_dnskey) &&
                     dns_name_equal(name, gorigin)) {
                        isc_boolean_t have_ksk;
                        dns_dnsseckey_t *tmpkey;
@@ -680,9 +682,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                            (iszsk(key) && !keyset_kskonly))
                                signwithkey(name, set, key->key, ttl, add,
                                            "signing with dnskey");
-               } else if (set->type == dns_rdatatype_cds ||
-                          set->type == dns_rdatatype_cdnskey ||
-                          iszsk(key)) {
+               } else if (iszsk(key)) {
                        signwithkey(name, set, key->key, ttl, add,
                                    "signing with dnskey");
                }
index 82089a96136b0b0e84e1c3905e39df58dfb78d95..79e5d25fab6d0969b6ec57cf543fb1d48c210a44 100644 (file)
         <term>-x</term>
         <listitem>
           <para>
-            Only sign the DNSKEY RRset with key-signing keys, and omit
-            signatures from zone-signing keys.  (This is similar to the
+            Only sign the DNSKEY, CDNSKEY, and CDS RRsets with
+            key-signing keys, and omit signatures from zone-signing
+            keys. (This is similar to the
             <command>dnssec-dnskey-kskonly yes;</command> zone option in
             <command>named</command>.)
           </para>
index 1033cbdbc20c98c766d837b7a14c1146929d8df6..ac393db64d2cbfa726c4f22f655ec434b4dd536a 100644 (file)
@@ -7,27 +7,29 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 rm -f */K* */dsset-* */*.signed */tmp* */*.jnl */*.bk
-rm -f */trusted.conf */private.conf
 rm -f */core
 rm -f */example.bk
 rm -f */named.memstats
 rm -f */named.run
+rm -f */trusted.conf */private.conf
 rm -f activate-now-publish-1day.key
 rm -f active.key inact.key del.key unpub.key standby.key rev.key
-rm -f sync.key
 rm -f delayksk.key delayzsk.key autoksk.key autozsk.key
 rm -f dig.out.*
 rm -f digcomp.out.test*
+rm -f digcomp.out.test*
 rm -f missingzsk.key inactivezsk.key
 rm -f nopriv.key vanishing.key del1.key del2.key
 rm -f ns*/named.lock
+rm -f ns*/named.lock
 rm -f ns1/root.db
 rm -f ns2/example.db
 rm -f ns2/private.secure.example.db ns2/bar.db
+rm -f ns3/*.nzd ns3/*.nzd-lock ns3/*.nzf
 rm -f ns3/*.nzf
 rm -f ns3/autonsec3.example.db
-rm -f ns3/sync.example.db
 rm -f ns3/kg.out ns3/s.out ns3/st.out
+rm -f ns3/kskonly.example.db
 rm -f ns3/nozsk.example.db ns3/inaczsk.example.db
 rm -f ns3/nsec.example.db
 rm -f ns3/nsec3-to-nsec.example.db
@@ -47,10 +49,9 @@ rm -f ns3/secure-to-insecure2.example.db
 rm -f ns3/secure.example.db
 rm -f ns3/secure.nsec3.example.db
 rm -f ns3/secure.optout.example.db
+rm -f ns3/sync.example.db
 rm -f ns3/ttl*.db
 rm -f nsupdate.out
-rm -f signing.out.*
 rm -f settime.out.*
-rm -f ns3/*.nzd ns3/*.nzd-lock ns3/*.nzf
-rm -f digcomp.out.test*
-rm -f ns*/named.lock
+rm -f signing.out.*
+rm -f sync.key
index 769171e64564c4ade29c3033650c626a9931f029..b3ded65eb65fa092a96ff63deb91f086bceeec4f 100644 (file)
@@ -248,7 +248,7 @@ echo $zsk > ../inactivezsk.key
 $SETTIME -I now $zsk > st.out 2>&1 || dumpit st.out
 
 #
-# A zone that is set to 'auto-dnssec maintain' during a recofnig
+# A zone that is set to 'auto-dnssec maintain' during a reconfig
 #
 setup reconf.example
 cp secure.example.db.in $zonefile
@@ -256,7 +256,7 @@ $KEYGEN -q -a RSASHA1 -3 -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out
 $KEYGEN -q -a RSASHA1 -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
 
 #
-# A zone which generates CDS and CDNSEY RRsets automatically
+# A zone which generates CDS and CDNSEY RRsets automatically
 #
 setup sync.example
 cp $infile $zonefile
@@ -264,3 +264,12 @@ ksk=`$KEYGEN -a RSASHA1 -3 -q -r $RANDFILE -fk -P sync now $zone 2> kg.out` || d
 $KEYGEN -a RSASHA1 -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
 $DSFROMKEY $ksk.key > dsset-${zone}$TP
 echo ns3/$ksk > ../sync.key
+
+#
+# A zone that generates CDS and CDNSKEY and uses dnssec-dnskey-kskonly
+#
+setup kskonly.example
+cp $infile $zonefile
+ksk=`$KEYGEN -a RSASHA1 -3 -q -r $RANDFILE -fk -P sync now $zone 2> kg.out` || dumpit kg.out
+$KEYGEN -a RSASHA1 -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
+$DSFROMKEY $ksk.key > dsset-${zone}$TP
diff --git a/bin/tests/system/autosign/ns3/kskonly.example.db.in b/bin/tests/system/autosign/ns3/kskonly.example.db.in
new file mode 100644 (file)
index 0000000..b8e46a6
--- /dev/null
@@ -0,0 +1,29 @@
+; Copyright (C) 2015, 2016  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/.
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2000042407 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns
+ns                     A       10.53.0.3
+
+a                      A       10.0.0.1
+b                      A       10.0.0.2
+d                      A       10.0.0.4
+z                      A       10.0.0.26
+a.a.a.a.a.a.a.a.a.a.e  A       10.0.0.27
+x                      CNAME   a
+
+private                        NS      ns.private
+ns.private             A       10.53.0.2
+
+insecure               NS      ns.insecure
+ns.insecure            A       10.53.0.2
index b45de3d7f607d8cc546d3b386b806aac36e27940..add46e5d0634813cd33910e9249b99c606776668 100644 (file)
@@ -6,8 +6,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-/* $Id: named.conf,v 1.15 2012/02/06 23:46:47 tbox Exp $ */
-
 // NS3
 
 controls { /* empty */ };
@@ -243,4 +241,12 @@ zone "sync.example" {
        auto-dnssec maintain;
 };
 
+zone "kskonly.example" {
+       type master;
+       file "kskonly.example.db";
+       allow-update { any; };
+       dnssec-dnskey-kskonly yes;
+       auto-dnssec maintain;
+};
+
 include "trusted.conf";
index 7cd19084e622cf13166e80ccf8be64e9cc07794a..e30d06306ba5162ba899fcb87034de91446ca599 100644 (file)
@@ -1166,8 +1166,38 @@ if [ "$lret" != 0 ]; then ret=$lret; fi
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:test 'dnssec-dnskey-kskonly no' affects DNSKEY/CDS/CDNSKEY ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.3 sync.example dnskey > dig.out.ns3.dnskeytest$n
+$DIG $DIGOPTS @10.53.0.3 sync.example cdnskey > dig.out.ns3.cdnskeytest$n
+$DIG $DIGOPTS @10.53.0.3 sync.example cds > dig.out.ns3.cdstest$n
+lines=`awk '$4 == "RRSIG" && $5 == "DNSKEY" {print}' dig.out.ns3.dnskeytest$n | wc -l`
+test ${lines:-0} -eq 2 || ret=1
+lines=`awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.ns3.cdnskeytest$n | wc -l`
+test ${lines:-0} -eq 2 || ret=1
+lines=`awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.ns3.cdstest$n | wc -l`
+test ${lines:-0} -eq 2 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:test 'dnssec-dnskey-kskonly yes' affects DNSKEY/CDS/CDNSKEY ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.3 kskonly.example dnskey > dig.out.ns3.dnskeytest$n
+$DIG $DIGOPTS @10.53.0.3 kskonly.example cdnskey > dig.out.ns3.cdnskeytest$n
+$DIG $DIGOPTS @10.53.0.3 kskonly.example cds > dig.out.ns3.cdstest$n
+lines=`awk '$4 == "RRSIG" && $5 == "DNSKEY" {print}' dig.out.ns3.dnskeytest$n | wc -l`
+test ${lines:-0} -eq 1 || ret=1
+lines=`awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.ns3.cdnskeytest$n | wc -l`
+test ${lines:-0} -eq 1 || ret=1
+lines=`awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.ns3.cdstest$n | wc -l`
+test ${lines:-0} -eq 1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:setting CDS and CDNSKEY deletion times and calling 'rndc loadkeys'"
-$SETTIME -D sync now+2 `cat sync.key`
+$SETTIME -D sync now+2 `cat sync.key` > /dev/null
 $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys sync.example
 echo "I:waiting for deletion to occur"
 sleep 3
index acb139904fee9011404eaed5a5bcdb9077b51cdd..d4549dc266c21eeb09c42c7d4574edad9f3b50b0 100644 (file)
@@ -30,9 +30,10 @@ rm -f ns2/algroll.db
 rm -f ns2/badparam.db ns2/badparam.db.bad
 rm -f ns2/cdnskey-update.secure.db
 rm -f ns2/cdnskey.secure.db
+rm -f ns2/cdnskey-x.secure.db
 rm -f ns2/cds-auto.secure.db ns2/cds-auto.secure.db.jnl
 rm -f ns2/cds-update.secure.db ns2/cds-update.secure.db.jnl
-rm -f ns2/cds.secure.db
+rm -f ns2/cds.secure.db ns2/cds-x.secure.db
 rm -f ns2/dlv.db
 rm -f ns2/in-addr.arpa.db
 rm -f ns2/nsec3chain-test.db
index 5233f1ec693123058af95851fe375db7bd75cef0..b76f7f3777ce29ba7b74677123216f337d211039 100644 (file)
@@ -102,6 +102,11 @@ zone "cds.secure" {
        file "cds.secure.db.signed";
 };
 
+zone "cds-x.secure" {
+       type master;
+       file "cds-x.secure.db.signed";
+};
+
 zone "cds-update.secure" {
        type master;
        file "cds-update.secure.db.signed";
@@ -120,6 +125,11 @@ zone "cdnskey.secure" {
        file "cdnskey.secure.db.signed";
 };
 
+zone "cdnskey-x.secure" {
+       type master;
+       file "cdnskey-x.secure.db.signed";
+};
+
 zone "cdnskey-update.secure" {
        type master;
        file "cdnskey-update.secure.db.signed";
index b7264f6d8cc09039dc373933db5153de91041cf0..fb4744d3e43e48bce851ef30c7d1a90c28985ee0 100644 (file)
@@ -194,6 +194,16 @@ $DSFROMKEY -C $key1.key > $key1.cds
 cat $infile $key1.key $key2.key $key1.cds >$zonefile
 $SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null
 
+zone=cds-x.secure
+infile=cds.secure.db.in
+zonefile=cds-x.secure.db
+key1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone`
+key2=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone`
+key3=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
+$DSFROMKEY -C $key2.key > $key2.cds
+cat $infile $key1.key $key3.key $key2.cds >$zonefile
+$SIGNER -P -g -x -r $RANDFILE -o $zone $zonefile > /dev/null
+
 zone=cds-update.secure
 infile=cds-update.secure.db.in
 zonefile=cds-update.secure.db
@@ -219,6 +229,16 @@ sed 's/DNSKEY/CDNSKEY/' $key1.key > $key1.cds
 cat $infile $key1.key $key2.key $key1.cds >$zonefile
 $SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null
 
+zone=cdnskey-x.secure
+infile=cdnskey.secure.db.in
+zonefile=cdnskey-x.secure.db
+key1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone`
+key2=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone`
+key3=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
+sed 's/DNSKEY/CDNSKEY/' $key1.key > $key1.cds
+cat $infile $key2.key $key3.key $key1.cds >$zonefile
+$SIGNER -P -g -x -r $RANDFILE -o $zone $zonefile > /dev/null
+
 zone=cdnskey-update.secure
 infile=cdnskey-update.secure.db.in
 zonefile=cdnskey-update.secure.db
index 3a1cd1027e9173cf3fe6d4b4fa499dd9e5aa2c15..e02b44cf45326b5133c0936cba49399f1ebdfaf7 100644 (file)
@@ -3002,6 +3002,15 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:check that CDS records are not signed using ZSK by dnssec-signzone -x ($n)"
+ret=0
+$DIG $DIGOPTS +noall +answer @10.53.0.2 cds cds-x.secure > dig.out.test$n
+lines=`awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l`
+test ${lines:-0} -eq 1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:checking that positive unknown NSEC3 hash algorithm does validate ($n)"
 ret=0
 $DIG $DIGOPTS +noauth +noadd +nodnssec +adflag -p 5300 @10.53.0.3 nsec3-unknown.example SOA > dig.out.ns3.test$n
@@ -3122,6 +3131,15 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:check that CDNSKEY records are not signed using ZSK by dnssec-signzone -x ($n)"
+ret=0
+$DIG $DIGOPTS +noall +answer @10.53.0.2 cdnskey cdnskey-x.secure > dig.out.test$n
+lines=`awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l`
+test ${lines:-0} -eq 1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:checking that negative unknown NSEC3 hash algorithm with OPTOUT does not validate ($n)"
 ret=0
 $DIG $DIGOPTS +noauth +noadd +nodnssec +adflag -p 5300 @10.53.0.3 optout-unknown.example A > dig.out.ns3.test$n
index d0afb11fdaea11b075773121af52fcb895c024c1..20584849081ef7093a3242b5bf9c48e8109867f3 100644 (file)
@@ -7139,9 +7139,9 @@ options {
                  When this option and <command>update-check-ksk</command>
                  are both set to <literal>yes</literal>, only key-signing
                  keys (that is, keys with the KSK bit set) will be used
-                 to sign the DNSKEY RRset at the zone apex.  Zone-signing
-                 keys (keys without the KSK bit set) will be used to sign
-                 the remainder of the zone, but not the DNSKEY RRset.
+                 to sign the DNSKEY, CDNSKEY, and CDS RRsets at the zone apex.
+                 Zone-signing keys (keys without the KSK bit set) will be used
+                 to sign the remainder of the zone, but not the DNSKEY RRset.
                  This is similar to the
                  <command>dnssec-signzone -x</command> command line option.
                </para>
index 22be2e53b2f53479d40be3296dd3f68c69112319..645ac46cffdfd21483a882e8c87a48bd456fb776 100644 (file)
          queries. [RT #45847]
        </para>
       </listitem>
+      <listitem>
+       <para>
+         The <command>dnssec-signzone -x</command> flag and the
+         <command>dnssec-dnskey-kskonly</command> option in
+         <command>named.conf</command>, which suppress the use of
+         the ZSK when signing DNSKEY records, now also apply to
+         CDNSKEY and CDS records. Thanks to Tony Finch for the
+         contribution. [RT #45689]
+       </para>
+      </listitem>
     </itemizedlist>
   </section>
 
index 85a171f40abf344cd386b620e15192341e08eea7..c15d31540d752051f5654ee8a413d35ec8c82ab7 100644 (file)
@@ -6234,7 +6234,10 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
                        }
                }
                if (both) {
-                       if (type == dns_rdatatype_dnskey) {
+                       if (type == dns_rdatatype_dnskey ||
+                           type == dns_rdatatype_cdnskey ||
+                           type == dns_rdatatype_cds)
+                       {
                                if (!KSK(keys[i]) && keyset_kskonly)
                                        continue;
                        } else if (KSK(keys[i]))
@@ -6652,24 +6655,34 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
                dns_rdatasetiter_current(iterator, &rdataset);
                if (rdataset.type == dns_rdatatype_soa ||
                    rdataset.type == dns_rdatatype_rrsig)
+               {
                        goto next_rdataset;
-               if (rdataset.type == dns_rdatatype_dnskey) {
-                       if (!is_ksk && keyset_kskonly)
-                               goto next_rdataset;
-               } else if (is_ksk) {
+               }
+               if (rdataset.type == dns_rdatatype_dnskey ||
+                   rdataset.type == dns_rdatatype_cdnskey ||
+                   rdataset.type == dns_rdatatype_cds)
+               {
                        /*
-                        * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
+                        * CDS and CDNSKEY are signed with KSK like DNSKEY.
+                        * (RFC 7344, section 4.1 specifies that they must
+                        * be signed with a key in the current DS RRset,
+                        * which would only include KSK's.)
                         */
-                       if (rdataset.type != dns_rdatatype_cds &&
-                           rdataset.type != dns_rdatatype_cdnskey)
+                       if (!is_ksk && keyset_kskonly) {
                                goto next_rdataset;
+                       }
+               } else if (is_ksk) {
+                       goto next_rdataset;
                }
                if (*delegation &&
                    rdataset.type != dns_rdatatype_ds &&
                    rdataset.type != dns_rdatatype_nsec)
+               {
                        goto next_rdataset;
-               if (signed_with_key(db, node, version, rdataset.type, key))
+               }
+               if (signed_with_key(db, node, version, rdataset.type, key)) {
                        goto next_rdataset;
+               }
                /* Calculate the signature, creating a RRSIG RDATA. */
                isc_buffer_clear(&buffer);
                CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,