1use crate::error::Error;
17use crate::payload_util::require_at_least;
18use alloc::vec::Vec;
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct KeySet {
23 pub key_type: u8,
25 pub key: Vec<u8>,
27}
28
29impl KeySet {
30 pub fn scbk(key: [u8; 16]) -> Self {
32 Self {
33 key_type: 0x01,
34 key: key.to_vec(),
35 }
36 }
37
38 pub fn encode(&self) -> Result<Vec<u8>, Error> {
40 if self.key.len() > u8::MAX as usize {
41 return Err(Error::MalformedPayload {
42 code: 0x75,
43 reason: "KEYSET key length exceeds 255",
44 });
45 }
46 let mut out = Vec::with_capacity(2 + self.key.len());
47 out.push(self.key_type);
48 out.push(self.key.len() as u8);
49 out.extend_from_slice(&self.key);
50 Ok(out)
51 }
52
53 pub fn decode(data: &[u8]) -> Result<Self, Error> {
55 require_at_least(data, 2, 0x75)?;
56 let key_len = data[1] as usize;
57 if data.len() != 2 + key_len {
58 return Err(Error::MalformedPayload {
59 code: 0x75,
60 reason: "KEYSET key length disagrees with payload",
61 });
62 }
63 Ok(Self {
64 key_type: data[0],
65 key: data[2..2 + key_len].to_vec(),
66 })
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn scbk_roundtrip() {
76 let key = [0xAAu8; 16];
77 let body = KeySet::scbk(key);
78 let bytes = body.encode().unwrap();
79 assert_eq!(bytes[0], 0x01);
80 assert_eq!(bytes[1], 16);
81 assert_eq!(&bytes[2..], &key);
82 assert_eq!(KeySet::decode(&bytes).unwrap(), body);
83 }
84
85 #[test]
86 fn decode_rejects_short() {
87 assert!(matches!(
88 KeySet::decode(&[0x01]),
89 Err(Error::PayloadTooShort { code: 0x75, .. })
90 ));
91 }
92
93 #[test]
94 fn decode_rejects_length_mismatch() {
95 assert!(matches!(
97 KeySet::decode(&[0x01, 0x04, 0xDE, 0xAD]),
98 Err(Error::MalformedPayload { code: 0x75, .. })
99 ));
100 }
101}