]> 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 00:18:16 +0000 (11:18 +1100)
bin/tests/system/dnssec/tests.sh
lib/dns/zone.c

index 89e98de86f26ef115903c4944de699ddae7e5c9d..e3f47640db54aa1e32ee961bea11f0dc1a63898b 100644 (file)
@@ -3362,6 +3362,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 a625d689f9dd337314eb36f09e1344120befc08d..ade48d8a59b2a42d5c7034d5b61b13d768489d1b 100644 (file)
@@ -19177,9 +19177,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;
@@ -19188,6 +19190,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;
@@ -19211,7 +19223,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;
                        }