Skip to main content

osdp/command/
keyset.rs

1//! `osdp_KEYSET` (`0x75`) — install encryption key.
2//!
3//! # Spec: §6.16
4//!
5//! Body layout:
6//!
7//! ```text
8//! +---------+---------+----------+
9//! | key_type| key_len | key data |
10//! +---------+---------+----------+
11//! ```
12//!
13//! `key_type` is currently always `0x01` (SCBK), `key_len` is the byte length
14//! of the key (16 for AES-128).
15
16use crate::error::Error;
17use alloc::vec::Vec;
18
19/// `osdp_KEYSET` body.
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct KeySet {
22    /// Key type (0x01 = SCBK).
23    pub key_type: u8,
24    /// Key bytes.
25    pub key: Vec<u8>,
26}
27
28impl KeySet {
29    /// Build with the standard `key_type = 0x01` (SCBK) and a 16-byte key.
30    pub fn scbk(key: [u8; 16]) -> Self {
31        Self {
32            key_type: 0x01,
33            key: key.to_vec(),
34        }
35    }
36
37    /// Encode.
38    pub fn encode(&self) -> Result<Vec<u8>, Error> {
39        if self.key.len() > u8::MAX as usize {
40            return Err(Error::MalformedPayload {
41                code: 0x75,
42                reason: "KEYSET key length exceeds 255",
43            });
44        }
45        let mut out = Vec::with_capacity(2 + self.key.len());
46        out.push(self.key_type);
47        out.push(self.key.len() as u8);
48        out.extend_from_slice(&self.key);
49        Ok(out)
50    }
51
52    /// Decode.
53    pub fn decode(data: &[u8]) -> Result<Self, Error> {
54        if data.len() < 2 {
55            return Err(Error::MalformedPayload {
56                code: 0x75,
57                reason: "KEYSET requires at least 2 bytes",
58            });
59        }
60        let key_len = data[1] as usize;
61        if data.len() != 2 + key_len {
62            return Err(Error::MalformedPayload {
63                code: 0x75,
64                reason: "KEYSET key length disagrees with payload",
65            });
66        }
67        Ok(Self {
68            key_type: data[0],
69            key: data[2..2 + key_len].to_vec(),
70        })
71    }
72}