Subject: [DNSOP] Unknown DNS RDATA type presentation syntax vs. e.g. TXT records?

From: Viktor Dukhovni <[email-masked]>
Date: Sun, 9 Feb 2020 04:28:14 -0500

RFC 3597 defines a syntax for generically presenting RDATA of an unknown
type, but possibly (not my take) leaves some room for creative
differences:

    https://tools.ietf.org/html/rfc3597#section-5

    5.  Text Representation

       In the "type" field of a master file line, an unknown RR type is
       represented by the word "TYPE" immediately followed by the decimal RR
       type number, with no intervening whitespace.  In the "class" field,
       an unknown class is similarly represented as the word "CLASS"
       immediately followed by the decimal class number.

       ...

 --->  An implementation MAY also choose to represent some RRs of known type
 --->  using the above generic representations for the type, class and/or
 --->  RDATA, which carries the benefit of making the resulting master file
 --->  portable to servers where these types are unknown.  Using the generic
       representation for the RDATA of an RR of known type can also be
       useful in the case of an RR type where the text format varies
       depending on a version, protocol, or similar field (or several)
       embedded in the RDATA when such a field has a value for which no text
       format is known, e.g., a LOC RR [RFC1876] with a VERSION other than 0.

 --->  Even though an RR of known type represented in the \# format is
 --->  effectively treated as an unknown type for the purpose of parsing the
 --->  RDATA text representation, all further processing by the server MUST
 --->  treat it as a known type and take into account any applicable type-
       specific rules regarding compression, canonicalization, etc.

In particular the middle paragraph's *MAY* could appear to suggest that
the choice is not just one of output format, but that *on input* parsers
don't need to support the generic "\# <len> <hex nibbles>" form for
*known* types.

I don't read it that way, rather my reading is that the generic RDATA
format MAY be selected on *output* for portability reasons, but *should*
MUST be supported for all types, whether known or unknown, on input.

I was therefore surprised to find that BIND 9.14 refuses load zone files
with TXT records in the generic form, for example named-checkzone does
not accept:

    example.org.    IN TXT \# 4 deadbeef

but does accept:

    example.org.    IN MX \# 3 000000
    example.org.    IN TXT "\222\173\190\239"

Is this is a BIND feature or bug?  It therefore seems that if one wants
to portably output the generic encoding, it is imperative to output the
rrtype as, e.g., TYPE16 rather than TXT, even when the type's standard
name is known, but the generic encoding is desirable for some reason.
The examples in the RFC do include combinations of known type, generic
data and vice versa:

      e.example.   IN          A               \# 4 0A000001
      e.example.   CLASS1      TYPE1           10.0.0.2

-- 
    Viktor.

---

From: Mark Andrews <[email-masked]>
Date: Sun, 9 Feb 2020 20:55:30 +1100

Put a valid txt record in

\# 5 04deadbeef

-- 
Mark Andrews

> On 9 Feb 2020, at 20:28, Viktor Dukhovni <[email-masked]> wrote:
> 
> presenting

---

From: Viktor Dukhovni <[email-masked]>
Date: Sun, 9 Feb 2020 05:23:29 -0500

> On Feb 9, 2020, at 4:55 AM, Mark Andrews <[email-masked]> wrote:
> 

Oops. :-(  Never mind, thanks for the correction.  Indeed not
forgetting the length works.  FWIW, I was just double-checking
the presentation form of special characters in TXT records for
a new codec I'm writing, to see to see how special characters
are encoded in TXT RRs when presented by "dig", ...

RFC 1035 isn't crystal-clear on whether "\DDD" decimal escapes
work inside the double quotes in <character-strings>, they do
naturally enough, but I wish the description were stated more
clearly.

-- 
	Viktor.

---

From: Tony Finch <[email-masked]>
Date: Mon, 10 Feb 2020 12:40:04 +0000

>     example.org.    IN TXT \# 4 deadbeef

The long version of Mark's message is that a TXT record consists of an
overall RDLENGTH (which is the number after the \#) and then each string
in the RDATA is prefixed with its own length byte. So the wire format of

	TXT "\222\173\190\239

is

	TYPE16 \# 5 04deadbeef

The multiple strings and nested lengths in TXT records are a curiously
gratuitous complication.

When I was working out how a SHA-1 attack could work with TXT records,
(https://www.dns.cam.ac.uk/news/2020-01-09-sha-mbles.html)
one of the problems was that the collision blocks in the best attack so
far are 588 bytes, which is too big to fit into a single TXT string. So
there will be length bytes inside the collision blocks which can't easily
be controlled by the attacker. The solution is to append 255 zero bytes
which is enough to fill the tail end of any string specified by the last
length byte in the collision blocks, and any excess zero bytes get treated
as a sequence of empty strings.

Tony.
-- 
f.anthony.n.finch  <[email-masked]>  http://dotat.at/
Dogger, Fisher, German Bight: West 7 to severe gale 9, decreasing 6 for a
time. Rough or very rough. Squally wintry showers. Good, occasionally poor.

---

From: 神明達哉 <[email-masked]>
Date: Mon, 10 Feb 2020 16:16:21 -0800

At Sun, 9 Feb 2020 04:28:14 -0500,

> MUST be supported for all types, whether known or unknown, on input.

It would be nice if we could clarify the meaning of this "MAY".  I've
also encountered an implementation (not BIND 9) that rejects the
RFC3597 form of RDATA for types that the implementation already
explicitly supports (e.g., type AAAA).  I was about to submit a bug
report but on re-reading the RFC and found this "MAY", and wondered
whether this allows such an implementation to still claim to be
compliant.

I personally agree with your interpretation, but the text could
actually be clearer.

--
JINMEI, Tatuya

---

From: Mark Andrews <[email-masked]>
Date: Tue, 11 Feb 2020 13:02:20 +1100

> On 11 Feb 2020, at 11:16, 神明達哉 <[email-masked]> wrote:
> 

I would submit a bug report.  The intention of RFC3597 is to allow servers
to load records regardless of whether they know the record’s presentation
format or not.

Mark

> --
> JINMEI, Tatuya
> 
> _______________________________________________
> DNSOP mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/dnsop

-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742              INTERNET: [email-masked]

---

From: Dick Franks <[email-masked]>
Date: Tue, 11 Feb 2020 09:29:44 +0000

On Mon, 10 Feb 2020 at 16:19, Tony Finch <[email-masked]> wrote:
>8

> as a sequence of empty strings.

The troublesome length bytes can be avoided by (ab)using a generic URI
RR instead:

    64kilobeef. TYPE256 \# 8 deadbeefdeadbeef

which allows arbitrary content (3 < length < ~64k).
Note that the URI target text occupies the remaining RDATA after the
weight field.

--
Dick

---

From: Tony Finch <[email-masked]>
Date: Tue, 11 Feb 2020 12:28:35 +0000

> The troublesome length bytes can be avoided by (ab)using a generic URI

Indeed :-) The reason I wanted to make the attack work with TXT was the
example scenario targeted ACME dns-01, so it's more pointed if we imagine
the attacker has very limited access to update the zone. Also it's a fun
opportunity to try smuggling arbitrary binary data through a parser that
you might not expect would allow it.

Tony.
-- 
f.anthony.n.finch  <[email-masked]>  http://dotat.at/
Shannon: Westerly 7 to severe gale 9, occasionally storm 10 at first in north,
backing southerly 4 to 6 later. High or very high, occasionally very rough
later. Occasional rain or showers. Moderate, occasionally poor.