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}