simple_dns/dns/rdata/
cert.rs1use crate::{bytes_buffer::BytesBuffer, dns::WireFormat, lib::Cow, lib::Write};
2
3use super::RR;
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone)]
7pub struct CERT<'a> {
8 pub type_code: u16,
10 pub key_tag: u16,
12 pub algorithm: u8,
14 pub certificate: Cow<'a, [u8]>,
16}
17
18impl RR for CERT<'_> {
19 const TYPE_CODE: u16 = 37;
20}
21
22impl<'a> WireFormat<'a> for CERT<'a> {
23 const MINIMUM_LEN: usize = 5;
24
25 fn parse(data: &mut BytesBuffer<'a>) -> crate::Result<Self>
26 where
27 Self: Sized,
28 {
29 let type_code = data.get_u16()?;
30 let key_tag = data.get_u16()?;
31 let algorithm = data.get_u8()?;
32 let certificate = data.get_remaining();
33
34 Ok(Self {
35 type_code,
36 key_tag,
37 algorithm,
38 certificate: Cow::Borrowed(certificate),
39 })
40 }
41
42 fn write_to<T: Write>(&self, out: &mut T) -> crate::Result<()> {
43 out.write_all(&self.type_code.to_be_bytes())?;
44 out.write_all(&self.key_tag.to_be_bytes())?;
45 out.write_all(&[self.algorithm])?;
46 out.write_all(&self.certificate)?;
47
48 Ok(())
49 }
50
51 fn len(&self) -> usize {
52 self.certificate.len() + Self::MINIMUM_LEN
53 }
54}
55
56impl CERT<'_> {
57 pub fn into_owned<'b>(self) -> CERT<'b> {
59 CERT {
60 type_code: self.type_code,
61 key_tag: self.key_tag,
62 algorithm: self.algorithm,
63 certificate: self.certificate.into_owned().into(),
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use crate::lib::{vec, Vec};
71
72 use super::*;
73
74 #[test]
75 fn parse_and_write_cert() {
76 let type_code = 12345u16;
77 let key_tag = 8u16;
78 let algorithm = 2u8;
79 let certificate = vec![1, 2, 3, 4, 5];
80 let rdata = CERT {
81 type_code,
82 key_tag,
83 algorithm,
84 certificate: Cow::Owned(certificate),
85 };
86 let mut writer = Vec::new();
87 rdata.write_to(&mut writer).unwrap();
88 let rdata = CERT::parse(&mut (&writer[..]).into()).unwrap();
89 assert_eq!(rdata.type_code, type_code);
90 assert_eq!(rdata.key_tag, key_tag);
91 assert_eq!(rdata.algorithm, algorithm);
92 assert_eq!(&*rdata.certificate, &[1, 2, 3, 4, 5]);
93 }
94
95 #[test]
96 #[cfg(feature = "std")]
97 fn parse_sample() -> Result<(), Box<dyn std::error::Error>> {
98 use crate::{rdata::RData, ResourceRecord};
99 let sample_file = std::fs::read("samples/zonefile/CERT.sample")?;
100
101 let sample_rdata = match ResourceRecord::parse(&mut (&sample_file[..]).into())?.rdata {
102 RData::CERT(rdata) => rdata,
103 _ => unreachable!(),
104 };
105
106 assert_eq!(sample_rdata.type_code, 3);
107 assert_eq!(sample_rdata.key_tag, 0);
108 assert_eq!(sample_rdata.algorithm, 0);
109 assert_eq!(*sample_rdata.certificate, *b"\x00\x00\x00\x00\x00");
110
111 Ok(())
112 }
113}