summaryrefslogtreecommitdiffstats
path: root/rust/vendor/der-parser-6.0.1/src/ber/print.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/vendor/der-parser-6.0.1/src/ber/print.rs')
-rw-r--r--rust/vendor/der-parser-6.0.1/src/ber/print.rs173
1 files changed, 173 insertions, 0 deletions
diff --git a/rust/vendor/der-parser-6.0.1/src/ber/print.rs b/rust/vendor/der-parser-6.0.1/src/ber/print.rs
new file mode 100644
index 0000000..e80eb5e
--- /dev/null
+++ b/rust/vendor/der-parser-6.0.1/src/ber/print.rs
@@ -0,0 +1,173 @@
+use crate::ber::BitStringObject;
+use crate::ber::{BerObject, BerObjectContent, BerTag};
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::fmt;
+use core::iter::FromIterator;
+use core::str;
+
+use rusticata_macros::debug;
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum PrettyPrinterFlag {
+ ShowHeader,
+}
+
+pub struct PrettyBer<'a> {
+ obj: &'a BerObject<'a>,
+ indent: usize,
+ inc: usize,
+
+ flags: Vec<PrettyPrinterFlag>,
+}
+
+impl<'a> BerObject<'a> {
+ pub fn as_pretty(&'a self, indent: usize, increment: usize) -> PrettyBer<'a> {
+ PrettyBer {
+ obj: self,
+ indent,
+ inc: increment,
+
+ flags: Vec::new(),
+ }
+ }
+}
+
+impl<'a> PrettyBer<'a> {
+ pub fn set_flag(&mut self, flag: PrettyPrinterFlag) {
+ if !self.flags.contains(&flag) {
+ self.flags.push(flag);
+ }
+ }
+
+ pub fn next_indent<'b>(&self, obj: &'b BerObject) -> PrettyBer<'b> {
+ PrettyBer {
+ obj,
+ indent: self.indent + self.inc,
+ inc: self.inc,
+ flags: self.flags.to_vec(),
+ }
+ }
+}
+
+impl<'a> fmt::Debug for PrettyBer<'a> {
+ #[rustfmt::skip]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.indent > 0 {
+ write!(f, "{:1$}", " ", self.indent)?;
+ };
+ if self.flags.contains(&PrettyPrinterFlag::ShowHeader) {
+ write!(f, "[c:{:?}, s:{}, t:{}] ", self.obj.header.class, self.obj.header.structured, self.obj.header.tag)?;
+ };
+ fn print_utf8_string_with_type(f: &mut fmt::Formatter, s: &[u8], ty: &str) -> fmt::Result {
+ match str::from_utf8(s) {
+ Ok(b) => writeln!(f, "{}(\"{}\")", ty, b),
+ Err(e) => writeln!(f, "{}({:?}) <error decoding utf8 string: {:?}>", ty, s, e),
+ }
+ }
+ fn print_utf16_string_with_type(f: &mut fmt::Formatter, s: &[u8], ty: &str) -> fmt::Result {
+ let chars: Vec<u16> = s
+ .chunks_exact(2)
+ .map(|a| u16::from_be_bytes([a[0], a[1]]))
+ .collect();
+
+ match String::from_utf16(&chars) {
+ Ok(b) => writeln!(f, "{}(\"{}\")", ty, b),
+ Err(e) => writeln!(f, "{}({:?}) <error decoding utf16 string: {:?}>", ty, s, e),
+ }
+ }
+ fn print_utf32_string_with_type(f: &mut fmt::Formatter, s: &[u8], ty: &str) -> fmt::Result {
+ let chars: Option<Vec<char>> = s
+ .chunks_exact(4)
+ .map(|a| core::char::from_u32(u32::from_be_bytes([a[0], a[1], a[2], a[3]])))
+ .collect();
+
+ match chars {
+ Some(b) => writeln!(f, "{}(\"{}\")", ty, String::from_iter(b)),
+ None => writeln!(f, "{}({:?}) <error decoding utf32 string>", ty, s),
+ }
+ }
+ match self.obj.content {
+ BerObjectContent::EndOfContent => writeln!(f, "EndOfContent"),
+ BerObjectContent::Boolean(b) => writeln!(f, "Boolean({:?})", b),
+ BerObjectContent::Integer(i) => writeln!(f, "Integer({:?})", debug::HexSlice(i)),
+ BerObjectContent::Enum(i) => writeln!(f, "Enum({})", i),
+ BerObjectContent::OID(ref v) => writeln!(f, "OID({:?})", v),
+ BerObjectContent::RelativeOID(ref v) => writeln!(f, "RelativeOID({:?})", v),
+ BerObjectContent::Null => writeln!(f, "Null"),
+ BerObjectContent::OctetString(v) => writeln!(f, "OctetString({:?})", debug::HexSlice(v)),
+ BerObjectContent::BitString(u,BitStringObject{data:v})
+ => writeln!(f, "BitString({},{:?})", u, debug::HexSlice(v)),
+ BerObjectContent::GeneralizedTime(s) => writeln!(f, "GeneralizedTime(\"{}\")", s),
+ BerObjectContent::UTCTime(s) => writeln!(f, "UTCTime(\"{}\")", s),
+ BerObjectContent::VisibleString(s) => writeln!(f, "VisibleString(\"{}\")", s),
+ BerObjectContent::PrintableString(s) => writeln!(f, "PrintableString(\"{}\")", s),
+ BerObjectContent::NumericString(s) => writeln!(f, "NumericString(\"{}\")", s),
+ BerObjectContent::UTF8String(s) => writeln!(f, "UTF8String(\"{}\")", s),
+ BerObjectContent::IA5String(s) => writeln!(f, "IA5String(\"{}\")", s),
+ BerObjectContent::T61String(v) => writeln!(f, "T61String({:?})", debug::HexSlice(v)),
+ BerObjectContent::VideotexString(v) => writeln!(f, "VideotexString({:?})", debug::HexSlice(v)),
+ BerObjectContent::BmpString(s) => print_utf16_string_with_type(f, s, "BmpString"),
+ BerObjectContent::UniversalString(s) => print_utf32_string_with_type(f, s, "UniversalString"),
+ BerObjectContent::ObjectDescriptor(s) => print_utf8_string_with_type(f, s, "ObjectDescriptor"),
+ BerObjectContent::GraphicString(s) => print_utf8_string_with_type(f, s, "GraphicString"),
+ BerObjectContent::GeneralString(s) => print_utf8_string_with_type(f, s, "GeneralString"),
+ BerObjectContent::Optional(ref o) => {
+ match o {
+ Some(obj) => writeln!(f, "OPTION {:?}", obj),
+ None => writeln!(f, "NONE"),
+ }
+ }
+ BerObjectContent::Private(ref hdr, bytes) => {
+ writeln!(f, "Private(c:{} s:{} t:{}): {:?}", hdr.class, hdr.structured, hdr.tag.0, debug::HexSlice(bytes))
+ },
+ BerObjectContent::Tagged(class, tag, ref obj) => {
+ writeln!(f, "ContextSpecific [{} {}] {{", class, tag)?;
+ write!(f, "{:?}", self.next_indent(obj))?;
+ if self.indent > 0 {
+ write!(f, "{:1$}", " ", self.indent)?;
+ };
+ writeln!(f, "}}")?;
+ Ok(())
+ },
+ BerObjectContent::Set(ref v) |
+ BerObjectContent::Sequence(ref v) => {
+ let ty = if self.obj.header.tag == BerTag::Sequence { "Sequence" } else { "Set" };
+ writeln!(f, "{}[", ty)?;
+ for o in v {
+ write!(f, "{:?}", self.next_indent(o))?;
+ };
+ if self.indent > 0 {
+ write!(f, "{:1$}", " ", self.indent)?;
+ };
+ writeln!(f, "]")?;
+ Ok(())
+ },
+ BerObjectContent::Unknown(class, tag,o) => writeln!(f, "Unknown({:?},{:?},{:x?})", class, tag, o),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::PrettyPrinterFlag;
+ use crate::ber::*;
+
+ #[test]
+ fn test_pretty_print() {
+ let d = BerObject::from_obj(BerObjectContent::Sequence(vec![
+ BerObject::from_int_slice(b"\x01\x00\x01"),
+ BerObject::from_int_slice(b"\x01\x00\x01"),
+ BerObject::from_obj(BerObjectContent::Set(vec![
+ BerObject::from_int_slice(b"\x01"),
+ BerObject::from_int_slice(b"\x02"),
+ ])),
+ ]));
+
+ println!("{:?}", d.as_pretty(0, 2));
+
+ let mut pp = d.as_pretty(0, 4);
+ pp.set_flag(PrettyPrinterFlag::ShowHeader);
+ println!("{:?}", pp);
+ }
+}