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}