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