1 use crate::ber::*;
2 use crate::error::*;
3 use nom::bytes::complete::take;
4 use nom::{Err, IResult};
5 
6 /// Read a TAGGED EXPLICIT value (function version)
7 ///
8 /// The following parses `[2] EXPLICIT INTEGER`:
9 ///
10 /// ```rust
11 /// # use der_parser::ber::*;
12 /// # use der_parser::error::BerResult;
13 /// use nom::combinator::map_res;
14 /// #
15 /// fn parse_int_explicit(i:&[u8]) -> BerResult<u32> {
16 ///     parse_ber_tagged_explicit(
17 ///         2,
18 ///         parse_ber_u32
19 ///     )(i)
20 /// }
21 ///
22 /// # let bytes = &[0xa2, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01];
23 /// let res = parse_int_explicit(bytes);
24 /// # match res {
25 /// #     Ok((rem,val)) => {
26 /// #         assert!(rem.is_empty());
27 /// #         assert_eq!(val, 0x10001);
28 /// #     },
29 /// #     _ => assert!(false)
30 /// # }
31 /// ```
parse_ber_tagged_explicit<'a, T, F, E>( tag: u32, f: F, ) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], T, E> where F: Fn(&'a [u8]) -> IResult<&'a [u8], T, E>, E: nom::error::ParseError<&'a [u8]> + From<BerError>,32 pub fn parse_ber_tagged_explicit<'a, T, F, E>(
33     tag: u32,
34     f: F,
35 ) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], T, E>
36 where
37     F: Fn(&'a [u8]) -> IResult<&'a [u8], T, E>,
38     E: nom::error::ParseError<&'a [u8]> + From<BerError>,
39 {
40     move |i: &[u8]| {
41         let (i, hdr) = ber_read_element_header(i).map_err(nom::Err::convert)?;
42         if hdr.tag.0 != tag {
43             return Err(Err::Error(BerError::InvalidTag.into()));
44         }
45         let (i, data) = take(hdr.len as usize)(i)?;
46         let (_rest, item) = f(data)?;
47         Ok((i, item))
48     }
49 }
50 
51 /// Read a TAGGED IMPLICIT value (function version)
52 ///
53 /// The following parses `[2] IMPLICIT INTEGER`:
54 ///
55 /// ```rust
56 /// # use der_parser::ber::*;
57 /// # use der_parser::error::BerResult;
58 /// use nom::combinator::map_res;
59 /// #
60 /// fn parse_int_implicit(i:&[u8]) -> BerResult<u32> {
61 ///     map_res(
62 ///         parse_ber_tagged_implicit(
63 ///             2,
64 ///             parse_ber_content(BerTag::Integer),
65 ///         ),
66 ///         |x: BerObjectContent| x.as_u32()
67 ///     )(i)
68 /// }
69 ///
70 /// # let bytes = &[0x82, 0x03, 0x01, 0x00, 0x01];
71 /// let res = parse_int_implicit(bytes);
72 /// # match res {
73 /// #     Ok((rem,val)) => {
74 /// #         assert!(rem.is_empty());
75 /// #         assert_eq!(val, 0x10001);
76 /// #     },
77 /// #     _ => assert!(false)
78 /// # }
79 /// ```
parse_ber_tagged_implicit<'a, T, F, E>( tag: u32, f: F, ) -> impl Fn(&'a [u8]) -> IResult<&[u8], T, E> where F: Fn(&'a [u8], &'_ BerObjectHeader, usize) -> IResult<&'a [u8], T, E>, E: nom::error::ParseError<&'a [u8]> + From<BerError>,80 pub fn parse_ber_tagged_implicit<'a, T, F, E>(
81     tag: u32,
82     f: F,
83 ) -> impl Fn(&'a [u8]) -> IResult<&[u8], T, E>
84 where
85     F: Fn(&'a [u8], &'_ BerObjectHeader, usize) -> IResult<&'a [u8], T, E>,
86     E: nom::error::ParseError<&'a [u8]> + From<BerError>,
87 {
88     move |i: &[u8]| {
89         let (i, hdr) = ber_read_element_header(i).map_err(nom::Err::convert)?;
90         if hdr.tag.0 != tag {
91             return Err(Err::Error(BerError::InvalidTag.into()));
92         }
93         let (i, data) = take(hdr.len as usize)(i)?;
94         let (_rest, item) = f(data, &hdr, MAX_RECURSION)?;
95         // XXX DER: check that _rest.is_empty()?
96         Ok((i, item))
97     }
98 }
99