hickory_proto/rr/dnssec/rdata/
mod.rs

1// Copyright 2015-2023 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! All record data structures and related serialization methods
9
10use std::fmt;
11
12#[cfg(feature = "serde-config")]
13use serde::{Deserialize, Serialize};
14
15// TODO: these should each be it's own struct, it would make parsing and decoding a little cleaner
16//  and also a little more ergonomic when accessing.
17// each of these module's has the parser for that rdata embedded, to keep the file sizes down...
18pub mod cdnskey;
19pub mod cds;
20pub mod dnskey;
21pub mod ds;
22#[allow(deprecated)]
23pub mod key;
24pub mod nsec;
25pub mod nsec3;
26pub mod nsec3param;
27pub mod rrsig;
28pub mod sig;
29pub mod tsig;
30
31use enum_as_inner::EnumAsInner;
32use tracing::trace;
33
34use crate::{
35    error::*,
36    rr::{rdata::NULL, RData, RecordDataDecodable, RecordType},
37    serialize::binary::{BinDecodable, BinDecoder, BinEncodable, BinEncoder, Restrict},
38};
39
40pub use self::cdnskey::CDNSKEY;
41pub use self::cds::CDS;
42pub use self::dnskey::DNSKEY;
43pub use self::ds::DS;
44pub use self::key::KEY;
45pub use self::nsec::NSEC;
46pub use self::nsec3::NSEC3;
47pub use self::nsec3param::NSEC3PARAM;
48pub use self::rrsig::RRSIG;
49pub use self::sig::SIG;
50pub use self::tsig::TSIG;
51
52/// The type of the resource record, for DNSSEC-specific records.
53#[deprecated(note = "All RecordType definitions have been moved into RecordType")]
54pub type DNSSECRecordType = RecordType;
55
56/// Record data enum variants for DNSSEC-specific records.
57#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
58#[derive(Debug, EnumAsInner, PartialEq, Clone, Eq)]
59#[non_exhaustive]
60pub enum DNSSECRData {
61    /// ```text
62    /// RFC 7344              Delegation Trust Maintenance        September 2014
63    ///
64    /// 3.2.  CDNSKEY Resource Record Format
65    ///
66    ///    The wire and presentation format of the CDNSKEY ("Child DNSKEY")
67    ///    resource record is identical to the DNSKEY record.  IANA has
68    ///    allocated RR code 60 for the CDNSKEY resource record via Expert
69    ///    Review.  The CDNSKEY RR uses the same registries as DNSKEY for its
70    ///    fields.
71    ///
72    ///    No special processing is performed by authoritative servers or by
73    ///    resolvers, when serving or resolving.  For all practical purposes,
74    ///    CDNSKEY is a regular RR type.
75    /// ```
76    CDNSKEY(CDNSKEY),
77
78    /// ```text
79    /// RFC 7344              Delegation Trust Maintenance        September 2014
80    ///
81    /// 3.1.  CDS Resource Record Format
82    ///    The wire and presentation format of the Child DS (CDS) resource
83    ///    record is identical to the DS record [RFC4034].  IANA has allocated
84    ///    RR code 59 for the CDS resource record via Expert Review
85    ///    [DNS-TRANSPORT].  The CDS RR uses the same registries as DS for its
86    ///    fields.
87    ///
88    ///    No special processing is performed by authoritative servers or by
89    ///    resolvers, when serving or resolving.  For all practical purposes,
90    ///    CDS is a regular RR type.
91    /// ```
92    CDS(CDS),
93
94    /// ```text
95    /// RFC 4034                DNSSEC Resource Records               March 2005
96    ///
97    /// 2.1.  DNSKEY RDATA Wire Format
98    ///
99    ///    The RDATA for a DNSKEY RR consists of a 2 octet Flags Field, a 1
100    ///    octet Protocol Field, a 1 octet Algorithm Field, and the Public Key
101    ///    Field.
102    ///
103    ///                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
104    ///     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
105    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106    ///    |              Flags            |    Protocol   |   Algorithm   |
107    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108    ///    /                                                               /
109    ///    /                            Public Key                         /
110    ///    /                                                               /
111    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
112    ///
113    /// 2.1.1.  The Flags Field
114    ///
115    ///    Bit 7 of the Flags field is the Zone Key flag.  If bit 7 has value 1,
116    ///    then the DNSKEY record holds a DNS zone key, and the DNSKEY RR's
117    ///    owner name MUST be the name of a zone.  If bit 7 has value 0, then
118    ///    the DNSKEY record holds some other type of DNS public key and MUST
119    ///    NOT be used to verify RRSIGs that cover RRsets.
120    ///
121    ///    Bit 15 of the Flags field is the Secure Entry Point flag, described
122    ///    in [RFC3757].  If bit 15 has value 1, then the DNSKEY record holds a
123    ///    key intended for use as a secure entry point.  This flag is only
124    ///    intended to be a hint to zone signing or debugging software as to the
125    ///    intended use of this DNSKEY record; validators MUST NOT alter their
126    ///    behavior during the signature validation process in any way based on
127    ///    the setting of this bit.  This also means that a DNSKEY RR with the
128    ///    SEP bit set would also need the Zone Key flag set in order to be able
129    ///    to generate signatures legally.  A DNSKEY RR with the SEP set and the
130    ///    Zone Key flag not set MUST NOT be used to verify RRSIGs that cover
131    ///    RRsets.
132    ///
133    ///    Bits 0-6 and 8-14 are reserved: these bits MUST have value 0 upon
134    ///    creation of the DNSKEY RR and MUST be ignored upon receipt.
135    ///
136    /// RFC 5011                  Trust Anchor Update             September 2007
137    ///
138    /// 7.  IANA Considerations
139    ///
140    ///   The IANA has assigned a bit in the DNSKEY flags field (see Section 7
141    ///   of [RFC4034]) for the REVOKE bit (8).
142    /// ```
143    DNSKEY(DNSKEY),
144
145    /// ```text
146    /// 5.1.  DS RDATA Wire Format
147    ///
148    /// The RDATA for a DS RR consists of a 2 octet Key Tag field, a 1 octet
149    ///           Algorithm field, a 1 octet Digest Type field, and a Digest field.
150    ///
151    ///                          1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
152    ///      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
153    ///     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154    ///     |           Key Tag             |  Algorithm    |  Digest Type  |
155    ///     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156    ///     /                                                               /
157    ///     /                            Digest                             /
158    ///     /                                                               /
159    ///     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160    ///
161    /// 5.1.1.  The Key Tag Field
162    ///
163    ///    The Key Tag field lists the key tag of the DNSKEY RR referred to by
164    ///    the DS record, in network byte order.
165    ///
166    ///    The Key Tag used by the DS RR is identical to the Key Tag used by
167    ///    RRSIG RRs.  Appendix B describes how to compute a Key Tag.
168    ///
169    /// 5.1.2.  The Algorithm Field
170    ///
171    ///    The Algorithm field lists the algorithm number of the DNSKEY RR
172    ///    referred to by the DS record.
173    ///
174    ///    The algorithm number used by the DS RR is identical to the algorithm
175    ///    number used by RRSIG and DNSKEY RRs.  Appendix A.1 lists the
176    ///    algorithm number types.
177    ///
178    /// 5.1.3.  The Digest Type Field
179    ///
180    ///    The DS RR refers to a DNSKEY RR by including a digest of that DNSKEY
181    ///    RR.  The Digest Type field identifies the algorithm used to construct
182    ///    the digest.  Appendix A.2 lists the possible digest algorithm types.
183    ///
184    /// 5.1.4.  The Digest Field
185    ///
186    ///    The DS record refers to a DNSKEY RR by including a digest of that
187    ///    DNSKEY RR.
188    ///
189    ///    The digest is calculated by concatenating the canonical form of the
190    ///    fully qualified owner name of the DNSKEY RR with the DNSKEY RDATA,
191    ///    and then applying the digest algorithm.
192    ///
193    ///      digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
194    ///
195    ///       "|" denotes concatenation
196    ///
197    ///      DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
198    ///
199    ///    The size of the digest may vary depending on the digest algorithm and
200    ///    DNSKEY RR size.  As of the time of this writing, the only defined
201    ///    digest algorithm is SHA-1, which produces a 20 octet digest.
202    /// ```
203    DS(DS),
204
205    /// ```text
206    /// RFC 2535                DNS Security Extensions               March 1999
207    ///
208    /// 3.1 KEY RDATA format
209    ///
210    ///  The RDATA for a KEY RR consists of flags, a protocol octet, the
211    ///  algorithm number octet, and the public key itself.  The format is as
212    ///  follows:
213    ///
214    ///                       1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
215    ///   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
216    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
217    ///  |             flags             |    protocol   |   algorithm   |
218    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
219    ///  |                                                               /
220    ///  /                          public key                           /
221    ///  /                                                               /
222    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
223    ///
224    ///  The KEY RR is not intended for storage of certificates and a separate
225    ///  certificate RR has been developed for that purpose, defined in [RFC
226    ///  2538].
227    ///
228    ///  The meaning of the KEY RR owner name, flags, and protocol octet are
229    ///  described in Sections 3.1.1 through 3.1.5 below.  The flags and
230    ///  algorithm must be examined before any data following the algorithm
231    ///  octet as they control the existence and format of any following data.
232    ///  The algorithm and public key fields are described in Section 3.2.
233    ///  The format of the public key is algorithm dependent.
234    ///
235    ///  KEY RRs do not specify their validity period but their authenticating
236    ///  SIG RR(s) do as described in Section 4 below.
237    /// ```
238    KEY(KEY),
239
240    /// ```text
241    /// RFC 4034                DNSSEC Resource Records               March 2005
242    ///
243    /// 4.1.  NSEC RDATA Wire Format
244    ///
245    ///  The RDATA of the NSEC RR is as shown below:
246    ///
247    ///                       1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
248    ///   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
249    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
250    ///  /                      Next Domain Name                         /
251    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
252    ///  /                       Type Bit Maps                           /
253    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
254    /// ```
255    NSEC(NSEC),
256
257    /// ```text
258    /// RFC 5155                         NSEC3                        March 2008
259    ///
260    /// 3.2.  NSEC3 RDATA Wire Format
261    ///
262    ///  The RDATA of the NSEC3 RR is as shown below:
263    ///
264    ///                       1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
265    ///   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
266    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
267    ///  |   Hash Alg.   |     Flags     |          Iterations           |
268    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
269    ///  |  Salt Length  |                     Salt                      /
270    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
271    ///  |  Hash Length  |             Next Hashed Owner Name            /
272    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
273    ///  /                         Type Bit Maps                         /
274    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
275    ///
276    ///  Hash Algorithm is a single octet.
277    ///
278    ///  Flags field is a single octet, the Opt-Out flag is the least
279    ///  significant bit, as shown below:
280    ///
281    ///   0 1 2 3 4 5 6 7
282    ///  +-+-+-+-+-+-+-+-+
283    ///  |             |O|
284    ///  +-+-+-+-+-+-+-+-+
285    ///
286    ///  Iterations is represented as a 16-bit unsigned integer, with the most
287    ///  significant bit first.
288    ///
289    ///  Salt Length is represented as an unsigned octet.  Salt Length
290    ///  represents the length of the Salt field in octets.  If the value is
291    ///  zero, the following Salt field is omitted.
292    ///
293    ///  Salt, if present, is encoded as a sequence of binary octets.  The
294    ///  length of this field is determined by the preceding Salt Length
295    ///  field.
296    ///
297    ///  Hash Length is represented as an unsigned octet.  Hash Length
298    ///  represents the length of the Next Hashed Owner Name field in octets.
299    ///
300    ///  The next hashed owner name is not base32 encoded, unlike the owner
301    ///  name of the NSEC3 RR.  It is the unmodified binary hash value.  It
302    ///  does not include the name of the containing zone.  The length of this
303    ///  field is determined by the preceding Hash Length field.
304    ///
305    /// 3.2.1.  Type Bit Maps Encoding
306    ///
307    ///  The encoding of the Type Bit Maps field is the same as that used by
308    ///  the NSEC RR, described in [RFC4034].  It is explained and clarified
309    ///  here for clarity.
310    ///
311    ///  The RR type space is split into 256 window blocks, each representing
312    ///  the low-order 8 bits of the 16-bit RR type space.  Each block that
313    ///  has at least one active RR type is encoded using a single octet
314    ///  window number (from 0 to 255), a single octet bitmap length (from 1
315    ///  to 32) indicating the number of octets used for the bitmap of the
316    ///  window block, and up to 32 octets (256 bits) of bitmap.
317    ///
318    ///  Blocks are present in the NSEC3 RR RDATA in increasing numerical
319    ///  order.
320    ///
321    ///     Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+
322    ///
323    ///     where "|" denotes concatenation.
324    ///
325    ///  Each bitmap encodes the low-order 8 bits of RR types within the
326    ///  window block, in network bit order.  The first bit is bit 0.  For
327    ///  window block 0, bit 1 corresponds to RR type 1 (A), bit 2 corresponds
328    ///  to RR type 2 (NS), and so forth.  For window block 1, bit 1
329    ///  corresponds to RR type 257, bit 2 to RR type 258.  If a bit is set to
330    ///  1, it indicates that an RRSet of that type is present for the
331    ///  original owner name of the NSEC3 RR.  If a bit is set to 0, it
332    ///  indicates that no RRSet of that type is present for the original
333    ///  owner name of the NSEC3 RR.
334    ///
335    ///  Since bit 0 in window block 0 refers to the non-existing RR type 0,
336    ///  it MUST be set to 0.  After verification, the validator MUST ignore
337    ///  the value of bit 0 in window block 0.
338    ///
339    ///  Bits representing Meta-TYPEs or QTYPEs as specified in Section 3.1 of
340    ///  [RFC2929] or within the range reserved for assignment only to QTYPEs
341    ///  and Meta-TYPEs MUST be set to 0, since they do not appear in zone
342    ///  data.  If encountered, they must be ignored upon reading.
343    ///
344    ///  Blocks with no types present MUST NOT be included.  Trailing zero
345    ///  octets in the bitmap MUST be omitted.  The length of the bitmap of
346    ///  each block is determined by the type code with the largest numerical
347    ///  value, within that block, among the set of RR types present at the
348    ///  original owner name of the NSEC3 RR.  Trailing octets not specified
349    ///  MUST be interpreted as zero octets.
350    /// ```
351    NSEC3(NSEC3),
352
353    /// ```text
354    /// RFC 5155                         NSEC3                        March 2008
355    ///
356    /// 4.2.  NSEC3PARAM RDATA Wire Format
357    ///
358    ///  The RDATA of the NSEC3PARAM RR is as shown below:
359    ///
360    ///                       1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
361    ///   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
362    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363    ///  |   Hash Alg.   |     Flags     |          Iterations           |
364    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365    ///  |  Salt Length  |                     Salt                      /
366    ///  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367    ///
368    ///  Hash Algorithm is a single octet.
369    ///
370    ///  Flags field is a single octet.
371    ///
372    ///  Iterations is represented as a 16-bit unsigned integer, with the most
373    ///  significant bit first.
374    ///
375    ///  Salt Length is represented as an unsigned octet.  Salt Length
376    ///  represents the length of the following Salt field in octets.  If the
377    ///  value is zero, the Salt field is omitted.
378    ///
379    ///  Salt, if present, is encoded as a sequence of binary octets.  The
380    ///  length of this field is determined by the preceding Salt Length
381    ///  field.
382    /// ```
383    NSEC3PARAM(NSEC3PARAM),
384
385    /// ```text
386    /// RFC 2535 & 2931   DNS Security Extensions               March 1999
387    /// RFC 4034          DNSSEC Resource Records               March 2005
388    ///
389    /// 3.1.  RRSIG RDATA Wire Format
390    ///
391    ///    The RDATA for an RRSIG RR consists of a 2 octet Type Covered field, a
392    ///    1 octet Algorithm field, a 1 octet Labels field, a 4 octet Original
393    ///    TTL field, a 4 octet Signature Expiration field, a 4 octet Signature
394    ///    Inception field, a 2 octet Key tag, the Signer's Name field, and the
395    ///    Signature field.
396    ///
397    ///                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
398    ///     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
399    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400    ///    |        Type Covered           |  Algorithm    |     Labels    |
401    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
402    ///    |                         Original TTL                          |
403    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
404    ///    |                      Signature Expiration                     |
405    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
406    ///    |                      Signature Inception                      |
407    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
408    ///    |            Key Tag            |                               /
409    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+         Signer's Name         /
410    ///    /                                                               /
411    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
412    ///    /                                                               /
413    ///    /                            Signature                          /
414    ///    /                                                               /
415    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
416    /// ```
417    RRSIG(RRSIG),
418
419    /// ```text
420    /// RFC 2535 & 2931   DNS Security Extensions               March 1999
421    /// RFC 4034          DNSSEC Resource Records               March 2005
422    ///
423    /// 3.1.  RRSIG RDATA Wire Format
424    ///
425    ///    The RDATA for an RRSIG RR consists of a 2 octet Type Covered field, a
426    ///    1 octet Algorithm field, a 1 octet Labels field, a 4 octet Original
427    ///    TTL field, a 4 octet Signature Expiration field, a 4 octet Signature
428    ///    Inception field, a 2 octet Key tag, the Signer's Name field, and the
429    ///    Signature field.
430    ///
431    ///                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
432    ///     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
433    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
434    ///    |        Type Covered           |  Algorithm    |     Labels    |
435    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
436    ///    |                         Original TTL                          |
437    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
438    ///    |                      Signature Expiration                     |
439    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
440    ///    |                      Signature Inception                      |
441    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
442    ///    |            Key Tag            |                               /
443    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+         Signer's Name         /
444    ///    /                                                               /
445    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
446    ///    /                                                               /
447    ///    /                            Signature                          /
448    ///    /                                                               /
449    ///    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
450    /// ```
451    SIG(SIG),
452
453    /// [RFC 8945, Secret Key Transaction Authentication for DNS](https://tools.ietf.org/html/rfc8945#section-4.2)
454    ///
455    /// ```text
456    /// 4.2.  TSIG Record Format
457    ///
458    ///   The fields of the TSIG RR are described below.  All multi-octet
459    ///   integers in the record are sent in network byte order (see
460    ///   Section 2.3.2 of [RFC1035]).
461    ///
462    ///   NAME:  The name of the key used, in domain name syntax.  The name
463    ///      should reflect the names of the hosts and uniquely identify the
464    ///      key among a set of keys these two hosts may share at any given
465    ///      time.  For example, if hosts A.site.example and B.example.net
466    ///      share a key, possibilities for the key name include
467    ///      <id>.A.site.example, <id>.B.example.net, and
468    ///      <id>.A.site.example.B.example.net.  It should be possible for more
469    ///      than one key to be in simultaneous use among a set of interacting
470    ///      hosts.  This allows for periodic key rotation as per best
471    ///      operational practices, as well as algorithm agility as indicated
472    ///      by [RFC7696].
473    ///
474    ///      The name may be used as a local index to the key involved, but it
475    ///      is recommended that it be globally unique.  Where a key is just
476    ///      shared between two hosts, its name actually need only be
477    ///      meaningful to them, but it is recommended that the key name be
478    ///      mnemonic and incorporate the names of participating agents or
479    ///      resources as suggested above.
480    ///
481    ///   TYPE:  This MUST be TSIG (250: Transaction SIGnature).
482    ///
483    ///   CLASS:  This MUST be ANY.
484    ///
485    ///   TTL:  This MUST be 0.
486    ///
487    ///   RDLENGTH:  (variable)
488    ///
489    ///   RDATA:  The RDATA for a TSIG RR consists of a number of fields,
490    ///      described below:
491    ///
492    ///                            1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
493    ///        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
494    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
495    ///       /                         Algorithm Name                        /
496    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
497    ///       |                                                               |
498    ///       |          Time Signed          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
499    ///       |                               |            Fudge              |
500    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
501    ///       |          MAC Size             |                               /
502    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+             MAC               /
503    ///       /                                                               /
504    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
505    ///       |          Original ID          |            Error              |
506    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
507    ///       |          Other Len            |                               /
508    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+           Other Data          /
509    ///       /                                                               /
510    ///       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
511    ///
512    ///   The contents of the RDATA fields are:
513    ///
514    ///   Algorithm Name:
515    ///      an octet sequence identifying the TSIG algorithm in the domain
516    ///      name syntax.  (Allowed names are listed in Table 3.)  The name is
517    ///      stored in the DNS name wire format as described in [RFC1034].  As
518    ///      per [RFC3597], this name MUST NOT be compressed.
519    ///
520    ///   Time Signed:
521    ///      an unsigned 48-bit integer containing the time the message was
522    ///      signed as seconds since 00:00 on 1970-01-01 UTC, ignoring leap
523    ///      seconds.
524    ///
525    ///   Fudge:
526    ///      an unsigned 16-bit integer specifying the allowed time difference
527    ///      in seconds permitted in the Time Signed field.
528    ///
529    ///   MAC Size:
530    ///      an unsigned 16-bit integer giving the length of the MAC field in
531    ///      octets.  Truncation is indicated by a MAC Size less than the size
532    ///      of the keyed hash produced by the algorithm specified by the
533    ///      Algorithm Name.
534    ///
535    ///   MAC:
536    ///      a sequence of octets whose contents are defined by the TSIG
537    ///      algorithm used, possibly truncated as specified by the MAC Size.
538    ///      The length of this field is given by the MAC Size.  Calculation of
539    ///      the MAC is detailed in Section 4.3.
540    ///
541    ///   Original ID:
542    ///      an unsigned 16-bit integer holding the message ID of the original
543    ///      request message.  For a TSIG RR on a request, it is set equal to
544    ///      the DNS message ID.  In a TSIG attached to a response -- or in
545    ///      cases such as the forwarding of a dynamic update request -- the
546    ///      field contains the ID of the original DNS request.
547    ///
548    ///   Error:
549    ///      in responses, an unsigned 16-bit integer containing the extended
550    ///      RCODE covering TSIG processing.  In requests, this MUST be zero.
551    ///
552    ///   Other Len:
553    ///      an unsigned 16-bit integer specifying the length of the Other Data
554    ///      field in octets.
555    ///
556    ///   Other Data:
557    ///      additional data relevant to the TSIG record.  In responses, this
558    ///      will be empty (i.e., Other Len will be zero) unless the content of
559    ///      the Error field is BADTIME, in which case it will be a 48-bit
560    ///      unsigned integer containing the server's current time as the
561    ///      number of seconds since 00:00 on 1970-01-01 UTC, ignoring leap
562    ///      seconds (see Section 5.2.3).  This document assigns no meaning to
563    ///      its contents in requests.
564    /// ```
565    TSIG(TSIG),
566
567    /// Unknown or unsupported DNSSEC record data
568    Unknown {
569        /// RecordType code
570        code: u16,
571        /// RData associated to the record
572        rdata: NULL,
573    },
574}
575
576impl DNSSECRData {
577    pub(crate) fn read(
578        decoder: &mut BinDecoder<'_>,
579        record_type: RecordType,
580        rdata_length: Restrict<u16>,
581    ) -> ProtoResult<Self> {
582        match record_type {
583            RecordType::CDNSKEY => {
584                trace!("reading CDNSKEY");
585                CDNSKEY::read_data(decoder, rdata_length).map(Self::CDNSKEY)
586            }
587            RecordType::CDS => {
588                trace!("reading CDS");
589                CDS::read_data(decoder, rdata_length).map(Self::CDS)
590            }
591            RecordType::DNSKEY => {
592                trace!("reading DNSKEY");
593                DNSKEY::read_data(decoder, rdata_length).map(Self::DNSKEY)
594            }
595            RecordType::DS => {
596                trace!("reading DS");
597                DS::read_data(decoder, rdata_length).map(Self::DS)
598            }
599            RecordType::KEY => {
600                trace!("reading KEY");
601                KEY::read_data(decoder, rdata_length).map(Self::KEY)
602            }
603            RecordType::NSEC => {
604                trace!("reading NSEC");
605                NSEC::read_data(decoder, rdata_length).map(Self::NSEC)
606            }
607            RecordType::NSEC3 => {
608                trace!("reading NSEC3");
609                NSEC3::read_data(decoder, rdata_length).map(Self::NSEC3)
610            }
611            RecordType::NSEC3PARAM => {
612                trace!("reading NSEC3PARAM");
613                NSEC3PARAM::read(decoder).map(Self::NSEC3PARAM)
614            }
615            RecordType::RRSIG => {
616                trace!("reading RRSIG");
617                RRSIG::read_data(decoder, rdata_length).map(Self::RRSIG)
618            }
619            RecordType::SIG => {
620                trace!("reading SIG");
621                SIG::read_data(decoder, rdata_length).map(Self::SIG)
622            }
623            RecordType::TSIG => {
624                trace!("reading TSIG");
625                TSIG::read_data(decoder, rdata_length).map(Self::TSIG)
626            }
627            r => {
628                panic!("not a dnssec RecordType: {}", r);
629            }
630        }
631    }
632
633    pub(crate) fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
634        match *self {
635            Self::CDNSKEY(ref cdnskey) => {
636                encoder.with_canonical_names(|encoder| cdnskey.emit(encoder))
637            }
638            Self::CDS(ref cds) => encoder.with_canonical_names(|encoder| cds.emit(encoder)),
639            Self::DS(ref ds) => encoder.with_canonical_names(|encoder| ds.emit(encoder)),
640            Self::KEY(ref key) => encoder.with_canonical_names(|encoder| key.emit(encoder)),
641            Self::DNSKEY(ref dnskey) => {
642                encoder.with_canonical_names(|encoder| dnskey.emit(encoder))
643            }
644            Self::NSEC(ref nsec) => encoder.with_canonical_names(|encoder| nsec.emit(encoder)),
645            Self::NSEC3(ref nsec3) => encoder.with_canonical_names(|encoder| nsec3.emit(encoder)),
646            Self::NSEC3PARAM(ref nsec3param) => {
647                encoder.with_canonical_names(|encoder| nsec3param.emit(encoder))
648            }
649            Self::RRSIG(ref rrsig) => encoder.with_canonical_names(|encoder| rrsig.emit(encoder)),
650            Self::SIG(ref sig) => encoder.with_canonical_names(|encoder| sig.emit(encoder)),
651            Self::TSIG(ref tsig) => tsig.emit(encoder),
652            Self::Unknown { ref rdata, .. } => {
653                encoder.with_canonical_names(|encoder| rdata.emit(encoder))
654            }
655        }
656    }
657
658    pub(crate) fn to_record_type(&self) -> RecordType {
659        match *self {
660            Self::CDNSKEY(..) => RecordType::CDNSKEY,
661            Self::CDS(..) => RecordType::CDS,
662            Self::DS(..) => RecordType::DS,
663            Self::KEY(..) => RecordType::KEY,
664            Self::DNSKEY(..) => RecordType::DNSKEY,
665            Self::NSEC(..) => RecordType::NSEC,
666            Self::NSEC3(..) => RecordType::NSEC3,
667            Self::NSEC3PARAM(..) => RecordType::NSEC3PARAM,
668            Self::SIG(..) => RecordType::SIG,
669            Self::RRSIG(..) => RecordType::RRSIG,
670            Self::TSIG(..) => RecordType::TSIG,
671            Self::Unknown { code, .. } => RecordType::Unknown(code),
672        }
673    }
674}
675
676impl fmt::Display for DNSSECRData {
677    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
678        fn w<D: fmt::Display>(f: &mut fmt::Formatter<'_>, rdata: D) -> Result<(), fmt::Error> {
679            write!(f, "{rdata}")
680        }
681
682        match self {
683            Self::CDNSKEY(key) => w(f, key),
684            Self::CDS(ds) => w(f, ds),
685            Self::DS(ds) => w(f, ds),
686            Self::KEY(key) => w(f, key),
687            Self::DNSKEY(key) => w(f, key),
688            Self::NSEC(nsec) => w(f, nsec),
689            Self::NSEC3(nsec3) => w(f, nsec3),
690            Self::NSEC3PARAM(nsec3param) => w(f, nsec3param),
691            Self::SIG(sig) => w(f, sig),
692            Self::RRSIG(rrsig) => w(f, rrsig),
693            Self::TSIG(ref tsig) => w(f, tsig),
694            Self::Unknown { rdata, .. } => w(f, rdata),
695        }
696    }
697}
698
699impl From<DNSSECRData> for RData {
700    fn from(rdata: DNSSECRData) -> Self {
701        Self::DNSSEC(rdata)
702    }
703}