/rust/registry/src/index.crates.io-1949cf8c6b5b557f/der-parser-9.0.0/src/der/parser.rs
Line | Count | Source |
1 | | use crate::ber::*; |
2 | | use crate::der::*; |
3 | | use crate::der_constraint_fail_if; |
4 | | use crate::error::*; |
5 | | use alloc::borrow::ToOwned; |
6 | | use asn1_rs::{Any, FromDer, Tag}; |
7 | | use nom::bytes::streaming::take; |
8 | | use nom::number::streaming::be_u8; |
9 | | use nom::{Err, Needed}; |
10 | | use rusticata_macros::custom_check; |
11 | | |
12 | | /// Parse DER object recursively |
13 | | /// |
14 | | /// Return a tuple containing the remaining (unparsed) bytes and the DER Object, or an error. |
15 | | /// |
16 | | /// *Note: this is the same as calling `parse_der_recursive` with `MAX_RECURSION`. |
17 | | /// |
18 | | /// ### Example |
19 | | /// |
20 | | /// ``` |
21 | | /// use der_parser::der::{parse_der, Tag}; |
22 | | /// |
23 | | /// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01]; |
24 | | /// let (_, obj) = parse_der(bytes).expect("parsing failed"); |
25 | | /// |
26 | | /// assert_eq!(obj.header.tag(), Tag::Integer); |
27 | | /// ``` |
28 | | #[inline] |
29 | 362k | pub fn parse_der(i: &[u8]) -> DerResult { |
30 | 362k | parse_der_recursive(i, MAX_RECURSION) |
31 | 362k | } der_parser::der::parser::parse_der Line | Count | Source | 29 | 144k | pub fn parse_der(i: &[u8]) -> DerResult { | 30 | 144k | parse_der_recursive(i, MAX_RECURSION) | 31 | 144k | } |
der_parser::der::parser::parse_der Line | Count | Source | 29 | 218k | pub fn parse_der(i: &[u8]) -> DerResult { | 30 | 218k | parse_der_recursive(i, MAX_RECURSION) | 31 | 218k | } |
|
32 | | |
33 | | /// Parse DER object recursively, specifying the maximum recursion depth |
34 | | /// |
35 | | /// Return a tuple containing the remaining (unparsed) bytes and the DER Object, or an error. |
36 | | /// |
37 | | /// ### Example |
38 | | /// |
39 | | /// ``` |
40 | | /// use der_parser::der::{parse_der_recursive, Tag}; |
41 | | /// |
42 | | /// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01]; |
43 | | /// let (_, obj) = parse_der_recursive(bytes, 1).expect("parsing failed"); |
44 | | /// |
45 | | /// assert_eq!(obj.header.tag(), Tag::Integer); |
46 | | /// ``` |
47 | 362k | pub fn parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult { |
48 | 362k | let (i, hdr) = der_read_element_header(i)?; |
49 | | // safety check: length cannot be more than 2^32 bytes |
50 | 316k | if let Length::Definite(l) = hdr.length() { |
51 | 316k | custom_check!(i, l > MAX_OBJECT_SIZE, BerError::InvalidLength)?; |
52 | 0 | } |
53 | 314k | der_read_element_content_recursive(i, hdr, max_depth) |
54 | 362k | } der_parser::der::parser::parse_der_recursive Line | Count | Source | 47 | 144k | pub fn parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult { | 48 | 144k | let (i, hdr) = der_read_element_header(i)?; | 49 | | // safety check: length cannot be more than 2^32 bytes | 50 | 121k | if let Length::Definite(l) = hdr.length() { | 51 | 121k | custom_check!(i, l > MAX_OBJECT_SIZE, BerError::InvalidLength)?; | 52 | 0 | } | 53 | 120k | der_read_element_content_recursive(i, hdr, max_depth) | 54 | 144k | } |
der_parser::der::parser::parse_der_recursive Line | Count | Source | 47 | 218k | pub fn parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult { | 48 | 218k | let (i, hdr) = der_read_element_header(i)?; | 49 | | // safety check: length cannot be more than 2^32 bytes | 50 | 195k | if let Length::Definite(l) = hdr.length() { | 51 | 195k | custom_check!(i, l > MAX_OBJECT_SIZE, BerError::InvalidLength)?; | 52 | 0 | } | 53 | 194k | der_read_element_content_recursive(i, hdr, max_depth) | 54 | 218k | } |
|
55 | | |
56 | | /// Parse a DER object, expecting a value with specified tag |
57 | | /// |
58 | | /// The object is parsed recursively, with a maximum depth of `MAX_RECURSION`. |
59 | | /// |
60 | | /// ### Example |
61 | | /// |
62 | | /// ``` |
63 | | /// use der_parser::der::{parse_der_with_tag, Tag}; |
64 | | /// |
65 | | /// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01]; |
66 | | /// let (_, obj) = parse_der_with_tag(bytes, Tag::Integer).expect("parsing failed"); |
67 | | /// |
68 | | /// assert_eq!(obj.header.tag(), Tag::Integer); |
69 | | /// ``` |
70 | 413k | pub fn parse_der_with_tag<T: Into<Tag>>(i: &[u8], tag: T) -> DerResult { |
71 | 413k | let tag = tag.into(); |
72 | 413k | let (i, hdr) = der_read_element_header(i)?; |
73 | 385k | hdr.assert_tag(tag)?; |
74 | 351k | let (i, content) = der_read_element_content_as( |
75 | 351k | i, |
76 | 351k | hdr.tag(), |
77 | 351k | hdr.length(), |
78 | 351k | hdr.is_constructed(), |
79 | | MAX_RECURSION, |
80 | 272k | )?; |
81 | 78.5k | Ok((i, DerObject::from_header_and_content(hdr, content))) |
82 | 413k | } der_parser::der::parser::parse_der_with_tag::<asn1_rs::tag::Tag> Line | Count | Source | 70 | 202k | pub fn parse_der_with_tag<T: Into<Tag>>(i: &[u8], tag: T) -> DerResult { | 71 | 202k | let tag = tag.into(); | 72 | 202k | let (i, hdr) = der_read_element_header(i)?; | 73 | 187k | hdr.assert_tag(tag)?; | 74 | 179k | let (i, content) = der_read_element_content_as( | 75 | 179k | i, | 76 | 179k | hdr.tag(), | 77 | 179k | hdr.length(), | 78 | 179k | hdr.is_constructed(), | 79 | | MAX_RECURSION, | 80 | 145k | )?; | 81 | 34.2k | Ok((i, DerObject::from_header_and_content(hdr, content))) | 82 | 202k | } |
Unexecuted instantiation: der_parser::der::parser::parse_der_with_tag::<asn1_rs::tag::Tag> Unexecuted instantiation: der_parser::der::parser::parse_der_with_tag::<_> der_parser::der::parser::parse_der_with_tag::<asn1_rs::tag::Tag> Line | Count | Source | 70 | 206k | pub fn parse_der_with_tag<T: Into<Tag>>(i: &[u8], tag: T) -> DerResult { | 71 | 206k | let tag = tag.into(); | 72 | 206k | let (i, hdr) = der_read_element_header(i)?; | 73 | 193k | hdr.assert_tag(tag)?; | 74 | 167k | let (i, content) = der_read_element_content_as( | 75 | 167k | i, | 76 | 167k | hdr.tag(), | 77 | 167k | hdr.length(), | 78 | 167k | hdr.is_constructed(), | 79 | | MAX_RECURSION, | 80 | 127k | )?; | 81 | 40.2k | Ok((i, DerObject::from_header_and_content(hdr, content))) | 82 | 206k | } |
der_parser::der::parser::parse_der_with_tag::<asn1_rs::tag::Tag> Line | Count | Source | 70 | 3.98k | pub fn parse_der_with_tag<T: Into<Tag>>(i: &[u8], tag: T) -> DerResult { | 71 | 3.98k | let tag = tag.into(); | 72 | 3.98k | let (i, hdr) = der_read_element_header(i)?; | 73 | 3.98k | hdr.assert_tag(tag)?; | 74 | 3.97k | let (i, content) = der_read_element_content_as( | 75 | 3.97k | i, | 76 | 3.97k | hdr.tag(), | 77 | 3.97k | hdr.length(), | 78 | 3.97k | hdr.is_constructed(), | 79 | | MAX_RECURSION, | 80 | 8 | )?; | 81 | 3.97k | Ok((i, DerObject::from_header_and_content(hdr, content))) | 82 | 3.98k | } |
Unexecuted instantiation: der_parser::der::parser::parse_der_with_tag::<_> |
83 | | |
84 | | /// Read end of content marker |
85 | | #[inline] |
86 | 0 | pub fn parse_der_endofcontent(i: &[u8]) -> DerResult { |
87 | 0 | parse_der_with_tag(i, Tag::EndOfContent) |
88 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_endofcontent Unexecuted instantiation: der_parser::der::parser::parse_der_endofcontent |
89 | | |
90 | | /// Read a boolean value |
91 | | /// |
92 | | /// The encoding of a boolean value shall be primitive. The contents octets shall consist of a |
93 | | /// single octet. |
94 | | /// |
95 | | /// If the boolean value is FALSE, the octet shall be zero. |
96 | | /// If the boolean value is TRUE, the octet shall be one byte, and have all bits set to one (0xff). |
97 | | #[inline] |
98 | 0 | pub fn parse_der_bool(i: &[u8]) -> DerResult { |
99 | 0 | parse_der_with_tag(i, Tag::Boolean) |
100 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_bool Unexecuted instantiation: der_parser::der::parser::parse_der_bool |
101 | | |
102 | | /// Read an integer value |
103 | | /// |
104 | | /// The encoding of a boolean value shall be primitive. The contents octets shall consist of one or |
105 | | /// more octets. |
106 | | /// |
107 | | /// To access the content, use the [`as_u64`](struct.BerObject.html#method.as_u64), |
108 | | /// [`as_u32`](struct.BerObject.html#method.as_u32), |
109 | | /// [`as_biguint`](struct.BerObject.html#method.as_biguint) or |
110 | | /// [`as_bigint`](struct.BerObject.html#method.as_bigint) methods. |
111 | | /// Remember that a BER integer has unlimited size, so these methods return `Result` or `Option` |
112 | | /// objects. |
113 | | /// |
114 | | /// # Examples |
115 | | /// |
116 | | /// ```rust |
117 | | /// # use der_parser::der::{parse_der_integer, DerObject, DerObjectContent}; |
118 | | /// let empty = &b""[..]; |
119 | | /// let bytes = [0x02, 0x03, 0x01, 0x00, 0x01]; |
120 | | /// let expected = DerObject::from_obj(DerObjectContent::Integer(b"\x01\x00\x01")); |
121 | | /// assert_eq!( |
122 | | /// parse_der_integer(&bytes), |
123 | | /// Ok((empty, expected)) |
124 | | /// ); |
125 | | /// ``` |
126 | | #[inline] |
127 | 0 | pub fn parse_der_integer(i: &[u8]) -> DerResult { |
128 | 0 | parse_der_with_tag(i, Tag::Integer) |
129 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_integer Unexecuted instantiation: der_parser::der::parser::parse_der_integer |
130 | | |
131 | | /// Read an bitstring value |
132 | | /// |
133 | | /// To access the content as plain bytes, you will have to |
134 | | /// interprete the resulting tuple which will contain in |
135 | | /// its first item the number of padding bits left at |
136 | | /// the end of the bit string, and in its second item |
137 | | /// a `BitStringObject` structure which will, in its sole |
138 | | /// structure field called `data`, contain a byte slice |
139 | | /// representing the value of the bit string which can |
140 | | /// be interpreted as a big-endian value with the padding |
141 | | /// bits on the right (as in ASN.1 raw BER or DER encoding). |
142 | | /// |
143 | | /// To access the content as an integer, use the [`as_u64`](struct.BerObject.html#method.as_u64) |
144 | | /// or [`as_u32`](struct.BerObject.html#method.as_u32) methods. |
145 | | /// Remember that a BER bit string has unlimited size, so these methods return `Result` or `Option` |
146 | | /// objects. |
147 | | #[inline] |
148 | 1.86k | pub fn parse_der_bitstring(i: &[u8]) -> DerResult { |
149 | 1.86k | parse_der_with_tag(i, Tag::BitString) |
150 | 1.86k | } Unexecuted instantiation: der_parser::der::parser::parse_der_bitstring der_parser::der::parser::parse_der_bitstring Line | Count | Source | 148 | 1.86k | pub fn parse_der_bitstring(i: &[u8]) -> DerResult { | 149 | 1.86k | parse_der_with_tag(i, Tag::BitString) | 150 | 1.86k | } |
|
151 | | |
152 | | /// Read an octetstring value |
153 | | #[inline] |
154 | 0 | pub fn parse_der_octetstring(i: &[u8]) -> DerResult { |
155 | 0 | parse_der_with_tag(i, Tag::OctetString) |
156 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_octetstring Unexecuted instantiation: der_parser::der::parser::parse_der_octetstring |
157 | | |
158 | | /// Read a null value |
159 | | #[inline] |
160 | 0 | pub fn parse_der_null(i: &[u8]) -> DerResult { |
161 | 0 | parse_der_with_tag(i, Tag::Null) |
162 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_null Unexecuted instantiation: der_parser::der::parser::parse_der_null |
163 | | |
164 | | /// Read an object identifier value |
165 | | #[inline] |
166 | 111k | pub fn parse_der_oid(i: &[u8]) -> DerResult { |
167 | 111k | parse_der_with_tag(i, Tag::Oid) |
168 | 111k | } der_parser::der::parser::parse_der_oid Line | Count | Source | 166 | 47.3k | pub fn parse_der_oid(i: &[u8]) -> DerResult { | 167 | 47.3k | parse_der_with_tag(i, Tag::Oid) | 168 | 47.3k | } |
der_parser::der::parser::parse_der_oid Line | Count | Source | 166 | 64.4k | pub fn parse_der_oid(i: &[u8]) -> DerResult { | 167 | 64.4k | parse_der_with_tag(i, Tag::Oid) | 168 | 64.4k | } |
|
169 | | |
170 | | /// Read an enumerated value |
171 | | #[inline] |
172 | 0 | pub fn parse_der_enum(i: &[u8]) -> DerResult { |
173 | 0 | parse_der_with_tag(i, Tag::Enumerated) |
174 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_enum Unexecuted instantiation: der_parser::der::parser::parse_der_enum |
175 | | |
176 | | /// Read a UTF-8 string value. The encoding is checked. |
177 | | #[inline] |
178 | 0 | pub fn parse_der_utf8string(i: &[u8]) -> DerResult { |
179 | 0 | parse_der_with_tag(i, Tag::Utf8String) |
180 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_utf8string Unexecuted instantiation: der_parser::der::parser::parse_der_utf8string |
181 | | |
182 | | /// Read a relative object identifier value |
183 | | #[inline] |
184 | 0 | pub fn parse_der_relative_oid(i: &[u8]) -> DerResult { |
185 | 0 | parse_der_with_tag(i, Tag::RelativeOid) |
186 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_relative_oid Unexecuted instantiation: der_parser::der::parser::parse_der_relative_oid |
187 | | |
188 | | /// Parse a sequence of DER elements |
189 | | /// |
190 | | /// Read a sequence of DER objects, without any constraint on the types. |
191 | | /// Sequence is parsed recursively, so if constructed elements are found, they are parsed using the |
192 | | /// same function. |
193 | | /// |
194 | | /// To read a specific sequence of objects (giving the expected types), use the |
195 | | /// [`parse_der_sequence_defined`](macro.parse_der_sequence_defined.html) macro. |
196 | | #[inline] |
197 | 300k | pub fn parse_der_sequence(i: &[u8]) -> DerResult { |
198 | 300k | parse_der_with_tag(i, Tag::Sequence) |
199 | 300k | } der_parser::der::parser::parse_der_sequence Line | Count | Source | 197 | 155k | pub fn parse_der_sequence(i: &[u8]) -> DerResult { | 198 | 155k | parse_der_with_tag(i, Tag::Sequence) | 199 | 155k | } |
der_parser::der::parser::parse_der_sequence Line | Count | Source | 197 | 144k | pub fn parse_der_sequence(i: &[u8]) -> DerResult { | 198 | 144k | parse_der_with_tag(i, Tag::Sequence) | 199 | 144k | } |
|
200 | | |
201 | | /// Parse a set of DER elements |
202 | | /// |
203 | | /// Read a set of DER objects, without any constraint on the types. |
204 | | /// Set is parsed recursively, so if constructed elements are found, they are parsed using the |
205 | | /// same function. |
206 | | /// |
207 | | /// To read a specific set of objects (giving the expected types), use the |
208 | | /// [`parse_der_set_defined`](macro.parse_der_set_defined.html) macro. |
209 | | #[inline] |
210 | 0 | pub fn parse_der_set(i: &[u8]) -> DerResult { |
211 | 0 | parse_der_with_tag(i, Tag::Set) |
212 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_set Unexecuted instantiation: der_parser::der::parser::parse_der_set |
213 | | |
214 | | /// Read a numeric string value. The content is verified to |
215 | | /// contain only digits and spaces. |
216 | | #[inline] |
217 | 0 | pub fn parse_der_numericstring(i: &[u8]) -> DerResult { |
218 | 0 | parse_der_with_tag(i, Tag::NumericString) |
219 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_numericstring Unexecuted instantiation: der_parser::der::parser::parse_der_numericstring |
220 | | |
221 | | /// Read a printable string value. The content is verified to |
222 | | /// contain only the allowed characters. |
223 | | #[inline] |
224 | 0 | pub fn parse_der_visiblestring(i: &[u8]) -> DerResult { |
225 | 0 | parse_der_with_tag(i, Tag::VisibleString) |
226 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_visiblestring Unexecuted instantiation: der_parser::der::parser::parse_der_visiblestring |
227 | | |
228 | | #[deprecated(since = "8.2.0", note = "Use `parse_der_visiblestring` instead")] |
229 | | #[inline] |
230 | 0 | pub fn visiblestring(i: &[u8]) -> DerResult { |
231 | 0 | parse_der_visiblestring(i) |
232 | 0 | } Unexecuted instantiation: der_parser::der::parser::visiblestring Unexecuted instantiation: der_parser::der::parser::visiblestring |
233 | | |
234 | | /// Read a printable string value. The content is verified to |
235 | | /// contain only the allowed characters. |
236 | | #[inline] |
237 | 0 | pub fn parse_der_printablestring(i: &[u8]) -> DerResult { |
238 | 0 | parse_der_with_tag(i, Tag::PrintableString) |
239 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_printablestring Unexecuted instantiation: der_parser::der::parser::parse_der_printablestring |
240 | | |
241 | | /// Read a T61 string value |
242 | | #[inline] |
243 | 0 | pub fn parse_der_t61string(i: &[u8]) -> DerResult { |
244 | 0 | parse_der_with_tag(i, Tag::T61String) |
245 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_t61string Unexecuted instantiation: der_parser::der::parser::parse_der_t61string |
246 | | |
247 | | /// Read a Videotex string value |
248 | | #[inline] |
249 | 0 | pub fn parse_der_videotexstring(i: &[u8]) -> DerResult { |
250 | 0 | parse_der_with_tag(i, Tag::VideotexString) |
251 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_videotexstring Unexecuted instantiation: der_parser::der::parser::parse_der_videotexstring |
252 | | |
253 | | /// Read an IA5 string value. The content is verified to be ASCII. |
254 | | #[inline] |
255 | 0 | pub fn parse_der_ia5string(i: &[u8]) -> DerResult { |
256 | 0 | parse_der_with_tag(i, Tag::Ia5String) |
257 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_ia5string Unexecuted instantiation: der_parser::der::parser::parse_der_ia5string |
258 | | |
259 | | /// Read an UTC time value |
260 | | #[inline] |
261 | 0 | pub fn parse_der_utctime(i: &[u8]) -> DerResult { |
262 | 0 | parse_der_with_tag(i, Tag::UtcTime) |
263 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_utctime Unexecuted instantiation: der_parser::der::parser::parse_der_utctime |
264 | | |
265 | | /// Read a Generalized time value |
266 | | #[inline] |
267 | 0 | pub fn parse_der_generalizedtime(i: &[u8]) -> DerResult { |
268 | 0 | parse_der_with_tag(i, Tag::GeneralizedTime) |
269 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_generalizedtime Unexecuted instantiation: der_parser::der::parser::parse_der_generalizedtime |
270 | | |
271 | | /// Read a ObjectDescriptor value |
272 | | #[inline] |
273 | 0 | pub fn parse_der_objectdescriptor(i: &[u8]) -> DerResult { |
274 | 0 | parse_der_with_tag(i, Tag::ObjectDescriptor) |
275 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_objectdescriptor Unexecuted instantiation: der_parser::der::parser::parse_der_objectdescriptor |
276 | | |
277 | | /// Read a GraphicString value |
278 | | #[inline] |
279 | 0 | pub fn parse_der_graphicstring(i: &[u8]) -> DerResult { |
280 | 0 | parse_der_with_tag(i, Tag::GraphicString) |
281 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_graphicstring Unexecuted instantiation: der_parser::der::parser::parse_der_graphicstring |
282 | | |
283 | | /// Read a GeneralString value |
284 | | #[inline] |
285 | 0 | pub fn parse_der_generalstring(i: &[u8]) -> DerResult { |
286 | 0 | parse_der_with_tag(i, Tag::GeneralString) |
287 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_generalstring Unexecuted instantiation: der_parser::der::parser::parse_der_generalstring |
288 | | |
289 | | /// Read a BmpString value |
290 | | #[inline] |
291 | 0 | pub fn parse_der_bmpstring(i: &[u8]) -> DerResult { |
292 | 0 | parse_der_with_tag(i, Tag::BmpString) |
293 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_bmpstring Unexecuted instantiation: der_parser::der::parser::parse_der_bmpstring |
294 | | |
295 | | /// Read a UniversalString value |
296 | | #[inline] |
297 | 0 | pub fn parse_der_universalstring(i: &[u8]) -> DerResult { |
298 | 0 | parse_der_with_tag(i, Tag::UniversalString) |
299 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_universalstring Unexecuted instantiation: der_parser::der::parser::parse_der_universalstring |
300 | | |
301 | | /// Parse an optional tagged object, applying function to get content |
302 | | /// |
303 | | /// This function returns a `DerObject`, trying to read content as generic DER objects. |
304 | | /// If parsing failed, return an optional object containing `None`. |
305 | | /// |
306 | | /// To support other return or error types, use |
307 | | /// [parse_der_tagged_explicit_g](fn.parse_der_tagged_explicit_g.html) |
308 | | /// |
309 | | /// This function will never fail: if parsing content failed, the BER value `Optional(None)` is |
310 | | /// returned. |
311 | | #[inline] |
312 | 0 | pub fn parse_der_explicit_optional<F>(i: &[u8], tag: Tag, f: F) -> DerResult |
313 | 0 | where |
314 | 0 | F: Fn(&[u8]) -> DerResult, |
315 | | { |
316 | 0 | parse_ber_explicit_optional(i, tag, f) |
317 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_explicit_optional::<_> Unexecuted instantiation: der_parser::der::parser::parse_der_explicit_optional::<_> |
318 | | |
319 | | /// Parse an implicit tagged object, applying function to read content |
320 | | /// |
321 | | /// Note: unlike explicit tagged functions, the callback must be a *content* parsing function, |
322 | | /// often based on the [`parse_der_content`](fn.parse_der_content.html) combinator. |
323 | | /// |
324 | | /// The built object will use the original header (and tag), so the content may not match the tag |
325 | | /// value. |
326 | | /// |
327 | | /// For a combinator version, see [parse_der_tagged_implicit](../ber/fn.parse_der_tagged_implicit.html). |
328 | | /// |
329 | | /// For a generic version (different output and error types), see |
330 | | /// [parse_der_tagged_implicit_g](../ber/fn.parse_der_tagged_implicit_g.html). |
331 | | /// |
332 | | /// # Examples |
333 | | /// |
334 | | /// The following parses `[3] IMPLICIT INTEGER` into a `DerObject`: |
335 | | /// |
336 | | /// ```rust |
337 | | /// # use der_parser::der::*; |
338 | | /// # use der_parser::error::DerResult; |
339 | | /// # |
340 | | /// fn parse_int_implicit(i:&[u8]) -> DerResult { |
341 | | /// parse_der_implicit( |
342 | | /// i, |
343 | | /// 3, |
344 | | /// parse_der_content(Tag::Integer), |
345 | | /// ) |
346 | | /// } |
347 | | /// |
348 | | /// # let bytes = &[0x83, 0x03, 0x01, 0x00, 0x01]; |
349 | | /// let res = parse_int_implicit(bytes); |
350 | | /// # match res { |
351 | | /// # Ok((rem, content)) => { |
352 | | /// # assert!(rem.is_empty()); |
353 | | /// # assert_eq!(content.as_u32(), Ok(0x10001)); |
354 | | /// # }, |
355 | | /// # _ => assert!(false) |
356 | | /// # } |
357 | | /// ``` |
358 | | #[inline] |
359 | 0 | pub fn parse_der_implicit<'a, T, F>(i: &'a [u8], tag: T, f: F) -> DerResult<'a> |
360 | 0 | where |
361 | 0 | F: Fn(&'a [u8], &'_ Header, usize) -> BerResult<'a, DerObjectContent<'a>>, |
362 | 0 | T: Into<Tag>, |
363 | | { |
364 | 0 | parse_ber_implicit(i, tag, f) |
365 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_implicit::<_, _> Unexecuted instantiation: der_parser::der::parser::parse_der_implicit::<u32, der_parser::der::parser::parse_der_content::{closure#0}>Unexecuted instantiation: der_parser::der::parser::parse_der_implicit::<_, _> Unexecuted instantiation: der_parser::der::parser::parse_der_implicit::<u32, der_parser::der::parser::parse_der_content::{closure#0}> |
366 | | |
367 | | /// Parse DER object and try to decode it as a 32-bits signed integer |
368 | | /// |
369 | | /// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target |
370 | | /// integer type. |
371 | | #[inline] |
372 | 0 | pub fn parse_der_i32(i: &[u8]) -> BerResult<i32> { |
373 | 0 | <i32>::from_der(i) |
374 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_i32 Unexecuted instantiation: der_parser::der::parser::parse_der_i32 |
375 | | |
376 | | /// Parse DER object and try to decode it as a 64-bits signed integer |
377 | | /// |
378 | | /// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target |
379 | | /// integer type. |
380 | | #[inline] |
381 | 0 | pub fn parse_der_i64(i: &[u8]) -> BerResult<i64> { |
382 | 0 | <i64>::from_der(i) |
383 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_i64 Unexecuted instantiation: der_parser::der::parser::parse_der_i64 |
384 | | |
385 | | /// Parse DER object and try to decode it as a 32-bits unsigned integer |
386 | | /// |
387 | | /// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target |
388 | | /// integer type. |
389 | 0 | pub fn parse_der_u32(i: &[u8]) -> BerResult<u32> { |
390 | 0 | <u32>::from_der(i) |
391 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_u32 Unexecuted instantiation: der_parser::der::parser::parse_der_u32 |
392 | | |
393 | | /// Parse DER object and try to decode it as a 64-bits unsigned integer |
394 | | /// |
395 | | /// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target |
396 | | /// integer type. |
397 | 0 | pub fn parse_der_u64(i: &[u8]) -> BerResult<u64> { |
398 | 0 | <u64>::from_der(i) |
399 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_u64 Unexecuted instantiation: der_parser::der::parser::parse_der_u64 |
400 | | |
401 | | /// Parse DER object and get content as slice |
402 | | #[inline] |
403 | 0 | pub fn parse_der_slice<T: Into<Tag>>(i: &[u8], tag: T) -> BerResult<&[u8]> { |
404 | 0 | let tag = tag.into(); |
405 | 0 | parse_der_container(move |content, hdr| { |
406 | 0 | hdr.assert_tag(tag)?; |
407 | 0 | Ok((&b""[..], content)) |
408 | 0 | })(i) Unexecuted instantiation: der_parser::der::parser::parse_der_slice::<_>::{closure#0}Unexecuted instantiation: der_parser::der::parser::parse_der_slice::<_>::{closure#0} |
409 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_slice::<_> Unexecuted instantiation: der_parser::der::parser::parse_der_slice::<_> |
410 | | |
411 | | /// Parse the next bytes as the content of a DER object (combinator, header reference) |
412 | | /// |
413 | | /// Content type is *not* checked to match tag, caller is responsible of providing the correct tag |
414 | | /// |
415 | | /// Caller is also responsible to check if parsing function consumed the expected number of |
416 | | /// bytes (`header.len`). |
417 | | /// |
418 | | /// This function differs from [`parse_der_content2`](fn.parse_der_content2.html) because it passes |
419 | | /// the BER object header by reference (required for ex. by `parse_der_implicit`). |
420 | | /// |
421 | | /// The arguments of the parse function are: `(input, ber_object_header, max_recursion)`. |
422 | | /// |
423 | | /// Example: manually parsing header and content |
424 | | /// |
425 | | /// ``` |
426 | | /// # use der_parser::ber::MAX_RECURSION; |
427 | | /// # use der_parser::der::*; |
428 | | /// # |
429 | | /// # let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01]; |
430 | | /// let (i, header) = der_read_element_header(bytes).expect("parsing failed"); |
431 | | /// let (rem, content) = parse_der_content(header.tag())(i, &header, MAX_RECURSION) |
432 | | /// .expect("parsing failed"); |
433 | | /// # |
434 | | /// # assert_eq!(header.tag(), Tag::Integer); |
435 | | /// ``` |
436 | 0 | pub fn parse_der_content<'a>( |
437 | 0 | tag: Tag, |
438 | 0 | ) -> impl Fn(&'a [u8], &'_ Header, usize) -> BerResult<'a, DerObjectContent<'a>> { |
439 | 4 | move |i: &[u8], hdr: &Header, max_recursion: usize| { |
440 | 4 | der_read_element_content_as(i, tag, hdr.length(), hdr.is_constructed(), max_recursion) |
441 | 4 | } Unexecuted instantiation: der_parser::der::parser::parse_der_content::{closure#0}Unexecuted instantiation: der_parser::der::parser::parse_der_content::{closure#0}der_parser::der::parser::parse_der_content::{closure#0}Line | Count | Source | 439 | 4 | move |i: &[u8], hdr: &Header, max_recursion: usize| { | 440 | 4 | der_read_element_content_as(i, tag, hdr.length(), hdr.is_constructed(), max_recursion) | 441 | 4 | } |
Unexecuted instantiation: der_parser::der::parser::parse_der_content::{closure#0} |
442 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_content Unexecuted instantiation: der_parser::der::parser::parse_der_content |
443 | | |
444 | | /// Parse the next bytes as the content of a DER object (combinator, owned header) |
445 | | /// |
446 | | /// Content type is *not* checked to match tag, caller is responsible of providing the correct tag |
447 | | /// |
448 | | /// Caller is also responsible to check if parsing function consumed the expected number of |
449 | | /// bytes (`header.len`). |
450 | | /// |
451 | | /// The arguments of the parse function are: `(input, ber_object_header, max_recursion)`. |
452 | | /// |
453 | | /// This function differs from [`parse_der_content`](fn.parse_der_content.html) because it passes |
454 | | /// an owned BER object header (required for ex. by `parse_der_tagged_implicit_g`). |
455 | | /// |
456 | | /// Example: manually parsing header and content |
457 | | /// |
458 | | /// ``` |
459 | | /// # use der_parser::ber::MAX_RECURSION; |
460 | | /// # use der_parser::der::*; |
461 | | /// # |
462 | | /// # let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01]; |
463 | | /// let (i, header) = der_read_element_header(bytes).expect("parsing failed"); |
464 | | /// # assert_eq!(header.tag(), Tag::Integer); |
465 | | /// let (rem, content) = parse_der_content2(header.tag())(i, header, MAX_RECURSION) |
466 | | /// .expect("parsing failed"); |
467 | | /// ``` |
468 | 0 | pub fn parse_der_content2<'a>( |
469 | 0 | tag: Tag, |
470 | 0 | ) -> impl Fn(&'a [u8], Header<'a>, usize) -> BerResult<'a, DerObjectContent<'a>> { |
471 | 0 | move |i: &[u8], hdr: Header, max_recursion: usize| { |
472 | 0 | der_read_element_content_as(i, tag, hdr.length(), hdr.is_constructed(), max_recursion) |
473 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_content2::{closure#0}Unexecuted instantiation: der_parser::der::parser::parse_der_content2::{closure#0} |
474 | 0 | } Unexecuted instantiation: der_parser::der::parser::parse_der_content2 Unexecuted instantiation: der_parser::der::parser::parse_der_content2 |
475 | | |
476 | | // --------- end of parse_der_xxx functions ---------- |
477 | | |
478 | | /// Parse the next bytes as the content of a DER object. |
479 | | /// |
480 | | /// Content type is *not* checked, caller is responsible of providing the correct tag |
481 | 591k | pub fn der_read_element_content_as( |
482 | 591k | i: &[u8], |
483 | 591k | tag: Tag, |
484 | 591k | length: Length, |
485 | 591k | constructed: bool, |
486 | 591k | max_depth: usize, |
487 | 591k | ) -> BerResult<DerObjectContent> { |
488 | | // Indefinite lengths are not allowed in DER (X.690 section 10.1) |
489 | 591k | let l = length.definite().map_err(BerError::from)?; |
490 | 591k | if i.len() < l { |
491 | 4.66k | return Err(Err::Incomplete(Needed::new(l))); |
492 | 586k | } |
493 | 586k | match tag { |
494 | | Tag::Boolean => { |
495 | 5.49k | custom_check!(i, l != 1, BerError::InvalidLength)?; |
496 | 3.97k | der_constraint_fail_if!(i, i[0] != 0 && i[0] != 0xff, DerConstraint::InvalidBoolean); |
497 | | } |
498 | | Tag::BitString => { |
499 | 31.8k | der_constraint_fail_if!(i, constructed, DerConstraint::Constructed); |
500 | | // exception: read and verify padding bits |
501 | 31.0k | return der_read_content_bitstring(i, l); |
502 | | } |
503 | | Tag::Integer => { |
504 | | // verify leading zeros |
505 | 7.04k | match i[..l] { |
506 | 7.04k | [] => { |
507 | 899 | return Err(nom::Err::Error(BerError::DerConstraintFailed( |
508 | 899 | DerConstraint::IntegerEmpty, |
509 | 899 | ))) |
510 | | } |
511 | 6.14k | [0, 0, ..] => { |
512 | 2.02k | return Err(nom::Err::Error(BerError::DerConstraintFailed( |
513 | 2.02k | DerConstraint::IntegerLeadingZeroes, |
514 | 2.02k | ))) |
515 | | } |
516 | 1.32k | [0, byte, ..] if byte < 0x80 => { |
517 | 422 | return Err(nom::Err::Error(BerError::DerConstraintFailed( |
518 | 422 | DerConstraint::IntegerLeadingZeroes, |
519 | 422 | ))); |
520 | | } |
521 | 3.70k | _ => (), |
522 | | } |
523 | | } |
524 | | Tag::NumericString |
525 | | | Tag::VisibleString |
526 | | | Tag::PrintableString |
527 | | | Tag::Ia5String |
528 | | | Tag::Utf8String |
529 | | | Tag::T61String |
530 | | | Tag::VideotexString |
531 | | | Tag::BmpString |
532 | | | Tag::UniversalString |
533 | | | Tag::ObjectDescriptor |
534 | | | Tag::GraphicString |
535 | | | Tag::GeneralString => { |
536 | 49.3k | der_constraint_fail_if!(i, constructed, DerConstraint::Constructed); |
537 | | } |
538 | | Tag::UtcTime | Tag::GeneralizedTime => { |
539 | 7.99k | if l == 0 || i.get(l - 1).cloned() != Some(b'Z') { |
540 | 5.65k | return Err(Err::Error(BerError::DerConstraintFailed( |
541 | 5.65k | DerConstraint::MissingTimeZone, |
542 | 5.65k | ))); |
543 | 2.33k | } |
544 | | } |
545 | 485k | _ => (), |
546 | | } |
547 | 536k | ber_read_element_content_as(i, tag, length, constructed, max_depth) |
548 | 591k | } der_parser::der::parser::der_read_element_content_as Line | Count | Source | 481 | 273k | pub fn der_read_element_content_as( | 482 | 273k | i: &[u8], | 483 | 273k | tag: Tag, | 484 | 273k | length: Length, | 485 | 273k | constructed: bool, | 486 | 273k | max_depth: usize, | 487 | 273k | ) -> BerResult<DerObjectContent> { | 488 | | // Indefinite lengths are not allowed in DER (X.690 section 10.1) | 489 | 273k | let l = length.definite().map_err(BerError::from)?; | 490 | 273k | if i.len() < l { | 491 | 1.95k | return Err(Err::Incomplete(Needed::new(l))); | 492 | 271k | } | 493 | 271k | match tag { | 494 | | Tag::Boolean => { | 495 | 1.63k | custom_check!(i, l != 1, BerError::InvalidLength)?; | 496 | 1.05k | der_constraint_fail_if!(i, i[0] != 0 && i[0] != 0xff, DerConstraint::InvalidBoolean); | 497 | | } | 498 | | Tag::BitString => { | 499 | 14.6k | der_constraint_fail_if!(i, constructed, DerConstraint::Constructed); | 500 | | // exception: read and verify padding bits | 501 | 14.4k | return der_read_content_bitstring(i, l); | 502 | | } | 503 | | Tag::Integer => { | 504 | | // verify leading zeros | 505 | 1.48k | match i[..l] { | 506 | 1.48k | [] => { | 507 | 98 | return Err(nom::Err::Error(BerError::DerConstraintFailed( | 508 | 98 | DerConstraint::IntegerEmpty, | 509 | 98 | ))) | 510 | | } | 511 | 1.38k | [0, 0, ..] => { | 512 | 108 | return Err(nom::Err::Error(BerError::DerConstraintFailed( | 513 | 108 | DerConstraint::IntegerLeadingZeroes, | 514 | 108 | ))) | 515 | | } | 516 | 379 | [0, byte, ..] if byte < 0x80 => { | 517 | 111 | return Err(nom::Err::Error(BerError::DerConstraintFailed( | 518 | 111 | DerConstraint::IntegerLeadingZeroes, | 519 | 111 | ))); | 520 | | } | 521 | 1.16k | _ => (), | 522 | | } | 523 | | } | 524 | | Tag::NumericString | 525 | | | Tag::VisibleString | 526 | | | Tag::PrintableString | 527 | | | Tag::Ia5String | 528 | | | Tag::Utf8String | 529 | | | Tag::T61String | 530 | | | Tag::VideotexString | 531 | | | Tag::BmpString | 532 | | | Tag::UniversalString | 533 | | | Tag::ObjectDescriptor | 534 | | | Tag::GraphicString | 535 | | | Tag::GeneralString => { | 536 | 24.7k | der_constraint_fail_if!(i, constructed, DerConstraint::Constructed); | 537 | | } | 538 | | Tag::UtcTime | Tag::GeneralizedTime => { | 539 | 3.51k | if l == 0 || i.get(l - 1).cloned() != Some(b'Z') { | 540 | 2.99k | return Err(Err::Error(BerError::DerConstraintFailed( | 541 | 2.99k | DerConstraint::MissingTimeZone, | 542 | 2.99k | ))); | 543 | 526 | } | 544 | | } | 545 | 225k | _ => (), | 546 | | } | 547 | 250k | ber_read_element_content_as(i, tag, length, constructed, max_depth) | 548 | 273k | } |
der_parser::der::parser::der_read_element_content_as Line | Count | Source | 481 | 317k | pub fn der_read_element_content_as( | 482 | 317k | i: &[u8], | 483 | 317k | tag: Tag, | 484 | 317k | length: Length, | 485 | 317k | constructed: bool, | 486 | 317k | max_depth: usize, | 487 | 317k | ) -> BerResult<DerObjectContent> { | 488 | | // Indefinite lengths are not allowed in DER (X.690 section 10.1) | 489 | 317k | let l = length.definite().map_err(BerError::from)?; | 490 | 317k | if i.len() < l { | 491 | 2.70k | return Err(Err::Incomplete(Needed::new(l))); | 492 | 315k | } | 493 | 315k | match tag { | 494 | | Tag::Boolean => { | 495 | 3.85k | custom_check!(i, l != 1, BerError::InvalidLength)?; | 496 | 2.91k | der_constraint_fail_if!(i, i[0] != 0 && i[0] != 0xff, DerConstraint::InvalidBoolean); | 497 | | } | 498 | | Tag::BitString => { | 499 | 17.1k | der_constraint_fail_if!(i, constructed, DerConstraint::Constructed); | 500 | | // exception: read and verify padding bits | 501 | 16.5k | return der_read_content_bitstring(i, l); | 502 | | } | 503 | | Tag::Integer => { | 504 | | // verify leading zeros | 505 | 5.55k | match i[..l] { | 506 | 5.55k | [] => { | 507 | 801 | return Err(nom::Err::Error(BerError::DerConstraintFailed( | 508 | 801 | DerConstraint::IntegerEmpty, | 509 | 801 | ))) | 510 | | } | 511 | 4.75k | [0, 0, ..] => { | 512 | 1.91k | return Err(nom::Err::Error(BerError::DerConstraintFailed( | 513 | 1.91k | DerConstraint::IntegerLeadingZeroes, | 514 | 1.91k | ))) | 515 | | } | 516 | 949 | [0, byte, ..] if byte < 0x80 => { | 517 | 311 | return Err(nom::Err::Error(BerError::DerConstraintFailed( | 518 | 311 | DerConstraint::IntegerLeadingZeroes, | 519 | 311 | ))); | 520 | | } | 521 | 2.53k | _ => (), | 522 | | } | 523 | | } | 524 | | Tag::NumericString | 525 | | | Tag::VisibleString | 526 | | | Tag::PrintableString | 527 | | | Tag::Ia5String | 528 | | | Tag::Utf8String | 529 | | | Tag::T61String | 530 | | | Tag::VideotexString | 531 | | | Tag::BmpString | 532 | | | Tag::UniversalString | 533 | | | Tag::ObjectDescriptor | 534 | | | Tag::GraphicString | 535 | | | Tag::GeneralString => { | 536 | 24.5k | der_constraint_fail_if!(i, constructed, DerConstraint::Constructed); | 537 | | } | 538 | | Tag::UtcTime | Tag::GeneralizedTime => { | 539 | 4.47k | if l == 0 || i.get(l - 1).cloned() != Some(b'Z') { | 540 | 2.65k | return Err(Err::Error(BerError::DerConstraintFailed( | 541 | 2.65k | DerConstraint::MissingTimeZone, | 542 | 2.65k | ))); | 543 | 1.81k | } | 544 | | } | 545 | 259k | _ => (), | 546 | | } | 547 | 286k | ber_read_element_content_as(i, tag, length, constructed, max_depth) | 548 | 317k | } |
|
549 | | |
550 | | /// Parse DER object content recursively |
551 | | /// |
552 | | /// *Note: an error is raised if recursion depth exceeds `MAX_RECURSION`. |
553 | 0 | pub fn der_read_element_content<'a>(i: &'a [u8], hdr: Header<'a>) -> DerResult<'a> { |
554 | 0 | der_read_element_content_recursive(i, hdr, MAX_RECURSION) |
555 | 0 | } Unexecuted instantiation: der_parser::der::parser::der_read_element_content Unexecuted instantiation: der_parser::der::parser::der_read_element_content |
556 | | |
557 | 314k | fn der_read_element_content_recursive<'a>( |
558 | 314k | i: &'a [u8], |
559 | 314k | hdr: Header<'a>, |
560 | 314k | max_depth: usize, |
561 | 314k | ) -> DerResult<'a> { |
562 | 314k | match hdr.class() { |
563 | 240k | Class::Universal => (), |
564 | | _ => { |
565 | 74.6k | let (i, data) = ber_get_object_content(i, &hdr, max_depth)?; |
566 | 68.0k | let any = Any::new(hdr.clone(), data); |
567 | 68.0k | let content = DerObjectContent::Unknown(any); |
568 | 68.0k | let obj = DerObject::from_header_and_content(hdr, content); |
569 | 68.0k | return Ok((i, obj)); |
570 | | } |
571 | | } |
572 | 240k | match der_read_element_content_as(i, hdr.tag(), hdr.length(), hdr.is_constructed(), max_depth) { |
573 | 90.1k | Ok((rem, content)) => Ok((rem, DerObject::from_header_and_content(hdr, content))), |
574 | | Err(Err::Error(BerError::UnknownTag(_))) => { |
575 | 0 | let (rem, data) = ber_get_object_content(i, &hdr, max_depth)?; |
576 | 0 | let any = Any::new(hdr.clone(), data); |
577 | 0 | let content = DerObjectContent::Unknown(any); |
578 | 0 | let obj = DerObject::from_header_and_content(hdr, content); |
579 | 0 | Ok((rem, obj)) |
580 | | } |
581 | 150k | Err(e) => Err(e), |
582 | | } |
583 | 314k | } der_parser::der::parser::der_read_element_content_recursive Line | Count | Source | 557 | 120k | fn der_read_element_content_recursive<'a>( | 558 | 120k | i: &'a [u8], | 559 | 120k | hdr: Header<'a>, | 560 | 120k | max_depth: usize, | 561 | 120k | ) -> DerResult<'a> { | 562 | 120k | match hdr.class() { | 563 | 93.7k | Class::Universal => (), | 564 | | _ => { | 565 | 26.4k | let (i, data) = ber_get_object_content(i, &hdr, max_depth)?; | 566 | 22.9k | let any = Any::new(hdr.clone(), data); | 567 | 22.9k | let content = DerObjectContent::Unknown(any); | 568 | 22.9k | let obj = DerObject::from_header_and_content(hdr, content); | 569 | 22.9k | return Ok((i, obj)); | 570 | | } | 571 | | } | 572 | 93.7k | match der_read_element_content_as(i, hdr.tag(), hdr.length(), hdr.is_constructed(), max_depth) { | 573 | 42.4k | Ok((rem, content)) => Ok((rem, DerObject::from_header_and_content(hdr, content))), | 574 | | Err(Err::Error(BerError::UnknownTag(_))) => { | 575 | 0 | let (rem, data) = ber_get_object_content(i, &hdr, max_depth)?; | 576 | 0 | let any = Any::new(hdr.clone(), data); | 577 | 0 | let content = DerObjectContent::Unknown(any); | 578 | 0 | let obj = DerObject::from_header_and_content(hdr, content); | 579 | 0 | Ok((rem, obj)) | 580 | | } | 581 | 51.2k | Err(e) => Err(e), | 582 | | } | 583 | 120k | } |
der_parser::der::parser::der_read_element_content_recursive Line | Count | Source | 557 | 194k | fn der_read_element_content_recursive<'a>( | 558 | 194k | i: &'a [u8], | 559 | 194k | hdr: Header<'a>, | 560 | 194k | max_depth: usize, | 561 | 194k | ) -> DerResult<'a> { | 562 | 194k | match hdr.class() { | 563 | 146k | Class::Universal => (), | 564 | | _ => { | 565 | 48.2k | let (i, data) = ber_get_object_content(i, &hdr, max_depth)?; | 566 | 45.1k | let any = Any::new(hdr.clone(), data); | 567 | 45.1k | let content = DerObjectContent::Unknown(any); | 568 | 45.1k | let obj = DerObject::from_header_and_content(hdr, content); | 569 | 45.1k | return Ok((i, obj)); | 570 | | } | 571 | | } | 572 | 146k | match der_read_element_content_as(i, hdr.tag(), hdr.length(), hdr.is_constructed(), max_depth) { | 573 | 47.7k | Ok((rem, content)) => Ok((rem, DerObject::from_header_and_content(hdr, content))), | 574 | | Err(Err::Error(BerError::UnknownTag(_))) => { | 575 | 0 | let (rem, data) = ber_get_object_content(i, &hdr, max_depth)?; | 576 | 0 | let any = Any::new(hdr.clone(), data); | 577 | 0 | let content = DerObjectContent::Unknown(any); | 578 | 0 | let obj = DerObject::from_header_and_content(hdr, content); | 579 | 0 | Ok((rem, obj)) | 580 | | } | 581 | 98.8k | Err(e) => Err(e), | 582 | | } | 583 | 194k | } |
|
584 | | |
585 | 31.0k | fn der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent> { |
586 | 31.0k | let (i, ignored_bits) = be_u8(i)?; |
587 | 30.7k | if ignored_bits > 7 { |
588 | 1.91k | return Err(Err::Error(BerError::invalid_value( |
589 | 1.91k | Tag::BitString, |
590 | 1.91k | "More than 7 unused bits".to_owned(), |
591 | 1.91k | ))); |
592 | 28.7k | } |
593 | 28.7k | if len == 0 { |
594 | 982 | return Err(Err::Error(BerError::InvalidLength)); |
595 | 27.8k | } |
596 | 27.8k | let (i, data) = take(len - 1)(i)?; |
597 | 27.8k | if len > 1 { |
598 | 27.0k | let mut last_byte = data[len - 2]; |
599 | 27.0k | for _ in 0..ignored_bits as usize { |
600 | 77.3k | der_constraint_fail_if!(i, last_byte & 1 != 0, DerConstraint::UnusedBitsNotZero); |
601 | 66.8k | last_byte >>= 1; |
602 | | } |
603 | 721 | } |
604 | 17.2k | Ok(( |
605 | 17.2k | i, |
606 | 17.2k | DerObjectContent::BitString(ignored_bits, BitStringObject { data }), |
607 | 17.2k | )) |
608 | | // do_parse! { |
609 | | // i, |
610 | | // ignored_bits: be_u8 >> |
611 | | // custom_check!(ignored_bits > 7, BerError::DerConstraintFailed) >> |
612 | | // custom_check!(len == 0, BerError::InvalidLength) >> |
613 | | // s: take!(len - 1) >> |
614 | | // call!(|input| { |
615 | | // if len > 1 { |
616 | | // let mut last_byte = s[len-2]; |
617 | | // for _ in 0..ignored_bits as usize { |
618 | | // der_constraint_fail_if!(i, last_byte & 1 != 0); |
619 | | // last_byte >>= 1; |
620 | | // } |
621 | | // } |
622 | | // Ok((input,())) |
623 | | // }) >> |
624 | | // ( DerObjectContent::BitString(ignored_bits,BitStringObject{ data:s }) ) |
625 | | // } |
626 | 31.0k | } der_parser::der::parser::der_read_content_bitstring Line | Count | Source | 585 | 14.4k | fn der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent> { | 586 | 14.4k | let (i, ignored_bits) = be_u8(i)?; | 587 | 14.4k | if ignored_bits > 7 { | 588 | 1.25k | return Err(Err::Error(BerError::invalid_value( | 589 | 1.25k | Tag::BitString, | 590 | 1.25k | "More than 7 unused bits".to_owned(), | 591 | 1.25k | ))); | 592 | 13.1k | } | 593 | 13.1k | if len == 0 { | 594 | 486 | return Err(Err::Error(BerError::InvalidLength)); | 595 | 12.6k | } | 596 | 12.6k | let (i, data) = take(len - 1)(i)?; | 597 | 12.6k | if len > 1 { | 598 | 12.3k | let mut last_byte = data[len - 2]; | 599 | 12.3k | for _ in 0..ignored_bits as usize { | 600 | 30.5k | der_constraint_fail_if!(i, last_byte & 1 != 0, DerConstraint::UnusedBitsNotZero); | 601 | 26.2k | last_byte >>= 1; | 602 | | } | 603 | 298 | } | 604 | 8.37k | Ok(( | 605 | 8.37k | i, | 606 | 8.37k | DerObjectContent::BitString(ignored_bits, BitStringObject { data }), | 607 | 8.37k | )) | 608 | | // do_parse! { | 609 | | // i, | 610 | | // ignored_bits: be_u8 >> | 611 | | // custom_check!(ignored_bits > 7, BerError::DerConstraintFailed) >> | 612 | | // custom_check!(len == 0, BerError::InvalidLength) >> | 613 | | // s: take!(len - 1) >> | 614 | | // call!(|input| { | 615 | | // if len > 1 { | 616 | | // let mut last_byte = s[len-2]; | 617 | | // for _ in 0..ignored_bits as usize { | 618 | | // der_constraint_fail_if!(i, last_byte & 1 != 0); | 619 | | // last_byte >>= 1; | 620 | | // } | 621 | | // } | 622 | | // Ok((input,())) | 623 | | // }) >> | 624 | | // ( DerObjectContent::BitString(ignored_bits,BitStringObject{ data:s }) ) | 625 | | // } | 626 | 14.4k | } |
der_parser::der::parser::der_read_content_bitstring Line | Count | Source | 585 | 16.5k | fn der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent> { | 586 | 16.5k | let (i, ignored_bits) = be_u8(i)?; | 587 | 16.3k | if ignored_bits > 7 { | 588 | 659 | return Err(Err::Error(BerError::invalid_value( | 589 | 659 | Tag::BitString, | 590 | 659 | "More than 7 unused bits".to_owned(), | 591 | 659 | ))); | 592 | 15.6k | } | 593 | 15.6k | if len == 0 { | 594 | 496 | return Err(Err::Error(BerError::InvalidLength)); | 595 | 15.1k | } | 596 | 15.1k | let (i, data) = take(len - 1)(i)?; | 597 | 15.1k | if len > 1 { | 598 | 14.7k | let mut last_byte = data[len - 2]; | 599 | 14.7k | for _ in 0..ignored_bits as usize { | 600 | 46.8k | der_constraint_fail_if!(i, last_byte & 1 != 0, DerConstraint::UnusedBitsNotZero); | 601 | 40.6k | last_byte >>= 1; | 602 | | } | 603 | 423 | } | 604 | 8.92k | Ok(( | 605 | 8.92k | i, | 606 | 8.92k | DerObjectContent::BitString(ignored_bits, BitStringObject { data }), | 607 | 8.92k | )) | 608 | | // do_parse! { | 609 | | // i, | 610 | | // ignored_bits: be_u8 >> | 611 | | // custom_check!(ignored_bits > 7, BerError::DerConstraintFailed) >> | 612 | | // custom_check!(len == 0, BerError::InvalidLength) >> | 613 | | // s: take!(len - 1) >> | 614 | | // call!(|input| { | 615 | | // if len > 1 { | 616 | | // let mut last_byte = s[len-2]; | 617 | | // for _ in 0..ignored_bits as usize { | 618 | | // der_constraint_fail_if!(i, last_byte & 1 != 0); | 619 | | // last_byte >>= 1; | 620 | | // } | 621 | | // } | 622 | | // Ok((input,())) | 623 | | // }) >> | 624 | | // ( DerObjectContent::BitString(ignored_bits,BitStringObject{ data:s }) ) | 625 | | // } | 626 | 16.5k | } |
|
627 | | |
628 | | /// Read an object header (DER) |
629 | | #[inline] |
630 | 3.69M | pub fn der_read_element_header(i: &[u8]) -> BerResult<Header> { |
631 | 3.69M | Header::from_der(i) |
632 | 3.69M | } der_parser::der::parser::der_read_element_header Line | Count | Source | 630 | 846k | pub fn der_read_element_header(i: &[u8]) -> BerResult<Header> { | 631 | 846k | Header::from_der(i) | 632 | 846k | } |
der_parser::der::parser::der_read_element_header Line | Count | Source | 630 | 2.84M | pub fn der_read_element_header(i: &[u8]) -> BerResult<Header> { | 631 | 2.84M | Header::from_der(i) | 632 | 2.84M | } |
|