Skip to content

Commit

Permalink
der: add test for application tags
Browse files Browse the repository at this point in the history
  • Loading branch information
dishmaker committed Oct 9, 2024
1 parent 86851cf commit 02c666a
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 238 deletions.
27 changes: 27 additions & 0 deletions der/src/asn1/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,30 @@ pub type ApplicationExplicitRef<'a, const TAG: u16, T> =
/// Application class, reference, IMPLICIT
pub type ApplicationImplicitRef<'a, const TAG: u16, T> =
CustomClassImplicitRef<'a, TAG, T, CLASS_APPLICATION>;

#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use crate::{
asn1::{context_specific::ContextSpecificExplicit, OctetStringRef},
Decode, Encode,
};
use hex_literal::hex;

#[test]
fn round_trip() {
const EXAMPLE_BYTES: &[u8] = &hex!(
"A2 06"
"04 04"
"01020304"
);

let field =
ContextSpecificExplicit::<2, OctetStringRef<'_>>::from_der(EXAMPLE_BYTES).unwrap();
assert_eq!(field.value, OctetStringRef::new(&[1, 2, 3, 4]).unwrap());

let mut buf = [0u8; 128];
let encoded = field.encode_to_slice(&mut buf).unwrap();
assert_eq!(encoded, EXAMPLE_BYTES);
}
}
22 changes: 0 additions & 22 deletions der/src/asn1/context_specific.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,6 @@ pub type ContextSpecificExplicitRef<'a, const TAG: u16, T> =
pub type ContextSpecificImplicitRef<'a, const TAG: u16, T> =
CustomClassImplicitRef<'a, TAG, T, CLASS_CONTEXT_SPECIFIC>;

// pub fn decode_implicit<'a, R: Reader<'a>, T: Tagged + DecodeValue<'a>>(
// number: TagNumber,
// reader: &mut R,
// ) -> Result<Option<T>, T::Error> {
// match AnyCustomClassImplicit::decode_skipping(Class::ContextSpecific, number, reader) {
// Ok(Some(custom)) => Ok(Some(custom.value)),
// Ok(None) => Ok(None),
// Err(err) => Err(err),
// }
// }

// pub fn decode_explicit<'a, R: Reader<'a>, T: Decode<'a>>(
// number: TagNumber,
// reader: &mut R,
// ) -> Result<Option<T>, T::Error> {
// match AnyCustomClassExplicit::decode_skipping(Class::ContextSpecific, number, reader) {
// Ok(Some(custom)) => Ok(Some(custom.value)),
// Ok(None) => Ok(None),
// Err(err) => Err(err),
// }
// }

#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
Expand Down
1 change: 0 additions & 1 deletion der/src/asn1/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ mod tests {
use crate::{asn1::BitStringRef, Decode, Encode, SliceReader};
use hex_literal::hex;

// Public key data from `pkcs8` crate's `ed25519-pkcs8-v2.der`
const EXAMPLE_BYTES: &[u8] =
&hex!("E123032100A3A7EAE3A8373830BC47E1167BC50E1DB551999651E0E2DC587623438EAC3F31");

Expand Down
30 changes: 22 additions & 8 deletions der/src/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ fn parse_parts<'a, R: Reader<'a>>(first_byte: u8, reader: &mut R) -> Result<(boo
Err(Error::new(ErrorKind::TagNumberInvalid, reader.position()))
}

/// Length of encoded tag depends only on number it encodes
fn tag_length(tag_number: u16) -> Length {
if tag_number <= 30 {
Length::ONE
Expand All @@ -389,6 +390,21 @@ fn tag_length(tag_number: u16) -> Length {
}
}

fn tag_class_number_bytes(
class: Class,
tag_number: TagNumber,
constructed: bool,
buf: &mut [u8; Tag::MAX_SIZE],
) -> &[u8] {
let mut first_byte = class as u8;
if constructed {
first_byte |= CONSTRUCTED_FLAG;
}
let num = tag_number.value();
tag_number_bytes(first_byte, num, buf)
}

/// Tag contains class bits, constructed flag and number
#[allow(clippy::cast_possible_truncation)]
fn tag_number_bytes(first_byte: u8, num: u16, buf: &mut [u8; Tag::MAX_SIZE]) -> &[u8] {
if num <= 30 {
Expand Down Expand Up @@ -418,14 +434,9 @@ impl Encode for Tag {
}

fn encode(&self, writer: &mut impl Writer) -> Result<()> {
let mut first_byte = self.class() as u8;
if self.is_constructed() {
first_byte |= CONSTRUCTED_FLAG;
}
let num = self.number().value();

let mut buf = [0u8; Tag::MAX_SIZE];
let tag_bytes = tag_number_bytes(first_byte, num, &mut buf);
let tag_bytes =
tag_class_number_bytes(self.class(), self.number(), self.is_constructed(), &mut buf);
writer.write(tag_bytes)
}
}
Expand Down Expand Up @@ -499,7 +510,10 @@ impl fmt::Display for Tag {

impl fmt::Debug for Tag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Tag(0x{:02x}: {})", self.number().value(), self)
let mut buf = [0u8; Tag::MAX_SIZE];
let tag_bytes =
tag_class_number_bytes(self.class(), self.number(), self.is_constructed(), &mut buf);
write!(f, "Tag({:02X?}: {})", tag_bytes, self)
}
}

Expand Down
Loading

0 comments on commit 02c666a

Please sign in to comment.