1use crate::attributes::stun::PasswordAlgorithm;
2use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
3use crate::common::{check_buffer_boundaries, fill_padding_value, padding};
4use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
5use crate::StunError;
6use std::sync::Arc;
7
8const PASSWORD_ALGORITHMS: u16 = 0x8002;
22
23#[derive(Debug, Clone, PartialEq, Eq, Default)]
40pub struct PasswordAlgorithms {
41 algorithms: Arc<Vec<PasswordAlgorithm>>,
42}
43
44impl PasswordAlgorithms {
45 pub fn add(&mut self, algorithm: PasswordAlgorithm) {
47 Arc::get_mut(&mut self.algorithms).unwrap().push(algorithm);
48 }
49
50 pub fn password_algorithms(&self) -> &[PasswordAlgorithm] {
52 &self.algorithms
53 }
54
55 pub fn iter(&self) -> impl Iterator<Item = &PasswordAlgorithm> {
57 self.algorithms.iter()
58 }
59}
60
61impl IntoIterator for PasswordAlgorithms {
62 type Item = PasswordAlgorithm;
63 type IntoIter = std::vec::IntoIter<PasswordAlgorithm>;
64
65 fn into_iter(self) -> Self::IntoIter {
66 self.algorithms.clone().as_ref().clone().into_iter()
67 }
68}
69
70impl From<Vec<PasswordAlgorithm>> for PasswordAlgorithms {
71 fn from(v: Vec<PasswordAlgorithm>) -> Self {
72 Self {
73 algorithms: Arc::new(v),
74 }
75 }
76}
77
78impl DecodeAttributeValue for PasswordAlgorithms {
79 fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
80 let mut attr = PasswordAlgorithms::default();
81
82 let raw_msg = ctx.decoded_message();
83 let raw_value = ctx.raw_value();
84
85 let mut size = 0;
86 let mut total_size = 0;
87 while total_size < raw_value.len() {
88 total_size += padding(size);
89 check_buffer_boundaries(raw_value, total_size)?;
90 let attr_ctx =
91 AttributeDecoderContext::new(ctx.context(), raw_msg, &raw_value[total_size..]);
92 let (val, len) = PasswordAlgorithm::decode(attr_ctx)?;
93 attr.add(val);
94 total_size += len;
95 size = len;
96 }
97
98 Ok((attr, total_size))
99 }
100}
101
102impl EncodeAttributeValue for PasswordAlgorithms {
103 fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
104 let mut it = self.algorithms.iter().peekable();
105 let mut size = 0;
106
107 while let Some(attr) = it.next() {
108 let len;
109 {
110 let raw_msg = ctx.encoded_message();
111 let raw_value = ctx.raw_value_mut();
112 check_buffer_boundaries(raw_value, size)?;
113 let attr_ctx = AttributeEncoderContext::new(None, raw_msg, &mut raw_value[size..]);
114 len = attr.encode(attr_ctx)?;
115 size += len;
116 }
117 if it.peek().is_some() {
118 let padding = padding(len);
119 let padding_value = ctx.context().unwrap_or_default().padding();
120 let raw_value = ctx.raw_value_mut();
121 fill_padding_value(&mut raw_value[size..], padding, padding_value)?;
122 size += padding;
123 }
124 }
125
126 Ok(size)
127 }
128}
129
130impl crate::attributes::AsVerifiable for PasswordAlgorithms {}
131
132stunt_attribute!(PasswordAlgorithms, PASSWORD_ALGORITHMS);
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137 use crate::error::StunErrorType;
138 use crate::StunAttribute;
139 use crate::{Algorithm, AlgorithmId};
140
141 #[test]
142 fn constructor() {
143 let mut attr = PasswordAlgorithms::default();
144 assert_eq!(attr.iter().count(), 0);
145
146 attr.add(PasswordAlgorithm::new(Algorithm::from(AlgorithmId::MD5)));
147 assert_eq!(attr.iter().count(), 1);
148
149 attr.add(PasswordAlgorithm::new(Algorithm::from(AlgorithmId::SHA256)));
150 assert_eq!(attr.iter().count(), 2);
151
152 let mut iter = attr.password_algorithms().iter();
153 let algorithm = iter.next().expect("Expected algorithm");
154 assert_eq!(algorithm.algorithm(), AlgorithmId::MD5);
155
156 let algorithm = iter.next().expect("Expected algorithm");
157 assert_eq!(algorithm.algorithm(), AlgorithmId::SHA256);
158
159 assert!(iter.next().is_none());
161
162 let attributes = vec![
163 PasswordAlgorithm::new(Algorithm::from(AlgorithmId::MD5)),
164 PasswordAlgorithm::new(Algorithm::from(AlgorithmId::SHA256)),
165 ];
166 let attr_1 = PasswordAlgorithms::from(attributes);
167
168 assert_eq!(attr, attr_1);
169 }
170
171 #[test]
172 fn decode_password_algorithms_attribute_value() {
173 let dummy_msg = [];
174 let buffer = [];
175 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
176 let (attr, size) =
177 PasswordAlgorithms::decode(ctx).expect("Could not decode PasswordAlgorithms");
178 assert_eq!(attr.into_iter().len(), 0);
179 assert_eq!(size, 0);
180
181 let buffer = [0x00, 0x01, 0x00, 0x00];
182 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
183 let (attr, size) =
184 PasswordAlgorithms::decode(ctx).expect("Could not decode PasswordAlgorithms");
185 assert_eq!(attr.into_iter().len(), 1);
186 assert_eq!(size, 4);
187
188 let buffer = [0x00, 0x01, 0x00, 0x02, 0x01, 0x02];
189 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
190 let (attr, size) =
191 PasswordAlgorithms::decode(ctx).expect("Could not decode PasswordAlgorithms");
192 assert_eq!(attr.into_iter().len(), 1);
193 assert_eq!(size, 6);
194
195 let buffer = [
197 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x03,
198 ];
199 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
200 let (attr, size) =
201 PasswordAlgorithms::decode(ctx).expect("Could not decode PasswordAlgorithms");
202 assert_eq!(attr.into_iter().len(), 2);
203 assert_eq!(size, 13);
204 }
205
206 #[test]
207 fn decode_password_algorithms_attribute_value_error() {
208 let dummy_msg = [];
209 let buffer = [0x00, 0x01, 0x00, 0x01];
210 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
211 assert_eq!(
212 PasswordAlgorithms::decode(ctx).expect_err("Error expected"),
213 StunErrorType::SmallBuffer
214 );
215
216 let buffer = [0x00, 0x01, 0x00, 0x00, 0x23];
217 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
218 assert_eq!(
219 PasswordAlgorithms::decode(ctx).expect_err("Error expected"),
220 StunErrorType::SmallBuffer
221 );
222 }
223
224 #[test]
225 fn decode_password_algorithms_attribute() {
226 let dummy_msg = [];
227 let buffer = [0x00, 0x01, 0x00, 0x00];
228 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
229 let (attr, size) =
230 PasswordAlgorithms::decode(ctx).expect("Could not decode PasswordAlgorithms");
231 assert_eq!(size, 4);
232 let mut iter = attr.into_iter();
233 assert_eq!(iter.len(), 1);
234 let val = iter
235 .next()
236 .expect("Can not get password algorithm attribute");
237 assert_eq!(val.algorithm(), AlgorithmId::MD5);
238
239 let buffer = [0x00, 0x01, 0x00, 0x02, 0x01, 0x02];
240 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
241 let (attr, size) =
242 PasswordAlgorithms::decode(ctx).expect("Could not decode PasswordAlgorithms");
243 assert_eq!(size, 6);
244 let mut iter = attr.into_iter();
245 assert_eq!(iter.len(), 1);
246 let val = iter
247 .next()
248 .expect("Can not get password algorithm attribute");
249 assert_eq!(val.algorithm(), AlgorithmId::MD5);
250 assert_eq!(val.parameters(), Some([0x01, 0x02].as_slice()));
251
252 let buffer = [
254 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x03,
255 ];
256 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
257 let (attr, size) =
258 PasswordAlgorithms::decode(ctx).expect("Could not decode PasswordAlgorithms");
259 assert_eq!(size, 13);
260 let mut iter = attr.into_iter();
261 assert_eq!(iter.len(), 2);
262
263 let val = iter
264 .next()
265 .expect("Can not get password algorithm attribute");
266 assert_eq!(val.algorithm(), AlgorithmId::MD5);
267 assert_eq!(val.parameters(), Some([0x01, 0x02].as_slice()));
268
269 let val = iter
270 .next()
271 .expect("Can not get password algorithm attribute");
272 assert_eq!(val.algorithm(), AlgorithmId::SHA256);
273 assert_eq!(val.parameters(), Some([0x03].as_slice()));
274 }
275
276 #[test]
277 fn decode_password_algorithms_attribute_error() {
278 let dummy_msg = [];
279 let buffer = [0x00, 0x01, 0x00];
280 let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
281 let result = PasswordAlgorithms::decode(ctx);
282 assert_eq!(
283 result.expect_err("Error expected"),
284 StunErrorType::SmallBuffer
285 );
286 }
287
288 #[test]
289 fn encode_password_algorithms_attribute_value() {
290 let dummy_msg: [u8; 0] = [0x0; 0];
291 let mut buffer = [];
292 let attr = PasswordAlgorithms::default();
293 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
294 let result = attr.encode(ctx);
295 assert_eq!(result, Ok(0));
296
297 let mut buffer: [u8; 4] = [0x0; 4];
298 let mut attr = PasswordAlgorithms::default();
299 attr.add(PasswordAlgorithm::new(Algorithm::from(AlgorithmId::MD5)));
300 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
301 let result = attr.encode(ctx);
302 let expected_buffer = [0x00, 0x01, 0x00, 0x00];
303 assert_eq!(result, Ok(4));
304 assert_eq!(&buffer[..], &expected_buffer[..]);
305
306 let mut buffer: [u8; 6] = [0x0; 6];
307 let mut attr = PasswordAlgorithms::default();
308 let params = [0x01, 0x02];
309 let algorithm = Algorithm::new(AlgorithmId::MD5, params.as_ref());
310 attr.add(PasswordAlgorithm::new(algorithm));
311 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
312 let result = attr.encode(ctx);
313 let expected_buffer = [0x00, 0x01, 0x00, 0x02, 0x01, 0x02];
314 assert_eq!(result, Ok(6));
315 assert_eq!(&buffer[..], &expected_buffer[..]);
316
317 let mut buffer: [u8; 13] = [0x0; 13];
319 let mut attr = PasswordAlgorithms::default();
320 let algorithm = Algorithm::new(AlgorithmId::MD5, params.as_ref());
321 attr.add(PasswordAlgorithm::new(algorithm));
322
323 let params = [0x03];
324 let algorithm = Algorithm::new(AlgorithmId::SHA256, params.as_ref());
325 attr.add(PasswordAlgorithm::new(algorithm));
326 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
327 let result = attr.encode(ctx);
328 let expected_buffer = [
329 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x03,
330 ];
331 assert_eq!(result, Ok(13));
332 assert_eq!(&buffer[..], &expected_buffer[..]);
333 }
334
335 #[test]
336 fn encode_password_algorithms_attribute_value_error() {
337 let dummy_msg: [u8; 0] = [0x0; 0];
338 let mut buffer = [];
339 let mut attr = PasswordAlgorithms::default();
340 attr.add(PasswordAlgorithm::new(Algorithm::from(AlgorithmId::MD5)));
341 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
342 let result = attr.encode(ctx);
343 assert_eq!(
344 result.expect_err("Error expected"),
345 StunErrorType::SmallBuffer
346 );
347
348 let mut buffer: [u8; 3] = [0x0; 3];
349 let mut attr = PasswordAlgorithms::default();
350 attr.add(PasswordAlgorithm::new(Algorithm::from(AlgorithmId::MD5)));
351 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
352 let result = attr.encode(ctx);
353 assert_eq!(
354 result.expect_err("Error expected"),
355 StunErrorType::SmallBuffer
356 );
357 }
358
359 #[test]
360 fn encode_password_algorithms_attribute() {
361 let dummy_msg: [u8; 0] = [];
362 let mut buffer = [];
363 let attr = PasswordAlgorithms::default();
364 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
365 let result = attr.encode(ctx);
366 let expected_buffer: [u8; 0] = [];
367 assert_eq!(result, Ok(0));
368 assert_eq!(&buffer[..], &expected_buffer[..]);
369
370 let mut buffer: [u8; 4] = [0x0; 4];
371 let mut attr = PasswordAlgorithms::default();
372 attr.add(PasswordAlgorithm::new(Algorithm::from(AlgorithmId::MD5)));
373 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
374 let result = attr.encode(ctx);
375 let expected_buffer = [0x00, 0x01, 0x00, 0x00];
376 assert_eq!(result, Ok(4));
377 assert_eq!(&buffer[..], &expected_buffer[..]);
378
379 let mut buffer: [u8; 13] = [0x0; 13];
380 let params = [0x01, 0x02];
381 let mut attr = PasswordAlgorithms::default();
382 let algorithm = Algorithm::new(AlgorithmId::MD5, params.as_ref());
383 attr.add(PasswordAlgorithm::new(algorithm));
384
385 let params = [0x03];
386 let algorithm = Algorithm::new(AlgorithmId::SHA256, params.as_ref());
387 attr.add(PasswordAlgorithm::new(algorithm));
388
389 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
390 let result = attr.encode(ctx);
391 let expected_buffer = [
392 0x00, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x03,
393 ];
394 assert_eq!(result, Ok(13));
395 assert_eq!(&buffer[..], &expected_buffer[..]);
396 }
397
398 #[test]
399 fn encode_password_algorithms_attribute_error() {
400 let dummy_msg: [u8; 0] = [0x0; 0];
401
402 let mut buffer: [u8; 3] = [0x0; 3];
403 let mut attr = PasswordAlgorithms::default();
404 attr.add(PasswordAlgorithm::new(Algorithm::from(AlgorithmId::MD5)));
405 let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
406 let result = attr.encode(ctx);
407 assert_eq!(
408 result.expect_err("Error expected"),
409 StunErrorType::SmallBuffer
410 );
411 }
412
413 #[test]
414 fn password_algorithms_attribute() {
415 let attr = StunAttribute::PasswordAlgorithms(PasswordAlgorithms::default());
416 assert!(attr.is_password_algorithms());
417 assert!(attr.as_password_algorithms().is_ok());
418 assert!(attr.as_unknown().is_err());
419
420 assert!(!attr.attribute_type().is_comprehension_required());
421 assert!(attr.attribute_type().is_comprehension_optional());
422
423 let dbg_fmt = format!("{:?}", attr);
424 assert_eq!(
425 "PasswordAlgorithms(PasswordAlgorithms { algorithms: [] })",
426 dbg_fmt
427 );
428 }
429}