lber_serde/
parse.rs

1use std::convert::TryFrom;
2
3use common::TagClass;
4use common::TagStructure;
5use structure::{StructureTag, PL};
6
7use nom;
8use nom::bits::streaming as bits;
9use nom::bytes::streaming::take;
10use nom::combinator::map_opt;
11use nom::error::{Error, ErrorKind, ParseError};
12use nom::number::streaming as number;
13use nom::sequence::tuple;
14use nom::{IResult, InputLength, Needed};
15
16fn class_bits(i: (&[u8], usize)) -> nom::IResult<(&[u8], usize), TagClass> {
17    map_opt(bits::take(2usize), TagClass::from_u8)(i)
18}
19
20fn pc_bit(i: (&[u8], usize)) -> nom::IResult<(&[u8], usize), TagStructure> {
21    map_opt(bits::take(1usize), TagStructure::from_u8)(i)
22}
23
24fn tagnr_bits(i: (&[u8], usize)) -> nom::IResult<(&[u8], usize), u64> {
25    bits::take(5usize)(i)
26}
27
28fn parse_type_header(i: &[u8]) -> nom::IResult<&[u8], (TagClass, TagStructure, u64)> {
29    nom::bits(tuple((class_bits, pc_bit, tagnr_bits)))(i)
30}
31
32fn parse_length(i: &[u8]) -> nom::IResult<&[u8], usize> {
33    let (i, len) = number::be_u8(i)?;
34    if len < 128 {
35        Ok((i, len as usize))
36    } else {
37        let len = len - 128;
38        let (i, b) = take(len)(i)?;
39        let (_, len) = parse_uint(b)?;
40        Ok((
41            i,
42            usize::try_from(len)
43                .map_err(|_| nom::Err::Failure(Error::from_error_kind(i, ErrorKind::TooLarge)))?,
44        ))
45    }
46}
47
48/// Extract an unsigned integer value from BER data.
49pub fn parse_uint(i: &[u8]) -> nom::IResult<&[u8], u64> {
50    Ok((i, i.iter().fold(0, |res, &byte| (res << 8) | byte as u64)))
51}
52
53/// Parse raw BER data into a serializable structure.
54pub fn parse_tag(i: &[u8]) -> nom::IResult<&[u8], StructureTag> {
55    let (mut i, ((class, structure, id), len)) = tuple((parse_type_header, parse_length))(i)?;
56
57    let pl: PL = match structure {
58        TagStructure::Primitive => {
59            let (j, content) = take(len)(i)?;
60            i = j;
61
62            PL::P(content.to_vec())
63        }
64        TagStructure::Constructed => {
65            let (j, mut content) = take(len)(i)?;
66            i = j;
67
68            let mut tv: Vec<StructureTag> = Vec::new();
69            while content.input_len() > 0 {
70                let (j, sub) = parse_tag(content)?;
71                content = j;
72                tv.push(sub);
73            }
74
75            PL::C(tv)
76        }
77    };
78
79    Ok((
80        i,
81        StructureTag {
82            class,
83            id,
84            payload: pl,
85        },
86    ))
87}
88
89pub struct Parser;
90
91impl Parser {
92    pub fn new() -> Self {
93        Self
94    }
95    pub fn parse<'a>(
96        &mut self,
97        input: &'a [u8],
98    ) -> IResult<&'a [u8], StructureTag, nom::error::Error<&'a [u8]>> {
99        if input.is_empty() {
100            return Err(nom::Err::Incomplete(Needed::Unknown));
101        };
102        parse_tag(input)
103    }
104}
105
106#[cfg(test)]
107mod test {
108    use super::*;
109    use common::TagClass;
110    use structure::{StructureTag, PL};
111
112    #[test]
113    fn test_primitive() {
114        let bytes: Vec<u8> = vec![2, 2, 255, 127];
115        let result_tag = StructureTag {
116            class: TagClass::Universal,
117            id: 2u64,
118            payload: PL::P(vec![255, 127]),
119        };
120        let rest_tag: Vec<u8> = vec![];
121
122        let tag = parse_tag(&bytes[..]);
123
124        assert_eq!(tag, Ok((&rest_tag[..], result_tag)));
125    }
126
127    #[test]
128    fn test_constructed() {
129        let bytes: Vec<u8> = vec![
130            48, 14, 12, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33,
131        ];
132        let result_tag = StructureTag {
133            class: TagClass::Universal,
134            id: 16u64,
135            payload: PL::C(vec![StructureTag {
136                class: TagClass::Universal,
137                id: 12u64,
138                payload: PL::P(vec![72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]),
139            }]),
140        };
141        let rest_tag: Vec<u8> = vec![];
142
143        let tag = parse_tag(&bytes[..]);
144
145        assert_eq!(tag, Ok((&rest_tag[..], result_tag)));
146    }
147
148    #[test]
149    fn test_long_length() {
150        let bytes: Vec<u8> = vec![
151            0x30, 0x82, 0x01, 0x01, 0x80, 0x0C, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E,
152            0x67, 0x54, 0x61, 0x67, 0x81, 0x81, 0xF0, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F,
153            0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67,
154            0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61,
155            0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A,
156            0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73,
157            0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41,
158            0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F,
159            0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67,
160            0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61,
161            0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A,
162            0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73,
163            0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41,
164            0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F,
165            0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67,
166            0x54, 0x61, 0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61,
167            0x67, 0x4A, 0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A,
168            0x75, 0x73, 0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67, 0x4A, 0x75, 0x73,
169            0x74, 0x41, 0x4C, 0x6F, 0x6E, 0x67, 0x54, 0x61, 0x67,
170        ];
171
172        let result_tag = StructureTag {
173            class: TagClass::Universal,
174            id: 16u64,
175            payload: PL::C(vec![
176                StructureTag {
177                    class: TagClass::Context,
178                    id: 0,
179                    payload: PL::P(vec![74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103]),
180                },
181                StructureTag {
182                    class: TagClass::Context,
183                    id: 1,
184                    payload: PL::P(vec![
185                        74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116,
186                        65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110,
187                        103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103,
188                        74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116,
189                        65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110,
190                        103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103,
191                        74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116,
192                        65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110,
193                        103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103,
194                        74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116,
195                        65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110,
196                        103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103,
197                        74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116,
198                        65, 76, 111, 110, 103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110,
199                        103, 84, 97, 103, 74, 117, 115, 116, 65, 76, 111, 110, 103, 84, 97, 103,
200                    ]),
201                },
202            ]),
203        };
204
205        let rest_tag = Vec::new();
206
207        let tag = parse_tag(&bytes[..]);
208        assert_eq!(tag, Ok((&rest_tag[..], result_tag)));
209    }
210}