diff --git a/CHANGES b/CHANGES index 8073f378b9..8499b441f6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +4199. [protocol] Add support for RKEY. [RT #40563] + 4198. [placeholder] 4197. [bug] 'named-checkconf -z' didn't handle 'in-view' clauses. diff --git a/bin/tests/system/genzone.sh b/bin/tests/system/genzone.sh index ce8d742b3e..c0dc872db7 100644 --- a/bin/tests/system/genzone.sh +++ b/bin/tests/system/genzone.sh @@ -241,6 +241,12 @@ dnskey01 DNSKEY 512 ( 255 1 AQMFD5raczCJHViKtLYhWGz8hMY sENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esg a60zyGW6LFe9r8n6paHrlG5ojqf0BaqHT+8= ) +; type 57 +rkey01 RKEY 512 ( 255 1 AQMFD5raczCJHViKtLYhWGz8hMY + 9UGRuniJDBzC7w0aRyzWZriO6i2odGWWQVucZqKV + sENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esg + a60zyGW6LFe9r8n6paHrlG5ojqf0BaqHT+8= ) + ; type 59 cds01 CDS 30795 1 1 ( 310D27F4D82C1FC2400704EA9939FE6E1CEA diff --git a/bin/tests/system/rrchecker/typelist.good b/bin/tests/system/rrchecker/typelist.good index ad2a914bba..b8818885e3 100644 --- a/bin/tests/system/rrchecker/typelist.good +++ b/bin/tests/system/rrchecker/typelist.good @@ -49,6 +49,7 @@ NSEC3 NSEC3PARAM TLSA HIP +RKEY CDS CDNSKEY OPENPGPKEY diff --git a/bin/tests/system/xfer/dig1.good b/bin/tests/system/xfer/dig1.good index 24367c4878..1fc60508b9 100644 --- a/bin/tests/system/xfer/dig1.good +++ b/bin/tests/system/xfer/dig1.good @@ -71,6 +71,7 @@ openpgpkey.example. 3600 IN OPENPGPKEY AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7 ptr01.example. 3600 IN PTR example. px01.example. 3600 IN PX 65535 foo. bar. px02.example. 3600 IN PX 65535 . . +rkey01.example. 3600 IN RKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8= rp01.example. 3600 IN RP mbox-dname.example. txt-dname.example. rp02.example. 3600 IN RP . . rt01.example. 3600 IN RT 0 intermediate-host.example. diff --git a/bin/tests/system/xfer/dig2.good b/bin/tests/system/xfer/dig2.good index 30e8146bba..4915920ec0 100644 --- a/bin/tests/system/xfer/dig2.good +++ b/bin/tests/system/xfer/dig2.good @@ -71,6 +71,7 @@ openpgpkey.example. 3600 IN OPENPGPKEY AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7 ptr01.example. 3600 IN PTR example. px01.example. 3600 IN PX 65535 foo. bar. px02.example. 3600 IN PX 65535 . . +rkey01.example. 3600 IN RKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8= rp01.example. 3600 IN RP mbox-dname.example. txt-dname.example. rp02.example. 3600 IN RP . . rt01.example. 3600 IN RT 0 intermediate-host.example. diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index b18b4a6aca..453e625a4b 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -75,12 +75,12 @@ This flaw was discovered by Breno Silveira Soares, and is disclosed in CVE-2015-4620. [RT #39795] - + On servers configured to perform DNSSEC validation using managed trust anchors (i.e., keys configured explicitly - via managed-keys, or implicitly + via managed-keys, or implicitly via dnssec-validation auto; or dnssec-lookaside auto;), revoking a trust anchor and sending a new untrusted replacement @@ -379,7 +379,7 @@ rndc modzone can be used to reconfigure - a zone, using similar syntax to rndc addzone. + a zone, using similar syntax to rndc addzone. @@ -440,7 +440,7 @@ The nxdomain-redirect option specifies - a DNS namespace to use for NXDOMAIN redirection. When a + a DNS namespace to use for NXDOMAIN redirection. When a recursive lookup returns NXDOMAIN, a second lookup is initiated with the specified name appended to the query name. This allows NXDOMAIN redirection data to be supplied @@ -450,6 +450,11 @@ better average performance but is less flexible.) [RT #37989] + + + The following types have been implemented: RKEY. + + diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 25a0518a24..5a7474ec19 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -219,6 +219,24 @@ static isc_result_t unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target); +static inline isc_result_t +generic_fromtext_key(ARGS_FROMTEXT); + +static inline isc_result_t +generic_totext_key(ARGS_TOTEXT); + +static inline isc_result_t +generic_fromwire_key(ARGS_FROMWIRE); + +static inline isc_result_t +generic_fromstruct_key(ARGS_FROMSTRUCT); + +static inline isc_result_t +generic_tostruct_key(ARGS_TOSTRUCT); + +static inline void +generic_freestruct_key(ARGS_FREESTRUCT); + /*% INT16 Size */ #define NS_INT16SZ 2 /*% IPv6 Address Size */ diff --git a/lib/dns/rdata/generic/cdnskey_60.c b/lib/dns/rdata/generic/cdnskey_60.c index 3fa22de366..9b4305d5db 100644 --- a/lib/dns/rdata/generic/cdnskey_60.c +++ b/lib/dns/rdata/generic/cdnskey_60.c @@ -25,188 +25,29 @@ static inline isc_result_t fromtext_cdnskey(ARGS_FROMTEXT) { - isc_result_t result; - isc_token_t token; - dns_secalg_t alg; - dns_secproto_t proto; - dns_keyflags_t flags; REQUIRE(type == dns_rdatatype_cdnskey); - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* flags */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - ISC_FALSE)); - RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); - RETERR(uint16_tobuffer(flags, target)); - - /* protocol */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - ISC_FALSE)); - RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &proto, 1)); - - /* algorithm */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - ISC_FALSE)); - RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &alg, 1)); - - /* No Key? */ - if ((flags & 0xc000) == 0xc000) - return (ISC_R_SUCCESS); - - result = isc_base64_tobuffer(lexer, target, -1); - if (result != ISC_R_SUCCESS) - return (result); - - /* Ensure there's at least enough data to compute a key ID for MD5 */ - if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) - return (ISC_R_UNEXPECTEDEND); - - return (ISC_R_SUCCESS); + return (generic_fromtext_key(rdclass, type, lexer, origin, + options, target, callbacks)); } static inline isc_result_t totext_cdnskey(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("[key id = 64000]")]; - unsigned int flags; - unsigned char algorithm; - char algbuf[DNS_NAME_FORMATSIZE]; - const char *keyinfo; - isc_region_t tmpr; + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_cdnskey); - REQUIRE(rdata->length != 0); - dns_rdata_toregion(rdata, &sr); - - /* flags */ - flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - sprintf(buf, "%u", flags); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - if ((flags & DNS_KEYFLAG_KSK) != 0) { - if (flags & DNS_KEYFLAG_REVOKE) - keyinfo = "revoked KSK"; - else - keyinfo = "KSK"; - } else - keyinfo = "ZSK"; - - /* protocol */ - sprintf(buf, "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* algorithm */ - algorithm = sr.base[0]; - sprintf(buf, "%u", algorithm); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - - /* No Key? */ - if ((flags & 0xc000) == 0xc000) - return (ISC_R_SUCCESS); - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && - algorithm == DNS_KEYALG_PRIVATEDNS) { - dns_name_t name; - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &sr); - dns_name_format(&name, algbuf, sizeof(algbuf)); - } else { - dns_secalg_format((dns_secalg_t) algorithm, algbuf, - sizeof(algbuf)); - } - - /* key */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - - if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 0, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - } else { - dns_rdata_toregion(rdata, &tmpr); - snprintf(buf, sizeof(buf), "[key id = %u]", - dst_region_computeid(&tmpr, algorithm)); - RETERR(str_totext(buf, target)); - } - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) - RETERR(str_totext(tctx->linebreak, target)); - else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" ", target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(")", target)); - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { - - RETERR(str_totext(" ; ", target)); - RETERR(str_totext(keyinfo, target)); - RETERR(str_totext("; alg = ", target)); - RETERR(str_totext(algbuf, target)); - RETERR(str_totext("; key id = ", target)); - dns_rdata_toregion(rdata, &tmpr); - sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); - RETERR(str_totext(buf, target)); - } - return (ISC_R_SUCCESS); + return (generic_totext_key(rdata, tctx, target)); } static inline isc_result_t fromwire_cdnskey(ARGS_FROMWIRE) { - unsigned char algorithm; - isc_region_t sr; REQUIRE(type == dns_rdatatype_cdnskey); - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - - algorithm = sr.base[3]; - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_region_consume(&sr, 4); - isc_buffer_forward(source, 4); - - if (algorithm == DNS_KEYALG_PRIVATEDNS) { - dns_name_t name; - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - } - - /* - * RSAMD5 computes key ID differently from other - * algorithms: we need to ensure there's enough data - * present for the computation - */ - if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_activeregion(source, &sr); - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); + return (generic_fromwire_key(rdclass, type, source, dctx, + options, target)); } static inline isc_result_t @@ -227,6 +68,8 @@ compare_cdnskey(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; + REQUIRE(rdata1 != NULL); + REQUIRE(rdata2 != NULL); REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_cdnskey); @@ -240,85 +83,35 @@ compare_cdnskey(ARGS_COMPARE) { static inline isc_result_t fromstruct_cdnskey(ARGS_FROMSTRUCT) { - dns_rdata_cdnskey_t *dnskey = source; REQUIRE(type == dns_rdatatype_cdnskey); - REQUIRE(source != NULL); - REQUIRE(dnskey->common.rdtype == type); - REQUIRE(dnskey->common.rdclass == rdclass); - UNUSED(type); - UNUSED(rdclass); - - /* Flags */ - RETERR(uint16_tobuffer(dnskey->flags, target)); - - /* Protocol */ - RETERR(uint8_tobuffer(dnskey->protocol, target)); - - /* Algorithm */ - RETERR(uint8_tobuffer(dnskey->algorithm, target)); - - /* Data */ - return (mem_tobuffer(target, dnskey->data, dnskey->datalen)); + return (generic_fromstruct_key(rdclass, type, source, target)); } static inline isc_result_t tostruct_cdnskey(ARGS_TOSTRUCT) { dns_rdata_cdnskey_t *dnskey = target; - isc_region_t sr; + REQUIRE(dnskey != NULL); + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_cdnskey); - REQUIRE(target != NULL); - REQUIRE(rdata->length != 0); dnskey->common.rdclass = rdata->rdclass; dnskey->common.rdtype = rdata->type; ISC_LINK_INIT(&dnskey->common, link); - dns_rdata_toregion(rdata, &sr); - - /* Flags */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - dnskey->flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* Protocol */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - dnskey->protocol = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Algorithm */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - dnskey->algorithm = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Data */ - dnskey->datalen = sr.length; - dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen); - if (dnskey->data == NULL) - return (ISC_R_NOMEMORY); - - dnskey->mctx = mctx; - return (ISC_R_SUCCESS); + return (generic_tostruct_key(rdata, target, mctx)); } static inline void freestruct_cdnskey(ARGS_FREESTRUCT) { dns_rdata_cdnskey_t *dnskey = (dns_rdata_cdnskey_t *) source; - REQUIRE(source != NULL); + REQUIRE(dnskey != NULL); REQUIRE(dnskey->common.rdtype == dns_rdatatype_cdnskey); - if (dnskey->mctx == NULL) - return; - - if (dnskey->data != NULL) - isc_mem_free(dnskey->mctx, dnskey->data); - dnskey->mctx = NULL; + generic_freestruct_key(source); } static inline isc_result_t @@ -336,6 +129,7 @@ static inline isc_result_t digest_cdnskey(ARGS_DIGEST) { isc_region_t r; + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_cdnskey); dns_rdata_toregion(rdata, &r); @@ -359,6 +153,7 @@ checkowner_cdnskey(ARGS_CHECKOWNER) { static inline isc_boolean_t checknames_cdnskey(ARGS_CHECKNAMES) { + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_cdnskey); UNUSED(rdata); diff --git a/lib/dns/rdata/generic/cdnskey_60.h b/lib/dns/rdata/generic/cdnskey_60.h index d284177c11..e2876f6cbe 100644 --- a/lib/dns/rdata/generic/cdnskey_60.h +++ b/lib/dns/rdata/generic/cdnskey_60.h @@ -18,15 +18,6 @@ #define GENERIC_CDNSKEY_60_H 1 /* CDNSKEY records have the same RDATA fields as DNSKEY records. */ -typedef struct dns_rdata_cdnskey { - dns_rdatacommon_t common; - isc_mem_t * mctx; - isc_uint16_t flags; - isc_uint8_t protocol; - isc_uint8_t algorithm; - isc_uint16_t datalen; - unsigned char * data; -} dns_rdata_cdnskey_t; - +typedef struct dns_rdata_key dns_rdata_cdnskey_t; #endif /* GENERIC_CDNSKEY_60_H */ diff --git a/lib/dns/rdata/generic/dnskey_48.c b/lib/dns/rdata/generic/dnskey_48.c index fa87b964f3..41afd57fe1 100644 --- a/lib/dns/rdata/generic/dnskey_48.c +++ b/lib/dns/rdata/generic/dnskey_48.c @@ -32,194 +32,36 @@ static inline isc_result_t fromtext_dnskey(ARGS_FROMTEXT) { - isc_result_t result; - isc_token_t token; - dns_secalg_t alg; - dns_secproto_t proto; - dns_keyflags_t flags; REQUIRE(type == dns_rdatatype_dnskey); - UNUSED(type); - UNUSED(rdclass); - UNUSED(origin); - UNUSED(options); - UNUSED(callbacks); - - /* flags */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - ISC_FALSE)); - RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); - RETERR(uint16_tobuffer(flags, target)); - - /* protocol */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - ISC_FALSE)); - RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &proto, 1)); - - /* algorithm */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - ISC_FALSE)); - RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); - RETERR(mem_tobuffer(target, &alg, 1)); - - /* No Key? */ - if ((flags & 0xc000) == 0xc000) - return (ISC_R_SUCCESS); - - result = isc_base64_tobuffer(lexer, target, -1); - if (result != ISC_R_SUCCESS) - return (result); - - /* Ensure there's at least enough data to compute a key ID for MD5 */ - if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) - return (ISC_R_UNEXPECTEDEND); - - return (ISC_R_SUCCESS); + return (generic_fromtext_key(rdclass, type, lexer, origin, + options, target, callbacks)); } static inline isc_result_t totext_dnskey(ARGS_TOTEXT) { - isc_region_t sr; - char buf[sizeof("[key id = 64000]")]; - unsigned int flags; - unsigned char algorithm; - char algbuf[DNS_NAME_FORMATSIZE]; - const char *keyinfo; - isc_region_t tmpr; + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_dnskey); - REQUIRE(rdata->length != 0); - dns_rdata_toregion(rdata, &sr); - - /* flags */ - flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - sprintf(buf, "%u", flags); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - if ((flags & DNS_KEYFLAG_KSK) != 0) { - if (flags & DNS_KEYFLAG_REVOKE) - keyinfo = "revoked KSK"; - else - keyinfo = "KSK"; - } else - keyinfo = "ZSK"; - - /* protocol */ - sprintf(buf, "%u", sr.base[0]); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* algorithm */ - algorithm = sr.base[0]; - sprintf(buf, "%u", algorithm); - isc_region_consume(&sr, 1); - RETERR(str_totext(buf, target)); - - /* No Key? */ - if ((flags & 0xc000) == 0xc000) - return (ISC_R_SUCCESS); - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && - algorithm == DNS_KEYALG_PRIVATEDNS) { - dns_name_t name; - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &sr); - dns_name_format(&name, algbuf, sizeof(algbuf)); - } else { - dns_secalg_format((dns_secalg_t) algorithm, algbuf, - sizeof(algbuf)); - } - - /* key */ - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - - if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 0, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); - } else { - dns_rdata_toregion(rdata, &tmpr); - snprintf(buf, sizeof(buf), "[key id = %u]", - dst_region_computeid(&tmpr, algorithm)); - RETERR(str_totext(buf, target)); - } - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) - RETERR(str_totext(tctx->linebreak, target)); - else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" ", target)); - - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(")", target)); - - if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { - - RETERR(str_totext(" ; ", target)); - RETERR(str_totext(keyinfo, target)); - RETERR(str_totext("; alg = ", target)); - RETERR(str_totext(algbuf, target)); - RETERR(str_totext("; key id = ", target)); - dns_rdata_toregion(rdata, &tmpr); - sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); - RETERR(str_totext(buf, target)); - } - return (ISC_R_SUCCESS); + return (generic_totext_key(rdata, tctx, target)); } static inline isc_result_t fromwire_dnskey(ARGS_FROMWIRE) { - unsigned char algorithm; - isc_region_t sr; REQUIRE(type == dns_rdatatype_dnskey); - UNUSED(type); - UNUSED(rdclass); - UNUSED(dctx); - UNUSED(options); - - isc_buffer_activeregion(source, &sr); - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - - algorithm = sr.base[3]; - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_region_consume(&sr, 4); - isc_buffer_forward(source, 4); - - if (algorithm == DNS_KEYALG_PRIVATEDNS) { - dns_name_t name; - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - dns_name_init(&name, NULL); - RETERR(dns_name_fromwire(&name, source, dctx, options, target)); - } - - /* - * RSAMD5 computes key ID differently from other - * algorithms: we need to ensure there's enough data - * present for the computation - */ - if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_activeregion(source, &sr); - isc_buffer_forward(source, sr.length); - return (mem_tobuffer(target, sr.base, sr.length)); + return (generic_fromwire_key(rdclass, type, source, dctx, + options, target)); } static inline isc_result_t towire_dnskey(ARGS_TOWIRE) { isc_region_t sr; + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_dnskey); REQUIRE(rdata->length != 0); @@ -234,6 +76,8 @@ compare_dnskey(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; + REQUIRE(rdata1 != NULL); + REQUIRE(rdata2 != NULL); REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_dnskey); @@ -247,89 +91,40 @@ compare_dnskey(ARGS_COMPARE) { static inline isc_result_t fromstruct_dnskey(ARGS_FROMSTRUCT) { - dns_rdata_dnskey_t *dnskey = source; REQUIRE(type == dns_rdatatype_dnskey); - REQUIRE(source != NULL); - REQUIRE(dnskey->common.rdtype == type); - REQUIRE(dnskey->common.rdclass == rdclass); - UNUSED(type); - UNUSED(rdclass); - - /* Flags */ - RETERR(uint16_tobuffer(dnskey->flags, target)); - - /* Protocol */ - RETERR(uint8_tobuffer(dnskey->protocol, target)); - - /* Algorithm */ - RETERR(uint8_tobuffer(dnskey->algorithm, target)); - - /* Data */ - return (mem_tobuffer(target, dnskey->data, dnskey->datalen)); + return (generic_fromstruct_key(rdclass, type, source, target)); } static inline isc_result_t tostruct_dnskey(ARGS_TOSTRUCT) { dns_rdata_dnskey_t *dnskey = target; - isc_region_t sr; + REQUIRE(dnskey != NULL); + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_dnskey); - REQUIRE(target != NULL); - REQUIRE(rdata->length != 0); dnskey->common.rdclass = rdata->rdclass; dnskey->common.rdtype = rdata->type; ISC_LINK_INIT(&dnskey->common, link); - dns_rdata_toregion(rdata, &sr); - - /* Flags */ - if (sr.length < 2) - return (ISC_R_UNEXPECTEDEND); - dnskey->flags = uint16_fromregion(&sr); - isc_region_consume(&sr, 2); - - /* Protocol */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - dnskey->protocol = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Algorithm */ - if (sr.length < 1) - return (ISC_R_UNEXPECTEDEND); - dnskey->algorithm = uint8_fromregion(&sr); - isc_region_consume(&sr, 1); - - /* Data */ - dnskey->datalen = sr.length; - dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen); - if (dnskey->data == NULL) - return (ISC_R_NOMEMORY); - - dnskey->mctx = mctx; - return (ISC_R_SUCCESS); + return (generic_tostruct_key(rdata, target, mctx)); } static inline void freestruct_dnskey(ARGS_FREESTRUCT) { dns_rdata_dnskey_t *dnskey = (dns_rdata_dnskey_t *) source; - REQUIRE(source != NULL); + REQUIRE(dnskey != NULL); REQUIRE(dnskey->common.rdtype == dns_rdatatype_dnskey); - if (dnskey->mctx == NULL) - return; - - if (dnskey->data != NULL) - isc_mem_free(dnskey->mctx, dnskey->data); - dnskey->mctx = NULL; + generic_freestruct_key(source); } static inline isc_result_t additionaldata_dnskey(ARGS_ADDLDATA) { + REQUIRE(rdata->type == dns_rdatatype_dnskey); UNUSED(rdata); @@ -343,6 +138,7 @@ static inline isc_result_t digest_dnskey(ARGS_DIGEST) { isc_region_t r; + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_dnskey); dns_rdata_toregion(rdata, &r); @@ -366,6 +162,7 @@ checkowner_dnskey(ARGS_CHECKOWNER) { static inline isc_boolean_t checknames_dnskey(ARGS_CHECKNAMES) { + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_dnskey); UNUSED(rdata); diff --git a/lib/dns/rdata/generic/dnskey_48.h b/lib/dns/rdata/generic/dnskey_48.h index ce88cd1bf3..2c07ecff82 100644 --- a/lib/dns/rdata/generic/dnskey_48.h +++ b/lib/dns/rdata/generic/dnskey_48.h @@ -18,20 +18,10 @@ #ifndef GENERIC_DNSKEY_48_H #define GENERIC_DNSKEY_48_H 1 -/* $Id: dnskey_48.h,v 1.7 2007/06/19 23:47:17 tbox Exp $ */ - /*! - * \brief per RFC2535 */ - -typedef struct dns_rdata_dnskey { - dns_rdatacommon_t common; - isc_mem_t * mctx; - isc_uint16_t flags; - isc_uint8_t protocol; - isc_uint8_t algorithm; - isc_uint16_t datalen; - unsigned char * data; -} dns_rdata_dnskey_t; + * \brief per RFC2535 + */ +typedef struct dns_rdata_key dns_rdata_dnskey_t; #endif /* GENERIC_DNSKEY_48_H */ diff --git a/lib/dns/rdata/generic/key_25.c b/lib/dns/rdata/generic/key_25.c index c2ddd57fc1..93d2d6fe70 100644 --- a/lib/dns/rdata/generic/key_25.c +++ b/lib/dns/rdata/generic/key_25.c @@ -31,15 +31,13 @@ #define RRTYPE_KEY_ATTRIBUTES (0) static inline isc_result_t -fromtext_key(ARGS_FROMTEXT) { +generic_fromtext_key(ARGS_FROMTEXT) { isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; dns_keyflags_t flags; - REQUIRE(type == dns_rdatatype_key); - UNUSED(type); UNUSED(rdclass); UNUSED(origin); @@ -80,14 +78,15 @@ fromtext_key(ARGS_FROMTEXT) { } static inline isc_result_t -totext_key(ARGS_TOTEXT) { +generic_totext_key(ARGS_TOTEXT) { isc_region_t sr; - char buf[sizeof("64000")]; + char buf[sizeof("[key id = 64000]")]; unsigned int flags; unsigned char algorithm; - char namebuf[DNS_NAME_FORMATSIZE]; + char algbuf[DNS_NAME_FORMATSIZE]; + const char *keyinfo; + isc_region_t tmpr; - REQUIRE(rdata->type == dns_rdatatype_key); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); @@ -98,6 +97,14 @@ totext_key(ARGS_TOTEXT) { sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); + if ((flags & DNS_KEYFLAG_KSK) != 0) { + if (flags & DNS_KEYFLAG_REVOKE) + keyinfo = "revoked KSK"; + else + keyinfo = "KSK"; + } else + keyinfo = "ZSK"; + /* protocol */ sprintf(buf, "%u", sr.base[0]); @@ -120,19 +127,29 @@ totext_key(ARGS_TOTEXT) { dns_name_t name; dns_name_init(&name, NULL); dns_name_fromregion(&name, &sr); - dns_name_format(&name, namebuf, sizeof(namebuf)); - } else - namebuf[0] = 0; + dns_name_format(&name, algbuf, sizeof(algbuf)); + } else { + dns_secalg_format((dns_secalg_t) algorithm, algbuf, + sizeof(algbuf)); + } /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - if (tctx->width == 0) /* No splitting */ - RETERR(isc_base64_totext(&sr, 60, "", target)); - else - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); + + if ((tctx->flags & DNS_STYLEFLAG_NOCRYPTO) == 0) { + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); + } else { + dns_rdata_toregion(rdata, &tmpr); + snprintf(buf, sizeof(buf), "[key id = %u]", + dst_region_computeid(&tmpr, algorithm)); + RETERR(str_totext(buf, target)); + } if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); @@ -143,28 +160,27 @@ totext_key(ARGS_TOTEXT) { RETERR(str_totext(")", target)); if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { - isc_region_t tmpr; + if (rdata->type == dns_rdatatype_dnskey || + rdata->type == dns_rdatatype_cdnskey) { + RETERR(str_totext(" ; ", target)); + RETERR(str_totext(keyinfo, target)); + } + RETERR(str_totext("; alg = ", target)); + RETERR(str_totext(algbuf, target)); RETERR(str_totext(" ; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); - if (algorithm == DNS_KEYALG_PRIVATEDNS) { - RETERR(str_totext(tctx->linebreak, target)); - RETERR(str_totext("; alg = ", target)); - RETERR(str_totext(namebuf, target)); - } } return (ISC_R_SUCCESS); } static inline isc_result_t -fromwire_key(ARGS_FROMWIRE) { +generic_fromwire_key(ARGS_FROMWIRE) { unsigned char algorithm; isc_region_t sr; - REQUIRE(type == dns_rdatatype_key); - UNUSED(type); UNUSED(rdclass); UNUSED(dctx); @@ -199,10 +215,38 @@ fromwire_key(ARGS_FROMWIRE) { return (mem_tobuffer(target, sr.base, sr.length)); } +static inline isc_result_t +fromtext_key(ARGS_FROMTEXT) { + + REQUIRE(type == dns_rdatatype_key); + + return (generic_fromtext_key(rdclass, type, lexer, origin, + options, target, callbacks)); +} + +static inline isc_result_t +totext_key(ARGS_TOTEXT) { + + REQUIRE(rdata != NULL); + REQUIRE(rdata->type == dns_rdatatype_key); + + return (generic_totext_key(rdata, tctx, target)); +} + +static inline isc_result_t +fromwire_key(ARGS_FROMWIRE) { + + REQUIRE(type == dns_rdatatype_key); + + return (generic_fromwire_key(rdclass, type, source, dctx, + options, target)); +} + static inline isc_result_t towire_key(ARGS_TOWIRE) { isc_region_t sr; + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_key); REQUIRE(rdata->length != 0); @@ -217,6 +261,8 @@ compare_key(ARGS_COMPARE) { isc_region_t r1; isc_region_t r2; + REQUIRE(rdata1 != NULL); + REQUIRE(rdata2 != NULL); REQUIRE(rdata1->type == rdata2->type); REQUIRE(rdata1->rdclass == rdata2->rdclass); REQUIRE(rdata1->type == dns_rdatatype_key); @@ -229,11 +275,10 @@ compare_key(ARGS_COMPARE) { } static inline isc_result_t -fromstruct_key(ARGS_FROMSTRUCT) { +generic_fromstruct_key(ARGS_FROMSTRUCT) { dns_rdata_key_t *key = source; - REQUIRE(type == dns_rdatatype_key); - REQUIRE(source != NULL); + REQUIRE(key != NULL); REQUIRE(key->common.rdtype == type); REQUIRE(key->common.rdclass == rdclass); @@ -254,17 +299,17 @@ fromstruct_key(ARGS_FROMSTRUCT) { } static inline isc_result_t -tostruct_key(ARGS_TOSTRUCT) { +generic_tostruct_key(ARGS_TOSTRUCT) { dns_rdata_key_t *key = target; isc_region_t sr; - REQUIRE(rdata->type == dns_rdatatype_key); - REQUIRE(target != NULL); + REQUIRE(rdata != NULL); REQUIRE(rdata->length != 0); - key->common.rdclass = rdata->rdclass; - key->common.rdtype = rdata->type; - ISC_LINK_INIT(&key->common, link); + REQUIRE(key != NULL); + REQUIRE(key->common.rdclass == rdata->rdclass); + REQUIRE(key->common.rdtype == rdata->type); + REQUIRE(!ISC_LINK_LINKED(&key->common, link)); dns_rdata_toregion(rdata, &sr); @@ -297,11 +342,10 @@ tostruct_key(ARGS_TOSTRUCT) { } static inline void -freestruct_key(ARGS_FREESTRUCT) { +generic_freestruct_key(ARGS_FREESTRUCT) { dns_rdata_key_t *key = (dns_rdata_key_t *) source; - REQUIRE(source != NULL); - REQUIRE(key->common.rdtype == dns_rdatatype_key); + REQUIRE(key != NULL); if (key->mctx == NULL) return; @@ -311,8 +355,43 @@ freestruct_key(ARGS_FREESTRUCT) { key->mctx = NULL; } +static inline isc_result_t +fromstruct_key(ARGS_FROMSTRUCT) { + + REQUIRE(type == dns_rdatatype_key); + + return (generic_fromstruct_key(rdclass, type, source, target)); +} + +static inline isc_result_t +tostruct_key(ARGS_TOSTRUCT) { + dns_rdata_key_t *key = target; + + REQUIRE(key != NULL); + REQUIRE(rdata != NULL); + REQUIRE(rdata->type == dns_rdatatype_key); + + key->common.rdclass = rdata->rdclass; + key->common.rdtype = rdata->type; + ISC_LINK_INIT(&key->common, link); + + return (generic_tostruct_key(rdata, target, mctx)); +} + +static inline void +freestruct_key(ARGS_FREESTRUCT) { + dns_rdata_key_t *key = (dns_rdata_key_t *) source; + + REQUIRE(key != NULL); + REQUIRE(key->common.rdtype == dns_rdatatype_key); + + generic_freestruct_key(source); +} + static inline isc_result_t additionaldata_key(ARGS_ADDLDATA) { + + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_key); UNUSED(rdata); @@ -326,6 +405,7 @@ static inline isc_result_t digest_key(ARGS_DIGEST) { isc_region_t r; + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_key); dns_rdata_toregion(rdata, &r); @@ -349,6 +429,7 @@ checkowner_key(ARGS_CHECKOWNER) { static inline isc_boolean_t checknames_key(ARGS_CHECKNAMES) { + REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_key); UNUSED(rdata); diff --git a/lib/dns/rdata/generic/key_25.h b/lib/dns/rdata/generic/key_25.h index bcf9cb6a22..8ee312152f 100644 --- a/lib/dns/rdata/generic/key_25.h +++ b/lib/dns/rdata/generic/key_25.h @@ -23,7 +23,7 @@ /*! * \brief Per RFC2535 */ -typedef struct dns_rdata_key_t { +typedef struct dns_rdata_key { dns_rdatacommon_t common; isc_mem_t * mctx; isc_uint16_t flags; diff --git a/lib/dns/rdata/generic/rkey_57.c b/lib/dns/rdata/generic/rkey_57.c new file mode 100644 index 0000000000..a57d1bc13f --- /dev/null +++ b/lib/dns/rdata/generic/rkey_57.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef RDATA_GENERIC_RKEY_57_C +#define RDATA_GENERIC_RKEY_57_C + +#define RRTYPE_RKEY_ATTRIBUTES 0 + +static inline isc_result_t +fromtext_rkey(ARGS_FROMTEXT) { + + REQUIRE(type == dns_rdatatype_rkey); + + return (generic_fromtext_key(rdclass, type, lexer, origin, + options, target, callbacks)); +} + +static inline isc_result_t +totext_rkey(ARGS_TOTEXT) { + + REQUIRE(rdata != NULL); + REQUIRE(rdata->type == dns_rdatatype_rkey); + + return (generic_totext_key(rdata, tctx, target)); +} + +static inline isc_result_t +fromwire_rkey(ARGS_FROMWIRE) { + + REQUIRE(type == dns_rdatatype_rkey); + + return (generic_fromwire_key(rdclass, type, source, dctx, + options, target)); +} + +static inline isc_result_t +towire_rkey(ARGS_TOWIRE) { + isc_region_t sr; + + REQUIRE(rdata != NULL); + REQUIRE(rdata->type == dns_rdatatype_rkey); + REQUIRE(rdata->length != 0); + + UNUSED(cctx); + + dns_rdata_toregion(rdata, &sr); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static inline int +compare_rkey(ARGS_COMPARE) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1 != NULL); + REQUIRE(rdata2 != NULL); + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == dns_rdatatype_rkey); + REQUIRE(rdata1->length != 0); + REQUIRE(rdata2->length != 0); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return (isc_region_compare(&r1, &r2)); +} + +static inline isc_result_t +fromstruct_rkey(ARGS_FROMSTRUCT) { + + REQUIRE(type == dns_rdatatype_rkey); + + return (generic_fromstruct_key(rdclass, type, source, target)); +} + +static inline isc_result_t +tostruct_rkey(ARGS_TOSTRUCT) { + dns_rdata_rkey_t *rkey = target; + + REQUIRE(rkey != NULL); + REQUIRE(rdata != NULL); + REQUIRE(rdata->type == dns_rdatatype_rkey); + + rkey->common.rdclass = rdata->rdclass; + rkey->common.rdtype = rdata->type; + ISC_LINK_INIT(&rkey->common, link); + + return (generic_tostruct_key(rdata, target, mctx)); +} + +static inline void +freestruct_rkey(ARGS_FREESTRUCT) { + dns_rdata_rkey_t *rkey = (dns_rdata_rkey_t *) source; + + REQUIRE(rkey != NULL); + REQUIRE(rkey->common.rdtype == dns_rdatatype_rkey); + + generic_freestruct_key(source); +} + +static inline isc_result_t +additionaldata_rkey(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == dns_rdatatype_rkey); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_rkey(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata != NULL); + REQUIRE(rdata->type == dns_rdatatype_rkey); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_rkey(ARGS_CHECKOWNER) { + + REQUIRE(type == dns_rdatatype_rkey); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_rkey(ARGS_CHECKNAMES) { + + REQUIRE(rdata != NULL); + REQUIRE(rdata->type == dns_rdatatype_rkey); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +static inline int +casecompare_rkey(ARGS_COMPARE) { + + /* + * Treat ALG 253 (private DNS) subtype name case sensistively. + */ + return (compare_rkey(rdata1, rdata2)); +} + +#endif /* RDATA_GENERIC_RKEY_57_C */ diff --git a/lib/dns/rdata/generic/rkey_57.h b/lib/dns/rdata/generic/rkey_57.h new file mode 100644 index 0000000000..330b3fbad8 --- /dev/null +++ b/lib/dns/rdata/generic/rkey_57.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef GENERIC_RKEY_57_H +#define GENERIC_RKEY_57_H 1 + +typedef struct dns_rdata_key dns_rdata_rkey_t; + +#endif /* GENERIC_RKEY_57_H */