trust_dns_proto/rr/dnssec/rdata/key.rs
1// Copyright 2015-2023 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! public key record data for signing zone records
9#![allow(clippy::use_self)]
10
11use std::fmt;
12
13#[cfg(feature = "serde-config")]
14use serde::{Deserialize, Serialize};
15
16use crate::{
17 error::{ProtoError, ProtoResult},
18 rr::{dnssec::Algorithm, record_data::RData, RecordData, RecordDataDecodable, RecordType},
19 serialize::binary::*,
20};
21
22use super::DNSSECRData;
23
24/// [RFC 2535](https://tools.ietf.org/html/rfc2535#section-3), Domain Name System Security Extensions, March 1999
25///
26/// ```text
27/// 3. The KEY Resource Record
28///
29/// The KEY resource record (RR) is used to store a public key that is
30/// associated with a Domain Name System (DNS) name. This can be the
31/// public key of a zone, a user, or a host or other end entity. Security
32/// aware DNS implementations MUST be designed to handle at least two
33/// simultaneously valid keys of the same type associated with the same
34/// name.
35///
36/// The type number for the KEY RR is 25.
37///
38/// A KEY RR is, like any other RR, authenticated by a SIG RR. KEY RRs
39/// must be signed by a zone level key.
40///
41/// 3.1 KEY RDATA format
42///
43/// The RDATA for a KEY RR consists of flags, a protocol octet, the
44/// algorithm number octet, and the public key itself. The format is as
45/// follows:
46///
47/// 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
48/// 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
49/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50/// | flags | protocol | algorithm |
51/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52/// | /
53/// / public key /
54/// / /
55/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
56///
57/// The KEY RR is not intended for storage of certificates and a separate
58/// certificate RR has been developed for that purpose, defined in [RFC
59/// 2538].
60///
61/// The meaning of the KEY RR owner name, flags, and protocol octet are
62/// described in Sections 3.1.1 through 3.1.5 below. The flags and
63/// algorithm must be examined before any data following the algorithm
64/// octet as they control the existence and format of any following data.
65/// The algorithm and public key fields are described in Section 3.2.
66/// The format of the public key is algorithm dependent.
67///
68/// KEY RRs do not specify their validity period but their authenticating
69/// SIG RR(s) do as described in Section 4 below.
70///
71/// 3.1.1 Object Types, DNS Names, and Keys
72///
73/// The public key in a KEY RR is for the object named in the owner name.
74///
75/// A DNS name may refer to three different categories of things. For
76/// example, foo.host.example could be (1) a zone, (2) a host or other
77/// end entity , or (3) the mapping into a DNS name of the user or
78/// account foo@host.example. Thus, there are flag bits, as described
79/// below, in the KEY RR to indicate with which of these roles the owner
80/// name and public key are associated. Note that an appropriate zone
81/// KEY RR MUST occur at the apex node of a secure zone and zone KEY RRs
82/// occur only at delegation points.
83///
84/// 3.1.2 The KEY RR Flag Field
85///
86/// In the "flags" field:
87///
88/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
89/// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
90/// | A/C | Z | XT| Z | Z | NAMTYP| Z | Z | Z | Z | SIG |
91/// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
92///
93/// Bit 0 and 1 are the key "type" bits whose values have the following
94/// meanings:
95///
96/// 10: Use of the key is prohibited for authentication.
97/// 01: Use of the key is prohibited for confidentiality.
98/// 00: Use of the key for authentication and/or confidentiality
99/// is permitted. Note that DNS security makes use of keys
100/// for authentication only. Confidentiality use flagging is
101/// provided for use of keys in other protocols.
102/// Implementations not intended to support key distribution
103/// for confidentiality MAY require that the confidentiality
104/// use prohibited bit be on for keys they serve.
105/// 11: If both bits are one, the "no key" value, there is no key
106/// information and the RR stops after the algorithm octet.
107/// By the use of this "no key" value, a signed KEY RR can
108/// authentically assert that, for example, a zone is not
109/// secured. See section 3.4 below.
110///
111/// Bits 2 is reserved and must be zero.
112///
113/// Bits 3 is reserved as a flag extension bit. If it is a one, a second
114/// 16 bit flag field is added after the algorithm octet and
115/// before the key data. This bit MUST NOT be set unless one or
116/// more such additional bits have been defined and are non-zero.
117///
118/// Bits 4-5 are reserved and must be zero.
119///
120/// Bits 6 and 7 form a field that encodes the name type. Field values
121/// have the following meanings:
122///
123/// 00: indicates that this is a key associated with a "user" or
124/// "account" at an end entity, usually a host. The coding
125/// of the owner name is that used for the responsible
126/// individual mailbox in the SOA and RP RRs: The owner name
127/// is the user name as the name of a node under the entity
128/// name. For example, "j_random_user" on
129/// host.subdomain.example could have a public key associated
130/// through a KEY RR with name
131/// j_random_user.host.subdomain.example. It could be used
132/// in a security protocol where authentication of a user was
133/// desired. This key might be useful in IP or other
134/// security for a user level service such a telnet, ftp,
135/// rlogin, etc.
136/// 01: indicates that this is a zone key for the zone whose name
137/// is the KEY RR owner name. This is the public key used
138/// for the primary DNS security feature of data origin
139/// authentication. Zone KEY RRs occur only at delegation
140/// points.
141/// 10: indicates that this is a key associated with the non-zone
142/// "entity" whose name is the RR owner name. This will
143/// commonly be a host but could, in some parts of the DNS
144/// tree, be some other type of entity such as a telephone
145/// number [RFC 1530] or numeric IP address. This is the
146/// public key used in connection with DNS request and
147/// transaction authentication services. It could also be
148/// used in an IP-security protocol where authentication at
149/// the host, rather than user, level was desired, such as
150/// routing, NTP, etc.
151/// 11: reserved.
152///
153/// Bits 8-11 are reserved and must be zero.
154///
155/// Bits 12-15 are the "signatory" field. If non-zero, they indicate
156/// that the key can validly sign things as specified in DNS
157/// dynamic update [RFC 2137]. Note that zone keys (see bits
158/// 6 and 7 above) always have authority to sign any RRs in
159/// the zone regardless of the value of the signatory field.
160/// ```
161#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
162#[derive(Debug, PartialEq, Eq, Hash, Clone)]
163pub struct KEY {
164 key_trust: KeyTrust,
165 key_usage: KeyUsage,
166 signatory: UpdateScope,
167 protocol: Protocol,
168 algorithm: Algorithm,
169 public_key: Vec<u8>,
170}
171
172/// Specifies in what contexts this key may be trusted for use
173#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
174#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
175pub enum KeyTrust {
176 /// Use of the key is prohibited for authentication
177 NotAuth,
178 /// Use of the key is prohibited for confidentiality
179 NotPrivate,
180 /// Use of the key for authentication and/or confidentiality is permitted
181 AuthOrPrivate,
182 /// If both bits are one, the "no key" value, (revocation?)
183 DoNotTrust,
184}
185
186impl Default for KeyTrust {
187 fn default() -> Self {
188 Self::AuthOrPrivate
189 }
190}
191
192impl From<u16> for KeyTrust {
193 fn from(flags: u16) -> Self {
194 // we only care about the first two bits, zero out the rest
195 match flags & 0b1100_0000_0000_0000 {
196 // 10: Use of the key is prohibited for authentication.
197 0b1000_0000_0000_0000 => Self::NotAuth,
198 // 01: Use of the key is prohibited for confidentiality.
199 0b0100_0000_0000_0000 => Self::NotPrivate,
200 // 00: Use of the key for authentication and/or confidentiality
201 0b0000_0000_0000_0000 => Self::AuthOrPrivate,
202 // 11: If both bits are one, the "no key" value, there is no key
203 0b1100_0000_0000_0000 => Self::DoNotTrust,
204 _ => panic!("All other bit fields should have been cleared"),
205 }
206 }
207}
208
209impl From<KeyTrust> for u16 {
210 fn from(key_trust: KeyTrust) -> Self {
211 match key_trust {
212 // 10: Use of the key is prohibited for authentication.
213 KeyTrust::NotAuth => 0b1000_0000_0000_0000,
214 // 01: Use of the key is prohibited for confidentiality.
215 KeyTrust::NotPrivate => 0b0100_0000_0000_0000,
216 // 00: Use of the key for authentication and/or confidentiality
217 KeyTrust::AuthOrPrivate => 0b0000_0000_0000_0000,
218 // 11: If both bits are one, the "no key" value, there is no key
219 KeyTrust::DoNotTrust => 0b1100_0000_0000_0000,
220 }
221 }
222}
223
224#[test]
225fn test_key_trust() {
226 assert_eq!(
227 KeyTrust::NotAuth,
228 KeyTrust::from(u16::from(KeyTrust::NotAuth))
229 );
230 assert_eq!(
231 KeyTrust::NotPrivate,
232 KeyTrust::from(u16::from(KeyTrust::NotPrivate))
233 );
234 assert_eq!(
235 KeyTrust::AuthOrPrivate,
236 KeyTrust::from(u16::from(KeyTrust::AuthOrPrivate))
237 );
238 assert_eq!(
239 KeyTrust::DoNotTrust,
240 KeyTrust::from(u16::from(KeyTrust::DoNotTrust))
241 );
242}
243
244/// Declares what this key is for
245#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
246#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
247pub enum KeyUsage {
248 /// key associated with a "user" or "account" at an end entity, usually a host
249 Host,
250 /// zone key for the zone whose name is the KEY RR owner name
251 #[deprecated = "For Zone signing DNSKEY should be used"]
252 Zone,
253 /// associated with the non-zone "entity" whose name is the RR owner name
254 Entity,
255 /// Reserved
256 Reserved,
257}
258
259impl Default for KeyUsage {
260 fn default() -> Self {
261 Self::Entity
262 }
263}
264
265impl From<u16> for KeyUsage {
266 fn from(flags: u16) -> Self {
267 // we only care about the 6&7 two bits, zero out the rest
268 match flags & 0b0000_0011_0000_0000 {
269 // 00: indicates that this is a key associated with a "user" or
270 0b0000_0000_0000_0000 => Self::Host,
271 // 01: indicates that this is a zone key for the zone whose name
272 0b0000_0001_0000_0000 => Self::Zone,
273 // 10: indicates that this is a key associated with the non-zone
274 0b0000_0010_0000_0000 => Self::Entity,
275 // 11: reserved.
276 0b0000_0011_0000_0000 => Self::Reserved,
277 _ => panic!("All other bit fields should have been cleared"),
278 }
279 }
280}
281
282impl From<KeyUsage> for u16 {
283 fn from(key_usage: KeyUsage) -> Self {
284 match key_usage {
285 // 00: indicates that this is a key associated with a "user" or
286 KeyUsage::Host => 0b0000_0000_0000_0000,
287 // 01: indicates that this is a zone key for the zone whose name
288 KeyUsage::Zone => 0b0000_0001_0000_0000,
289 // 10: indicates that this is a key associated with the non-zone
290 KeyUsage::Entity => 0b0000_0010_0000_0000,
291 // 11: reserved.
292 KeyUsage::Reserved => 0b0000_0011_0000_0000,
293 }
294 }
295}
296
297#[test]
298
299fn test_key_usage() {
300 assert_eq!(KeyUsage::Host, KeyUsage::from(u16::from(KeyUsage::Host)));
301 assert_eq!(KeyUsage::Zone, KeyUsage::from(u16::from(KeyUsage::Zone)));
302 assert_eq!(
303 KeyUsage::Entity,
304 KeyUsage::from(u16::from(KeyUsage::Entity))
305 );
306 assert_eq!(
307 KeyUsage::Reserved,
308 KeyUsage::from(u16::from(KeyUsage::Reserved))
309 );
310}
311
312/// [RFC 2137](https://tools.ietf.org/html/rfc2137#section-3.1), Secure Domain Name System Dynamic Update, April 1997
313///
314/// ```text
315/// 3.1.1 Update Key Name Scope
316///
317/// The owner name of any update authorizing KEY RR must (1) be the same
318/// as the owner name of any RRs being added or deleted or (2) a wildcard
319/// name including within its extended scope (see section 3.3) the name
320/// of any RRs being added or deleted and those RRs must be in the same
321/// zone.
322///
323/// 3.1.2 Update Key Class Scope
324///
325/// The class of any update authorizing KEY RR must be the same as the
326/// class of any RR's being added or deleted.
327///
328/// 3.1.3 Update Key Signatory Field
329///
330/// The four bit "signatory field" (see RFC 2065) of any update
331/// authorizing KEY RR must be non-zero. The bits have the meanings
332/// described below for non-zone keys (see section 3.2 for zone type
333/// keys).
334///
335/// UPDATE KEY RR SIGNATORY FIELD BITS
336///
337/// 0 1 2 3
338/// +-----------+-----------+-----------+-----------+
339/// | zone | strong | unique | general |
340/// +-----------+-----------+-----------+-----------+
341///
342/// Bit 0, zone control - If nonzero, this key is authorized to attach,
343/// detach, and move zones by creating and deleting NS, glue A, and
344/// zone KEY RR(s). If zero, the key can not authorize any update
345/// that would effect such RRs. This bit is meaningful for both
346/// type A and type B dynamic secure zones.
347///
348/// NOTE: do not confuse the "zone" signatory field bit with the
349/// "zone" key type bit.
350///
351/// Bit 1, strong update - If nonzero, this key is authorized to add and
352/// delete RRs even if there are other RRs with the same owner name
353/// and class that are authenticated by a SIG signed with a
354/// different dynamic update KEY. If zero, the key can only
355/// authorize updates where any existing RRs of the same owner and
356/// class are authenticated by a SIG using the same key. This bit
357/// is meaningful only for type A dynamic zones and is ignored in
358/// type B dynamic zones.
359///
360/// Keeping this bit zero on multiple KEY RRs with the same or
361/// nested wild card owner names permits multiple entities to exist
362/// that can create and delete names but can not effect RRs with
363/// different owner names from any they created. In effect, this
364/// creates two levels of dynamic update key, strong and weak, where
365/// weak keys are limited in interfering with each other but a
366/// strong key can interfere with any weak keys or other strong
367/// keys.
368///
369/// Bit 2, unique name update - If nonzero, this key is authorized to add
370/// and update RRs for only a single owner name. If there already
371/// exist RRs with one or more names signed by this key, they may be
372/// updated but no new name created until the number of existing
373/// names is reduced to zero. This bit is meaningful only for mode
374/// A dynamic zones and is ignored in mode B dynamic zones. This bit
375/// is meaningful only if the owner name is a wildcard. (Any
376/// dynamic update KEY with a non-wildcard name is, in effect, a
377/// unique name update key.)
378///
379/// This bit can be used to restrict a KEY from flooding a zone with
380/// new names. In conjunction with a local administratively imposed
381/// limit on the number of dynamic RRs with a particular name, it
382/// can completely restrict a KEY from flooding a zone with RRs.
383///
384/// Bit 3, general update - The general update signatory field bit has no
385/// special meaning. If the other three bits are all zero, it must
386/// be one so that the field is non-zero to designate that the key
387/// is an update key. The meaning of all values of the signatory
388/// field with the general bit and one or more other signatory field
389/// bits on is reserved.
390///
391/// All the signatory bit update authorizations described above only
392/// apply if the update is within the name and class scope as per
393/// sections 3.1.1 and 3.1.2.
394/// ```
395///
396/// [RFC 3007](https://tools.ietf.org/html/rfc3007#section-1.5), Secure Dynamic Update, November 2000
397///
398/// ```text
399/// [RFC2535, section 3.1.2] defines the signatory field of a key as the
400/// final 4 bits of the flags field, but does not define its value. This
401/// proposal leaves this field undefined. Updating [RFC2535], this field
402/// SHOULD be set to 0 in KEY records, and MUST be ignored.
403///
404/// ```
405#[deprecated = "Deprecated by RFC3007"]
406#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
407#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
408pub struct UpdateScope {
409 /// this key is authorized to attach,
410 /// detach, and move zones by creating and deleting NS, glue A, and
411 /// zone KEY RR(s)
412 pub zone: bool,
413 /// this key is authorized to add and
414 /// delete RRs even if there are other RRs with the same owner name
415 /// and class that are authenticated by a SIG signed with a
416 /// different dynamic update KEY
417 pub strong: bool,
418 /// this key is authorized to add and update RRs for only a single owner name
419 pub unique: bool,
420 /// The general update signatory field bit has no special meaning, (true if the others are false)
421 pub general: bool,
422}
423
424impl From<u16> for UpdateScope {
425 fn from(flags: u16) -> Self {
426 // we only care about the final four bits, zero out the rest
427 Self {
428 // Bit 0, zone control - If nonzero, this key is authorized to attach,
429 zone: flags & 0b0000_0000_0000_1000 != 0,
430 // Bit 1, strong update - If nonzero, this key is authorized to add and
431 strong: flags & 0b0000_0000_0000_0100 != 0,
432 // Bit 2, unique name update - If nonzero, this key is authorized to add
433 unique: flags & 0b0000_0000_0000_0010 != 0,
434 // Bit 3, general update - The general update signatory field bit has no
435 general: flags & 0b0000_0000_0000_0001 != 0,
436 }
437 }
438}
439
440impl From<UpdateScope> for u16 {
441 fn from(update_scope: UpdateScope) -> Self {
442 let mut flags = 0_u16;
443
444 if update_scope.zone {
445 flags |= 0b0000_0000_0000_1000;
446 }
447
448 if update_scope.strong {
449 flags |= 0b0000_0000_0000_0100;
450 }
451
452 if update_scope.unique {
453 flags |= 0b0000_0000_0000_0010;
454 }
455
456 if update_scope.general {
457 flags |= 0b0000_0000_0000_0001;
458 }
459
460 flags
461 }
462}
463
464#[test]
465fn test_update_scope() {
466 assert_eq!(
467 UpdateScope::default(),
468 UpdateScope::from(u16::from(UpdateScope::default()))
469 );
470
471 let update_scope = UpdateScope {
472 zone: true,
473 strong: true,
474 unique: true,
475 general: true,
476 };
477 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
478
479 let update_scope = UpdateScope {
480 zone: true,
481 strong: false,
482 unique: true,
483 general: false,
484 };
485 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
486
487 let update_scope = UpdateScope {
488 zone: false,
489 strong: true,
490 unique: false,
491 general: true,
492 };
493 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
494
495 let update_scope = UpdateScope {
496 zone: false,
497 strong: true,
498 unique: true,
499 general: false,
500 };
501 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
502
503 let update_scope = UpdateScope {
504 zone: true,
505 strong: false,
506 unique: false,
507 general: true,
508 };
509 assert_eq!(update_scope, UpdateScope::from(u16::from(update_scope)));
510}
511
512/// [RFC 2535](https://tools.ietf.org/html/rfc2535#section-3.1.3), Domain Name System Security Extensions, March 1999
513///
514/// ```text
515/// 3.1.3 The Protocol Octet
516///
517/// It is anticipated that keys stored in DNS will be used in conjunction
518/// with a variety of Internet protocols. It is intended that the
519/// protocol octet and possibly some of the currently unused (must be
520/// zero) bits in the KEY RR flags as specified in the future will be
521/// used to indicate a key's validity for different protocols.
522///
523/// The following values of the Protocol Octet are reserved as indicated:
524///
525/// VALUE Protocol
526///
527/// 0 -reserved
528/// 1 TLS
529/// 2 email
530/// 3 dnssec
531/// 4 IPSEC
532/// 5-254 - available for assignment by IANA
533/// 255 All
534///
535/// In more detail:
536/// 1 is reserved for use in connection with TLS.
537/// 2 is reserved for use in connection with email.
538/// 3 is used for DNS security. The protocol field SHOULD be set to
539/// this value for zone keys and other keys used in DNS security.
540/// Implementations that can determine that a key is a DNS
541/// security key by the fact that flags label it a zone key or the
542/// signatory flag field is non-zero are NOT REQUIRED to check the
543/// protocol field.
544/// 4 is reserved to refer to the Oakley/IPSEC [RFC 2401] protocol
545/// and indicates that this key is valid for use in conjunction
546/// with that security standard. This key could be used in
547/// connection with secured communication on behalf of an end
548/// entity or user whose name is the owner name of the KEY RR if
549/// the entity or user flag bits are set. The presence of a KEY
550/// resource with this protocol value is an assertion that the
551/// host speaks Oakley/IPSEC.
552/// 255 indicates that the key can be used in connection with any
553/// protocol for which KEY RR protocol octet values have been
554/// defined. The use of this value is discouraged and the use of
555/// different keys for different protocols is encouraged.
556/// ```
557///
558/// [RFC3445](https://tools.ietf.org/html/rfc3445#section-4), Limiting the KEY Resource Record (RR), December 2002
559///
560/// ```text
561/// All Protocol Octet values except DNSSEC (3) are eliminated
562/// ```
563#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
564#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
565pub enum Protocol {
566 /// Not in use
567 #[deprecated = "Deprecated by RFC3445"]
568 Reserved,
569 /// Reserved for use with TLS
570 #[deprecated = "Deprecated by RFC3445"]
571 TLS,
572 /// Reserved for use with email
573 #[deprecated = "Deprecated by RFC3445"]
574 Email,
575 /// Reserved for use with DNSSEC (Trust-DNS only supports DNSKEY with DNSSEC)
576 DNSSEC,
577 /// Reserved to refer to the Oakley/IPSEC
578 #[deprecated = "Deprecated by RFC3445"]
579 IPSec,
580 /// Undefined
581 #[deprecated = "Deprecated by RFC3445"]
582 Other(u8),
583 /// the key can be used in connection with any protocol
584 #[deprecated = "Deprecated by RFC3445"]
585 All,
586}
587
588impl Default for Protocol {
589 fn default() -> Self {
590 Self::DNSSEC
591 }
592}
593
594impl From<u8> for Protocol {
595 fn from(field: u8) -> Self {
596 match field {
597 0 => Self::Reserved,
598 1 => Self::TLS,
599 2 => Self::Email,
600 3 => Self::DNSSEC,
601 4 => Self::IPSec,
602 255 => Self::All,
603 _ => Self::Other(field),
604 }
605 }
606}
607
608impl From<Protocol> for u8 {
609 fn from(protocol: Protocol) -> Self {
610 match protocol {
611 Protocol::Reserved => 0,
612 Protocol::TLS => 1,
613 Protocol::Email => 2,
614 Protocol::DNSSEC => 3,
615 Protocol::IPSec => 4,
616 Protocol::All => 255,
617 Protocol::Other(field) => field,
618 }
619 }
620}
621
622impl KEY {
623 /// Construct a new KEY RData
624 ///
625 /// # Arguments
626 ///
627 /// * `key_trust` - declare the security level of this key
628 /// * `key_usage` - what type of thing is this key associated to
629 /// * `revoke` - this key has been revoked
630 /// * `algorithm` - specifies the algorithm which this Key uses to sign records
631 /// * `public_key` - the public key material, in native endian, the emitter will perform any necessary conversion
632 ///
633 /// # Return
634 ///
635 /// A new KEY RData for use in a Resource Record
636 pub fn new(
637 key_trust: KeyTrust,
638 key_usage: KeyUsage,
639 signatory: UpdateScope,
640 protocol: Protocol,
641 algorithm: Algorithm,
642 public_key: Vec<u8>,
643 ) -> Self {
644 Self {
645 key_trust,
646 key_usage,
647 signatory,
648 protocol,
649 algorithm,
650 public_key,
651 }
652 }
653
654 /// Returns the trust level of the key
655 pub fn key_trust(&self) -> KeyTrust {
656 self.key_trust
657 }
658
659 /// Returns the entity type using this key
660 pub fn key_usage(&self) -> KeyUsage {
661 self.key_usage
662 }
663
664 /// Returns the signatory information of the KEY
665 pub fn signatory(&self) -> UpdateScope {
666 self.signatory
667 }
668
669 /// Returns true if the key_trust is DoNotTrust
670 pub fn revoke(&self) -> bool {
671 self.key_trust == KeyTrust::DoNotTrust
672 }
673
674 /// Returns the protocol which this key can be used with
675 pub fn protocol(&self) -> Protocol {
676 self.protocol
677 }
678
679 /// [RFC 4034, DNSSEC Resource Records, March 2005](https://tools.ietf.org/html/rfc4034#section-2.1.3)
680 ///
681 /// ```text
682 /// 2.1.3. The Algorithm Field
683 ///
684 /// The Algorithm field identifies the public key's cryptographic
685 /// algorithm and determines the format of the Public Key field. A list
686 /// of DNSSEC algorithm types can be found in Appendix A.1
687 /// ```
688 pub fn algorithm(&self) -> Algorithm {
689 self.algorithm
690 }
691
692 /// [RFC 4034, DNSSEC Resource Records, March 2005](https://tools.ietf.org/html/rfc4034#section-2.1.4)
693 ///
694 /// ```text
695 /// 2.1.4. The Public Key Field
696 ///
697 /// The Public Key Field holds the public key material. The format
698 /// depends on the algorithm of the key being stored and is described in
699 /// separate documents.
700 /// ```
701 pub fn public_key(&self) -> &[u8] {
702 &self.public_key
703 }
704
705 /// Output the encoded form of the flags
706 pub fn flags(&self) -> u16 {
707 let mut flags: u16 = 0;
708 flags |= u16::from(self.key_trust);
709 flags |= u16::from(self.key_usage);
710 flags |= u16::from(self.signatory);
711
712 flags
713 }
714
715 // /// Creates a message digest for this KEY record.
716 // ///
717 // /// ```text
718 // /// 5.1.4. The Digest Field
719 // ///
720 // /// The DS record refers to a KEY RR by including a digest of that
721 // /// KEY RR.
722 // ///
723 // /// The digest is calculated by concatenating the canonical form of the
724 // /// fully qualified owner name of the KEY RR with the KEY RDATA,
725 // /// and then applying the digest algorithm.
726 // ///
727 // /// digest = digest_algorithm( KEY owner name | KEY RDATA);
728 // ///
729 // /// "|" denotes concatenation
730 // ///
731 // /// KEY RDATA = Flags | Protocol | Algorithm | Public Key.
732 // ///
733 // /// The size of the digest may vary depending on the digest algorithm and
734 // /// KEY RR size. As of the time of this writing, the only defined
735 // /// digest algorithm is SHA-1, which produces a 20 octet digest.
736 // /// ```
737 // ///
738 // /// # Arguments
739 // ///
740 // /// * `name` - the label of of the KEY record.
741 // /// * `digest_type` - the `DigestType` with which to create the message digest.
742 // pub fn to_digest(&self, name: &Name, digest_type: DigestType) -> ProtoResult<Vec<u8>> {
743 // let mut buf: Vec<u8> = Vec::new();
744 // {
745 // let mut encoder: BinEncoder = BinEncoder::new(&mut buf);
746 // encoder.set_canonical_names(true);
747 // if let Err(e) = name.emit(&mut encoder)
748 // .and_then(|_| emit(&mut encoder, self)) {
749 // warn!("error serializing KEY: {}", e);
750 // return Err(format!("error serializing KEY: {}", e).into());
751 // }
752 // }
753
754 // digest_type.hash(&buf).map_err(|e| e.into())
755 // }
756}
757
758impl From<KEY> for RData {
759 fn from(key: KEY) -> Self {
760 Self::DNSSEC(super::DNSSECRData::KEY(key))
761 }
762}
763
764impl BinEncodable for KEY {
765 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
766 encoder.emit_u16(self.flags())?;
767 encoder.emit(u8::from(self.protocol))?;
768 self.algorithm().emit(encoder)?;
769 encoder.emit_vec(self.public_key())?;
770
771 Ok(())
772 }
773}
774
775impl<'r> RecordDataDecodable<'r> for KEY {
776 fn read_data(decoder: &mut BinDecoder<'r>, length: Restrict<u16>) -> ProtoResult<KEY> {
777 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
778 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
779 // | A/C | Z | XT| Z | Z | NAMTYP| Z | Z | Z | Z | SIG |
780 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
781 let flags: u16 = decoder
782 .read_u16()?
783 .verify_unwrap(|flags| {
784 // Bits 2 is reserved and must be zero.
785 // Bits 4-5 are reserved and must be zero.
786 // Bits 8-11 are reserved and must be zero.
787 flags & 0b0010_1100_1111_0000 == 0
788 })
789 .map_err(|_| ProtoError::from("flag 2, 4-5, and 8-11 are reserved, must be zero"))?;
790
791 let key_trust = KeyTrust::from(flags);
792 let extended_flags: bool = flags & 0b0001_0000_0000_0000 != 0;
793 let key_usage = KeyUsage::from(flags);
794 let signatory = UpdateScope::from(flags);
795
796 if extended_flags {
797 // TODO: add an optional field to return the raw u16?
798 return Err("extended flags currently not supported".into());
799 }
800
801 // TODO: protocol my be infallible
802 let protocol =
803 Protocol::from(decoder.read_u8()?.unverified(/*Protocol is verified as safe*/));
804
805 let algorithm: Algorithm = Algorithm::read(decoder)?;
806
807 // the public key is the left-over bytes minus 4 for the first fields
808 // TODO: decode the key here?
809 let key_len = length
810 .map(|u| u as usize)
811 .checked_sub(4)
812 .map_err(|_| ProtoError::from("invalid rdata length in KEY"))?
813 .unverified(/*used only as length safely*/);
814 let public_key: Vec<u8> =
815 decoder.read_vec(key_len)?.unverified(/*the byte array will fail in usage if invalid*/);
816
817 Ok(Self::new(
818 key_trust, key_usage, signatory, protocol, algorithm, public_key,
819 ))
820 }
821}
822
823impl RecordData for KEY {
824 fn try_from_rdata(data: RData) -> Result<Self, RData> {
825 match data {
826 RData::DNSSEC(DNSSECRData::KEY(csync)) => Ok(csync),
827 _ => Err(data),
828 }
829 }
830
831 fn try_borrow(data: &RData) -> Option<&Self> {
832 match data {
833 RData::DNSSEC(DNSSECRData::KEY(csync)) => Some(csync),
834 _ => None,
835 }
836 }
837
838 fn record_type(&self) -> RecordType {
839 RecordType::KEY
840 }
841
842 fn into_rdata(self) -> RData {
843 RData::DNSSEC(DNSSECRData::KEY(self))
844 }
845}
846
847/// Note that KEY is a deprecated type in DNS
848///
849/// [RFC 2535](https://tools.ietf.org/html/rfc2535#section-7.1), Domain Name System Security Extensions, March 1999
850///
851/// ```text
852/// 7.1 Presentation of KEY RRs
853///
854/// KEY RRs may appear as single logical lines in a zone data master file
855/// [RFC 1033].
856///
857/// The flag field is represented as an unsigned integer or a sequence of
858/// mnemonics as follows separated by instances of the vertical bar ("|")
859/// character:
860///
861/// BIT Mnemonic Explanation
862/// 0-1 key type
863/// NOCONF =1 confidentiality use prohibited
864/// NOAUTH =2 authentication use prohibited
865/// NOKEY =3 no key present
866/// 2 FLAG2 - reserved
867/// 3 EXTEND flags extension
868/// 4 FLAG4 - reserved
869/// 5 FLAG5 - reserved
870/// 6-7 name type
871/// USER =0 (default, may be omitted)
872/// ZONE =1
873/// HOST =2 (host or other end entity)
874/// NTYP3 - reserved
875/// 8 FLAG8 - reserved
876/// 9 FLAG9 - reserved
877/// 10 FLAG10 - reserved
878/// 11 FLAG11 - reserved
879/// 12-15 signatory field, values 0 to 15
880/// can be represented by SIG0, SIG1, ... SIG15
881///
882/// No flag mnemonic need be present if the bit or field it represents is
883/// zero.
884///
885/// The protocol octet can be represented as either an unsigned integer
886/// or symbolically. The following initial symbols are defined:
887///
888/// 000 NONE
889/// 001 TLS
890/// 002 EMAIL
891/// 003 DNSSEC
892/// 004 IPSEC
893/// 255 ALL
894///
895/// Note that if the type flags field has the NOKEY value, nothing
896/// appears after the algorithm octet.
897///
898/// The remaining public key portion is represented in base 64 (see
899/// Appendix A) and may be divided up into any number of white space
900/// separated substrings, down to single base 64 digits, which are
901/// concatenated to obtain the full signature. These substrings can span
902/// lines using the standard parenthesis.
903///
904/// Note that the public key may have internal sub-fields but these do
905/// not appear in the master file representation. For example, with
906/// algorithm 1 there is a public exponent size, then a public exponent,
907/// and then a modulus. With algorithm 254, there will be an OID size,
908/// an OID, and algorithm dependent information. But in both cases only a
909/// single logical base 64 string will appear in the master file.
910/// ```
911impl fmt::Display for KEY {
912 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
913 write!(
914 f,
915 "{flags} {proto} {alg} {key}",
916 flags = self.flags(),
917 proto = u8::from(self.protocol),
918 alg = self.algorithm,
919 key = data_encoding::BASE64.encode(&self.public_key)
920 )
921 }
922}
923
924#[cfg(test)]
925mod tests {
926 #![allow(clippy::dbg_macro, clippy::print_stdout)]
927
928 use super::*;
929
930 #[test]
931 fn test() {
932 let rdata = KEY::new(
933 KeyTrust::default(),
934 KeyUsage::default(),
935 UpdateScope::default(),
936 Protocol::default(),
937 Algorithm::RSASHA256,
938 vec![0, 1, 2, 3, 4, 5, 6, 7],
939 );
940
941 let mut bytes = Vec::new();
942 let mut encoder: BinEncoder<'_> = BinEncoder::new(&mut bytes);
943 assert!(rdata.emit(&mut encoder).is_ok());
944 let bytes = encoder.into_bytes();
945
946 println!("bytes: {bytes:?}");
947
948 let mut decoder: BinDecoder<'_> = BinDecoder::new(bytes);
949 let restrict = Restrict::new(bytes.len() as u16);
950 let read_rdata = KEY::read_data(&mut decoder, restrict).expect("Decoding error");
951 assert_eq!(rdata, read_rdata);
952 // #[cfg(any(feature = "openssl", feature = "ring"))]
953 // assert!(rdata
954 // .to_digest(&Name::parse("www.example.com.", None).unwrap(),
955 // DigestType::SHA256)
956 // .is_ok());
957 }
958}