use alloc::boxed::Box;
use rasn::prelude::*;
pub use crate::v2::{
GetBulkRequest, GetNextRequest, GetRequest, InformRequest, Pdus, Response, SetRequest, Trap,
VarBind, VarBindValue,
};
#[derive(AsnType, Debug, Decode, Encode, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct Message {
pub version: Integer,
pub global_data: HeaderData,
pub security_parameters: OctetString,
pub scoped_data: ScopedPduData,
}
impl Message {
pub fn decode_security_parameters<T: SecurityParameters>(
&self,
codec: rasn::Codec,
) -> Result<T, alloc::boxed::Box<dyn core::fmt::Display>> {
if self.global_data.security_model != T::ID.into() {
return Err(Box::new(alloc::format!(
"`{}` doesn't match security model `{}`",
self.global_data.security_model,
T::ID
)) as Box<_>);
}
codec
.decode_from_binary::<T>(&self.security_parameters)
.map_err(|error| Box::new(error) as Box<_>)
}
pub fn encode_security_parameters<T: SecurityParameters>(
&mut self,
codec: rasn::Codec,
value: &T,
) -> Result<(), alloc::boxed::Box<dyn core::fmt::Display>> {
self.global_data.security_model = T::ID.into();
self.security_parameters = codec
.encode_to_binary::<T>(value)
.map_err(|error| Box::new(error) as Box<_>)?
.into();
Ok(())
}
}
pub trait SecurityParameters: Decode + Encode {
const ID: u32;
}
impl SecurityParameters for USMSecurityParameters {
const ID: u32 = 3;
}
#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct HeaderData {
pub message_id: Integer,
pub max_size: Integer,
pub flags: OctetString,
pub security_model: Integer,
}
#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[rasn(choice)]
pub enum ScopedPduData {
CleartextPdu(ScopedPdu),
EncryptedPdu(OctetString),
}
#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct ScopedPdu {
pub engine_id: OctetString,
pub name: OctetString,
pub data: Pdus,
}
#[derive(AsnType, Debug, Clone, Decode, Encode, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct USMSecurityParameters {
pub authoritative_engine_id: OctetString,
pub authoritative_engine_boots: Integer,
pub authoritative_engine_time: Integer,
pub user_name: OctetString,
pub authentication_parameters: OctetString,
pub privacy_parameters: OctetString,
}