test "$ret" -eq 0 || echo_i "failed"
status=$((status+ret))
+echo_i "check that a CDNSKEY deletion record is accepted ($n)"
+ret=0
+(
+echo zone cdnskey-update.secure
+echo server 10.53.0.2 "$PORT"
+echo update delete cdnskey-update.secure CDNSKEY
+echo update add cdnskey-update.secure 0 CDNSKEY 0 3 0 AA==
+echo send
+) | $NSUPDATE > nsupdate.out.test$n 2>&1
+dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n
+lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
+test "${lines:-10}" -eq 1 || ret=1
+n=$((n+1))
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
echo_i "checking that unknown DNSKEY algorithm + unknown NSEC3 has algorithm validates as insecure ($n)"
ret=0
dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-nsec3-unknown.example A > dig.out.ns3.test$n
/*
* For each DNSSEC algorithm in the CDNSKEY RRset there must be
- * a matching DNSKEY record.
+ * a matching DNSKEY record with the exception of a CDNSKEY deletion
+ * record which must be by itself.
*/
if (dns_rdataset_isassociated(&cdnskey)) {
+ bool delete = false;
memset(algorithms, 0, sizeof(algorithms));
for (result = dns_rdataset_first(&cdnskey);
result == ISC_R_SUCCESS;
dns_rdata_cdnskey_t structcdnskey;
dns_rdataset_current(&cdnskey, &crdata);
+ /*
+ * CDNSKEY deletion record has this form
+ * "0 3 0 AA==" which is 2 zero octets, a 3,
+ * and 2 zero octets.
+ */
+ if (crdata.length == 5U &&
+ memcmp(crdata.data, "\0\0\003\0", 5) == 0)
+ {
+ delete = true;
+ continue;
+ }
CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
NULL));
if (algorithms[structcdnskey.algorithm] == 0)
goto failure;
}
for (i = 0; i < sizeof(algorithms); i++) {
- if (algorithms[i] == 1) {
+ if (delete) {
+ if (algorithms[i] != 0) {
+ result = DNS_R_BADCDS;
+ goto failure;
+ }
+ } else if (algorithms[i] == 1) {
result = DNS_R_BADCDS;
goto failure;
}