1ffe74184SMartin Algesten use super::{param_header::*, param_type::*, *};
2ffe74184SMartin Algesten 
3ffe74184SMartin Algesten use bytes::{Buf, BufMut, Bytes, BytesMut};
4ffe74184SMartin Algesten use std::fmt;
5ffe74184SMartin Algesten 
6ffe74184SMartin Algesten #[derive(Debug, Copy, Clone, PartialEq)]
7ffe74184SMartin Algesten #[repr(C)]
8ffe74184SMartin Algesten pub(crate) enum HmacAlgorithm {
9ffe74184SMartin Algesten     HmacResv1 = 0,
10ffe74184SMartin Algesten     HmacSha128 = 1,
11ffe74184SMartin Algesten     HmacResv2 = 2,
12ffe74184SMartin Algesten     HmacSha256 = 3,
13ffe74184SMartin Algesten     Unknown,
14ffe74184SMartin Algesten }
15ffe74184SMartin Algesten 
16ffe74184SMartin Algesten impl fmt::Display for HmacAlgorithm {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result17ffe74184SMartin Algesten     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18ffe74184SMartin Algesten         let s = match *self {
19ffe74184SMartin Algesten             HmacAlgorithm::HmacResv1 => "HMAC Reserved (0x00)",
20ffe74184SMartin Algesten             HmacAlgorithm::HmacSha128 => "HMAC SHA-128",
21ffe74184SMartin Algesten             HmacAlgorithm::HmacResv2 => "HMAC Reserved (0x02)",
22ffe74184SMartin Algesten             HmacAlgorithm::HmacSha256 => "HMAC SHA-256",
23ffe74184SMartin Algesten             _ => "Unknown HMAC Algorithm",
24ffe74184SMartin Algesten         };
25*5d8fe953SJoão Oliveira         write!(f, "{s}")
26ffe74184SMartin Algesten     }
27ffe74184SMartin Algesten }
28ffe74184SMartin Algesten 
29ffe74184SMartin Algesten impl From<u16> for HmacAlgorithm {
from(v: u16) -> HmacAlgorithm30ffe74184SMartin Algesten     fn from(v: u16) -> HmacAlgorithm {
31ffe74184SMartin Algesten         match v {
32ffe74184SMartin Algesten             0 => HmacAlgorithm::HmacResv1,
33ffe74184SMartin Algesten             1 => HmacAlgorithm::HmacSha128,
34ffe74184SMartin Algesten             2 => HmacAlgorithm::HmacResv2,
35ffe74184SMartin Algesten             3 => HmacAlgorithm::HmacSha256,
36ffe74184SMartin Algesten             _ => HmacAlgorithm::Unknown,
37ffe74184SMartin Algesten         }
38ffe74184SMartin Algesten     }
39ffe74184SMartin Algesten }
40ffe74184SMartin Algesten 
41ffe74184SMartin Algesten #[derive(Default, Debug, Clone, PartialEq)]
42ffe74184SMartin Algesten pub(crate) struct ParamRequestedHmacAlgorithm {
43ffe74184SMartin Algesten     pub(crate) available_algorithms: Vec<HmacAlgorithm>,
44ffe74184SMartin Algesten }
45ffe74184SMartin Algesten 
46ffe74184SMartin Algesten impl fmt::Display for ParamRequestedHmacAlgorithm {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result47ffe74184SMartin Algesten     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48ffe74184SMartin Algesten         write!(
49ffe74184SMartin Algesten             f,
50ffe74184SMartin Algesten             "{} {}",
51ffe74184SMartin Algesten             self.header(),
52ffe74184SMartin Algesten             self.available_algorithms
53ffe74184SMartin Algesten                 .iter()
54ffe74184SMartin Algesten                 .map(|ct| ct.to_string())
55ffe74184SMartin Algesten                 .collect::<Vec<String>>()
56ffe74184SMartin Algesten                 .join(" "),
57ffe74184SMartin Algesten         )
58ffe74184SMartin Algesten     }
59ffe74184SMartin Algesten }
60ffe74184SMartin Algesten 
61ffe74184SMartin Algesten impl Param for ParamRequestedHmacAlgorithm {
header(&self) -> ParamHeader62ffe74184SMartin Algesten     fn header(&self) -> ParamHeader {
63ffe74184SMartin Algesten         ParamHeader {
64ffe74184SMartin Algesten             typ: ParamType::ReqHmacAlgo,
65ffe74184SMartin Algesten             value_length: self.value_length() as u16,
66ffe74184SMartin Algesten         }
67ffe74184SMartin Algesten     }
68ffe74184SMartin Algesten 
unmarshal(raw: &Bytes) -> Result<Self>69ffe74184SMartin Algesten     fn unmarshal(raw: &Bytes) -> Result<Self> {
70ffe74184SMartin Algesten         let header = ParamHeader::unmarshal(raw)?;
71ffe74184SMartin Algesten 
72ffe74184SMartin Algesten         let reader =
73ffe74184SMartin Algesten             &mut raw.slice(PARAM_HEADER_LENGTH..PARAM_HEADER_LENGTH + header.value_length());
74ffe74184SMartin Algesten 
75ffe74184SMartin Algesten         let mut available_algorithms = vec![];
76ffe74184SMartin Algesten         let mut offset = 0;
77ffe74184SMartin Algesten         while offset + 1 < header.value_length() {
78ffe74184SMartin Algesten             let a: HmacAlgorithm = reader.get_u16().into();
79ffe74184SMartin Algesten             if a == HmacAlgorithm::HmacSha128 || a == HmacAlgorithm::HmacSha256 {
80ffe74184SMartin Algesten                 available_algorithms.push(a);
81ffe74184SMartin Algesten             } else {
82ffe74184SMartin Algesten                 return Err(Error::ErrInvalidAlgorithmType);
83ffe74184SMartin Algesten             }
84ffe74184SMartin Algesten 
85ffe74184SMartin Algesten             offset += 2;
86ffe74184SMartin Algesten         }
87ffe74184SMartin Algesten 
88ffe74184SMartin Algesten         Ok(ParamRequestedHmacAlgorithm {
89ffe74184SMartin Algesten             available_algorithms,
90ffe74184SMartin Algesten         })
91ffe74184SMartin Algesten     }
92ffe74184SMartin Algesten 
marshal_to(&self, buf: &mut BytesMut) -> Result<usize>93ffe74184SMartin Algesten     fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> {
94ffe74184SMartin Algesten         self.header().marshal_to(buf)?;
95ffe74184SMartin Algesten         for a in &self.available_algorithms {
96ffe74184SMartin Algesten             buf.put_u16(*a as u16);
97ffe74184SMartin Algesten         }
98ffe74184SMartin Algesten         Ok(buf.len())
99ffe74184SMartin Algesten     }
100ffe74184SMartin Algesten 
value_length(&self) -> usize101ffe74184SMartin Algesten     fn value_length(&self) -> usize {
102ffe74184SMartin Algesten         2 * self.available_algorithms.len()
103ffe74184SMartin Algesten     }
104ffe74184SMartin Algesten 
clone_to(&self) -> Box<dyn Param + Send + Sync>105ffe74184SMartin Algesten     fn clone_to(&self) -> Box<dyn Param + Send + Sync> {
106ffe74184SMartin Algesten         Box::new(self.clone())
107ffe74184SMartin Algesten     }
108ffe74184SMartin Algesten 
as_any(&self) -> &(dyn Any + Send + Sync)109ffe74184SMartin Algesten     fn as_any(&self) -> &(dyn Any + Send + Sync) {
110ffe74184SMartin Algesten         self
111ffe74184SMartin Algesten     }
112ffe74184SMartin Algesten }
113