From: Matthijs Mekking Date: Fri, 9 Jan 2026 11:19:42 +0000 (+0100) Subject: Lower case the NSEC next owner name when signing X-Git-Tag: v9.21.18~14^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24aa490a9bd33cc952ccfa1f6930f345188797d1;p=thirdparty%2Fbind9.git Lower case the NSEC next owner name when signing When building the NSEC rdata, lower case the next owner name before storing it in the Next Domain Name Field. Note that this is not required according to RFC 6840, Section 5.1: When canonicalizing DNS names (for both ordering and signing), DNS names in the RDATA section of NSEC resource records are not converted to lowercase. DNS names in the RDATA section of RRSIG resource records are converted to lowercase. The guidance in the above paragraph differs from what has been published before but is consistent with current common practice. Item 3 of Section 6.2 of [RFC4034] says that names in both of these RR types should be converted to lowercase. The earlier [RFC3755] says that they should not. Since there is inconsistency in the documents over time, having uppercase next owner names in the NSEC records may cause validation failures if validators are not implementing RFC 6840. Also, RFC 4034 section 6.2 is not about how NSEC record content is created, but how RRset content is normalized in order to produce and validate RRSIG records for a given RRset. Since the next owner name of the NSEC record is about ordening, and the canonical DNS name order requires that uppercase US-ASCII letters must be treated as if they were lowercase US-ASCII letters, case is not meaningful for NSEC next owner names, as it cannot be compressed on the wire, so we may lowercase the next owner name in the NSEC rdata before signing, being more kind to validators. --- diff --git a/lib/dns/nsec.c b/lib/dns/nsec.c index 74fde42ee6e..d444374e8ce 100644 --- a/lib/dns/nsec.c +++ b/lib/dns/nsec.c @@ -100,11 +100,18 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, unsigned char *nsec_bits, *bm; unsigned int max_type; dns_rdatasetiter_t *rdsiter; + dns_fixedname_t fnextname; + dns_name_t *nextname; REQUIRE(target != NULL); + /* + * Downcase next owner name. + */ + nextname = dns_fixedname_initname(&fnextname); + RUNTIME_CHECK(dns_name_downcase(target, nextname) == ISC_R_SUCCESS); memset(buffer, 0, DNS_NSEC_BUFFERSIZE); - dns_name_toregion(target, &r); + dns_name_toregion(nextname, &r); memmove(buffer, r.base, r.length); r.base = buffer; /*