rrsigonly A 10.0.0.29
cnameandkey CNAME @
-cnamenokey CNAME @
dnameandkey DNAME @
+; Legacy DNSSEC types (RFC 3755) carried as opaque zone data and signed.
+sigrr SIG A 6 2 86400 20260331170000 20260318160000 21831 . AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+nxtrr NXT next.secure.example. A
+keyrr KEY 0 3 13 zJxo/L9JqctLZuL8CqocSmgHUhmQCrQQmRHjwhzXfjDgPoPjRo1nofU7yXHeli8myiulQLZk3h1CTayP8dOvkQ==
+
mixedcase A 10.0.0.30
mixedCASE TXT "mixed case"
MIXEDcase AAAA 2002::
infile=secure.example.db.in
zonefile=secure.example.db
-cnameandkey=$("$KEYGEN" -T KEY -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "cnameandkey.$zone")
dnameandkey=$("$KEYGEN" -T KEY -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "dnameandkey.$zone")
keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
-cat "$infile" dsset-badalg.secure.example. "$cnameandkey.key" "$dnameandkey.key" "$keyname.key" >"$zonefile"
+cat "$infile" dsset-badalg.secure.example. "$dnameandkey.key" "$keyname.key" >"$zonefile"
"$SIGNER" -z -D -o "$zone" "$zonefile" >/dev/null
cat "$zonefile" "$zonefile".signed >"$zonefile".tmp
isctest.check.adflag(res2)
assert answer_has(res2, rdatatype.CNAME)
- # check KEY lookup via CNAME
- msg = isctest.query.create("cnameandkey.secure.example", "KEY")
- res1 = isctest.query.tcp(msg, "10.53.0.3")
- res2 = isctest.query.tcp(msg, "10.53.0.4")
- isctest.check.same_answer(res1, res2)
- isctest.check.adflag(res2)
- assert not answer_has(res2, rdatatype.CNAME)
-
- # check KEY lookup via CNAME (not present)
- msg = isctest.query.create("cnamenokey.secure.example", "KEY")
- res1 = isctest.query.tcp(msg, "10.53.0.3")
- res2 = isctest.query.tcp(msg, "10.53.0.4")
- isctest.check.same_answer(res1, res2)
- isctest.check.adflag(res2)
- assert not answer_has(res2, rdatatype.CNAME)
-
# check DNSKEY lookup via DNAME
msg = isctest.query.create("a.dnameandkey.secure.example", "DNSKEY")
res1 = isctest.query.tcp(msg, "10.53.0.3")
isctest.check.noadflag(res2)
+def test_legacy_dnssec_types_are_signed():
+ """SIG (24), NXT (30) and KEY (25) records carry a covering RRSIG.
+
+ Per RFC 3755 SIG and NXT are obsolete and treated as opaque zone
+ data; KEY remains valid for SIG(0)/TKEY use. All three are
+ ordinary zone data and must be signed like any other RRset.
+ """
+ for owner, rrtype in [
+ ("sigrr.secure.example", "SIG"),
+ ("nxtrr.secure.example", "NXT"),
+ ("keyrr.secure.example", "KEY"),
+ ]:
+ expected = rdatatype.from_text(rrtype)
+ msg = isctest.query.create(owner, rrtype, cd=True)
+ res = isctest.query.tcp(msg, "10.53.0.3")
+ isctest.check.noerror(res)
+ assert any(
+ rr.rdtype == expected for rr in res.answer
+ ), f"{rrtype} record missing in answer for {owner}: {res.answer}"
+ assert any(
+ rr.rdtype == rdatatype.RRSIG and rr.covers == expected for rr in res.answer
+ ), f"RRSIG({rrtype}) missing in answer for {owner}: {res.answer}"
+
+
def test_rrsigs_for_glue():
msg = isctest.query.create("ns3.secure.example", "A", cd=True)
res = isctest.query.tcp(msg, "10.53.0.4")
return ISC_R_IGNORE;
}
if (type == dns_rdatatype_cname || type == dns_rdatatype_nsec ||
- type == dns_rdatatype_key ||
!dns_nsec_typepresent(&rdata, dns_rdatatype_cname))
{
*exists = true;
}
if (type == dns_rdatatype_cname ||
type == dns_rdatatype_nsec ||
- type == dns_rdatatype_key ||
!dns_nsec3_typepresent(&rdata, dns_rdatatype_cname))
{
*exists = true;
/*
* Certain DNSSEC types are not subject to CNAME matching
- * (RFC4035, section 2.5 and RFC3007).
+ * (RFC4035, section 2.5).
*/
- if (type == dns_rdatatype_key || type == dns_rdatatype_nsec ||
- type == dns_rdatatype_rrsig)
- {
+ if (type == dns_rdatatype_nsec || type == dns_rdatatype_rrsig) {
cname_ok = false;
}
if (first_existing_header(top, serial) != NULL) {
cname = true;
}
- } else if (rdtype != dns_rdatatype_key &&
- rdtype != dns_rdatatype_nsec &&
+ } else if (rdtype != dns_rdatatype_nsec &&
rdtype != dns_rdatatype_rrsig)
{
if (first_existing_header(top, serial) != NULL) {
/*
* Certain DNSSEC types are not subject to CNAME matching
- * (RFC4035, section 2.5 and RFC3007).
+ * (RFC4035, section 2.5).
*
* We don't check for RRSIG, because we don't store RRSIG records
* directly.
*/
- if (type == dns_rdatatype_key || type == dns_rdatatype_nsec) {
+ if (type == dns_rdatatype_nsec) {
cname_ok = false;
}
search.need_cleanup = true;
maybe_zonecut = false;
at_zonecut = true;
- /*
- * It is not clear if KEY should still be
- * allowed at the parent side of the zone
- * cut or not. It is needed for RFC3007
- * validated updates.
- */
+
if ((search.options & DNS_DBFIND_GLUEOK) == 0 &&
- type != dns_rdatatype_nsec &&
- type != dns_rdatatype_key)
+ type != dns_rdatatype_nsec)
{
/*
* Glue is not OK, but any answer we
/*
* If we're beneath a zone cut, we must indicate that the
* result is glue, unless we're actually at the zone cut
- * and the type is NSEC or KEY.
+ * and the type is NSEC.
*/
if (search.zonecut == node) {
- /*
- * It is not clear if KEY should still be
- * allowed at the parent side of the zone
- * cut or not. It is needed for RFC3007
- * validated updates.
- */
- if (dns_rdatatype_isnsec(type) ||
- type == dns_rdatatype_key)
- {
+ if (dns_rdatatype_isnsec(type)) {
result = ISC_R_SUCCESS;
} else if (type == dns_rdatatype_any) {
result = DNS_R_ZONECUT;
#include <dst/dst.h>
-#define RRTYPE_KEY_ATTRIBUTES \
- (DNS_RDATATYPEATTR_ATCNAME | DNS_RDATATYPEATTR_ZONECUTAUTH)
+#define RRTYPE_KEY_ATTRIBUTES (0)
static isc_result_t
generic_fromtext_key(ARGS_FROMTEXT) {
*/
if ((result == DNS_R_CNAME || result == DNS_R_DNAME) &&
fctx->qmin_labels == dns_name_countlabels(fctx->name) &&
- fctx->type != dns_rdatatype_key &&
fctx->type != dns_rdatatype_nsec &&
fctx->type != dns_rdatatype_any &&
fctx->type != dns_rdatatype_rrsig)
dns_typepair_t typepair = DNS_TYPEPAIR_VALUE(rdataset.type,
rdataset.covers);
switch (typepair) {
- /* KEY and NSEC records are allowed */
+ /* NSEC records are allowed */
case DNS_TYPEPAIR(dns_rdatatype_nsec):
- case DNS_TYPEPAIR(dns_rdatatype_key):
case DNS_SIGTYPEPAIR(dns_rdatatype_nsec):
- case DNS_SIGTYPEPAIR(dns_rdatatype_key):
/* Keep the CNAME and its signature */
case DNS_TYPEPAIR(dns_rdatatype_cname):
case DNS_SIGTYPEPAIR(dns_rdatatype_cname):
* along with the covered RRset in 'delete_rrset()'.
*/
if (!dns_rdataset_matchestype(rdataset, dns_rdatatype_cname) &&
- !dns_rdataset_matchestype(rdataset, dns_rdatatype_key) &&
!dns_rdataset_matchestype(rdataset, dns_rdatatype_nsec))
{
delete_rrset(fctx, name, dns_rdatatype_cname);
}
if (rctx->type == dns_rdatatype_rrsig ||
- rctx->type == dns_rdatatype_key || rctx->type == dns_rdatatype_nsec)
+ rctx->type == dns_rdatatype_nsec)
{
char buf[DNS_RDATATYPE_FORMATSIZE];
dns_rdatatype_format(rctx->type, buf, sizeof(buf));
bool tf = dns_rdatatype_atcname((dns_rdatatype_t)i);
switch (i) {
case dns_rdatatype_nsec:
- case dns_rdatatype_key:
case dns_rdatatype_rrsig:
if (!tf) {
print_message(UNR, i);
case dns_rdatatype_ns:
case dns_rdatatype_ds:
case dns_rdatatype_nsec:
- case dns_rdatatype_key:
case dns_rdatatype_rrsig:
if (!tf) {
print_message(UNR, i);