Skip to content

Commit

Permalink
feat(asn1-parser): implement Null type
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBestTvarynka committed Nov 19, 2023
1 parent 49ebb71 commit 69c87c5
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 4 deletions.
2 changes: 1 addition & 1 deletion crates/asn1-parser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ This `asn1` parser is aimed to parse input bytes and return an AST as the result

- [ ] [Integer](https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/integer.html)
- [X] [Boolean](https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/boolean.html)
- [ ] [Null](https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/null.html)
- [X] [Null](https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/null.html)
- [ ] [ObjectIdentifier](https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/object-identifier.html)
- [ ] [Real](https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/real.html)

Expand Down
13 changes: 11 additions & 2 deletions crates/asn1-parser/src/asn1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use core::ops::Range;
use crate::reader::Reader;
use crate::writer::Writer;
use crate::{
Asn1Decoder, Asn1Encoder, Asn1Entity, Asn1Result, BitString, Bool, Error, ExplicitTag, OctetString, Sequence, Tag,
Utf8String,
Asn1Decoder, Asn1Encoder, Asn1Entity, Asn1Result, BitString, Bool, Error, ExplicitTag, Null, OctetString, Sequence,
Tag, Utf8String,
};

#[derive(Debug, Clone, PartialEq, Eq)]
Expand All @@ -17,6 +17,7 @@ pub enum Asn1Type<'data> {
BitString(BitString<'data>),

Bool(Bool),
Null(Null),

ExplicitTag(ExplicitTag<'data>),
}
Expand All @@ -31,6 +32,7 @@ impl Asn1Type<'_> {
Asn1Type::Utf8String(u) => Asn1Type::Utf8String(u.to_owned()),
Asn1Type::BitString(b) => Asn1Type::BitString(b.to_owned()),
Asn1Type::Bool(b) => Asn1Type::Bool(b.clone()),
Asn1Type::Null(n) => Asn1Type::Null(n.clone()),
// Asn1Type::ExplicitTag(_) => todo!(),
_ => unimplemented!(),
}
Expand All @@ -46,6 +48,7 @@ impl Asn1Entity for Asn1Type<'_> {
Asn1Type::BitString(bit) => bit.tag(),
Asn1Type::Bool(boolean) => boolean.tag(),
Asn1Type::ExplicitTag(e) => e.tag(),
Asn1Type::Null(n) => n.tag(),
}
}
}
Expand All @@ -70,6 +73,8 @@ impl<'data> Asn1Decoder<'data> for Asn1Type<'data> {
Ok(Asn1Type::Bool(Bool::decode(reader)?))
} else if ExplicitTag::compare_tags(&tag) {
Ok(Asn1Type::ExplicitTag(ExplicitTag::decode(reader)?))
} else if Null::compare_tags(&tag) {
Ok(Asn1Type::Null(Null::decode(reader)?))
} else {
Err(Error::from("Invalid data"))
}
Expand All @@ -90,6 +95,8 @@ impl<'data> Asn1Decoder<'data> for Asn1Type<'data> {
Bool::decode_asn1(reader)
} else if ExplicitTag::compare_tags(&tag) {
ExplicitTag::decode_asn1(reader)
} else if Null::compare_tags(&tag) {
Null::decode_asn1(reader)
} else {
Err(Error::from("Invalid data"))
}
Expand All @@ -105,6 +112,7 @@ impl Asn1Encoder for Asn1Type<'_> {
Asn1Type::BitString(bit) => bit.needed_buf_size(),
Asn1Type::Bool(boolean) => boolean.needed_buf_size(),
Asn1Type::ExplicitTag(e) => e.needed_buf_size(),
Asn1Type::Null(n) => n.needed_buf_size(),
}
}

Expand All @@ -116,6 +124,7 @@ impl Asn1Encoder for Asn1Type<'_> {
Asn1Type::BitString(bit) => bit.encode(writer),
Asn1Type::Bool(boolean) => boolean.encode(writer),
Asn1Type::ExplicitTag(e) => e.encode(writer),
Asn1Type::Null(n) => n.encode(writer),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/asn1-parser/src/generic_types/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::reader::{read_data, Reader};
use crate::writer::Writer;
use crate::{Asn1, Asn1Decoder, Asn1Encoder, Asn1Entity, Asn1Result, Asn1Type, Error, Tag};

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Bool {
flag: bool,
}
Expand Down
2 changes: 2 additions & 0 deletions crates/asn1-parser/src/generic_types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod boolean;
mod null;

pub use boolean::Bool;
pub use null::Null;
74 changes: 74 additions & 0 deletions crates/asn1-parser/src/generic_types/null.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use alloc::borrow::Cow;
use alloc::boxed::Box;

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

#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Null;

impl Null {
pub const TAG: Tag = Tag(5);
}

impl Asn1Entity for Null {
fn tag(&self) -> Tag {
Self::TAG
}
}

impl<'data> Asn1Decoder<'data> for Null {
fn compare_tags(tag: &Tag) -> bool {
*tag == Self::TAG
}

fn decode(reader: &mut Reader<'data>) -> Asn1Result<Self> {
check_tag!(in: reader);

let (len, _len_range) = read_len(reader)?;

if len != 0 {
return Err(Error::from("Bool length must be equal to 0"));
}

Ok(Self)
}

fn decode_asn1(reader: &mut Reader<'data>) -> Asn1Result<Asn1<'data>> {
let tag_position = reader.position();
check_tag!(in: reader);

let (len, len_range) = read_len(reader)?;

if len != 0 {
return Err(Error::from("Bool length must be equal to 0"));
}

let (_, data_range) = read_data(reader, len)?;

Ok(Asn1 {
raw_data: RawAsn1EntityData {
raw_data: Cow::Borrowed(reader.data_in_range(tag_position..data_range.end)?),
tag: tag_position,
length: len_range,
data: data_range,
},
asn1_type: Box::new(Asn1Type::Null(Self)),
})
}
}

impl Asn1Encoder for Null {
fn needed_buf_size(&self) -> usize {
1 /* tag */ + 1 /* length (always zero) */
}

fn encode(&self, writer: &mut Writer) -> Asn1Result<()> {
writer.write_byte(Self::TAG.into())?;
write_len(0, writer)?;

Ok(())
}
}

0 comments on commit 69c87c5

Please sign in to comment.