use crate::{
impl_command_display, impl_command_ops, impl_default, impl_message_from_buf, impl_response_ops,
impl_wrapped_message_ops, len, CommandOps, Error, MessageOps, MessageType, Result,
};
#[repr(C)]
#[derive(Clone, Debug, PartialEq, zeroize::Zeroize, zeroize::ZeroizeOnDrop)]
pub struct WrappedEncryptedMessage {
buf: [u8; len::WRAPPED_ENCRYPTED_MESSAGE],
stuffing: usize,
}
impl WrappedEncryptedMessage {
pub fn new() -> Self {
let mut msg = Self {
buf: [0u8; len::WRAPPED_ENCRYPTED_MESSAGE],
stuffing: 0,
};
msg.init();
msg.set_command(MessageType::Encrypted);
msg
}
pub fn is_encrypted(&self) -> bool {
use crate::message::STEX;
self.data()[0] == STEX
}
pub fn encrypted_data(&self) -> &[u8] {
use crate::message::index;
let start = index::DATA + 1;
let end = start + self.data_len() - 1;
self.buf[start..end].as_ref()
}
pub fn is_stuffed(&self) -> bool {
self.stuffing != 0
}
pub fn stuff_encrypted_data(&mut self) -> Result<usize> {
use super::stuff;
use crate::message::index;
let start = index::DATA + 1;
let end = start + self.data_len() + 2;
let new_end = stuff(&mut self.buf[start..], end)?;
self.stuffing = new_end.saturating_sub(end);
Ok(self.stuffing)
}
pub fn unstuff_encrypted_data(&mut self) -> Result<()> {
use super::unstuff;
use crate::message::{index, STX};
let start = index::DATA + 1;
let exp_end = start + self.data_len() + 2;
let len = self.buf.len();
let mut i = start;
let mut end = exp_end;
while end < len && i < end {
if self.buf[i] == STX && self.buf[i + 1] == STX {
i += 2;
end += 1;
} else {
i += 1;
}
}
let calc_end = unstuff(&mut self.buf[start..], end)?;
if calc_end != exp_end {
Err(Error::InvalidLength((calc_end, exp_end)))
} else {
self.stuffing = 0;
Ok(())
}
}
}
impl_default!(WrappedEncryptedMessage);
impl_command_display!(WrappedEncryptedMessage);
impl_message_from_buf!(WrappedEncryptedMessage);
impl_wrapped_message_ops!(WrappedEncryptedMessage);
impl_command_ops!(WrappedEncryptedMessage);
impl_response_ops!(WrappedEncryptedMessage);