• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::ber::*;
2 use crate::der::*;
3 use crate::error::*;
4 use nom::bytes::streaming::take;
5 use nom::number::streaming::be_u8;
6 use nom::{Err, Needed};
7 use rusticata_macros::custom_check;
8 
9 /// Parse DER object recursively
10 ///
11 /// Return a tuple containing the remaining (unparsed) bytes and the DER Object, or an error.
12 ///
13 /// *Note: this is the same as calling `parse_der_recursive` with `MAX_RECURSION`.
14 ///
15 /// ### Example
16 ///
17 /// ```
18 /// use der_parser::der::{parse_der, DerTag};
19 ///
20 /// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
21 /// let (_, obj) = parse_der(bytes).expect("parsing failed");
22 ///
23 /// assert_eq!(obj.header.tag, DerTag::Integer);
24 /// ```
25 #[inline]
parse_der(i: &[u8]) -> DerResult26 pub fn parse_der(i: &[u8]) -> DerResult {
27     parse_der_recursive(i, MAX_RECURSION)
28 }
29 
30 /// Parse DER object recursively, specifying the maximum recursion depth
31 ///
32 /// Return a tuple containing the remaining (unparsed) bytes and the DER Object, or an error.
33 ///
34 /// ### Example
35 ///
36 /// ```
37 /// use der_parser::der::{parse_der_recursive, DerTag};
38 ///
39 /// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
40 /// let (_, obj) = parse_der_recursive(bytes, 1).expect("parsing failed");
41 ///
42 /// assert_eq!(obj.header.tag, DerTag::Integer);
43 /// ```
parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult44 pub fn parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult {
45     let (i, hdr) = der_read_element_header(i)?;
46     // safety check: length cannot be more than 2^32 bytes
47     if let BerSize::Definite(l) = hdr.len {
48         custom_check!(i, l > MAX_OBJECT_SIZE, BerError::InvalidLength)?;
49     }
50     der_read_element_content_recursive(i, hdr, max_depth)
51 }
52 
53 #[doc(hidden)]
54 #[macro_export]
55 macro_rules! der_constraint_fail_if(
56     ($slice:expr, $cond:expr) => (
57         {
58             if $cond {
59                 return Err(::nom::Err::Error(BerError::DerConstraintFailed));
60             }
61         }
62     );
63 );
64 
65 /// Parse a DER object, expecting a value with specified tag
66 ///
67 /// The object is parsed recursively, with a maximum depth of `MAX_RECURSION`.
68 ///
69 /// ### Example
70 ///
71 /// ```
72 /// use der_parser::der::{parse_der_with_tag, DerTag};
73 ///
74 /// let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
75 /// let (_, obj) = parse_der_with_tag(bytes, DerTag::Integer).expect("parsing failed");
76 ///
77 /// assert_eq!(obj.header.tag, DerTag::Integer);
78 /// ```
parse_der_with_tag<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> DerResult79 pub fn parse_der_with_tag<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> DerResult {
80     let tag = tag.into();
81     let (i, hdr) = der_read_element_header(i)?;
82     if hdr.tag != tag {
83         return Err(nom::Err::Error(BerError::InvalidTag));
84     }
85     let (i, content) =
86         der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), MAX_RECURSION)?;
87     Ok((i, DerObject::from_header_and_content(hdr, content)))
88 }
89 
90 /// Read end of content marker
91 #[inline]
parse_der_endofcontent(i: &[u8]) -> DerResult92 pub fn parse_der_endofcontent(i: &[u8]) -> DerResult {
93     parse_der_with_tag(i, DerTag::EndOfContent)
94 }
95 
96 /// Read a boolean value
97 ///
98 /// The encoding of a boolean value shall be primitive. The contents octets shall consist of a
99 /// single octet.
100 ///
101 /// If the boolean value is FALSE, the octet shall be zero.
102 /// If the boolean value is TRUE, the octet shall be one byte, and have all bits set to one (0xff).
103 #[inline]
parse_der_bool(i: &[u8]) -> DerResult104 pub fn parse_der_bool(i: &[u8]) -> DerResult {
105     parse_der_with_tag(i, DerTag::Boolean)
106 }
107 
108 /// Read an integer value
109 ///
110 /// The encoding of a boolean value shall be primitive. The contents octets shall consist of one or
111 /// more octets.
112 ///
113 /// To access the content, use the [`as_u64`](struct.BerObject.html#method.as_u64),
114 /// [`as_u32`](struct.BerObject.html#method.as_u32),
115 /// [`as_biguint`](struct.BerObject.html#method.as_biguint) or
116 /// [`as_bigint`](struct.BerObject.html#method.as_bigint) methods.
117 /// Remember that a BER integer has unlimited size, so these methods return `Result` or `Option`
118 /// objects.
119 ///
120 /// # Examples
121 ///
122 /// ```rust
123 /// # use der_parser::der::{parse_der_integer, DerObject, DerObjectContent};
124 /// let empty = &b""[..];
125 /// let bytes = [0x02, 0x03, 0x01, 0x00, 0x01];
126 /// let expected  = DerObject::from_obj(DerObjectContent::Integer(b"\x01\x00\x01"));
127 /// assert_eq!(
128 ///     parse_der_integer(&bytes),
129 ///     Ok((empty, expected))
130 /// );
131 /// ```
132 #[inline]
parse_der_integer(i: &[u8]) -> DerResult133 pub fn parse_der_integer(i: &[u8]) -> DerResult {
134     parse_der_with_tag(i, DerTag::Integer)
135 }
136 
137 /// Read an bitstring value
138 ///
139 /// To access the content as plain bytes, you will have to
140 /// interprete the resulting tuple which will contain in
141 /// its first item the number of padding bits left at
142 /// the end of the bit string, and in its second item
143 /// a `BitStringObject` structure which will, in its sole
144 /// structure field called `data`, contain a byte slice
145 /// representing the value of the bit string which can
146 /// be interpreted as a big-endian value with the padding
147 /// bits on the right (as in ASN.1 raw BER or DER encoding).
148 ///
149 /// To access the content as an integer, use the [`as_u64`](struct.BerObject.html#method.as_u64)
150 /// or [`as_u32`](struct.BerObject.html#method.as_u32) methods.
151 /// Remember that a BER bit string has unlimited size, so these methods return `Result` or `Option`
152 /// objects.
153 #[inline]
parse_der_bitstring(i: &[u8]) -> DerResult154 pub fn parse_der_bitstring(i: &[u8]) -> DerResult {
155     parse_der_with_tag(i, DerTag::BitString)
156 }
157 
158 /// Read an octetstring value
159 #[inline]
parse_der_octetstring(i: &[u8]) -> DerResult160 pub fn parse_der_octetstring(i: &[u8]) -> DerResult {
161     parse_der_with_tag(i, DerTag::OctetString)
162 }
163 
164 /// Read a null value
165 #[inline]
parse_der_null(i: &[u8]) -> DerResult166 pub fn parse_der_null(i: &[u8]) -> DerResult {
167     parse_der_with_tag(i, DerTag::Null)
168 }
169 
170 /// Read an object identifier value
171 #[inline]
parse_der_oid(i: &[u8]) -> DerResult172 pub fn parse_der_oid(i: &[u8]) -> DerResult {
173     parse_der_with_tag(i, DerTag::Oid)
174 }
175 
176 /// Read an enumerated value
177 #[inline]
parse_der_enum(i: &[u8]) -> DerResult178 pub fn parse_der_enum(i: &[u8]) -> DerResult {
179     parse_der_with_tag(i, DerTag::Enumerated)
180 }
181 
182 /// Read a UTF-8 string value. The encoding is checked.
183 #[inline]
parse_der_utf8string(i: &[u8]) -> DerResult184 pub fn parse_der_utf8string(i: &[u8]) -> DerResult {
185     parse_der_with_tag(i, DerTag::Utf8String)
186 }
187 
188 /// Read a relative object identifier value
189 #[inline]
parse_der_relative_oid(i: &[u8]) -> DerResult190 pub fn parse_der_relative_oid(i: &[u8]) -> DerResult {
191     parse_der_with_tag(i, DerTag::RelativeOid)
192 }
193 
194 /// Parse a sequence of DER elements
195 ///
196 /// Read a sequence of DER objects, without any constraint on the types.
197 /// Sequence is parsed recursively, so if structured elements are found, they are parsed using the
198 /// same function.
199 ///
200 /// To read a specific sequence of objects (giving the expected types), use the
201 /// [`parse_der_sequence_defined`](macro.parse_der_sequence_defined.html) macro.
202 #[inline]
parse_der_sequence(i: &[u8]) -> DerResult203 pub fn parse_der_sequence(i: &[u8]) -> DerResult {
204     parse_der_with_tag(i, DerTag::Sequence)
205 }
206 
207 /// Parse a set of DER elements
208 ///
209 /// Read a set of DER objects, without any constraint on the types.
210 /// Set is parsed recursively, so if structured elements are found, they are parsed using the
211 /// same function.
212 ///
213 /// To read a specific set of objects (giving the expected types), use the
214 /// [`parse_der_set_defined`](macro.parse_der_set_defined.html) macro.
215 #[inline]
parse_der_set(i: &[u8]) -> DerResult216 pub fn parse_der_set(i: &[u8]) -> DerResult {
217     parse_der_with_tag(i, DerTag::Set)
218 }
219 
220 /// Read a numeric string value. The content is verified to
221 /// contain only digits and spaces.
222 #[inline]
parse_der_numericstring(i: &[u8]) -> DerResult223 pub fn parse_der_numericstring(i: &[u8]) -> DerResult {
224     parse_der_with_tag(i, DerTag::NumericString)
225 }
226 
227 /// Read a printable string value. The content is verified to
228 /// contain only the allowed characters.
229 #[inline]
visiblestring(i: &[u8]) -> DerResult230 pub fn visiblestring(i: &[u8]) -> DerResult {
231     parse_der_with_tag(i, DerTag::VisibleString)
232 }
233 
234 /// Read a printable string value. The content is verified to
235 /// contain only the allowed characters.
236 #[inline]
parse_der_printablestring(i: &[u8]) -> DerResult237 pub fn parse_der_printablestring(i: &[u8]) -> DerResult {
238     parse_der_with_tag(i, DerTag::PrintableString)
239 }
240 
241 /// Read a T61 string value
242 #[inline]
parse_der_t61string(i: &[u8]) -> DerResult243 pub fn parse_der_t61string(i: &[u8]) -> DerResult {
244     parse_der_with_tag(i, DerTag::T61String)
245 }
246 
247 /// Read a Videotex string value
248 #[inline]
parse_der_videotexstring(i: &[u8]) -> DerResult249 pub fn parse_der_videotexstring(i: &[u8]) -> DerResult {
250     parse_der_with_tag(i, DerTag::VideotexString)
251 }
252 
253 /// Read an IA5 string value. The content is verified to be ASCII.
254 #[inline]
parse_der_ia5string(i: &[u8]) -> DerResult255 pub fn parse_der_ia5string(i: &[u8]) -> DerResult {
256     parse_der_with_tag(i, DerTag::Ia5String)
257 }
258 
259 /// Read an UTC time value
260 #[inline]
parse_der_utctime(i: &[u8]) -> DerResult261 pub fn parse_der_utctime(i: &[u8]) -> DerResult {
262     parse_der_with_tag(i, DerTag::UtcTime)
263 }
264 
265 /// Read a Generalized time value
266 #[inline]
parse_der_generalizedtime(i: &[u8]) -> DerResult267 pub fn parse_der_generalizedtime(i: &[u8]) -> DerResult {
268     parse_der_with_tag(i, DerTag::GeneralizedTime)
269 }
270 
271 /// Read a ObjectDescriptor value
272 #[inline]
parse_der_objectdescriptor(i: &[u8]) -> DerResult273 pub fn parse_der_objectdescriptor(i: &[u8]) -> DerResult {
274     parse_der_with_tag(i, DerTag::ObjDescriptor)
275 }
276 
277 /// Read a GraphicString value
278 #[inline]
parse_der_graphicstring(i: &[u8]) -> DerResult279 pub fn parse_der_graphicstring(i: &[u8]) -> DerResult {
280     parse_der_with_tag(i, DerTag::GraphicString)
281 }
282 
283 /// Read a GeneralString value
284 #[inline]
parse_der_generalstring(i: &[u8]) -> DerResult285 pub fn parse_der_generalstring(i: &[u8]) -> DerResult {
286     parse_der_with_tag(i, DerTag::GeneralString)
287 }
288 
289 /// Read a BmpString value
290 #[inline]
parse_der_bmpstring(i: &[u8]) -> DerResult291 pub fn parse_der_bmpstring(i: &[u8]) -> DerResult {
292     parse_der_with_tag(i, DerTag::BmpString)
293 }
294 
295 /// Read a UniversalString value
296 #[inline]
parse_der_universalstring(i: &[u8]) -> DerResult297 pub fn parse_der_universalstring(i: &[u8]) -> DerResult {
298     parse_der_with_tag(i, DerTag::UniversalString)
299 }
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]
parse_der_explicit_optional<F>(i: &[u8], tag: DerTag, f: F) -> DerResult where F: Fn(&[u8]) -> DerResult,312 pub fn parse_der_explicit_optional<F>(i: &[u8], tag: DerTag, f: F) -> DerResult
313 where
314     F: Fn(&[u8]) -> DerResult,
315 {
316     parse_ber_explicit_optional(i, tag, f)
317 }
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(DerTag::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]
parse_der_implicit<'a, Tag, F>(i: &'a [u8], tag: Tag, f: F) -> DerResult<'a> where F: Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>>, Tag: Into<DerTag>,359 pub fn parse_der_implicit<'a, Tag, F>(i: &'a [u8], tag: Tag, f: F) -> DerResult<'a>
360 where
361     F: Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>>,
362     Tag: Into<DerTag>,
363 {
364     parse_ber_implicit(i, tag, f)
365 }
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]
parse_der_i32(i: &[u8]) -> BerResult<i32>372 pub fn parse_der_i32(i: &[u8]) -> BerResult<i32> {
373     let (rem, der) = parse_der_integer(i)?;
374     let int = der.as_i32().map_err(nom::Err::Error)?;
375     Ok((rem, int))
376 }
377 
378 /// Parse DER object and try to decode it as a 64-bits signed integer
379 ///
380 /// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target
381 /// integer type.
382 #[inline]
parse_der_i64(i: &[u8]) -> BerResult<i64>383 pub fn parse_der_i64(i: &[u8]) -> BerResult<i64> {
384     let (rem, der) = parse_der_integer(i)?;
385     let int = der.as_i64().map_err(nom::Err::Error)?;
386     Ok((rem, int))
387 }
388 
389 /// Parse DER object and try to decode it as a 32-bits unsigned integer
390 ///
391 /// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target
392 /// integer type.
parse_der_u32(i: &[u8]) -> BerResult<u32>393 pub fn parse_der_u32(i: &[u8]) -> BerResult<u32> {
394     let (rem, der) = parse_der_integer(i)?;
395     let int = der.as_u32().map_err(nom::Err::Error)?;
396     Ok((rem, int))
397 }
398 
399 /// Parse DER object and try to decode it as a 64-bits unsigned integer
400 ///
401 /// Return `IntegerTooLarge` if object is an integer, but can not be represented in the target
402 /// integer type.
parse_der_u64(i: &[u8]) -> BerResult<u64>403 pub fn parse_der_u64(i: &[u8]) -> BerResult<u64> {
404     let (rem, der) = parse_der_integer(i)?;
405     let int = der.as_u64().map_err(nom::Err::Error)?;
406     Ok((rem, int))
407 }
408 
409 /// Parse DER object and get content as slice
410 #[inline]
parse_der_slice<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> BerResult<&[u8]>411 pub fn parse_der_slice<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> BerResult<&[u8]> {
412     let tag = tag.into();
413     parse_der_container(move |content, hdr| {
414         if hdr.tag != tag {
415             return Err(Err::Error(BerError::InvalidTag));
416         }
417         Ok((&b""[..], content))
418     })(i)
419 }
420 
421 /// Parse the next bytes as the content of a DER object (combinator, header reference)
422 ///
423 /// Content type is *not* checked to match tag, caller is responsible of providing the correct tag
424 ///
425 /// Caller is also responsible to check if parsing function consumed the expected number of
426 /// bytes (`header.len`).
427 ///
428 /// This function differs from [`parse_der_content2`](fn.parse_der_content2.html) because it passes
429 /// the BER object header by reference (required for ex. by `parse_der_implicit`).
430 ///
431 /// The arguments of the parse function are: `(input, ber_object_header, max_recursion)`.
432 ///
433 /// Example: manually parsing header and content
434 ///
435 /// ```
436 /// # use der_parser::ber::MAX_RECURSION;
437 /// # use der_parser::der::*;
438 /// #
439 /// # let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
440 /// let (i, header) = der_read_element_header(bytes).expect("parsing failed");
441 /// let (rem, content) = parse_der_content(header.tag)(i, &header, MAX_RECURSION)
442 ///     .expect("parsing failed");
443 /// #
444 /// # assert_eq!(header.tag, DerTag::Integer);
445 /// ```
parse_der_content<'a>( tag: DerTag, ) -> impl Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>>446 pub fn parse_der_content<'a>(
447     tag: DerTag,
448 ) -> impl Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>> {
449     move |i: &[u8], hdr: &DerObjectHeader, max_recursion: usize| {
450         der_read_element_content_as(i, tag, hdr.len, hdr.is_constructed(), max_recursion)
451     }
452 }
453 
454 /// Parse the next bytes as the content of a DER object (combinator, owned header)
455 ///
456 /// Content type is *not* checked to match tag, caller is responsible of providing the correct tag
457 ///
458 /// Caller is also responsible to check if parsing function consumed the expected number of
459 /// bytes (`header.len`).
460 ///
461 /// The arguments of the parse function are: `(input, ber_object_header, max_recursion)`.
462 ///
463 /// This function differs from [`parse_der_content`](fn.parse_der_content.html) because it passes
464 /// an owned BER object header (required for ex. by `parse_der_tagged_implicit_g`).
465 ///
466 /// Example: manually parsing header and content
467 ///
468 /// ```
469 /// # use der_parser::ber::MAX_RECURSION;
470 /// # use der_parser::der::*;
471 /// #
472 /// # let bytes = &[0x02, 0x03, 0x01, 0x00, 0x01];
473 /// let (i, header) = der_read_element_header(bytes).expect("parsing failed");
474 /// # assert_eq!(header.tag, DerTag::Integer);
475 /// let (rem, content) = parse_der_content2(header.tag)(i, header, MAX_RECURSION)
476 ///     .expect("parsing failed");
477 /// ```
parse_der_content2<'a>( tag: DerTag, ) -> impl Fn(&'a [u8], DerObjectHeader<'a>, usize) -> BerResult<'a, DerObjectContent<'a>>478 pub fn parse_der_content2<'a>(
479     tag: DerTag,
480 ) -> impl Fn(&'a [u8], DerObjectHeader<'a>, usize) -> BerResult<'a, DerObjectContent<'a>> {
481     move |i: &[u8], hdr: DerObjectHeader, max_recursion: usize| {
482         der_read_element_content_as(i, tag, hdr.len, hdr.is_constructed(), max_recursion)
483     }
484 }
485 
486 // --------- end of parse_der_xxx functions ----------
487 
488 /// Parse the next bytes as the content of a DER object.
489 ///
490 /// Content type is *not* checked, caller is responsible of providing the correct tag
der_read_element_content_as( i: &[u8], tag: DerTag, len: BerSize, constructed: bool, max_depth: usize, ) -> BerResult<DerObjectContent>491 pub fn der_read_element_content_as(
492     i: &[u8],
493     tag: DerTag,
494     len: BerSize,
495     constructed: bool,
496     max_depth: usize,
497 ) -> BerResult<DerObjectContent> {
498     // Indefinite lengths are not allowed in DER (X.690 section 10.1)
499     let l = len.primitive()?;
500     if i.len() < l {
501         return Err(Err::Incomplete(Needed::new(l)));
502     }
503     match tag {
504         DerTag::Boolean => {
505             custom_check!(i, l != 1, BerError::InvalidLength)?;
506             der_constraint_fail_if!(i, i[0] != 0 && i[0] != 0xff);
507         }
508         DerTag::BitString => {
509             der_constraint_fail_if!(i, constructed);
510             // exception: read and verify padding bits
511             return der_read_content_bitstring(i, l);
512         }
513         DerTag::Integer => {
514             // verify leading zeros
515             match i[..l] {
516                 [] => return Err(nom::Err::Error(BerError::DerConstraintFailed)),
517                 [0, 0, ..] => return Err(nom::Err::Error(BerError::DerConstraintFailed)),
518                 [0, byte, ..] if byte < 0x80 => {
519                     return Err(nom::Err::Error(BerError::DerConstraintFailed));
520                 }
521                 _ => (),
522             }
523         }
524         DerTag::NumericString
525         | DerTag::VisibleString
526         | DerTag::PrintableString
527         | DerTag::Ia5String
528         | DerTag::Utf8String
529         | DerTag::T61String
530         | DerTag::VideotexString
531         | DerTag::BmpString
532         | DerTag::UniversalString
533         | DerTag::ObjDescriptor
534         | DerTag::GraphicString
535         | DerTag::GeneralString => {
536             der_constraint_fail_if!(i, constructed);
537         }
538         DerTag::UtcTime | DerTag::GeneralizedTime => {
539             if l == 0 || i.get(l - 1).cloned() != Some(b'Z') {
540                 return Err(Err::Error(BerError::DerConstraintFailed));
541             }
542         }
543         _ => (),
544     }
545     ber_read_element_content_as(i, tag, len, constructed, max_depth)
546 }
547 
548 /// Parse DER object content recursively
549 ///
550 /// *Note: an error is raised if recursion depth exceeds `MAX_RECURSION`.
der_read_element_content<'a>(i: &'a [u8], hdr: DerObjectHeader<'a>) -> DerResult<'a>551 pub fn der_read_element_content<'a>(i: &'a [u8], hdr: DerObjectHeader<'a>) -> DerResult<'a> {
552     der_read_element_content_recursive(i, hdr, MAX_RECURSION)
553 }
554 
der_read_element_content_recursive<'a>( i: &'a [u8], hdr: DerObjectHeader<'a>, max_depth: usize, ) -> DerResult<'a>555 fn der_read_element_content_recursive<'a>(
556     i: &'a [u8],
557     hdr: DerObjectHeader<'a>,
558     max_depth: usize,
559 ) -> DerResult<'a> {
560     match hdr.class {
561         BerClass::Universal => (),
562         BerClass::Private => {
563             let (rem, content) = ber_get_object_content(i, &hdr, max_depth)?;
564             let content = BerObjectContent::Private(hdr.clone(), content);
565             let obj = BerObject::from_header_and_content(hdr, content);
566             return Ok((rem, obj));
567         }
568         _ => {
569             let (i, content) = ber_get_object_content(i, &hdr, max_depth)?;
570             let content = DerObjectContent::Unknown(hdr.class, hdr.tag, content);
571             let obj = DerObject::from_header_and_content(hdr, content);
572             return Ok((i, obj));
573         }
574     }
575     match der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), max_depth) {
576         Ok((rem, content)) => Ok((rem, DerObject::from_header_and_content(hdr, content))),
577         Err(Err::Error(BerError::UnknownTag)) => {
578             let (rem, content) = ber_get_object_content(i, &hdr, max_depth)?;
579             let content = DerObjectContent::Unknown(hdr.class, hdr.tag, content);
580             let obj = DerObject::from_header_and_content(hdr, content);
581             Ok((rem, obj))
582         }
583         Err(e) => Err(e),
584     }
585 }
586 
der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent>587 fn der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent> {
588     let (i, ignored_bits) = be_u8(i)?;
589     if ignored_bits > 7 {
590         return Err(Err::Error(BerError::DerConstraintFailed));
591     }
592     if len == 0 {
593         return Err(Err::Error(BerError::InvalidLength));
594     }
595     let (i, data) = take(len - 1)(i)?;
596     if len > 1 {
597         let mut last_byte = data[len - 2];
598         for _ in 0..ignored_bits as usize {
599             der_constraint_fail_if!(i, last_byte & 1 != 0);
600             last_byte >>= 1;
601         }
602     }
603     Ok((
604         i,
605         DerObjectContent::BitString(ignored_bits, BitStringObject { data }),
606     ))
607     // do_parse! {
608     //     i,
609     //     ignored_bits: be_u8 >>
610     //                   custom_check!(ignored_bits > 7, BerError::DerConstraintFailed) >>
611     //                   custom_check!(len == 0, BerError::InvalidLength) >>
612     //     s:            take!(len - 1) >>
613     //                   call!(|input| {
614     //                       if len > 1 {
615     //                           let mut last_byte = s[len-2];
616     //                           for _ in 0..ignored_bits as usize {
617     //                               der_constraint_fail_if!(i, last_byte & 1 != 0);
618     //                               last_byte >>= 1;
619     //                           }
620     //                       }
621     //                       Ok((input,()))
622     //                   }) >>
623     //     ( DerObjectContent::BitString(ignored_bits,BitStringObject{ data:s }) )
624     // }
625 }
626 
627 /// Read an object header (DER)
der_read_element_header(i: &[u8]) -> BerResult<DerObjectHeader>628 pub fn der_read_element_header(i: &[u8]) -> BerResult<DerObjectHeader> {
629     let (i1, el) = parse_identifier(i)?;
630     let class = match DerClass::try_from(el.0) {
631         Ok(c) => c,
632         Err(_) => unreachable!(), // Cannot fail, we have read exactly 2 bits
633     };
634     let (i2, len) = parse_ber_length_byte(i1)?;
635     let (i3, len) = match (len.0, len.1) {
636         (0, l1) => {
637             // Short form: MSB is 0, the rest encodes the length (which can be 0) (8.1.3.4)
638             (i2, BerSize::Definite(usize::from(l1)))
639         }
640         (_, 0) => {
641             // Indefinite form is not allowed in DER (10.1)
642             return Err(::nom::Err::Error(BerError::DerConstraintFailed));
643         }
644         (_, l1) => {
645             // if len is 0xff -> error (8.1.3.5)
646             if l1 == 0b0111_1111 {
647                 return Err(::nom::Err::Error(BerError::InvalidTag));
648             }
649             // DER(9.1) if len is 0 (indefinite form), obj must be constructed
650             der_constraint_fail_if!(&i[1..], len.1 == 0 && el.1 != 1);
651             let (i3, llen) = take(l1)(i2)?;
652             match bytes_to_u64(llen) {
653                 Ok(l) => {
654                     // DER: should have been encoded in short form (< 127)
655                     der_constraint_fail_if!(i, l < 127);
656                     let l =
657                         usize::try_from(l).or(Err(::nom::Err::Error(BerError::InvalidLength)))?;
658                     (i3, BerSize::Definite(l))
659                 }
660                 Err(_) => {
661                     return Err(::nom::Err::Error(BerError::InvalidTag));
662                 }
663             }
664         }
665     };
666     let hdr = DerObjectHeader::new(class, el.1, BerTag(el.2), len).with_raw_tag(Some(el.3));
667     Ok((i3, hdr))
668 }
669