]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
handle CDS deletion record in consistancy checks
authorMark Andrews <marka@isc.org>
Mon, 13 Jan 2020 04:08:17 +0000 (15:08 +1100)
committerMark Andrews <marka@isc.org>
Thu, 30 Jan 2020 13:15:15 +0000 (00:15 +1100)
(cherry picked from commit 0adb4b25d38b6e2332b0cee8ab3f65be8e457c83)

bin/tests/system/dnssec/tests.sh
lib/dns/zone.c

index b9493b9f277de89494c0fed38d3e6aa0e11c2687..aff5ce31c579a957ad43324c625fa46dee9e8a03 100644 (file)
@@ -3422,6 +3422,25 @@ n=$((n+1))
 test "$ret" -eq 0 || echo_i "failed"
 status=$((status+ret))
 
+echo_i "check that CDS deletion records are signed only using KSK when added by"
+echo_i "   nsupdate when dnssec-dnskey-kskonly is yes ($n)"
+ret=0
+(
+echo zone cds-kskonly.secure
+echo server 10.53.0.2 "$PORT"
+echo update delete cds-kskonly.secure CDS
+echo update add cds-kskonly.secure 0 CDS 0 0 0 00
+echo send
+) | $NSUPDATE
+dig_with_opts +noall +answer @10.53.0.2 cds cds-kskonly.secure > dig.out.test$n
+lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
+test "$lines" -eq 1 || ret=1
+lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l)
+test "$lines" -eq 1 || ret=1
+n=$((n+1))
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
 echo_i "checking that positive unknown NSEC3 hash algorithm with OPTOUT does validate ($n)"
 ret=0
 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 optout-unknown.example SOA > dig.out.ns3.test$n
index edfddc8ac5f1335e8d9729a91681d836c5061cfc..b756bb7696dc507d86729b4e40a296aa550035ce 100644 (file)
@@ -19025,9 +19025,11 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
 
        /*
         * For each DNSSEC algorithm in the CDS RRset there must be
-        * a matching DNSKEY record.
+        * a matching DNSKEY record with the exception of a CDS deletion
+        * record which must be by itself.
         */
        if (dns_rdataset_isassociated(&cds)) {
+               bool delete = false;
                memset(algorithms, 0, sizeof(algorithms));
                for (result = dns_rdataset_first(&cds);
                     result == ISC_R_SUCCESS;
@@ -19036,6 +19038,16 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
                        dns_rdata_cds_t structcds;
 
                        dns_rdataset_current(&cds, &crdata);
+                       /*
+                        * CDS deletion record has this form "0 0 0 00" which
+                        * is 5 zero octets.
+                        */
+                       if (crdata.length == 5U &&
+                           memcmp(crdata.data, "\0\0\0\0", 5) == 0)
+                       {
+                               delete = true;
+                               continue;
+                       }
                        CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
                        if (algorithms[structcds.algorithm] == 0)
                                algorithms[structcds.algorithm] = 1;
@@ -19059,7 +19071,12 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
                                goto failure;
                }
                for (i = 0; i < sizeof(algorithms); i++) {
-                       if (algorithms[i] == 1) {
+                       if (delete) {
+                               if (algorithms[i] != 0) {
+                                       result = DNS_R_BADCDNSKEY;
+                                       goto failure;
+                               }
+                       } else if (algorithms[i] == 1) {
                                result = DNS_R_BADCDNSKEY;
                                goto failure;
                        }