diff --git a/crates/asn1-parser/src/generic_types/boolean.rs b/crates/asn1-parser/src/generic_types/boolean.rs index f42d644f..d3237c80 100644 --- a/crates/asn1-parser/src/generic_types/boolean.rs +++ b/crates/asn1-parser/src/generic_types/boolean.rs @@ -23,25 +23,20 @@ impl Bool { self.flag } - pub fn from_id_and_byte(id: u64, byte: u8) -> Asn1Result { - 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 for Bool { -// fn from(flag: bool) -> Self { -// Self { flag } -// } -// } +impl From for Bool { + fn from(flag: bool) -> Self { + Self { id: 0, flag } + } +} // impl TryFrom for Bool { // type Error = Error; @@ -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> { @@ -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]))), }) } } diff --git a/crates/asn1-parser/src/reader.rs b/crates/asn1-parser/src/reader.rs index e5f5d5b4..52db7906 100644 --- a/crates/asn1-parser/src/reader.rs +++ b/crates/asn1-parser/src/reader.rs @@ -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) -> Asn1Result<&'data [u8]> { if range.end > self.inner.len() { return Err(Error::from("Invalid range")); diff --git a/crates/asn1-parser/src/string/bit_string.rs b/crates/asn1-parser/src/string/bit_string.rs index 4f47adc8..70c6f7b5 100644 --- a/crates/asn1-parser/src/string/bit_string.rs +++ b/crates/asn1-parser/src/string/bit_string.rs @@ -63,11 +63,14 @@ impl BitString<'_> { } // we assume here that firs vector byte contains amount of unused bytes -// impl From> for BitString<'_> { -// fn from(bits: Vec) -> Self { -// Self { bits: Cow::Owned(bits) } -// } -// } +impl From> for BitString<'_> { + fn from(bits: Vec) -> Self { + Self { + id: 0, + bits: Cow::Owned(bits), + } + } +} impl Asn1Entity for BitString<'_> { fn tag(&self) -> Tag { diff --git a/crates/asn1-parser/src/string/bmp_string.rs b/crates/asn1-parser/src/string/bmp_string.rs index 00d58308..9a72c49c 100644 --- a/crates/asn1-parser/src/string/bmp_string.rs +++ b/crates/asn1-parser/src/string/bmp_string.rs @@ -34,14 +34,24 @@ impl BmpString<'_> { data: self.data.to_vec().into(), } } + + pub fn new_owned(id: u64, data: Vec) -> Self { + Self { + id, + data: Cow::Owned(data), + } + } } -// impl From<&str> for OwnedBmpString { -// fn from(value: &str) -> Self { -// let data: Vec = 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 = 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 { diff --git a/crates/asn1-parser/src/string/octet_string.rs b/crates/asn1-parser/src/string/octet_string.rs index e1b699a6..3a24fa8b 100644 --- a/crates/asn1-parser/src/string/octet_string.rs +++ b/crates/asn1-parser/src/string/octet_string.rs @@ -35,15 +35,23 @@ impl OctetString<'_> { octets: self.octets.to_vec().into(), } } + + pub fn new_owned(id: u64, octets: Vec) -> Self { + Self { + id, + octets: Cow::Owned(octets), + } + } } -// impl From> for OwnedOctetString { -// fn from(data: Vec) -> Self { -// Self { -// octets: Cow::Owned(data), -// } -// } -// } +impl From> for OwnedOctetString { + fn from(data: Vec) -> Self { + Self { + id: 0, + octets: Cow::Owned(data), + } + } +} impl<'data> Asn1Decoder<'data> for OctetString<'data> { fn compare_tags(tag: &Tag) -> bool { diff --git a/crates/asn1-parser/src/string/utf8_string.rs b/crates/asn1-parser/src/string/utf8_string.rs index b29e6973..9f20696d 100644 --- a/crates/asn1-parser/src/string/utf8_string.rs +++ b/crates/asn1-parser/src/string/utf8_string.rs @@ -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 for OwnedUtf8String { + fn from(data: String) -> Self { + Self { + id: 0, + string: Cow::Owned(data), + } + } } -// impl From 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 { @@ -146,6 +155,7 @@ mod tests { assert_eq!( utf8_string.asn1(), &Asn1Type::Utf8String(Utf8String { + id: 0, string: Cow::Borrowed("thebesttvarynka"), }) ); diff --git a/crates/asn1-parser/src/tags/application.rs b/crates/asn1-parser/src/tags/application.rs index 74122ed1..5583f8b1 100644 --- a/crates/asn1-parser/src/tags/application.rs +++ b/crates/asn1-parser/src/tags/application.rs @@ -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}; diff --git a/crates/asn1-parser/tests/decode_encode.rs b/crates/asn1-parser/tests/decode_encode.rs index 81b48977..2af59785 100644 --- a/crates/asn1-parser/tests/decode_encode.rs +++ b/crates/asn1-parser/tests/decode_encode.rs @@ -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];