use minicbor::{encode::Write, Decode, Decoder, Encode, Encoder};
use serde::{Deserialize, Serialize};
use crate::attributes::attribute::Attribute;
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct RelativeDistinguishedName(Vec<Attribute>);
impl Default for RelativeDistinguishedName {
fn default() -> Self {
Self::new()
}
}
impl RelativeDistinguishedName {
#[must_use]
pub fn new() -> Self {
Self(Vec::new())
}
pub fn add_attr(&mut self, attribute: Attribute) {
self.0.push(attribute.set_pen_supported());
}
pub(crate) fn get_attributes(&self) -> &Vec<Attribute> {
&self.0
}
}
impl Encode<()> for RelativeDistinguishedName {
fn encode<W: Write>(
&self, e: &mut Encoder<W>, ctx: &mut (),
) -> Result<(), minicbor::encode::Error<W::Error>> {
if self.0.is_empty() {
return Err(minicbor::encode::Error::message(
"RelativeDistinguishedName should not be empty",
));
}
if self.0.len() == 1 {
self.0.first().encode(e, ctx)?;
} else {
e.array(self.0.len() as u64 * 2)?;
for attr in &self.0 {
attr.encode(e, ctx)?;
}
}
Ok(())
}
}
impl Decode<'_, ()> for RelativeDistinguishedName {
fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
let mut rdn = RelativeDistinguishedName::new();
match d.datatype()? {
minicbor::data::Type::Array => {
let len = d.array()?.ok_or(minicbor::decode::Error::message(
"Failed to get array length for relative distinguished name",
))?;
if len == 0 {
return Err(minicbor::decode::Error::message(
"RelativeDistinguishedName should not be empty",
));
}
for _ in 0..len / 2 {
rdn.add_attr(Attribute::decode(d, ctx)?);
}
},
_ => rdn.add_attr(Attribute::decode(d, ctx)?),
}
Ok(rdn)
}
}
#[cfg(test)]
mod test_relative_distinguished_name {
use asn1_rs::oid;
use super::*;
use crate::attributes::attribute::AttributeValue;
#[test]
fn encode_decode_rdn() {
let mut buffer = Vec::new();
let mut encoder = Encoder::new(&mut buffer);
let mut attr = Attribute::new(oid!(1.2.840 .113549 .1 .9 .1));
attr.add_value(AttributeValue::Text("example@example.com".to_string()));
let mut rdn = RelativeDistinguishedName::new();
rdn.add_attr(attr);
rdn.encode(&mut encoder, &mut ())
.expect("Failed to encode RDN");
assert_eq!(
hex::encode(buffer.clone()),
"00736578616d706c65406578616d706c652e636f6d"
);
let mut decoder = Decoder::new(&buffer);
let rdn_decoded = RelativeDistinguishedName::decode(&mut decoder, &mut ())
.expect("Failed to decode RelativeDistinguishedName");
assert_eq!(rdn_decoded, rdn);
}
#[test]
fn encode_decode_rdns() {
let mut buffer = Vec::new();
let mut encoder = Encoder::new(&mut buffer);
let mut attr1 = Attribute::new(oid!(1.2.840 .113549 .1 .9 .1));
attr1.add_value(AttributeValue::Text("example@example.com".to_string()));
let mut attr2 = Attribute::new(oid!(2.5.4 .3));
attr2.add_value(AttributeValue::Text("example".to_string()));
let mut rdns = RelativeDistinguishedName::new();
rdns.add_attr(attr1);
rdns.add_attr(attr2);
rdns.encode(&mut encoder, &mut ())
.expect("Failed to encode RDN");
assert_eq!(
hex::encode(buffer.clone()),
"8400736578616d706c65406578616d706c652e636f6d01676578616d706c65"
);
let mut decoder = Decoder::new(&buffer);
let rdn_decoded = RelativeDistinguishedName::decode(&mut decoder, &mut ())
.expect("Failed to decode RelativeDistinguishedName");
assert_eq!(rdn_decoded, rdns);
}
#[test]
fn empty_rdn() {
let mut buffer = Vec::new();
let mut encoder = Encoder::new(&mut buffer);
let rdn = RelativeDistinguishedName::new();
rdn.encode(&mut encoder, &mut ())
.expect_err("Failed to encode RDN");
}
}