summaryrefslogtreecommitdiffstats
path: root/rust/vendor/der-parser-6.0.1/src/der
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
commita0aa2307322cd47bbf416810ac0292925e03be87 (patch)
tree37076262a026c4b48c8a0e84f44ff9187556ca35 /rust/vendor/der-parser-6.0.1/src/der
parentInitial commit. (diff)
downloadsuricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz
suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'rust/vendor/der-parser-6.0.1/src/der')
-rw-r--r--rust/vendor/der-parser-6.0.1/src/der/mod.rs88
-rw-r--r--rust/vendor/der-parser-6.0.1/src/der/multi.rs535
-rw-r--r--rust/vendor/der-parser-6.0.1/src/der/parser.rs668
-rw-r--r--rust/vendor/der-parser-6.0.1/src/der/tagged.rs263
4 files changed, 1554 insertions, 0 deletions
diff --git a/rust/vendor/der-parser-6.0.1/src/der/mod.rs b/rust/vendor/der-parser-6.0.1/src/der/mod.rs
new file mode 100644
index 0000000..bad3f23
--- /dev/null
+++ b/rust/vendor/der-parser-6.0.1/src/der/mod.rs
@@ -0,0 +1,88 @@
+//! Distinguished Encoding Rules (DER) objects and parser
+//!
+//! All functions in this crate use BER parsing functions (see the `ber` module)
+//! internally, adding constraints verification where needed.
+//!
+//! The objects [`BerObject`] and [`DerObject`] are the same (type alias): all BER functions,
+//! combinators and macros can be used, and provide additional tools for DER parsing.
+//! However, DER parsing functions enforce DER constraints in addition of their BER counterparts.
+//!
+//! # DER Objects
+//!
+//! The main object of this crate is [`DerObject`]. It contains a header (ber tag, class, and size)
+//! and content.
+//!
+//! To parse primitive objects (for ex. integers or strings), use the `parse_der_` set of
+//! functions.
+//!
+//! Constructed objects (like sequences, sets or tagged objects) require to use a combinator. This
+//! combinator takes a function or closure as input, and returns a new, specialized parser.
+//! See the [nom](https://github.com/geal/nom) parser combinator library for more details on
+//! combinators.
+//!
+//! # Examples
+//!
+//! Parse two DER integers:
+//!
+//! ```rust
+//! use der_parser::der::parse_der_integer;
+//!
+//! let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
+//! 0x02, 0x03, 0x01, 0x00, 0x00,
+//! ];
+//!
+//! let (rem, obj1) = parse_der_integer(&bytes).expect("parsing failed");
+//! let (rem, obj2) = parse_der_integer(&bytes).expect("parsing failed");
+//! ```
+//!
+//! Parse a BER sequence containing one integer and an octetstring:
+//!
+//! ```rust
+//! use der_parser::der::*;
+//!
+//! let bytes = [ 0x30, 0x0a,
+//! 0x02, 0x03, 0x01, 0x00, 0x01,
+//! 0x04, 0x03, 0x62, 0x61, 0x64,
+//! ];
+//!
+//! let (rem, seq) = parse_der_sequence_defined(|content| {
+//! let (rem, obj1) = parse_der_integer(content)?;
+//! let (rem, obj2) = parse_der_octetstring(rem)?;
+//! Ok((rem, vec![obj1, obj2]))
+//! })(&bytes)
+//! .expect("parsing failed");
+//! ```
+
+use crate::ber::{BerClass, BerObject, BerObjectContent, BerObjectHeader, BerTag};
+
+mod multi;
+mod parser;
+mod tagged;
+pub use crate::der::multi::*;
+pub use crate::der::parser::*;
+pub use crate::der::tagged::*;
+
+use alloc::boxed::Box;
+use alloc::vec::Vec;
+use core::convert::{Into, TryFrom};
+
+/// DER Object class of tag (same as `BerClass`)
+pub type DerClass = BerClass;
+
+/// DER tag (same as BER tag)
+pub type DerTag = BerTag;
+
+/// Representation of a DER-encoded (X.690) object
+///
+/// Note that a DER object is just a BER object, with additional constraints.
+pub type DerObject<'a> = BerObject<'a>;
+
+/// DER object header (identifier and length)
+///
+/// This is the same object as `BerObjectHeader`.
+pub type DerObjectHeader<'a> = BerObjectHeader<'a>;
+
+/// BER object content
+///
+/// This is the same object as `BerObjectContent`.
+pub type DerObjectContent<'a> = BerObjectContent<'a>;
diff --git a/rust/vendor/der-parser-6.0.1/src/der/multi.rs b/rust/vendor/der-parser-6.0.1/src/der/multi.rs
new file mode 100644
index 0000000..f4f22fa
--- /dev/null
+++ b/rust/vendor/der-parser-6.0.1/src/der/multi.rs
@@ -0,0 +1,535 @@
+use crate::ber::BerSize;
+use crate::der::*;
+use crate::error::*;
+use nom::bytes::streaming::take;
+use nom::combinator::{all_consuming, complete, cut, map};
+use nom::error::ParseError;
+use nom::multi::many0;
+use nom::{Err, IResult};
+
+/// Parse a SEQUENCE OF object
+///
+/// Given a subparser for a DER type, parse a sequence of identical objects.
+///
+/// ```rust
+/// # use der_parser::der::{parse_der_integer, parse_der_sequence_of, DerObject};
+/// # use der_parser::error::BerResult;
+/// #
+/// /// Read a SEQUENCE OF INTEGER
+/// fn parser(i:&[u8]) -> BerResult<DerObject> {
+/// parse_der_sequence_of(parse_der_integer)(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x30, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x02, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = DerObject::from_seq(vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_int_slice(b"\x01\x00\x00"),
+/// # ]);
+/// # assert_eq!(parser(&bytes), Ok((empty, expected)));
+/// let (rem, v) = parser(&bytes).expect("parsing failed");
+/// ```
+pub fn parse_der_sequence_of<'a, F>(f: F) -> impl FnMut(&'a [u8]) -> BerResult
+where
+ F: Fn(&'a [u8]) -> BerResult,
+{
+ map(parse_der_sequence_of_v(f), DerObject::from_seq)
+}
+
+/// Parse a SEQUENCE OF object (returning a vec)
+///
+/// Given a subparser for a DER type, parse a sequence of identical objects.
+///
+/// This differs from `parse_der_sequence_of` in the parse function and return type.
+///
+/// ```rust
+/// # use der_parser::der::{parse_der_integer, parse_der_sequence_of_v, DerObject};
+/// # use der_parser::error::BerResult;
+/// #
+/// /// Read a SEQUENCE OF INTEGER
+/// fn parser(i:&[u8]) -> BerResult<Vec<DerObject>> {
+/// parse_der_sequence_of_v(parse_der_integer)(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x30, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x02, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_int_slice(b"\x01\x00\x00"),
+/// # ];
+/// let (rem, v) = parser(&bytes).expect("parsing failed");
+/// # assert_eq!(v, expected);
+/// ```
+pub fn parse_der_sequence_of_v<'a, T, F, E>(
+ f: F,
+) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], Vec<T>, E>
+where
+ F: FnMut(&'a [u8]) -> IResult<&'a [u8], T, E>,
+ E: ParseError<&'a [u8]> + From<BerError>,
+{
+ let mut subparser = all_consuming(many0(complete(cut(f))));
+ parse_der_sequence_defined_g(move |data, _| subparser(data))
+}
+
+/// Parse a defined sequence of DER elements (function version)
+///
+/// Given a list of expected parsers, apply them to build a DER sequence and
+/// return the remaining bytes and the built object.
+///
+/// The remaining bytes point *after* the sequence: any bytes that are part of the sequence but not
+/// parsed are ignored.
+///
+/// The object header is not available to the parsing function, and the returned type is always a
+/// `DerObject`.
+/// For a generic version, see
+/// [`parse_der_sequence_defined_g`](fn.parse_der_sequence_defined_g.html).
+///
+/// # Examples
+///
+/// Parsing a sequence of identical types (same as `parse_der_sequence_of`):
+///
+/// ```rust
+/// # use der_parser::der::{parse_der_integer, parse_der_sequence_defined, DerObject};
+/// # use der_parser::error::BerResult;
+/// use nom::combinator::complete;
+/// use nom::multi::many1;
+///
+/// fn localparse_seq(i:&[u8]) -> BerResult {
+/// parse_der_sequence_defined(
+/// many1(complete(parse_der_integer))
+/// )(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x30, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x02, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = DerObject::from_seq(vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_int_slice(b"\x01\x00\x00"),
+/// # ]);
+/// # assert_eq!(localparse_seq(&bytes), Ok((empty, expected)));
+/// let (rem, v) = localparse_seq(&bytes).expect("parsing failed");
+/// ```
+///
+/// Parsing a defined sequence with different types:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// use nom::combinator::map;
+/// use nom::sequence::tuple;
+///
+/// /// Read a DER-encoded object:
+/// /// SEQUENCE {
+/// /// a INTEGER,
+/// /// b OCTETSTRING
+/// /// }
+/// fn localparse_seq(i:&[u8]) -> BerResult {
+/// parse_der_sequence_defined(
+/// // the nom `tuple` combinator returns a tuple, so we have to map it
+/// // to a list
+/// map(
+/// tuple((parse_der_integer, parse_der_octetstring)),
+/// |(a, b)| vec![a, b]
+/// )
+/// )(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x30, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x04, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = DerObject::from_seq(vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_obj(DerObjectContent::OctetString(b"\x01\x00\x00")),
+/// # ]);
+/// # assert_eq!(localparse_seq(&bytes), Ok((empty, expected)));
+/// let (rem, v) = localparse_seq(&bytes).expect("parsing failed");
+/// ```
+pub fn parse_der_sequence_defined<'a, F>(mut f: F) -> impl FnMut(&'a [u8]) -> BerResult
+where
+ F: FnMut(&'a [u8]) -> BerResult<Vec<DerObject>>,
+{
+ map(
+ parse_der_sequence_defined_g(move |data, _| f(data)),
+ DerObject::from_seq,
+ )
+}
+
+/// Parse a defined SEQUENCE object (generic function)
+///
+/// Given a parser for sequence content, apply it to build a DER sequence and
+/// return the remaining bytes and the built object.
+///
+/// The remaining bytes point *after* the sequence: any bytes that are part of the sequence but not
+/// parsed are ignored.
+///
+/// Unlike `parse_der_sequence_defined`, this function allows returning any object or error type,
+/// and also passes the object header to the callback.
+///
+/// # Examples
+///
+/// Parsing a defined sequence with different types:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// #
+/// # #[derive(Debug, PartialEq)]
+/// pub struct MyObject<'a> {
+/// a: u32,
+/// b: &'a [u8],
+/// }
+///
+/// /// Read a DER-encoded object:
+/// /// SEQUENCE {
+/// /// a INTEGER (0..4294967295),
+/// /// b OCTETSTRING
+/// /// }
+/// fn parse_myobject(i: &[u8]) -> BerResult<MyObject> {
+/// parse_der_sequence_defined_g(
+/// |i:&[u8], _| {
+/// let (i, a) = parse_der_u32(i)?;
+/// let (i, obj) = parse_der_octetstring(i)?;
+/// let b = obj.as_slice().unwrap();
+/// Ok((i, MyObject{ a, b }))
+/// }
+/// )(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x30, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x04, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = MyObject {
+/// # a: 0x010001,
+/// # b: &[01, 00, 00]
+/// # };
+/// # assert_eq!(parse_myobject(&bytes), Ok((empty, expected)));
+/// let (rem, v) = parse_myobject(&bytes).expect("parsing failed");
+/// ```
+pub fn parse_der_sequence_defined_g<'a, O, F, E>(
+ mut f: F,
+) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], O, E>
+where
+ F: FnMut(&'a [u8], DerObjectHeader<'a>) -> IResult<&'a [u8], O, E>,
+ E: ParseError<&'a [u8]> + From<BerError>,
+{
+ parse_der_container(move |i, hdr| {
+ if hdr.tag != DerTag::Sequence {
+ return Err(Err::Error(BerError::InvalidTag.into()));
+ }
+ f(i, hdr)
+ })
+}
+
+/// Parse a SET OF object
+///
+/// Given a subparser for a DER type, parse a set of identical objects.
+///
+/// ```rust
+/// # use der_parser::der::{parse_der_integer, parse_der_set_of, DerObject};
+/// # use der_parser::error::BerResult;
+/// #
+/// /// Read a SET OF INTEGER
+/// fn parser(i:&[u8]) -> BerResult<DerObject> {
+/// parse_der_set_of(parse_der_integer)(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x31, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x02, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = DerObject::from_set(vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_int_slice(b"\x01\x00\x00"),
+/// # ]);
+/// # assert_eq!(parser(&bytes), Ok((empty, expected)));
+/// let (rem, v) = parser(&bytes).expect("parsing failed");
+/// ```
+pub fn parse_der_set_of<'a, F>(f: F) -> impl FnMut(&'a [u8]) -> BerResult
+where
+ F: Fn(&'a [u8]) -> BerResult,
+{
+ map(parse_der_set_of_v(f), DerObject::from_set)
+}
+
+/// Parse a SET OF object (returning a vec)
+///
+/// Given a subparser for a DER type, parse a set of identical objects.
+///
+/// This differs from `parse_der_set_of` in the parse function and return type.
+///
+/// ```rust
+/// # use der_parser::der::{parse_der_integer, parse_der_set_of_v, DerObject};
+/// # use der_parser::error::BerResult;
+/// #
+/// /// Read a SET OF INTEGER
+/// fn parser(i:&[u8]) -> BerResult<Vec<DerObject>> {
+/// parse_der_set_of_v(parse_der_integer)(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x31, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x02, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_int_slice(b"\x01\x00\x00"),
+/// # ];
+/// let (rem, v) = parser(&bytes).expect("parsing failed");
+/// # assert_eq!(v, expected);
+/// ```
+pub fn parse_der_set_of_v<'a, T, F, E>(f: F) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], Vec<T>, E>
+where
+ F: FnMut(&'a [u8]) -> IResult<&'a [u8], T, E>,
+ E: ParseError<&'a [u8]> + From<BerError>,
+{
+ let mut subparser = all_consuming(many0(complete(cut(f))));
+ parse_der_set_defined_g(move |data, _| subparser(data))
+}
+
+/// Parse a defined set of DER elements (function version)
+///
+/// Given a list of expected parsers, apply them to build a DER set and
+/// return the remaining bytes and the built object.
+///
+/// The remaining bytes point *after* the set: any bytes that are part of the sequence but not
+/// parsed are ignored.
+/// The nom combinator `all_consuming` can be used to ensure all the content is parsed.
+///
+/// The object header is not available to the parsing function, and the returned type is always a
+/// `DerObject`.
+/// For a generic version, see [`parse_der_set_defined_g`](fn.parse_der_set_defined_g.html).
+///
+/// # Examples
+///
+/// Parsing a set of identical types (same as `parse_der_set_of`):
+///
+/// ```rust
+/// # use der_parser::der::{parse_der_integer, parse_der_set_defined, DerObject};
+/// # use der_parser::error::BerResult;
+/// use nom::combinator::complete;
+/// use nom::multi::many1;
+///
+/// fn localparse_seq(i:&[u8]) -> BerResult {
+/// parse_der_set_defined(
+/// many1(complete(parse_der_integer))
+/// )(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x31, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x02, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = DerObject::from_set(vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_int_slice(b"\x01\x00\x00"),
+/// # ]);
+/// # assert_eq!(localparse_seq(&bytes), Ok((empty, expected)));
+/// let (rem, v) = localparse_seq(&bytes).expect("parsing failed");
+/// ```
+///
+/// Parsing a defined set with different types:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// use nom::combinator::map;
+/// use nom::sequence::tuple;
+///
+/// /// Read a DER-encoded object:
+/// /// SET {
+/// /// a INTEGER,
+/// /// b OCTETSTRING
+/// /// }
+/// fn localparse_set(i:&[u8]) -> BerResult {
+/// parse_der_set_defined(
+/// // the nom `tuple` combinator returns a tuple, so we have to map it
+/// // to a list
+/// map(
+/// tuple((parse_der_integer, parse_der_octetstring)),
+/// |(a, b)| vec![a, b]
+/// )
+/// )(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x31, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x04, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = DerObject::from_set(vec![
+/// # DerObject::from_int_slice(b"\x01\x00\x01"),
+/// # DerObject::from_obj(DerObjectContent::OctetString(b"\x01\x00\x00")),
+/// # ]);
+/// # assert_eq!(localparse_set(&bytes), Ok((empty, expected)));
+/// let (rem, v) = localparse_set(&bytes).expect("parsing failed");
+/// ```
+pub fn parse_der_set_defined<'a, F>(mut f: F) -> impl FnMut(&'a [u8]) -> BerResult
+where
+ F: FnMut(&'a [u8]) -> BerResult<Vec<DerObject>>,
+{
+ map(
+ parse_der_set_defined_g(move |data, _| f(data)),
+ DerObject::from_set,
+ )
+}
+
+/// Parse a defined SET object (generic version)
+///
+/// Given a parser for set content, apply it to build a DER set and
+/// return the remaining bytes and the built object.
+///
+/// The remaining bytes point *after* the set: any bytes that are part of the sequence but not
+/// parsed are ignored.
+/// The nom combinator `all_consuming` can be used to ensure all the content is parsed.
+///
+/// Unlike `parse_der_set_defined`, this function allows returning any object or error type,
+/// and also passes the object header to the callback.
+///
+/// # Examples
+///
+/// Parsing a defined set with different types:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// #
+/// # #[derive(Debug, PartialEq)]
+/// pub struct MyObject<'a> {
+/// a: u32,
+/// b: &'a [u8],
+/// }
+///
+/// /// Read a DER-encoded object:
+/// /// SET {
+/// /// a INTEGER (0..4294967295),
+/// /// b OCTETSTRING
+/// /// }
+/// fn parse_myobject(i: &[u8]) -> BerResult<MyObject> {
+/// parse_der_set_defined_g(
+/// |i:&[u8], _| {
+/// let (i, a) = parse_der_u32(i)?;
+/// let (i, obj) = parse_der_octetstring(i)?;
+/// let b = obj.as_slice().unwrap();
+/// Ok((i, MyObject{ a, b }))
+/// }
+/// )(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x31, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x04, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = MyObject {
+/// # a: 0x010001,
+/// # b: &[01, 00, 00]
+/// # };
+/// # assert_eq!(parse_myobject(&bytes), Ok((empty, expected)));
+/// let (rem, v) = parse_myobject(&bytes).expect("parsing failed");
+/// ```
+pub fn parse_der_set_defined_g<'a, O, F, E>(
+ mut f: F,
+) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], O, E>
+where
+ F: FnMut(&'a [u8], DerObjectHeader<'a>) -> IResult<&'a [u8], O, E>,
+ E: ParseError<&'a [u8]> + From<BerError>,
+{
+ parse_der_container(move |i, hdr| {
+ if hdr.tag != DerTag::Set {
+ return Err(Err::Error(BerError::InvalidTag.into()));
+ }
+ f(i, hdr)
+ })
+}
+
+/// Parse a DER object and apply provided function to content
+///
+/// Given a parser for content, read DER object header and apply parser to
+/// return the remaining bytes and the parser result.
+///
+/// The remaining bytes point *after* the content: any bytes that are part of the content but not
+/// parsed are ignored.
+/// The nom combinator `all_consuming` can be used to ensure all the content is parsed.
+///
+/// This function is mostly intended for structured objects, but can be used for any valid DER
+/// object.
+///
+/// # Examples
+///
+/// Parsing a defined sequence with different types:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::{BerError, BerResult};
+/// #
+/// # #[derive(Debug, PartialEq)]
+/// pub struct MyObject<'a> {
+/// a: u32,
+/// b: &'a [u8],
+/// }
+///
+/// /// Read a DER-encoded object:
+/// /// SEQUENCE {
+/// /// a INTEGER (0..4294967295),
+/// /// b OCTETSTRING
+/// /// }
+/// fn parse_myobject(i: &[u8]) -> BerResult<MyObject> {
+/// parse_der_container(
+/// |i: &[u8], hdr: DerObjectHeader| {
+/// if hdr.tag != DerTag::Sequence {
+/// return Err(nom::Err::Error(BerError::BerTypeError.into()));
+/// }
+/// let (i, a) = parse_der_u32(i)?;
+/// let (i, obj) = parse_der_octetstring(i)?;
+/// let b = obj.as_slice().unwrap();
+/// Ok((i, MyObject{ a, b }))
+/// }
+/// )(i)
+/// }
+///
+/// # let empty = &b""[..];
+/// # let bytes = [ 0x30, 0x0a,
+/// # 0x02, 0x03, 0x01, 0x00, 0x01,
+/// # 0x04, 0x03, 0x01, 0x00, 0x00,
+/// # ];
+/// # let expected = MyObject {
+/// # a: 0x010001,
+/// # b: &[01, 00, 00]
+/// # };
+/// # assert_eq!(parse_myobject(&bytes), Ok((empty, expected)));
+/// let (rem, v) = parse_myobject(&bytes).expect("parsing failed");
+/// ```
+pub fn parse_der_container<'a, O, F, E>(mut f: F) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], O, E>
+where
+ F: FnMut(&'a [u8], DerObjectHeader<'a>) -> IResult<&'a [u8], O, E>,
+ E: ParseError<&'a [u8]> + From<BerError>,
+{
+ move |i: &[u8]| {
+ let (i, hdr) = der_read_element_header(i).map_err(nom::Err::convert)?;
+ // X.690 10.1: the definitive form of length encoding shall be used
+ let (i, data) = match hdr.len {
+ BerSize::Definite(len) => take(len)(i)?,
+ BerSize::Indefinite => {
+ return Err(Err::Error(BerError::DerConstraintFailed.into()));
+ }
+ };
+ let (_rest, v) = f(data, hdr)?;
+ Ok((i, v))
+ }
+}
diff --git a/rust/vendor/der-parser-6.0.1/src/der/parser.rs b/rust/vendor/der-parser-6.0.1/src/der/parser.rs
new file mode 100644
index 0000000..04b4b23
--- /dev/null
+++ b/rust/vendor/der-parser-6.0.1/src/der/parser.rs
@@ -0,0 +1,668 @@
+use crate::ber::*;
+use crate::der::*;
+use crate::error::*;
+use nom::bytes::streaming::take;
+use nom::number::streaming::be_u8;
+use nom::{Err, Needed};
+use rusticata_macros::custom_check;
+
+/// Parse DER object recursively
+///
+/// Return a tuple containing the remaining (unparsed) bytes and the DER Object, or an error.
+///
+/// *Note: this is the same as calling `parse_der_recursive` with `MAX_RECURSION`.
+///
+/// ### Example
+///
+/// ```
+/// use der_parser::der::{parse_der, DerTag};
+///
+/// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
+/// let (_, obj) = parse_der(bytes).expect("parsing failed");
+///
+/// assert_eq!(obj.header.tag, DerTag::Integer);
+/// ```
+#[inline]
+pub fn parse_der(i: &[u8]) -> DerResult {
+ parse_der_recursive(i, MAX_RECURSION)
+}
+
+/// Parse DER object recursively, specifying the maximum recursion depth
+///
+/// Return a tuple containing the remaining (unparsed) bytes and the DER Object, or an error.
+///
+/// ### Example
+///
+/// ```
+/// use der_parser::der::{parse_der_recursive, DerTag};
+///
+/// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
+/// let (_, obj) = parse_der_recursive(bytes, 1).expect("parsing failed");
+///
+/// assert_eq!(obj.header.tag, DerTag::Integer);
+/// ```
+pub fn parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult {
+ let (i, hdr) = der_read_element_header(i)?;
+ // safety check: length cannot be more than 2^32 bytes
+ if let BerSize::Definite(l) = hdr.len {
+ custom_check!(i, l > MAX_OBJECT_SIZE, BerError::InvalidLength)?;
+ }
+ der_read_element_content_recursive(i, hdr, max_depth)
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! der_constraint_fail_if(
+ ($slice:expr, $cond:expr) => (
+ {
+ if $cond {
+ return Err(::nom::Err::Error(BerError::DerConstraintFailed));
+ }
+ }
+ );
+);
+
+/// Parse a DER object, expecting a value with specified tag
+///
+/// The object is parsed recursively, with a maximum depth of `MAX_RECURSION`.
+///
+/// ### Example
+///
+/// ```
+/// use der_parser::der::{parse_der_with_tag, DerTag};
+///
+/// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
+/// let (_, obj) = parse_der_with_tag(bytes, DerTag::Integer).expect("parsing failed");
+///
+/// assert_eq!(obj.header.tag, DerTag::Integer);
+/// ```
+pub fn parse_der_with_tag<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> DerResult {
+ let tag = tag.into();
+ let (i, hdr) = der_read_element_header(i)?;
+ if hdr.tag != tag {
+ return Err(nom::Err::Error(BerError::InvalidTag));
+ }
+ let (i, content) =
+ der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), MAX_RECURSION)?;
+ Ok((i, DerObject::from_header_and_content(hdr, content)))
+}
+
+/// Read end of content marker
+#[inline]
+pub fn parse_der_endofcontent(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::EndOfContent)
+}
+
+/// Read a boolean value
+///
+/// The encoding of a boolean value shall be primitive. The contents octets shall consist of a
+/// single octet.
+///
+/// If the boolean value is FALSE, the octet shall be zero.
+/// If the boolean value is TRUE, the octet shall be one byte, and have all bits set to one (0xff).
+#[inline]
+pub fn parse_der_bool(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Boolean)
+}
+
+/// Read an integer value
+///
+/// The encoding of a boolean value shall be primitive. The contents octets shall consist of one or
+/// more octets.
+///
+/// To access the content, use the [`as_u64`](struct.BerObject.html#method.as_u64),
+/// [`as_u32`](struct.BerObject.html#method.as_u32),
+/// [`as_biguint`](struct.BerObject.html#method.as_biguint) or
+/// [`as_bigint`](struct.BerObject.html#method.as_bigint) methods.
+/// Remember that a BER integer has unlimited size, so these methods return `Result` or `Option`
+/// objects.
+///
+/// # Examples
+///
+/// ```rust
+/// # use der_parser::der::{parse_der_integer, DerObject, DerObjectContent};
+/// let empty = &b""[..];
+/// let bytes = [0x02, 0x03, 0x01, 0x00, 0x01];
+/// let expected = DerObject::from_obj(DerObjectContent::Integer(b"\x01\x00\x01"));
+/// assert_eq!(
+/// parse_der_integer(&bytes),
+/// Ok((empty, expected))
+/// );
+/// ```
+#[inline]
+pub fn parse_der_integer(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Integer)
+}
+
+/// Read an bitstring value
+///
+/// To access the content as plain bytes, you will have to
+/// interprete the resulting tuple which will contain in
+/// its first item the number of padding bits left at
+/// the end of the bit string, and in its second item
+/// a `BitStringObject` structure which will, in its sole
+/// structure field called `data`, contain a byte slice
+/// representing the value of the bit string which can
+/// be interpreted as a big-endian value with the padding
+/// bits on the right (as in ASN.1 raw BER or DER encoding).
+///
+/// To access the content as an integer, use the [`as_u64`](struct.BerObject.html#method.as_u64)
+/// or [`as_u32`](struct.BerObject.html#method.as_u32) methods.
+/// Remember that a BER bit string has unlimited size, so these methods return `Result` or `Option`
+/// objects.
+#[inline]
+pub fn parse_der_bitstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::BitString)
+}
+
+/// Read an octetstring value
+#[inline]
+pub fn parse_der_octetstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::OctetString)
+}
+
+/// Read a null value
+#[inline]
+pub fn parse_der_null(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Null)
+}
+
+/// Read an object identifier value
+#[inline]
+pub fn parse_der_oid(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Oid)
+}
+
+/// Read an enumerated value
+#[inline]
+pub fn parse_der_enum(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Enumerated)
+}
+
+/// Read a UTF-8 string value. The encoding is checked.
+#[inline]
+pub fn parse_der_utf8string(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Utf8String)
+}
+
+/// Read a relative object identifier value
+#[inline]
+pub fn parse_der_relative_oid(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::RelativeOid)
+}
+
+/// Parse a sequence of DER elements
+///
+/// Read a sequence of DER objects, without any constraint on the types.
+/// Sequence is parsed recursively, so if structured elements are found, they are parsed using the
+/// same function.
+///
+/// To read a specific sequence of objects (giving the expected types), use the
+/// [`parse_der_sequence_defined`](macro.parse_der_sequence_defined.html) macro.
+#[inline]
+pub fn parse_der_sequence(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Sequence)
+}
+
+/// Parse a set of DER elements
+///
+/// Read a set of DER objects, without any constraint on the types.
+/// Set is parsed recursively, so if structured elements are found, they are parsed using the
+/// same function.
+///
+/// To read a specific set of objects (giving the expected types), use the
+/// [`parse_der_set_defined`](macro.parse_der_set_defined.html) macro.
+#[inline]
+pub fn parse_der_set(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Set)
+}
+
+/// Read a numeric string value. The content is verified to
+/// contain only digits and spaces.
+#[inline]
+pub fn parse_der_numericstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::NumericString)
+}
+
+/// Read a printable string value. The content is verified to
+/// contain only the allowed characters.
+#[inline]
+pub fn visiblestring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::VisibleString)
+}
+
+/// Read a printable string value. The content is verified to
+/// contain only the allowed characters.
+#[inline]
+pub fn parse_der_printablestring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::PrintableString)
+}
+
+/// Read a T61 string value
+#[inline]
+pub fn parse_der_t61string(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::T61String)
+}
+
+/// Read a Videotex string value
+#[inline]
+pub fn parse_der_videotexstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::VideotexString)
+}
+
+/// Read an IA5 string value. The content is verified to be ASCII.
+#[inline]
+pub fn parse_der_ia5string(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::Ia5String)
+}
+
+/// Read an UTC time value
+#[inline]
+pub fn parse_der_utctime(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::UtcTime)
+}
+
+/// Read a Generalized time value
+#[inline]
+pub fn parse_der_generalizedtime(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::GeneralizedTime)
+}
+
+/// Read a ObjectDescriptor value
+#[inline]
+pub fn parse_der_objectdescriptor(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::ObjDescriptor)
+}
+
+/// Read a GraphicString value
+#[inline]
+pub fn parse_der_graphicstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::GraphicString)
+}
+
+/// Read a GeneralString value
+#[inline]
+pub fn parse_der_generalstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::GeneralString)
+}
+
+/// Read a BmpString value
+#[inline]
+pub fn parse_der_bmpstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::BmpString)
+}
+
+/// Read a UniversalString value
+#[inline]
+pub fn parse_der_universalstring(i: &[u8]) -> DerResult {
+ parse_der_with_tag(i, DerTag::UniversalString)
+}
+
+/// Parse an optional tagged object, applying function to get content
+///
+/// This function returns a `DerObject`, trying to read content as generic DER objects.
+/// If parsing failed, return an optional object containing `None`.
+///
+/// To support other return or error types, use
+/// [parse_der_tagged_explicit_g](fn.parse_der_tagged_explicit_g.html)
+///
+/// This function will never fail: if parsing content failed, the BER value `Optional(None)` is
+/// returned.
+#[inline]
+pub fn parse_der_explicit_optional<F>(i: &[u8], tag: DerTag, f: F) -> DerResult
+where
+ F: Fn(&[u8]) -> DerResult,
+{
+ parse_ber_explicit_optional(i, tag, f)
+}
+
+/// Parse an implicit tagged object, applying function to read content
+///
+/// Note: unlike explicit tagged functions, the callback must be a *content* parsing function,
+/// often based on the [`parse_der_content`](fn.parse_der_content.html) combinator.
+///
+/// The built object will use the original header (and tag), so the content may not match the tag
+/// value.
+///
+/// For a combinator version, see [parse_der_tagged_implicit](../ber/fn.parse_der_tagged_implicit.html).
+///
+/// For a generic version (different output and error types), see
+/// [parse_der_tagged_implicit_g](../ber/fn.parse_der_tagged_implicit_g.html).
+///
+/// # Examples
+///
+/// The following parses `[3] IMPLICIT INTEGER` into a `DerObject`:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::DerResult;
+/// #
+/// fn parse_int_implicit(i:&[u8]) -> DerResult {
+/// parse_der_implicit(
+/// i,
+/// 3,
+/// parse_der_content(DerTag::Integer),
+/// )
+/// }
+///
+/// # let bytes = &[0x83, 0x03, 0x01, 0x00, 0x01];
+/// let res = parse_int_implicit(bytes);
+/// # match res {
+/// # Ok((rem, content)) => {
+/// # assert!(rem.is_empty());
+/// # assert_eq!(content.as_u32(), Ok(0x10001));
+/// # },
+/// # _ => assert!(false)
+/// # }
+/// ```
+#[inline]
+pub fn parse_der_implicit<'a, Tag, F>(i: &'a [u8], tag: Tag, f: F) -> DerResult<'a>
+where
+ F: Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>>,
+ Tag: Into<DerTag>,
+{
+ parse_ber_implicit(i, tag, f)
+}
+
+/// Parse DER object and try to decode it as a 32-bits signed integer
+///
+/// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target
+/// integer type.
+#[inline]
+pub fn parse_der_i32(i: &[u8]) -> BerResult<i32> {
+ let (rem, der) = parse_der_integer(i)?;
+ let int = der.as_i32().map_err(nom::Err::Error)?;
+ Ok((rem, int))
+}
+
+/// Parse DER object and try to decode it as a 64-bits signed integer
+///
+/// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target
+/// integer type.
+#[inline]
+pub fn parse_der_i64(i: &[u8]) -> BerResult<i64> {
+ let (rem, der) = parse_der_integer(i)?;
+ let int = der.as_i64().map_err(nom::Err::Error)?;
+ Ok((rem, int))
+}
+
+/// Parse DER object and try to decode it as a 32-bits unsigned integer
+///
+/// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target
+/// integer type.
+pub fn parse_der_u32(i: &[u8]) -> BerResult<u32> {
+ let (rem, der) = parse_der_integer(i)?;
+ let int = der.as_u32().map_err(nom::Err::Error)?;
+ Ok((rem, int))
+}
+
+/// Parse DER object and try to decode it as a 64-bits unsigned integer
+///
+/// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target
+/// integer type.
+pub fn parse_der_u64(i: &[u8]) -> BerResult<u64> {
+ let (rem, der) = parse_der_integer(i)?;
+ let int = der.as_u64().map_err(nom::Err::Error)?;
+ Ok((rem, int))
+}
+
+/// Parse DER object and get content as slice
+#[inline]
+pub fn parse_der_slice<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> BerResult<&[u8]> {
+ let tag = tag.into();
+ parse_der_container(move |content, hdr| {
+ if hdr.tag != tag {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ Ok((&b""[..], content))
+ })(i)
+}
+
+/// Parse the next bytes as the content of a DER object (combinator, header reference)
+///
+/// Content type is *not* checked to match tag, caller is responsible of providing the correct tag
+///
+/// Caller is also responsible to check if parsing function consumed the expected number of
+/// bytes (`header.len`).
+///
+/// This function differs from [`parse_der_content2`](fn.parse_der_content2.html) because it passes
+/// the BER object header by reference (required for ex. by `parse_der_implicit`).
+///
+/// The arguments of the parse function are: `(input, ber_object_header, max_recursion)`.
+///
+/// Example: manually parsing header and content
+///
+/// ```
+/// # use der_parser::ber::MAX_RECURSION;
+/// # use der_parser::der::*;
+/// #
+/// # let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
+/// let (i, header) = der_read_element_header(bytes).expect("parsing failed");
+/// let (rem, content) = parse_der_content(header.tag)(i, &header, MAX_RECURSION)
+/// .expect("parsing failed");
+/// #
+/// # assert_eq!(header.tag, DerTag::Integer);
+/// ```
+pub fn parse_der_content<'a>(
+ tag: DerTag,
+) -> impl Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>> {
+ move |i: &[u8], hdr: &DerObjectHeader, max_recursion: usize| {
+ der_read_element_content_as(i, tag, hdr.len, hdr.is_constructed(), max_recursion)
+ }
+}
+
+/// Parse the next bytes as the content of a DER object (combinator, owned header)
+///
+/// Content type is *not* checked to match tag, caller is responsible of providing the correct tag
+///
+/// Caller is also responsible to check if parsing function consumed the expected number of
+/// bytes (`header.len`).
+///
+/// The arguments of the parse function are: `(input, ber_object_header, max_recursion)`.
+///
+/// This function differs from [`parse_der_content`](fn.parse_der_content.html) because it passes
+/// an owned BER object header (required for ex. by `parse_der_tagged_implicit_g`).
+///
+/// Example: manually parsing header and content
+///
+/// ```
+/// # use der_parser::ber::MAX_RECURSION;
+/// # use der_parser::der::*;
+/// #
+/// # let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
+/// let (i, header) = der_read_element_header(bytes).expect("parsing failed");
+/// # assert_eq!(header.tag, DerTag::Integer);
+/// let (rem, content) = parse_der_content2(header.tag)(i, header, MAX_RECURSION)
+/// .expect("parsing failed");
+/// ```
+pub fn parse_der_content2<'a>(
+ tag: DerTag,
+) -> impl Fn(&'a [u8], DerObjectHeader<'a>, usize) -> BerResult<'a, DerObjectContent<'a>> {
+ move |i: &[u8], hdr: DerObjectHeader, max_recursion: usize| {
+ der_read_element_content_as(i, tag, hdr.len, hdr.is_constructed(), max_recursion)
+ }
+}
+
+// --------- end of parse_der_xxx functions ----------
+
+/// Parse the next bytes as the content of a DER object.
+///
+/// Content type is *not* checked, caller is responsible of providing the correct tag
+pub fn der_read_element_content_as(
+ i: &[u8],
+ tag: DerTag,
+ len: BerSize,
+ constructed: bool,
+ max_depth: usize,
+) -> BerResult<DerObjectContent> {
+ // Indefinite lengths are not allowed in DER (X.690 section 10.1)
+ let l = len.primitive()?;
+ if i.len() < l {
+ return Err(Err::Incomplete(Needed::new(l)));
+ }
+ match tag {
+ DerTag::Boolean => {
+ custom_check!(i, l != 1, BerError::InvalidLength)?;
+ der_constraint_fail_if!(i, i[0] != 0 && i[0] != 0xff);
+ }
+ DerTag::BitString => {
+ der_constraint_fail_if!(i, constructed);
+ // exception: read and verify padding bits
+ return der_read_content_bitstring(i, l);
+ }
+ DerTag::Integer => {
+ // verify leading zeros
+ match i[..l] {
+ [] => return Err(nom::Err::Error(BerError::DerConstraintFailed)),
+ [0, 0, ..] => return Err(nom::Err::Error(BerError::DerConstraintFailed)),
+ [0, byte, ..] if byte < 0x80 => {
+ return Err(nom::Err::Error(BerError::DerConstraintFailed));
+ }
+ _ => (),
+ }
+ }
+ DerTag::NumericString
+ | DerTag::VisibleString
+ | DerTag::PrintableString
+ | DerTag::Ia5String
+ | DerTag::Utf8String
+ | DerTag::T61String
+ | DerTag::VideotexString
+ | DerTag::BmpString
+ | DerTag::UniversalString
+ | DerTag::ObjDescriptor
+ | DerTag::GraphicString
+ | DerTag::GeneralString => {
+ der_constraint_fail_if!(i, constructed);
+ }
+ DerTag::UtcTime | DerTag::GeneralizedTime => {
+ if l == 0 || i.get(l - 1).cloned() != Some(b'Z') {
+ return Err(Err::Error(BerError::DerConstraintFailed));
+ }
+ }
+ _ => (),
+ }
+ ber_read_element_content_as(i, tag, len, constructed, max_depth)
+}
+
+/// Parse DER object content recursively
+///
+/// *Note: an error is raised if recursion depth exceeds `MAX_RECURSION`.
+pub fn der_read_element_content<'a>(i: &'a [u8], hdr: DerObjectHeader<'a>) -> DerResult<'a> {
+ der_read_element_content_recursive(i, hdr, MAX_RECURSION)
+}
+
+fn der_read_element_content_recursive<'a>(
+ i: &'a [u8],
+ hdr: DerObjectHeader<'a>,
+ max_depth: usize,
+) -> DerResult<'a> {
+ match hdr.class {
+ BerClass::Universal => (),
+ BerClass::Private => {
+ let (rem, content) = ber_get_object_content(i, &hdr, max_depth)?;
+ let content = BerObjectContent::Private(hdr.clone(), content);
+ let obj = BerObject::from_header_and_content(hdr, content);
+ return Ok((rem, obj));
+ }
+ _ => {
+ let (i, content) = ber_get_object_content(i, &hdr, max_depth)?;
+ let content = DerObjectContent::Unknown(hdr.class, hdr.tag, content);
+ let obj = DerObject::from_header_and_content(hdr, content);
+ return Ok((i, obj));
+ }
+ }
+ match der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), max_depth) {
+ Ok((rem, content)) => Ok((rem, DerObject::from_header_and_content(hdr, content))),
+ Err(Err::Error(BerError::UnknownTag)) => {
+ let (rem, content) = ber_get_object_content(i, &hdr, max_depth)?;
+ let content = DerObjectContent::Unknown(hdr.class, hdr.tag, content);
+ let obj = DerObject::from_header_and_content(hdr, content);
+ Ok((rem, obj))
+ }
+ Err(e) => Err(e),
+ }
+}
+
+fn der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent> {
+ let (i, ignored_bits) = be_u8(i)?;
+ if ignored_bits > 7 {
+ return Err(Err::Error(BerError::DerConstraintFailed));
+ }
+ if len == 0 {
+ return Err(Err::Error(BerError::InvalidLength));
+ }
+ let (i, data) = take(len - 1)(i)?;
+ if len > 1 {
+ let mut last_byte = data[len - 2];
+ for _ in 0..ignored_bits as usize {
+ der_constraint_fail_if!(i, last_byte & 1 != 0);
+ last_byte >>= 1;
+ }
+ }
+ Ok((
+ i,
+ DerObjectContent::BitString(ignored_bits, BitStringObject { data }),
+ ))
+ // do_parse! {
+ // i,
+ // ignored_bits: be_u8 >>
+ // custom_check!(ignored_bits > 7, BerError::DerConstraintFailed) >>
+ // custom_check!(len == 0, BerError::InvalidLength) >>
+ // s: take!(len - 1) >>
+ // call!(|input| {
+ // if len > 1 {
+ // let mut last_byte = s[len-2];
+ // for _ in 0..ignored_bits as usize {
+ // der_constraint_fail_if!(i, last_byte & 1 != 0);
+ // last_byte >>= 1;
+ // }
+ // }
+ // Ok((input,()))
+ // }) >>
+ // ( DerObjectContent::BitString(ignored_bits,BitStringObject{ data:s }) )
+ // }
+}
+
+/// Read an object header (DER)
+pub fn der_read_element_header(i: &[u8]) -> BerResult<DerObjectHeader> {
+ let (i1, el) = parse_identifier(i)?;
+ let class = match DerClass::try_from(el.0) {
+ Ok(c) => c,
+ Err(_) => unreachable!(), // Cannot fail, we have read exactly 2 bits
+ };
+ let (i2, len) = parse_ber_length_byte(i1)?;
+ let (i3, len) = match (len.0, len.1) {
+ (0, l1) => {
+ // Short form: MSB is 0, the rest encodes the length (which can be 0) (8.1.3.4)
+ (i2, BerSize::Definite(usize::from(l1)))
+ }
+ (_, 0) => {
+ // Indefinite form is not allowed in DER (10.1)
+ return Err(::nom::Err::Error(BerError::DerConstraintFailed));
+ }
+ (_, l1) => {
+ // if len is 0xff -> error (8.1.3.5)
+ if l1 == 0b0111_1111 {
+ return Err(::nom::Err::Error(BerError::InvalidTag));
+ }
+ // DER(9.1) if len is 0 (indefinite form), obj must be constructed
+ der_constraint_fail_if!(&i[1..], len.1 == 0 && el.1 != 1);
+ let (i3, llen) = take(l1)(i2)?;
+ match bytes_to_u64(llen) {
+ Ok(l) => {
+ // DER: should have been encoded in short form (< 127)
+ der_constraint_fail_if!(i, l < 127);
+ let l =
+ usize::try_from(l).or(Err(::nom::Err::Error(BerError::InvalidLength)))?;
+ (i3, BerSize::Definite(l))
+ }
+ Err(_) => {
+ return Err(::nom::Err::Error(BerError::InvalidTag));
+ }
+ }
+ }
+ };
+ let hdr = DerObjectHeader::new(class, el.1, BerTag(el.2), len).with_raw_tag(Some(el.3));
+ Ok((i3, hdr))
+}
diff --git a/rust/vendor/der-parser-6.0.1/src/der/tagged.rs b/rust/vendor/der-parser-6.0.1/src/der/tagged.rs
new file mode 100644
index 0000000..c7d0fec
--- /dev/null
+++ b/rust/vendor/der-parser-6.0.1/src/der/tagged.rs
@@ -0,0 +1,263 @@
+use crate::ber::MAX_RECURSION;
+use crate::der::*;
+use crate::error::*;
+use nom::error::ParseError;
+use nom::{Err, IResult};
+
+/// Read a TAGGED EXPLICIT value (combinator)
+///
+/// The built object will use the outer header (and tag), and contains a `Tagged` object
+/// with class, value and content.
+///
+/// For a generic version (different output and error types), see
+/// [parse_der_tagged_explicit_g](fn.parse_der_tagged_explicit_g.html).
+///
+/// The following parses `[2] EXPLICIT INTEGER`:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// use nom::combinator::map_res;
+/// #
+/// fn parse_int_explicit(i:&[u8]) -> BerResult<u32> {
+/// map_res(
+/// parse_der_tagged_explicit(2, parse_der_integer),
+/// |x: DerObject| x.as_tagged()?.2.as_u32()
+/// )(i)
+/// }
+///
+/// # let bytes = &[0xa2, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01];
+/// let res = parse_int_explicit(bytes);
+/// # match res {
+/// # Ok((rem,val)) => {
+/// # assert!(rem.is_empty());
+/// # assert_eq!(val, 0x10001);
+/// # },
+/// # _ => assert!(false)
+/// # }
+/// ```
+pub fn parse_der_tagged_explicit<'a, Tag, F>(tag: Tag, f: F) -> impl FnMut(&'a [u8]) -> BerResult
+where
+ F: Fn(&'a [u8]) -> BerResult<DerObject>,
+ Tag: Into<DerTag>,
+{
+ let tag = tag.into();
+ parse_der_tagged_explicit_g(tag, move |content, hdr| {
+ let (rem, obj) = f(content)?;
+ let class = hdr.class;
+ let obj2 = DerObject::from_header_and_content(
+ hdr,
+ DerObjectContent::Tagged(class, tag, Box::new(obj)),
+ );
+ Ok((rem, obj2))
+ })
+}
+
+/// Read a TAGGED EXPLICIT value (generic version)
+///
+/// The following parses `[2] EXPLICIT INTEGER`:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// #
+/// fn parse_int_explicit(i:&[u8]) -> BerResult<u32> {
+/// parse_der_tagged_explicit_g(2, move |content, hdr| {
+/// let (rem, obj) = parse_der_integer(content)?;
+/// let value = obj.as_u32()?;
+/// Ok((rem, value))
+/// })(i)
+/// }
+///
+/// # let bytes = &[0xa2, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01];
+/// let res = parse_int_explicit(bytes);
+/// # match res {
+/// # Ok((rem,val)) => {
+/// # assert!(rem.is_empty());
+/// # assert_eq!(val, 0x10001);
+/// # },
+/// # _ => assert!(false)
+/// # }
+/// ```
+pub fn parse_der_tagged_explicit_g<'a, Tag, Output, F, E>(
+ tag: Tag,
+ f: F,
+) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], Output, E>
+where
+ F: Fn(&'a [u8], DerObjectHeader<'a>) -> IResult<&'a [u8], Output, E>,
+ E: ParseError<&'a [u8]> + From<BerError>,
+ Tag: Into<DerTag>,
+{
+ let tag = tag.into();
+ parse_der_container(move |i, hdr| {
+ if hdr.class == DerClass::Universal {
+ return Err(Err::Error(BerError::InvalidClass.into()));
+ }
+ if hdr.tag != tag {
+ return Err(Err::Error(BerError::InvalidTag.into()));
+ }
+ // X.690 8.14.2: if implicit tagging was not used, the encoding shall be constructed
+ if !hdr.is_constructed() {
+ return Err(Err::Error(BerError::ConstructExpected.into()));
+ }
+ f(i, hdr)
+ // trailing bytes are ignored
+ })
+}
+
+/// Read a TAGGED IMPLICIT value (combinator)
+///
+/// Parse a TAGGED IMPLICIT value, given the expected tag, and the content parsing function.
+///
+/// The built object will use the original header (and tag), so the content may not match the tag
+/// value.
+///
+/// For a generic version (different output and error types), see
+/// [parse_der_tagged_implicit_g](fn.parse_der_tagged_implicit_g.html).
+///
+/// # Examples
+///
+/// The following parses `[2] IMPLICIT INTEGER` into a `DerObject`:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// #
+/// fn parse_int_implicit(i:&[u8]) -> BerResult<DerObject> {
+/// parse_der_tagged_implicit(
+/// 2,
+/// parse_der_content(DerTag::Integer),
+/// )(i)
+/// }
+///
+/// # let bytes = &[0x82, 0x03, 0x01, 0x00, 0x01];
+/// let res = parse_int_implicit(bytes);
+/// # match res {
+/// # Ok((rem, content)) => {
+/// # assert!(rem.is_empty());
+/// # assert_eq!(content.as_u32(), Ok(0x10001));
+/// # },
+/// # _ => assert!(false)
+/// # }
+/// ```
+///
+/// The following parses `[2] IMPLICIT INTEGER` into an `u32`, raising an error if the integer is
+/// too large:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// use nom::combinator::map_res;
+/// #
+/// fn parse_int_implicit(i:&[u8]) -> BerResult<u32> {
+/// map_res(
+/// parse_der_tagged_implicit(
+/// 2,
+/// parse_der_content(DerTag::Integer),
+/// ),
+/// |x: DerObject| x.as_u32()
+/// )(i)
+/// }
+///
+/// # let bytes = &[0x82, 0x03, 0x01, 0x00, 0x01];
+/// let res = parse_int_implicit(bytes);
+/// # match res {
+/// # Ok((rem, val)) => {
+/// # assert!(rem.is_empty());
+/// # assert_eq!(val, 0x10001);
+/// # },
+/// # _ => assert!(false)
+/// # }
+/// ```
+pub fn parse_der_tagged_implicit<'a, Tag, F>(tag: Tag, f: F) -> impl FnMut(&'a [u8]) -> BerResult
+where
+ F: Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>>,
+ Tag: Into<DerTag>,
+{
+ let tag = tag.into();
+ parse_der_tagged_implicit_g(tag, move |i, hdr, depth| {
+ let (rem, content) = f(i, &hdr, depth)?;
+ // trailing bytes are ignored
+ let obj = DerObject::from_header_and_content(hdr, content);
+ Ok((rem, obj))
+ })
+}
+
+/// Read a TAGGED IMPLICIT value (generic version)
+///
+/// Parse a TAGGED IMPLICIT value, given the expected tag, and the content parsing function.
+///
+/// # Examples
+///
+/// The following parses `[1] IMPLICIT OCTETSTRING`, returning a `DerObject`:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// #
+/// fn parse_implicit_0_octetstring(i:&[u8]) -> BerResult<DerObjectContent> {
+/// parse_der_tagged_implicit_g(
+/// 2,
+/// parse_der_content2(DerTag::OctetString)
+/// )(i)
+/// }
+///
+/// # let bytes = &[0x02, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f];
+/// let res = parse_implicit_0_octetstring(bytes);
+/// # match res {
+/// # Ok((rem, val)) => {
+/// # assert!(rem.is_empty());
+/// # let s = val.as_slice().unwrap();
+/// # assert_eq!(s, b"hello");
+/// # },
+/// # _ => assert!(false)
+/// # }
+/// ```
+///
+/// The following parses `[2] IMPLICIT INTEGER` into an `u32`, raising an error if the integer is
+/// too large:
+///
+/// ```rust
+/// # use der_parser::der::*;
+/// # use der_parser::error::BerResult;
+/// #
+/// fn parse_int_implicit(i:&[u8]) -> BerResult<u32> {
+/// parse_der_tagged_implicit_g(
+/// 2,
+/// |content, hdr, depth| {
+/// let (rem, obj_content) = parse_der_content(DerTag::Integer)(content, &hdr, depth)?;
+/// let value = obj_content.as_u32()?;
+/// Ok((rem, value))
+/// }
+/// )(i)
+/// }
+///
+/// # let bytes = &[0x82, 0x03, 0x01, 0x00, 0x01];
+/// let res = parse_int_implicit(bytes);
+/// # match res {
+/// # Ok((rem, val)) => {
+/// # assert!(rem.is_empty());
+/// # assert_eq!(val, 0x10001);
+/// # },
+/// # _ => assert!(false)
+/// # }
+/// ```
+pub fn parse_der_tagged_implicit_g<'a, Tag, Output, F, E>(
+ tag: Tag,
+ f: F,
+) -> impl FnMut(&'a [u8]) -> IResult<&[u8], Output, E>
+where
+ F: Fn(&'a [u8], DerObjectHeader<'a>, usize) -> IResult<&'a [u8], Output, E>,
+ E: ParseError<&'a [u8]> + From<BerError>,
+ Tag: Into<DerTag>,
+{
+ let tag = tag.into();
+ parse_der_container(move |i, hdr| {
+ if hdr.tag != tag {
+ return Err(Err::Error(BerError::InvalidTag.into()));
+ }
+ // XXX MAX_RECURSION should not be used, it resets the depth counter
+ f(i, hdr, MAX_RECURSION)
+ // trailing bytes are ignored
+ })
+}