Skip to content

Commit

Permalink
feat(asn1-parser): uncomment traits implementations. fix bool decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBestTvarynka committed Dec 3, 2023
1 parent d5c262c commit 4cb4813
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 69 deletions.
34 changes: 13 additions & 21 deletions crates/asn1-parser/src/generic_types/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,20 @@ impl Bool {
self.flag
}

pub fn from_id_and_byte(id: u64, byte: u8) -> Asn1Result<Bool> {
Ok(Bool {
id,
flag: if byte == 0 {
false
} else if byte == 0xff {
true
} else {
return Err(Error::from("Invalid bool value"));
},
})
pub fn from_id_and_byte(id: u64, byte: u8) -> Self {
Bool { id, flag: byte != 0 }
}

pub fn new(id: u64, flag: bool) -> Self {
Bool { id, flag }
}
}

// impl From<bool> for Bool {
// fn from(flag: bool) -> Self {
// Self { flag }
// }
// }
impl From<bool> for Bool {
fn from(flag: bool) -> Self {
Self { id: 0, flag }
}
}

// impl TryFrom<u8> for Bool {
// type Error = Error;
Expand Down Expand Up @@ -79,7 +74,7 @@ impl<'data> Asn1Decoder<'data> for Bool {
return Err(Error::from("Bool length must be equal to 1"));
}

Self::from_id_and_byte(reader.next_id(), reader.read_byte()?)
Ok(Self::from_id_and_byte(reader.next_id(), reader.read_byte()?))
}

fn decode_asn1(reader: &mut Reader<'data>) -> Asn1Result<Asn1<'data>> {
Expand All @@ -101,10 +96,7 @@ impl<'data> Asn1Decoder<'data> for Bool {
length: len_range,
data: data_range,
},
asn1_type: Box::new(Asn1Type::Bool(Self::from_id_and_byte(
reader.next_id(),
reader.read_byte()?,
)?)),
asn1_type: Box::new(Asn1Type::Bool(Self::from_id_and_byte(reader.next_id(), data[0]))),
})
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/asn1-parser/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ impl<'data> Reader<'data> {
self.position == self.inner.len()
}

pub fn remaining(&self) -> &'data [u8] {
&self.inner[self.position..]
}

pub fn data_in_range(&self, range: Range<usize>) -> Asn1Result<&'data [u8]> {
if range.end > self.inner.len() {
return Err(Error::from("Invalid range"));
Expand Down
13 changes: 8 additions & 5 deletions crates/asn1-parser/src/string/bit_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,14 @@ impl BitString<'_> {
}

// we assume here that firs vector byte contains amount of unused bytes
// impl From<Vec<u8>> for BitString<'_> {
// fn from(bits: Vec<u8>) -> Self {
// Self { bits: Cow::Owned(bits) }
// }
// }
impl From<Vec<u8>> for BitString<'_> {
fn from(bits: Vec<u8>) -> Self {
Self {
id: 0,
bits: Cow::Owned(bits),
}
}
}

impl Asn1Entity for BitString<'_> {
fn tag(&self) -> Tag {
Expand Down
22 changes: 16 additions & 6 deletions crates/asn1-parser/src/string/bmp_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,24 @@ impl BmpString<'_> {
data: self.data.to_vec().into(),
}
}

pub fn new_owned(id: u64, data: Vec<u8>) -> Self {
Self {
id,
data: Cow::Owned(data),
}
}
}

// impl From<&str> for OwnedBmpString {
// fn from(value: &str) -> Self {
// let data: Vec<u8> = value.encode_utf16().flat_map(|c| c.to_be_bytes()).collect();
// Self { data: Cow::Owned(data) }
// }
// }
impl From<&str> for OwnedBmpString {
fn from(value: &str) -> Self {
let data: Vec<u8> = value.encode_utf16().flat_map(|c| c.to_be_bytes()).collect();
Self {
id: 0,
data: Cow::Owned(data),
}
}
}

impl Asn1Entity for BmpString<'_> {
fn tag(&self) -> Tag {
Expand Down
22 changes: 15 additions & 7 deletions crates/asn1-parser/src/string/octet_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,23 @@ impl OctetString<'_> {
octets: self.octets.to_vec().into(),
}
}

pub fn new_owned(id: u64, octets: Vec<u8>) -> Self {
Self {
id,
octets: Cow::Owned(octets),
}
}
}

// impl From<Vec<u8>> for OwnedOctetString {
// fn from(data: Vec<u8>) -> Self {
// Self {
// octets: Cow::Owned(data),
// }
// }
// }
impl From<Vec<u8>> for OwnedOctetString {
fn from(data: Vec<u8>) -> Self {
Self {
id: 0,
octets: Cow::Owned(data),
}
}
}

impl<'data> Asn1Decoder<'data> for OctetString<'data> {
fn compare_tags(tag: &Tag) -> bool {
Expand Down
40 changes: 25 additions & 15 deletions crates/asn1-parser/src/string/utf8_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,32 @@ impl Utf8String<'_> {
string: self.string.to_string().into(),
}
}

pub fn new_owned(id: u64, string: String) -> Self {
Self {
id,
string: Cow::Owned(string),
}
}
}

impl From<String> for OwnedUtf8String {
fn from(data: String) -> Self {
Self {
id: 0,
string: Cow::Owned(data),
}
}
}

// impl From<String> for OwnedUtf8String {
// fn from(data: String) -> Self {
// Self {
// string: Cow::Owned(data),
// }
// }
// }

