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
48pub 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
53pub 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}