mirror of
https://github.com/hickory-dns/hickory-dns.git
synced 2026-04-25 11:15:54 +03:00
[GH-ISSUE #2934] BinEncoder's canonical_names flag is overloaded #1096
Labels
No labels
blocked
breaking-change
bug
bug:critical
bug:tests
cleanup
compliance
compliance
compliance
crate:all
crate:client
crate:native-tls
crate:proto
crate:recursor
crate:resolver
crate:resolver
crate:rustls
crate:server
crate:util
dependencies
docs
duplicate
easy
easy
enhance
enhance
enhance
feature:dns-over-https
feature:dns-over-quic
feature:dns-over-tls
feature:dnsssec
feature:global_lb
feature:mdns
feature:tsig
features:edns
has workaround
ops
perf
platform:WASM
platform:android
platform:fuchsia
platform:linux
platform:macos
platform:windows
pull-request
question
test
tools
tools
trust
unclear
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/hickory-dns#1096
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @divergentdave on GitHub (Apr 15, 2025).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2934
The
canonical_namesflag in theBinEncoderstruct is overloaded, as it is used in different places both to decide whether to change encoded names to lower-case form, and whether to enable name compression. The flag can be set in multiple places, both before callingemit()on a message or record, and within<RData as BinEncodable>::emit(), which useswith_canonical_names()for only some record types when encoding the RDATA. The set of record types that do or don't always setcanonical_names = truefor RDATA is inconsistent with both the list of well-known record types from RFC 1035 (which may use compression inside RDATA) and the list of record types from RFC 4034 section 6.2 (which must use lowercase names inside RDATA for DNSSEC canonical form). To get this right, I think we first need to split up this flag into two or three separate flags.The encoder struct and encodable trait need to serve three different purposes: writing to wire protocol messages, constructing to-be-signed data for DNSSEC signing and verification, and any use of the encoder that does not encode an entire DNS message. The server's
ResponseHandleleavescanonical_namesset to false, while the encoders used byTBSalways havecanonical_namesset to true. For the wire protocol, we should generally keep the case of names as-is, and we need to preserve the case for names that are in RDATA of record types not listed in RFC 4034 section 6.2 (for instance, CAA and SVCB). We may use name compression in RDATA for well-known record types, but we must not use name compression in the RDATA of any record type introduced after RFC 1035. For DNSSEC canonical form, we must use lowercase names in RDATA for types listed in RFC 4034 section 6.2, and we must preserve the case of names in RDATA for types not listed there. We must not use name compression anywhere. For uses where we encode something other than an entire message into a buffer, for example when using temporary buffers in some routines, we can't use name compression, because the temporary buffer will get copied somewhere else in the final message, invalidating offsets in compression pointers.From code inspection, it looks like we have incorrect behavior in multiple directions. For example:
with_canonical_names(), and<ANAME as BinEncodable>::emit()passes the canonical names flag as thelowercaseargument toName::emit_with_lowercase(). This results in an incorrect DNSSEC canonical encoding, sinceANAMEis not on the list in RFC4034 for lowercasing.canonical_namesset to false. As a result, name compression could be used inside the RDATA. This would cause problems when interacting with other servers that don't have support for the SVCB record type, because they would have to obliviously copy the RDATA into a message when forwarding, which could invalidate the meaning of a compression pointer inside the name.@divergentdave commented on GitHub (Apr 15, 2025):
RFC 6840 has some updates that override RFC 4034 section 6.2 for NSEC and RRSIG record RDATA, based on common practice.