// impl From<&'static str> for OwnedUtf8String {
// fn from(data: &'static str) -> Self {
// Self {
// string: Cow::Borrowed(data),
// }
// }
// }
impl From<&'static str> for OwnedUtf8String {
fn from(data: &'static str) -> Self {
Self {
id: 0,
string: Cow::Borrowed(data),
}
}
}

impl<'data> Asn1Decoder<'data> for Utf8String<'data> {
fn compare_tags(tag: &Tag) -> bool {
Expand Down Expand Up @@ -146,6 +155,7 @@ mod tests {
assert_eq!(
utf8_string.asn1(),
&Asn1Type::Utf8String(Utf8String {
id: 0,
string: Cow::Borrowed("thebesttvarynka"),
})
);
Expand Down
2 changes: 1 addition & 1 deletion crates/asn1-parser/src/tags/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use alloc::boxed::Box;

use crate::asn1::RawAsn1EntityData;
use crate::length::{len_size, read_len, write_len};
use crate::reader::{read_data, Reader};
use crate::reader::Reader;
use crate::writer::Writer;
use crate::{Asn1, Asn1Decoder, Asn1Encoder, Asn1Entity, Asn1Result, Asn1Type, Error, Tag};

Expand Down
140 changes: 126 additions & 14 deletions crates/asn1-parser/tests/decode_encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,135 @@ fn asn1() {
}

#[test]
fn full_example() {
fn bug() {
use asn1_parser::*;

let asn1 = Sequence::new(vec![
Asn1::new(Default::default(), Box::new(Asn1Type::Bool(true.into()))),
let asn1 = Asn1Type::ExplicitTag(ExplicitTag::new(
0,
4,
Asn1::new(Default::default(), Box::new(Asn1Type::Bool(false.into()))),
Asn1::new(Default::default(), Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(0, Asn1::new(Default::default(), Box::new(Asn1Type::Utf8String("TbeBestTvarynka".into()))))))),
Asn1::new(Default::default(), Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(1, Asn1::new(Default::default(), Box::new(Asn1Type::Sequence(Sequence::new(vec![
Asn1::new(Default::default(), Box::new(Asn1Type::Null(Null))),
Asn1::new(Default::default(), Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(4, Asn1::new(Default::default(), Box::new(Asn1Type::OctetString(vec![48, 5, 160, 3, 1, 1, 255].into()))))))),
Asn1::new(Default::default(), Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(4, Asn1::new(Default::default(), Box::new(Asn1Type::BitString(BitString::from_raw_vec(32, vec![64, 129, 0, 16]).unwrap()))))))),
Asn1::new(Default::default(), Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(4, Asn1::new(Default::default(), Box::new(Asn1Type::ApplicationTag(ApplicationTag::new(12, Asn1::new(Default::default(), Box::new(Asn1Type::Sequence(Sequence::new(vec![
Asn1::new(Default::default(), Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(0, Asn1::new(Default::default(), Box::new(Asn1Type::Null(Null))))))),
Asn1::new(Default::default(), Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(1, Asn1::new(Default::default(), Box::new(Asn1Type::BmpString("Certificate".into()))))))),
])))))))))))),
])))))))),
]);
));

let asn1_tag = asn1.tag();

let buff_len = asn1.needed_buf_size();
let mut buff = vec![0; buff_len];

asn1.encode_buff(&mut buff).unwrap();

println!("encoded: {:?}", buff);

let mut decoded = Asn1Type::decode_asn1_buff(&buff).unwrap();
}

#[test]
fn full_example() {
use asn1_parser::*;

let asn1 = Sequence::new(
9,
vec![
Asn1::new(Default::default(), Box::new(Asn1Type::Bool(true.into()))),
Asn1::new(Default::default(), Box::new(Asn1Type::Bool(false.into()))),
Asn1::new(
Default::default(),
Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(
1,
0,
Asn1::new(
Default::default(),
Box::new(Asn1Type::Utf8String("TbeBestTvarynka".into())),
),
))),
),
Asn1::new(
Default::default(),
Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(
2,
1,
Asn1::new(
Default::default(),
Box::new(Asn1Type::Sequence(Sequence::new(
3,
vec![
Asn1::new(Default::default(), Box::new(Asn1Type::Null(Null::default()))),
Asn1::new(
Default::default(),
Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(
3,
4,
Asn1::new(
Default::default(),
Box::new(Asn1Type::OctetString(vec![48, 5, 160, 3, 1, 1, 255].into())),
),
))),
),
Asn1::new(
Default::default(),
Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(
4,
4,
Asn1::new(
Default::default(),
Box::new(Asn1Type::BitString(
BitString::from_raw_vec(5, 32, vec![64, 129, 0, 16]).unwrap(),
)),
),
))),
),
Asn1::new(
Default::default(),
Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(
5,
4,
Asn1::new(
Default::default(),
Box::new(Asn1Type::ApplicationTag(ApplicationTag::new(
3,
12,
Asn1::new(
Default::default(),
Box::new(Asn1Type::Sequence(Sequence::new(
8,
vec![
Asn1::new(
Default::default(),
Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(
6,
0,
Asn1::new(
Default::default(),
Box::new(Asn1Type::Null(Null::default())),
),
))),
),
Asn1::new(
Default::default(),
Box::new(Asn1Type::ExplicitTag(ExplicitTag::new(
7,
1,
Asn1::new(
Default::default(),
Box::new(Asn1Type::BmpString(
"Certificate".into(),
)),
),
))),
),
],
))),
),
))),
),
))),
),
],
))),
),
))),
),
],
);

let buff_len = asn1.needed_buf_size();
let mut buff = vec![0; buff_len];
Expand Down

0 comments on commit 4cb4813

Please sign in to comment.