From 103cd665e1d8a301bac458cdac51cefea33dea0d Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 13 Jan 2020 15:08:17 +1100 Subject: [PATCH 01/10] handle CDS deletion record in consistancy checks (cherry picked from commit 0adb4b25d38b6e2332b0cee8ab3f65be8e457c83) --- bin/tests/system/dnssec/tests.sh | 19 +++++++++++++++++++ lib/dns/zone.c | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index b9493b9f27..aff5ce31c5 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -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 diff --git a/lib/dns/zone.c b/lib/dns/zone.c index edfddc8ac5..b756bb7696 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -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; } From 735dfc1ab867036cc1e5d1ebd3bd34b9a81959bf Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 13 Jan 2020 15:30:28 +1100 Subject: [PATCH 02/10] check that a CDNSKEY deletion record is accepted (cherry picked from commit f91b3a69ce19333327cba338d4af12404bec6243) --- bin/tests/system/dnssec/tests.sh | 16 ++++++++++++++++ lib/dns/zone.c | 22 ++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index aff5ce31c5..9f511fa279 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3576,6 +3576,22 @@ n=$((n+1)) 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 diff --git a/lib/dns/zone.c b/lib/dns/zone.c index b756bb7696..7310556766 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -19085,9 +19085,11 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { /* * 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; @@ -19096,6 +19098,17 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { 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) @@ -19116,7 +19129,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_BADCDS; + goto failure; + } + } else if (algorithms[i] == 1) { result = DNS_R_BADCDS; goto failure; } From c2a2e1f4547deb34c89524f715d63e0753829ca6 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 13 Jan 2020 15:34:16 +1100 Subject: [PATCH 03/10] return the correct error code for the type being checked (cherry picked from commit a09c464a201934b83782a5f3db968100e90fb5ce) --- lib/dns/zone.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 7310556766..6f5bbba2d7 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -19073,11 +19073,11 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { for (i = 0; i < sizeof(algorithms); i++) { if (delete) { if (algorithms[i] != 0) { - result = DNS_R_BADCDNSKEY; + result = DNS_R_BADCDS; goto failure; } } else if (algorithms[i] == 1) { - result = DNS_R_BADCDNSKEY; + result = DNS_R_BADCDS; goto failure; } } @@ -19131,11 +19131,11 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { for (i = 0; i < sizeof(algorithms); i++) { if (delete) { if (algorithms[i] != 0) { - result = DNS_R_BADCDS; + result = DNS_R_BADCDNSKEY; goto failure; } } else if (algorithms[i] == 1) { - result = DNS_R_BADCDS; + result = DNS_R_BADCDNSKEY; goto failure; } } From 3a87b02b1ae922ddb2dce50cb2d853a50aefc521 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 13 Jan 2020 15:41:35 +1100 Subject: [PATCH 04/10] style (cherry picked from commit 279f6b01de3c399081d0471d2914889bde6efe5d) --- lib/dns/zone.c | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 6f5bbba2d7..c94bcc5398 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -18988,8 +18988,9 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { REQUIRE(DNS_ZONE_VALID(zone)); result = dns_db_getoriginnode(db, &node); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } dns_rdataset_init(&cds); dns_rdataset_init(&dnskey); @@ -18997,16 +18998,19 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds, dns_rdatatype_none, 0, &cds, NULL); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { goto failure; + } result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey, dns_rdatatype_none, 0, &cdnskey, NULL); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { goto failure; + } if (!dns_rdataset_isassociated(&cds) && - !dns_rdataset_isassociated(&cdnskey)) { + !dns_rdataset_isassociated(&cdnskey)) + { result = ISC_R_SUCCESS; goto failure; } @@ -19014,14 +19018,16 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, dns_rdatatype_none, 0, &dnskey, NULL); if (result == ISC_R_NOTFOUND) { - if (dns_rdataset_isassociated(&cds)) + if (dns_rdataset_isassociated(&cds)) { result = DNS_R_BADCDS; - else + } else { result = DNS_R_BADCDNSKEY; + } goto failure; } - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { goto failure; + } /* * For each DNSSEC algorithm in the CDS RRset there must be @@ -19049,8 +19055,9 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { continue; } CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); - if (algorithms[structcds.algorithm] == 0) + if (algorithms[structcds.algorithm] == 0) { algorithms[structcds.algorithm] = 1; + } for (result = dns_rdataset_first(&dnskey); result == ISC_R_SUCCESS; result = dns_rdataset_next(&dnskey)) { @@ -19063,12 +19070,14 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { buffer, &dsrdata)); if (crdata.length == dsrdata.length && memcmp(crdata.data, dsrdata.data, - dsrdata.length) == 0) { + dsrdata.length) == 0) + { algorithms[structcds.algorithm] = 2; } } - if (result != ISC_R_NOMORE) + if (result != ISC_R_NOMORE) { goto failure; + } } for (i = 0; i < sizeof(algorithms); i++) { if (delete) { @@ -19111,8 +19120,9 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { } CHECK(dns_rdata_tostruct(&crdata, &structcdnskey, NULL)); - if (algorithms[structcdnskey.algorithm] == 0) + if (algorithms[structcdnskey.algorithm] == 0) { algorithms[structcdnskey.algorithm] = 1; + } for (result = dns_rdataset_first(&dnskey); result == ISC_R_SUCCESS; result = dns_rdataset_next(&dnskey)) { @@ -19121,12 +19131,14 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { dns_rdataset_current(&dnskey, &rdata); if (crdata.length == rdata.length && memcmp(crdata.data, rdata.data, - rdata.length) == 0) { + rdata.length) == 0) + { algorithms[structcdnskey.algorithm] = 2; } } - if (result != ISC_R_NOMORE) + if (result != ISC_R_NOMORE) { goto failure; + } } for (i = 0; i < sizeof(algorithms); i++) { if (delete) { @@ -19143,12 +19155,15 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { result = ISC_R_SUCCESS; failure: - if (dns_rdataset_isassociated(&cds)) + if (dns_rdataset_isassociated(&cds)) { dns_rdataset_disassociate(&cds); - if (dns_rdataset_isassociated(&dnskey)) + } + if (dns_rdataset_isassociated(&dnskey)) { dns_rdataset_disassociate(&dnskey); - if (dns_rdataset_isassociated(&cdnskey)) + } + if (dns_rdataset_isassociated(&cdnskey)) { dns_rdataset_disassociate(&cdnskey); + } dns_db_detachnode(db, &node); return (result); } From d403b3621d3ff3ca66ba7145a8090705dea9d57c Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 14 Jan 2020 15:22:22 +1100 Subject: [PATCH 05/10] add CHANGES (cherry picked from commit 272a31f7589972183a369f88b48f321f81c8d2b8) --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 51ac2ec601..02ba72f801 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5351. [bug] CDS / CDNSKEY consistency checks failed to handle + removal records. [GL #1554] + 5350. [bug] When a view was configured with class CHAOS, the server could crash while processing a query for a non-existent record. [GL #1540] From 7f079c4fa37e03de5d01c1908fc1cf378c9d4e8e Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 29 Jan 2020 19:02:01 +1100 Subject: [PATCH 06/10] check kskonly key ids (cherry picked from commit 379949cce43be56ec3132cd1c1f4c9b24d9d04fb) --- bin/tests/system/dnssec/clean.sh | 12 +++++++----- bin/tests/system/dnssec/ns2/sign.sh | 2 ++ bin/tests/system/dnssec/tests.sh | 9 +++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index bee3bbfd62..550b5a7f7f 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -24,9 +24,9 @@ rm -f ./canonical?.* rm -f ./delv.out* rm -f ./delve.out* rm -f ./dig.out.* +rm -f ./dnssectools.out* rm -f ./dsfromkey.out.* rm -f ./keygen.err -rm -f ./dnssectools.out* rm -f ./named.secroots.test* rm -f ./nosign.before rm -f ./ns*/*.nta @@ -37,11 +37,13 @@ rm -f ./ns1/root.db ./ns2/example.db ./ns2/managed.db ./ns2/trusted.db rm -f ./ns2/algroll.db rm -f ./ns2/badparam.db ./ns2/badparam.db.bad rm -f ./ns2/cdnskey-kskonly.secure.db +rm -f ./ns2/cdnskey-kskonly.secure.id rm -f ./ns2/cdnskey-update.secure.db rm -f ./ns2/cdnskey-x.secure.db rm -f ./ns2/cdnskey.secure.db rm -f ./ns2/cds-auto.secure.db ./ns2/cds-auto.secure.db.jnl rm -f ./ns2/cds-kskonly.secure.db +rm -f ./ns2/cds-kskonly.secure.id rm -f ./ns2/cds-update.secure.db ./ns2/cds-update.secure.db.jnl rm -f ./ns2/cds.secure.db ./ns2/cds-x.secure.db rm -f ./ns2/dlv.db @@ -50,8 +52,6 @@ rm -f ./ns2/nsec3chain-test.db rm -f ./ns2/private.secure.example.db rm -f ./ns2/single-nsec3.db rm -f ./ns2/updatecheck-kskonly.secure.* -rm -f ./ns3/secure.example.db ./ns3/*.managed.db ./ns3/*.trusted.db -rm -f ./ns3/unsupported.managed.db.tmp ./ns3/unsupported.trusted.db.tmp rm -f ./ns3/auto-nsec.example.db ./ns3/auto-nsec3.example.db rm -f ./ns3/badds.example.db rm -f ./ns3/dname-at-apex-nsec3.example.db @@ -59,10 +59,10 @@ rm -f ./ns3/dnskey-nsec3-unknown.example.db rm -f ./ns3/dnskey-nsec3-unknown.example.db.tmp rm -f ./ns3/dnskey-unknown.example.db rm -f ./ns3/dnskey-unknown.example.db.tmp -rm -f ./ns3/dnskey-unsupported.example.db -rm -f ./ns3/dnskey-unsupported.example.db.tmp rm -f ./ns3/dnskey-unsupported-2.example.db rm -f ./ns3/dnskey-unsupported-2.example.db.tmp +rm -f ./ns3/dnskey-unsupported.example.db +rm -f ./ns3/dnskey-unsupported.example.db.tmp rm -f ./ns3/dynamic.example.db ./ns3/dynamic.example.db.signed.jnl rm -f ./ns3/expired.example.db ./ns3/update-nsec3.example.db rm -f ./ns3/expiring.example.db ./ns3/nosign.example.db @@ -82,6 +82,7 @@ rm -f ./ns3/publish-inactive.example.db rm -f ./ns3/revkey.example.db rm -f ./ns3/rsasha256.example.db ./ns3/rsasha512.example.db rm -f ./ns3/secure.below-cname.example.db +rm -f ./ns3/secure.example.db ./ns3/*.managed.db ./ns3/*.trusted.db rm -f ./ns3/secure.nsec3.example.db rm -f ./ns3/secure.optout.example.db rm -f ./ns3/siginterval.conf @@ -91,6 +92,7 @@ rm -f ./ns3/split-smart.example.db rm -f ./ns3/ttlpatch.example.db ./ns3/ttlpatch.example.db.signed rm -f ./ns3/ttlpatch.example.db.patched rm -f ./ns3/unsecure.example.db ./ns3/bogus.example.db ./ns3/keyless.example.db +rm -f ./ns3/unsupported.managed.db.tmp ./ns3/unsupported.trusted.db.tmp rm -f ./ns4/managed-keys.bind* rm -f ./ns4/named_dump.db* rm -f ./ns6/optout-tld.db diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index 23964b9818..0c588f2e54 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -263,6 +263,7 @@ key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$ key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$key1.key" "$key2.key" > "$zonefile" "$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +keyfile_to_key_id "$key1" > cds-kskonly.secure.id zone=cds-auto.secure infile=cds-auto.secure.db.in @@ -306,6 +307,7 @@ key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$ key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$key1.key" "$key2.key" > "$zonefile" "$SIGNER" -P -g -o "$zone" "$zonefile" > /dev/null 2>&1 +keyfile_to_key_id "$key1" > cdnskey-kskonly.secure.id zone=cdnskey-auto.secure infile=cdnskey-auto.secure.db.in diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 9f511fa279..c645a89781 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3402,6 +3402,7 @@ status=$((status+ret)) echo_i "check that CDS records are signed only using KSK when added by" echo_i " nsupdate when dnssec-dnskey-kskonly is yes ($n)" ret=0 +keyid=$(cat ns2/cds-kskonly.secure.id) ( echo zone cds-kskonly.secure echo server 10.53.0.2 "$PORT" @@ -3416,6 +3417,8 @@ echo send 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 -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {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 2 || ret=1 n=$((n+1)) @@ -3425,6 +3428,7 @@ 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 +keyid=$(cat ns2/cds-kskonly.secure.id) ( echo zone cds-kskonly.secure echo server 10.53.0.2 "$PORT" @@ -3435,6 +3439,8 @@ echo send 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 -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {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)) @@ -3625,6 +3631,7 @@ status=$((status+ret)) echo_i "check that CDNSKEY records are signed only using KSK when added by" echo_i " nsupdate when dnssec-dnskey-kskonly is yes ($n)" ret=0 +keyid=$(cat ns2/cdnskey-kskonly.secure.id) ( echo zone cdnskey-kskonly.secure echo server 10.53.0.2 "$PORT" @@ -3636,6 +3643,8 @@ echo send dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) test "$lines" -eq 1 || ret=1 +lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l) +test "$lines" -eq 1 || ret=1 lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) test "$lines" -eq 1 || ret=1 n=$((n+1)) From a7e5a14624433ae684e9d3a9d1c5b0f7d5540bed Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 29 Jan 2020 19:10:47 +1100 Subject: [PATCH 07/10] check CDS and CDNSKEY content (cherry picked from commit 68a360772f42727a9c56733db0a2be3a70b5acad) --- bin/tests/system/dnssec/tests.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index c645a89781..58dddea282 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3443,6 +3443,8 @@ lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {print}' test "$lines" -eq 1 || ret=1 lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) test "$lines" -eq 1 || ret=1 +lines=$(awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {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)) @@ -3594,6 +3596,8 @@ echo send 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 +lines=$(awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {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)) From ea5e1ad76248164ade7cf25cce7f64a616c279ff Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 29 Jan 2020 19:42:21 +1100 Subject: [PATCH 08/10] add more CDS / CDNSKEY deletion record tests (cherry picked from commit d159fdf25d61b69a8ea17517ca6931604d0e17ae) --- bin/tests/system/dnssec/tests.sh | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 58dddea282..7fa7e2335a 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3377,6 +3377,24 @@ n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) +echo_i "check that a CDS deletion record is accepted ($n)" +ret=0 +( +echo zone cds-update.secure +echo server 10.53.0.2 "$PORT" +echo update delete cds-update.secure CDS +echo update add cds-update.secure 0 CDS 0 0 0 00 +echo send +) | $NSUPDATE > nsupdate.out.test$n 2>&1 +dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n +lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) +test "${lines:-10}" -eq 1 || ret=1 +lines=$(awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {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 "check that CDS records are signed using KSK when added by nsupdate ($n)" ret=0 ( @@ -3655,6 +3673,30 @@ n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) +echo_i "check that CDNSKEY deletion records are signed only using KSK when added by" +echo_i " nsupdate when dnssec-dnskey-kskonly is yes ($n)" +ret=0 +keyid=$(cat ns2/cdnskey-kskonly.secure.id) +( +echo zone cdnskey-kskonly.secure +echo server 10.53.0.2 "$PORT" +echo update delete cdnskey-kskonly.secure CDNSKEY +echo update add cdnskey-kskonly.secure 0 CDNSKEY 0 3 0 AA== +echo send +) | $NSUPDATE +dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n +lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) +test "$lines" -eq 1 || ret=1 +lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l) +test "$lines" -eq 1 || ret=1 +lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) +test "$lines" -eq 1 || ret=1 +lines=$(awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {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 initialization with a revoked managed key ($n)" ret=0 copy_setports ns5/named2.conf.in ns5/named.conf From 5432e365d5bac90ff506c28b3d104997641fef86 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 30 Jan 2020 06:57:51 +1100 Subject: [PATCH 09/10] use enum (cherry picked from commit 7c0d9dac9fa961e0bea49b86304b28ac41b2ae8b) --- lib/dns/zone.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c94bcc5398..790401f91b 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -18985,6 +18985,8 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { unsigned char algorithms[256]; unsigned int i; + enum { notexpected = 0, expected = 1, found = 2 }; + REQUIRE(DNS_ZONE_VALID(zone)); result = dns_db_getoriginnode(db, &node); @@ -19036,7 +19038,7 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { */ if (dns_rdataset_isassociated(&cds)) { bool delete = false; - memset(algorithms, 0, sizeof(algorithms)); + memset(algorithms, notexpected, sizeof(algorithms)); for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS; result = dns_rdataset_next(&cds)) { @@ -19056,7 +19058,7 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { } CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); if (algorithms[structcds.algorithm] == 0) { - algorithms[structcds.algorithm] = 1; + algorithms[structcds.algorithm] = expected; } for (result = dns_rdataset_first(&dnskey); result == ISC_R_SUCCESS; @@ -19072,7 +19074,7 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { memcmp(crdata.data, dsrdata.data, dsrdata.length) == 0) { - algorithms[structcds.algorithm] = 2; + algorithms[structcds.algorithm] = found; } } if (result != ISC_R_NOMORE) { @@ -19081,11 +19083,11 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { } for (i = 0; i < sizeof(algorithms); i++) { if (delete) { - if (algorithms[i] != 0) { + if (algorithms[i] != notexpected) { result = DNS_R_BADCDS; goto failure; } - } else if (algorithms[i] == 1) { + } else if (algorithms[i] == expected) { result = DNS_R_BADCDS; goto failure; } @@ -19099,7 +19101,7 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { */ if (dns_rdataset_isassociated(&cdnskey)) { bool delete = false; - memset(algorithms, 0, sizeof(algorithms)); + memset(algorithms, notexpected, sizeof(algorithms)); for (result = dns_rdataset_first(&cdnskey); result == ISC_R_SUCCESS; result = dns_rdataset_next(&cdnskey)) { @@ -19113,7 +19115,7 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { * and 2 zero octets. */ if (crdata.length == 5U && - memcmp(crdata.data, "\0\0\003\0", 5) == 0) + memcmp(crdata.data, "\0\0\3\0", 5) == 0) { delete = true; continue; @@ -19121,7 +19123,7 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { CHECK(dns_rdata_tostruct(&crdata, &structcdnskey, NULL)); if (algorithms[structcdnskey.algorithm] == 0) { - algorithms[structcdnskey.algorithm] = 1; + algorithms[structcdnskey.algorithm] = expected; } for (result = dns_rdataset_first(&dnskey); result == ISC_R_SUCCESS; @@ -19133,7 +19135,8 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { memcmp(crdata.data, rdata.data, rdata.length) == 0) { - algorithms[structcdnskey.algorithm] = 2; + algorithms[structcdnskey.algorithm] = + found; } } if (result != ISC_R_NOMORE) { @@ -19142,11 +19145,11 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { } for (i = 0; i < sizeof(algorithms); i++) { if (delete) { - if (algorithms[i] != 0) { + if (algorithms[i] != notexpected) { result = DNS_R_BADCDNSKEY; goto failure; } - } else if (algorithms[i] == 1) { + } else if (algorithms[i] == expected) { result = DNS_R_BADCDNSKEY; goto failure; } From e79a87566d50998df673cffcea981e7418a35da4 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 30 Jan 2020 07:25:10 +1100 Subject: [PATCH 10/10] use anonomous constants (cherry picked from commit 02c2fc5ad31560483d1a586b4c474fd38afb819f) --- lib/dns/zone.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 790401f91b..76b270feef 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -19051,7 +19051,8 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { * is 5 zero octets. */ if (crdata.length == 5U && - memcmp(crdata.data, "\0\0\0\0", 5) == 0) + memcmp(crdata.data, + (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0) { delete = true; continue; @@ -19115,7 +19116,8 @@ dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { * and 2 zero octets. */ if (crdata.length == 5U && - memcmp(crdata.data, "\0\0\3\0", 5) == 0) + memcmp(crdata.data, + (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0) { delete = true; continue;