blob: 6c8931e75e8f6f327fbd6fe861ec1a7bb6b82935 [file] [log] [blame] [edit]
use crate::ber::BerSize;
use crate::der::*;
use crate::error::*;
use nom::bytes::complete::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))
}
}