dns_message_parser/rr/
rfc_4034.rs

1use crate::rr::Class;
2use crate::DomainName;
3use hex::encode;
4use std::fmt::{Display, Formatter, Result as FmtResult};
5
6/// The bit at offset 7 of the DNSKEY flags field is the [Zone Key flag].
7///
8/// [Zone Key flag]: https://tools.ietf.org/html/rfc4034#section-2.1.1
9pub const ZONE_KEY_FLAG: u16 = 0b0000_0001_0000_0000;
10/// The  bit at offset 15 of the DNSKEY flags field is the [Secure Entry Point flag].
11///
12/// [Secure Entry Point flag]: https://tools.ietf.org/html/rfc4034#section-2.1.1
13pub const SECURE_ENTRY_POINT_FLAG: u16 = 0b0000_0000_0000_0001;
14pub const DNSKEY_ZERO_MASK: u16 = 0b1111_1110_1111_1110;
15
16try_from_enum_to_integer! {
17    #[repr(u8)]
18    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19    /// https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
20    pub enum AlgorithmType {
21        Reserved = 0x00,
22        RsaMd5 = 0x01,
23        DiffiHellman = 0x02,
24        DsaSha1 = 0x03,
25        EllipticCurve = 0x04,
26        RsaSha1 = 0x05,
27        DsaNsec3 = 0x06,
28        RsaSha1Nsec3Sha1 = 0x07,
29        RsaSha256 = 0x08,
30        GostR = 0x0c,
31        EcDsaP256 = 0x0d,
32        EcDsaP386 = 0x0e,
33        Ed25519 = 0x0f,
34        Ed448 = 0x10,
35        Indirect = 0xfc,
36        PrivateDns = 0xfd,
37        PrivateOid = 0xfe,
38    }
39}
40
41try_from_enum_to_integer! {
42    #[repr(u8)]
43    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
44    /// https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml#ds-rr-types-1
45    pub enum DigestType {
46        Reserved = 0x00,
47        Sha1 = 0x01,
48        Sha256 = 0x02,
49        GostR = 0x03,
50        Sha384 = 0x04,
51    }
52}
53
54#[derive(Debug, PartialEq, Clone, Eq, Hash)]
55pub struct DNSKEY {
56    pub domain_name: DomainName,
57    pub ttl: u32,
58    pub class: Class,
59    pub zone_key_flag: bool,
60    pub secure_entry_point_flag: bool,
61    pub algorithm_type: AlgorithmType,
62    pub public_key: Vec<u8>,
63}
64
65impl DNSKEY {
66    pub fn get_flags(&self) -> u16 {
67        let mut flags: u16 = 0;
68        if self.zone_key_flag {
69            flags |= ZONE_KEY_FLAG;
70        }
71        if self.secure_entry_point_flag {
72            flags |= SECURE_ENTRY_POINT_FLAG;
73        }
74        flags
75    }
76}
77
78impl Display for DNSKEY {
79    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
80        write!(
81            f,
82            "{} {} {} DNSKEY {} 3 {} {}",
83            self.domain_name,
84            self.ttl,
85            self.class,
86            self.get_flags(),
87            self.algorithm_type as u8,
88            encode(&self.public_key),
89        )
90    }
91}
92
93#[derive(Debug, PartialEq, Clone, Eq, Hash)]
94pub struct DS {
95    pub domain_name: DomainName,
96    pub ttl: u32,
97    pub class: Class,
98    pub key_tag: u16,
99    pub algorithm_type: AlgorithmType,
100    pub digest_type: DigestType,
101    pub digest: Vec<u8>,
102}
103
104impl Display for DS {
105    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
106        write!(
107            f,
108            "{} {} {} DS {} {} {} {}",
109            self.domain_name,
110            self.ttl,
111            self.class,
112            self.key_tag,
113            self.algorithm_type as u8,
114            self.digest_type as u8,
115            encode(&self.digest),
116        )
117    }
118}