hickory_proto/rr/dnssec/
supported_algorithm.rs1use std::fmt::{self, Display, Formatter};
20
21#[cfg(feature = "serde-config")]
22use serde::{Deserialize, Serialize};
23
24use tracing::warn;
25
26use crate::error::*;
27use crate::rr::dnssec::Algorithm;
28use crate::serialize::binary::{BinEncodable, BinEncoder};
29
30#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
32#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
33pub struct SupportedAlgorithms {
34 bit_map: u8,
36}
37
38impl SupportedAlgorithms {
39 pub fn new() -> Self {
41 Self { bit_map: 0 }
42 }
43
44 pub fn all() -> Self {
46 Self {
47 bit_map: 0b0111_1111,
48 }
49 }
50
51 pub fn from_vec(algorithms: &[Algorithm]) -> Self {
53 let mut supported = Self::new();
54
55 for a in algorithms {
56 supported.set(*a);
57 }
58
59 supported
60 }
61
62 fn pos(algorithm: Algorithm) -> Option<u8> {
63 #[allow(deprecated)]
65 let bit_pos: Option<u8> = match algorithm {
66 Algorithm::RSASHA1 => Some(0),
67 Algorithm::RSASHA256 => Some(1),
68 Algorithm::RSASHA1NSEC3SHA1 => Some(2),
69 Algorithm::RSASHA512 => Some(3),
70 Algorithm::ECDSAP256SHA256 => Some(4),
71 Algorithm::ECDSAP384SHA384 => Some(5),
72 Algorithm::ED25519 => Some(6),
73 Algorithm::RSAMD5 | Algorithm::DSA | Algorithm::Unknown(_) => None,
74 };
75
76 bit_pos.map(|b| 1u8 << b)
77 }
78
79 fn from_pos(pos: u8) -> Option<Algorithm> {
80 #[allow(deprecated)]
82 match pos {
83 0 => Some(Algorithm::RSASHA1),
84 1 => Some(Algorithm::RSASHA256),
85 2 => Some(Algorithm::RSASHA1NSEC3SHA1),
86 3 => Some(Algorithm::RSASHA512),
87 4 => Some(Algorithm::ECDSAP256SHA256),
88 5 => Some(Algorithm::ECDSAP384SHA384),
89 6 => Some(Algorithm::ED25519),
90 _ => None,
91 }
92 }
93
94 pub fn set(&mut self, algorithm: Algorithm) {
96 if let Some(bit_pos) = Self::pos(algorithm) {
97 self.bit_map |= bit_pos;
98 }
99 }
100
101 pub fn has(self, algorithm: Algorithm) -> bool {
103 if let Some(bit_pos) = Self::pos(algorithm) {
104 (bit_pos & self.bit_map) == bit_pos
105 } else {
106 false
107 }
108 }
109
110 pub fn iter(&self) -> SupportedAlgorithmsIter<'_> {
112 SupportedAlgorithmsIter::new(self)
113 }
114
115 pub fn len(self) -> u16 {
117 self.iter().count() as u16
119 }
120
121 pub fn is_empty(self) -> bool {
123 self.bit_map == 0
124 }
125}
126
127impl Default for SupportedAlgorithms {
128 fn default() -> Self {
129 Self::new()
130 }
131}
132
133impl Display for SupportedAlgorithms {
134 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
135 for a in self.iter() {
136 a.fmt(f)?;
137 f.write_str(", ")?;
138 }
139
140 Ok(())
141 }
142}
143
144impl<'a> From<&'a [u8]> for SupportedAlgorithms {
145 fn from(values: &'a [u8]) -> Self {
146 let mut supported = Self::new();
147
148 for a in values.iter().map(|i| Algorithm::from_u8(*i)) {
149 match a {
150 Algorithm::Unknown(v) => warn!("unrecognized algorithm: {}", v),
151 a => supported.set(a),
152 }
153 }
154
155 supported
156 }
157}
158
159impl<'a> From<&'a SupportedAlgorithms> for Vec<u8> {
160 fn from(value: &'a SupportedAlgorithms) -> Self {
161 let mut bytes = Self::with_capacity(8); for a in value.iter() {
164 bytes.push(a.into());
165 }
166
167 bytes.shrink_to_fit();
168 bytes
169 }
170}
171
172impl From<Algorithm> for SupportedAlgorithms {
173 fn from(algorithm: Algorithm) -> Self {
174 Self::from_vec(&[algorithm])
175 }
176}
177
178pub struct SupportedAlgorithmsIter<'a> {
179 algorithms: &'a SupportedAlgorithms,
180 current: usize,
181}
182
183impl<'a> SupportedAlgorithmsIter<'a> {
184 pub fn new(algorithms: &'a SupportedAlgorithms) -> Self {
185 SupportedAlgorithmsIter {
186 algorithms,
187 current: 0,
188 }
189 }
190}
191
192impl Iterator for SupportedAlgorithmsIter<'_> {
193 type Item = Algorithm;
194 fn next(&mut self) -> Option<Self::Item> {
195 if self.current > u8::MAX as usize {
197 return None;
198 }
199
200 while let Some(algorithm) = SupportedAlgorithms::from_pos(self.current as u8) {
201 self.current += 1;
202 if self.algorithms.has(algorithm) {
203 return Some(algorithm);
204 }
205 }
206
207 None
208 }
209}
210
211impl BinEncodable for SupportedAlgorithms {
212 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
213 for a in self.iter() {
214 encoder.emit_u8(a.into())?;
215 }
216 Ok(())
217 }
218}
219
220#[test]
221#[allow(deprecated)]
222fn test_has() {
223 let mut supported = SupportedAlgorithms::new();
224
225 supported.set(Algorithm::RSASHA1);
226
227 assert!(supported.has(Algorithm::RSASHA1));
228 assert!(!supported.has(Algorithm::RSASHA1NSEC3SHA1));
229
230 let mut supported = SupportedAlgorithms::new();
231
232 supported.set(Algorithm::RSASHA256);
233 assert!(!supported.has(Algorithm::RSASHA1));
234 assert!(!supported.has(Algorithm::RSASHA1NSEC3SHA1));
235 assert!(supported.has(Algorithm::RSASHA256));
236}
237
238#[test]
239#[allow(deprecated)]
240fn test_iterator() {
241 let supported = SupportedAlgorithms::all();
242 assert_eq!(supported.iter().count(), 7);
243
244 let supported = SupportedAlgorithms::all();
246 let mut iter = supported.iter();
247 assert_eq!(iter.next(), Some(Algorithm::RSASHA1));
248 assert_eq!(iter.next(), Some(Algorithm::RSASHA256));
249 assert_eq!(iter.next(), Some(Algorithm::RSASHA1NSEC3SHA1));
250 assert_eq!(iter.next(), Some(Algorithm::RSASHA512));
251 assert_eq!(iter.next(), Some(Algorithm::ECDSAP256SHA256));
252 assert_eq!(iter.next(), Some(Algorithm::ECDSAP384SHA384));
253 assert_eq!(iter.next(), Some(Algorithm::ED25519));
254
255 let mut supported = SupportedAlgorithms::new();
256 supported.set(Algorithm::RSASHA256);
257 supported.set(Algorithm::RSASHA512);
258
259 let mut iter = supported.iter();
260 assert_eq!(iter.next(), Some(Algorithm::RSASHA256));
261 assert_eq!(iter.next(), Some(Algorithm::RSASHA512));
262}
263
264#[test]
265#[allow(deprecated)]
266fn test_vec() {
267 let supported = SupportedAlgorithms::all();
268 let array: Vec<u8> = (&supported).into();
269 let decoded: SupportedAlgorithms = (&array as &[_]).into();
270
271 assert_eq!(supported, decoded);
272
273 let mut supported = SupportedAlgorithms::new();
274 supported.set(Algorithm::RSASHA256);
275 supported.set(Algorithm::ECDSAP256SHA256);
276 supported.set(Algorithm::ECDSAP384SHA384);
277 supported.set(Algorithm::ED25519);
278 let array: Vec<u8> = (&supported).into();
279 let decoded: SupportedAlgorithms = (&array as &[_]).into();
280
281 assert_eq!(supported, decoded);
282 assert!(!supported.has(Algorithm::RSASHA1));
283 assert!(!supported.has(Algorithm::RSASHA1NSEC3SHA1));
284 assert!(supported.has(Algorithm::RSASHA256));
285 assert!(supported.has(Algorithm::ECDSAP256SHA256));
286 assert!(supported.has(Algorithm::ECDSAP384SHA384));
287 assert!(supported.has(Algorithm::ED25519));
288}