diff --git a/lib/dns/rdata/generic/zonemd_63.c b/lib/dns/rdata/generic/zonemd_63.c index 8148593a85..604a901d3e 100644 --- a/lib/dns/rdata/generic/zonemd_63.c +++ b/lib/dns/rdata/generic/zonemd_63.c @@ -70,7 +70,7 @@ totext_zonemd(ARGS_TOTEXT) { char buf[sizeof("0123456789")]; unsigned long num; - REQUIRE(rdata->length != 0); + REQUIRE(rdata->length > 6); UNUSED(tctx); @@ -136,9 +136,13 @@ fromwire_zonemd(ARGS_FROMWIRE) { isc_buffer_activeregion(source, &sr); /* - * Check digest lengths if we know them. + * If we do not recognize the digest type, only ensure that the digest + * is present at all. + * + * If we do recognize the digest type, ensure that the digest is of the + * correct length. */ - if (sr.length < 6 || + if (sr.length < 7 || (sr.base[4] == DNS_ZONEMD_DIGEST_SHA384 && sr.length < 6 + ISC_SHA384_DIGESTLENGTH)) { @@ -146,9 +150,10 @@ fromwire_zonemd(ARGS_FROMWIRE) { } /* - * Only copy digest lengths if we know them. - * If there is extra data dns_rdata_fromwire() will - * detect that. + * Only specify the number of octets to consume if we recognize the + * digest type. + * + * If there is extra data, dns_rdata_fromwire() will detect that. */ if (sr.base[4] == DNS_ZONEMD_DIGEST_SHA384) { sr.length = 6 + ISC_SHA384_DIGESTLENGTH; diff --git a/lib/dns/tests/rdata_test.c b/lib/dns/tests/rdata_test.c index 3bb104f0b8..0e8e2763d8 100644 --- a/lib/dns/tests/rdata_test.c +++ b/lib/dns/tests/rdata_test.c @@ -1642,7 +1642,7 @@ zonemd(void **state) { TEXT_INVALID("0 0"), TEXT_INVALID("0 0 0"), TEXT_INVALID("99999999 0 0"), - TEXT_INVALID("2019020700 0 0 "), + TEXT_INVALID("2019020700 0 0"), TEXT_INVALID("2019020700 1 0 DEADBEEF"), TEXT_VALID("2019020700 2 0 DEADBEEF"), TEXT_VALID("2019020700 255 0 DEADBEEF"), @@ -1676,26 +1676,20 @@ zonemd(void **state) { */ WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00), /* - * Serial + type + reserved only - digest type - * undefined, so we accept the missing digest. + * Short. */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00), /* - * SHA-384 is defined, so we insist there be a digest. + * Minimal, one-octet hash for an undefined digest type. */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00), + WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), /* - * Four octets, too short for SHA-384. + * SHA-384 is defined, so we insist there be a digest of + * the expected length. */ - WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xde, 0xad, 0xbe, 0xef), + WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00), /* - * Digest type undefined, so accept the short digest. - */ - WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0xff, 0x00, - 0xde, 0xad, 0xbe, 0xef), - /* - * 48 octets, valid for SHA-384. + * 48-octet digest, valid for SHA-384. */ WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, @@ -1706,6 +1700,32 @@ zonemd(void **state) { 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce), + /* + * 56-octet digest, too long for SHA-384. + */ + WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce), + /* + * 56-octet digest, valid for an undefined digest type. + */ + WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, + 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce), /* * Sentinel. */