Skip to content
Merged
23 changes: 13 additions & 10 deletions rust/c509-certificate/src/algorithm_identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ use asn1_rs::Oid;
use minicbor::{encode::Write, Decode, Decoder, Encode, Encoder};
use serde::{Deserialize, Serialize};

use crate::oid::C509oid;

use crate::{
helper::{
decode::{decode_array_len, decode_bytes, decode_datatype},
encode::{encode_array_len, encode_bytes},
},
oid::C509oid,
};
/// A struct represents the `AlgorithmIdentifier` type.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct AlgorithmIdentifier {
Expand Down Expand Up @@ -58,9 +63,9 @@ impl Encode<()> for AlgorithmIdentifier {
match &self.param {
// [ algorithm: ~oid, parameters: bytes ]
Some(p) => {
e.array(2)?;
encode_array_len(e, "Algorithm Identifier", 2)?;
self.c509_oid.encode(e, ctx)?;
e.bytes(p.as_bytes())?;
encode_bytes(e, "Algorithm Identifier", p.as_bytes())?;
},
// ~oid
None => {
Expand All @@ -74,16 +79,14 @@ impl Encode<()> for AlgorithmIdentifier {
impl Decode<'_, ()> for AlgorithmIdentifier {
fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
// [ algorithm: ~oid, parameters: bytes ]
if d.datatype()? == minicbor::data::Type::Array {
let len = d.array()?.ok_or(minicbor::decode::Error::message(
"Failed to get array length",
))?;
if decode_datatype(d, "Algorithm Identifier")? == minicbor::data::Type::Array {
let len = decode_array_len(d, "Algorithm Identifier")?;
if len != 2 {
return Err(minicbor::decode::Error::message("Array length must be 2"));
}
let c509_oid = C509oid::decode(d, ctx)?;
let param =
String::from_utf8(d.bytes()?.to_vec()).map_err(minicbor::decode::Error::message)?;
let param = String::from_utf8(decode_bytes(d, "Algorithm Identifier")?)
.map_err(minicbor::decode::Error::message)?;
Ok(AlgorithmIdentifier::new(
c509_oid.oid().clone(),
Some(param),
Expand Down
49 changes: 32 additions & 17 deletions rust/c509-certificate/src/attributes/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ use minicbor::{encode::Write, Decode, Decoder, Encode, Encoder};
use serde::{Deserialize, Deserializer, Serialize};

use super::data::{get_oid_from_int, ATTRIBUTES_LOOKUP};
use crate::oid::{C509oid, C509oidRegistered};

use crate::{
helper::{
decode::{decode_array_len, decode_datatype, decode_helper},
encode::{encode_array_len, encode_helper},
},
oid::{C509oid, C509oidRegistered},
};
/// A struct of C509 `Attribute`
#[derive(Debug, Clone, PartialEq)]
pub struct Attribute {
Expand Down Expand Up @@ -107,7 +112,7 @@ impl Encode<()> for Attribute {
.get_map()
.get_by_right(self.registered_oid().c509_oid().oid())
{
e.i16(oid)?;
encode_helper(e, "Attribute as OID int", ctx, &oid)?;
} else {
// Encode unwrapped CBOR OID
self.registered_oid().c509_oid().encode(e, ctx)?;
Expand All @@ -120,7 +125,7 @@ impl Encode<()> for Attribute {

// If multi-value attributes, encode it as array
if self.multi_value {
e.array(self.value.len() as u64)?;
encode_array_len(e, "Attribute multiple value", self.value.len() as u64)?;
}

// Encode each value in the attribute
Expand All @@ -135,8 +140,8 @@ impl Encode<()> for Attribute {
impl Decode<'_, ()> for Attribute {
fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
// Handle CBOR int
let mut attr = if d.datatype()? == minicbor::data::Type::U8 {
let i = d.i16()?;
let mut attr = if decode_datatype(d, "Attribute as OID int")? == minicbor::data::Type::U8 {
let i = decode_helper(d, "Attribute as OID int", ctx)?;
let oid = get_oid_from_int(i).map_err(minicbor::decode::Error::message)?;
Attribute::new(oid.clone())
} else {
Expand All @@ -146,11 +151,9 @@ impl Decode<'_, ()> for Attribute {
};

// Handle attribute value
if d.datatype()? == minicbor::data::Type::Array {
if decode_datatype(d, "Attribute")? == minicbor::data::Type::Array {
// When multi-value attribute
let len = d.array()?.ok_or_else(|| {
minicbor::decode::Error::message("Failed to get array length for attribute value")
})?;
let len = decode_array_len(d, "Attribute multiple value")?;

if len == 0 {
return Err(minicbor::decode::Error::message("Attribute value is empty"));
Expand Down Expand Up @@ -183,21 +186,33 @@ pub enum AttributeValue {

impl Encode<()> for AttributeValue {
fn encode<W: Write>(
&self, e: &mut Encoder<W>, _ctx: &mut (),
&self, e: &mut Encoder<W>, ctx: &mut (),
) -> Result<(), minicbor::encode::Error<W::Error>> {
match self {
AttributeValue::Text(text) => e.str(text)?,
AttributeValue::Bytes(bytes) => e.bytes(bytes)?,
AttributeValue::Text(text) => encode_helper(e, "Attribute value", ctx, text)?,
AttributeValue::Bytes(bytes) => encode_helper(e, "Attribute value", ctx, bytes)?,
};
Ok(())
}
}

impl Decode<'_, ()> for AttributeValue {
fn decode(d: &mut Decoder<'_>, _ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
match d.datatype()? {
minicbor::data::Type::String => Ok(AttributeValue::Text(d.str()?.to_string())),
minicbor::data::Type::Bytes => Ok(AttributeValue::Bytes(d.bytes()?.to_vec())),
fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
match decode_datatype(d, "Attribute value")? {
minicbor::data::Type::String => {
Ok(AttributeValue::Text(decode_helper(
d,
"Attribute value",
ctx,
)?))
},
minicbor::data::Type::Bytes => {
Ok(AttributeValue::Bytes(decode_helper(
d,
"Attribute value",
ctx,
)?))
},
_ => {
Err(minicbor::decode::Error::message(
"Invalid AttributeValue, value should be either String or Bytes",
Expand Down
12 changes: 6 additions & 6 deletions rust/c509-certificate/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use attribute::Attribute;
use minicbor::{encode::Write, Decode, Decoder, Encode, Encoder};
use serde::{Deserialize, Serialize};

use crate::helper::{decode::decode_array_len, encode::encode_array_len};

pub mod attribute;
mod data;

Expand Down Expand Up @@ -60,7 +62,7 @@ impl Encode<()> for Attributes {
));
}
// The attribute type should be included in array too
e.array(self.0.len() as u64 * 2)?;
encode_array_len(e, "Attributes", self.0.len() as u64 * 2)?;
for attribute in &self.0 {
attribute.encode(e, ctx)?;
}
Expand All @@ -69,10 +71,8 @@ impl Encode<()> for Attributes {
}

impl Decode<'_, ()> for Attributes {
fn decode(d: &mut Decoder<'_>, _ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
let len = d
.array()?
.ok_or_else(|| minicbor::decode::Error::message("Failed to get array length"))?;
fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
let len = decode_array_len(d, "Attributes")?;
if len == 0 {
return Err(minicbor::decode::Error::message("Attributes is empty"));
}
Expand All @@ -81,7 +81,7 @@ impl Decode<'_, ()> for Attributes {

// The attribute type is included in an array, so divide by 2
for _ in 0..len / 2 {
let attribute = Attribute::decode(d, &mut ())?;
let attribute = Attribute::decode(d, ctx)?;
attributes.add_attribute(attribute);
}

Expand Down
6 changes: 3 additions & 3 deletions rust/c509-certificate/src/big_uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use minicbor::{encode::Write, Decode, Decoder, Encode, Encoder};
use serde::{Deserialize, Serialize};

use crate::helper::{decode::decode_bytes, encode::encode_bytes};
/// A struct representing an unwrapped CBOR unsigned bignum.
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
Expand Down Expand Up @@ -45,16 +46,15 @@ impl Encode<()> for UnwrappedBigUint {
.copied()
.collect::<Vec<u8>>();

e.bytes(&significant_bytes)?;
encode_bytes(e, "Unwrapped big uint", &significant_bytes)?;
Ok(())
}
}

impl Decode<'_, ()> for UnwrappedBigUint {
fn decode(d: &mut Decoder<'_>, _ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
// Turn bytes into u64
let b = d
.bytes()?
let b = decode_bytes(d, "Unwrapped big uint")?
.iter()
.fold(0, |acc, &b| (acc << 8) | u64::from(b));
Ok(UnwrappedBigUint::new(b))
Expand Down
16 changes: 11 additions & 5 deletions rust/c509-certificate/src/c509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
use minicbor::{encode::Write, Decode, Decoder, Encode, Encoder};
use serde::{Deserialize, Serialize};

use crate::tbs_cert::TbsCert;
use crate::{
helper::{
decode::{decode_bytes, decode_datatype},
encode::{encode_bytes, encode_null},
},
tbs_cert::TbsCert,
};

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
/// A struct represents the `C509` Certificate.
Expand Down Expand Up @@ -43,8 +49,8 @@ impl Encode<()> for C509 {
) -> Result<(), minicbor::encode::Error<W::Error>> {
self.tbs_cert.encode(e, ctx)?;
match self.issuer_signature_value {
Some(ref value) => e.bytes(value)?,
None => e.null()?,
Some(ref value) => encode_bytes(e, "C509 Issuer Signature value", value)?,
None => encode_null(e, "C509 Issuer Signature value")?,
};
Ok(())
}
Expand All @@ -53,8 +59,8 @@ impl Encode<()> for C509 {
impl Decode<'_, ()> for C509 {
fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
let tbs_cert = TbsCert::decode(d, ctx)?;
let issuer_signature_value = match d.datatype()? {
minicbor::data::Type::Bytes => Some(d.bytes()?.to_vec()),
let issuer_signature_value = match decode_datatype(d, "C509 Issuer Signature value")? {
minicbor::data::Type::Bytes => Some(decode_bytes(d, "C509 Issuer Signature value")?),
_ => None,
};
Ok(Self::new(tbs_cert, issuer_signature_value))
Expand Down
26 changes: 19 additions & 7 deletions rust/c509-certificate/src/extensions/alt_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
use minicbor::{encode::Write, Decode, Decoder, Encode, Encoder};
use serde::{Deserialize, Serialize};

use crate::general_names::{
general_name::{GeneralName, GeneralNameTypeRegistry, GeneralNameValue},
GeneralNames,
use crate::{
general_names::{
general_name::{GeneralName, GeneralNameTypeRegistry, GeneralNameValue},
GeneralNames,
},
helper::{
decode::{decode_datatype, decode_helper},
encode::encode_helper,
},
};

/// Alternative Name extension.
Expand Down Expand Up @@ -45,6 +51,8 @@ impl Decode<'_, ()> for AlternativeName {
// ------------------GeneralNamesOrText--------------------

/// Enum for type that can be a `GeneralNames` or a text use in `AlternativeName`.
/// Type `Text` is also considered as a `GeneralNames` with only 1 `DNSName` as
/// a special case.
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum GeneralNamesOrText {
Expand All @@ -63,7 +71,7 @@ impl Encode<()> for GeneralNamesOrText {
let gn = gns
.general_names()
.first()
.ok_or(minicbor::encode::Error::message("GeneralNames is empty"))?;
.ok_or(minicbor::encode::Error::message("General Names is empty"))?;
// Check whether there is only 1 item in the array which is a DNSName
if gns.general_names().len() == 1 && gn.gn_type().is_dns_name() {
gn.gn_value().encode(e, ctx)?;
Expand All @@ -72,7 +80,7 @@ impl Encode<()> for GeneralNamesOrText {
}
},
GeneralNamesOrText::Text(text) => {
e.str(text)?;
encode_helper(e, "Alternative Name - General Name Text", ctx, text)?;
},
}
Ok(())
Expand All @@ -81,12 +89,16 @@ impl Encode<()> for GeneralNamesOrText {

impl Decode<'_, ()> for GeneralNamesOrText {
fn decode(d: &mut Decoder<'_>, ctx: &mut ()) -> Result<Self, minicbor::decode::Error> {
match d.datatype()? {
match decode_datatype(d, "Alternative Name - General Names")? {
// If it is a string it is a GeneralNames with only 1 DNSName
minicbor::data::Type::String => {
let gn_dns = GeneralName::new(
GeneralNameTypeRegistry::DNSName,
GeneralNameValue::Text(d.str()?.to_string()),
GeneralNameValue::Text(decode_helper(
d,
"Alternative Name - General Name Text",
ctx,
)?),
);
let mut gns = GeneralNames::new();
gns.add_general_name(gn_dns);
Expand Down
Loading