flex_dns/rdata/
sig.rs

1use crate::{Buffer, DnsMessage, DnsMessageError, MutBuffer};
2use crate::characters::Characters;
3use crate::name::DnsName;
4use crate::parse::Parse;
5use crate::rdata::{RData, RDataParse};
6use crate::write::WriteBytes;
7
8/// # Signature
9/// This record is used to authenticate the data in a message
10#[derive(Copy, Clone, Debug, PartialEq)]
11pub struct Sig<'a> {
12    /// The type of the record covered by this signature
13    pub type_covered: u16,
14    /// The algorithm used
15    pub algorithm: u8,
16    /// The number of labels in the original RDATA
17    pub labels: u8,
18    /// The original TTL
19    pub original_ttl: u32,
20    /// The signature expiration
21    pub signature_expiration: u32,
22    /// The signature inception
23    pub signature_inception: u32,
24    /// The key tag
25    pub key_tag: u16,
26    /// The signer's name
27    pub signer_name: DnsName<'a>,
28    /// The signature
29    pub signature: Characters<'a>,
30}
31
32impl<'a> RDataParse<'a> for Sig<'a> {
33    #[inline]
34    fn parse(rdata: &RData<'a>, i: &mut usize) -> Result<Self, DnsMessageError> {
35        let type_covered = u16::parse(rdata, i)?;
36        let algorithm = u8::parse(rdata, i)?;
37        let labels = u8::parse(rdata, i)?;
38        let original_ttl = u32::parse(rdata, i)?;
39        let signature_expiration = u32::parse(rdata, i)?;
40        let signature_inception = u32::parse(rdata, i)?;
41        let key_tag = u16::parse(rdata, i)?;
42        let signer_name = DnsName::parse(rdata, i)?;
43        let signature = Characters::parse(rdata, i)?;
44
45        Ok(Self {
46            type_covered,
47            algorithm,
48            labels,
49            original_ttl,
50            signature_expiration,
51            signature_inception,
52            key_tag,
53            signer_name,
54            signature,
55        })
56    }
57}
58
59impl<'a> WriteBytes for Sig<'a> {
60    #[inline]
61    fn write<
62        const PTR_STORAGE: usize,
63        const DNS_SECTION: usize,
64        B: MutBuffer + Buffer,
65    >(&self, message: &mut DnsMessage<PTR_STORAGE, DNS_SECTION, B>) -> Result<usize, DnsMessageError> {
66        let mut bytes = 0;
67
68        bytes += self.type_covered.write(message)?;
69        bytes += self.algorithm.write(message)?;
70        bytes += self.labels.write(message)?;
71        bytes += self.original_ttl.write(message)?;
72        bytes += self.signature_expiration.write(message)?;
73        bytes += self.signature_inception.write(message)?;
74        bytes += self.key_tag.write(message)?;
75        bytes += self.signer_name.write(message)?;
76        bytes += self.signature.write(message)?;
77
78        Ok(bytes)
79    }
80}
81
82#[cfg(test)]
83mod test {
84    use crate::rdata::testutils::parse_write_test;
85
86    use super::*;
87
88    parse_write_test!(
89        43,
90        [
91            0x00, 0x0e, // type covered
92            0x05, // algorithm
93            0x06, // labels
94            0x00, 0x00, 0x00, 0x0a, // original ttl
95            0x00, 0x00, 0x00, 0x0b, // signature expiration
96            0x00, 0x00, 0x00, 0x0c, // signature inception
97            0x00, 0x0d, // key tag
98            0x03, b'w', b'w', b'w',
99            0x07, b'e', b'x', b'a', b'm', b'p', b'l', b'e',
100            0x03, b'c', b'o', b'm',
101            0x00, // signer name
102            0x07, b'f', b'o', b'o', b'-', b'b', b'a', b'r', // signature
103        ],
104        Sig {
105            type_covered: 14,
106            algorithm: 5,
107            labels: 6,
108            original_ttl: 10,
109            signature_expiration: 11,
110            signature_inception: 12,
111            key_tag: 13,
112            signer_name: unsafe { DnsName::new_unchecked(b"\x03www\x07example\x03com\x00") },
113            signature: unsafe { Characters::new_unchecked(b"foo-bar") },
114        },
115    );
116}