Coverage Report

Created: 2026-02-14 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/der-parser-6.0.1/src/der/parser.rs
Line
Count
Source
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]
26
286k
pub fn parse_der(i: &[u8]) -> DerResult {
27
286k
    parse_der_recursive(i, MAX_RECURSION)
28
286k
}
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
/// ```
44
286k
pub fn parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult {
45
286k
    let (i, hdr) = der_read_element_header(i)?;
46
    // safety check: length cannot be more than 2^32 bytes
47
240k
    if let BerSize::Definite(l) = hdr.len {
48
240k
        custom_check!(i, l > MAX_OBJECT_SIZE, BerError::InvalidLength)?;
49
0
    }
50
238k
    der_read_element_content_recursive(i, hdr, max_depth)
51
286k
}
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
/// ```
79
818k
pub fn parse_der_with_tag<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> DerResult {
80
818k
    let tag = tag.into();
81
818k
    let (i, hdr) = der_read_element_header(i)?;
82
730k
    if hdr.tag != tag {
83
28.7k
        return Err(nom::Err::Error(BerError::InvalidTag));
84
702k
    }
85
688k
    let (i, content) =
86
702k
        der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), MAX_RECURSION)?;
87
688k
    Ok((i, DerObject::from_header_and_content(hdr, content)))
88
818k
}
der_parser::der::parser::parse_der_with_tag::<der_parser::ber::ber::BerTag>
Line
Count
Source
79
78.1k
pub fn parse_der_with_tag<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> DerResult {
80
78.1k
    let tag = tag.into();
81
78.1k
    let (i, hdr) = der_read_element_header(i)?;
82
55.4k
    if hdr.tag != tag {
83
23.7k
        return Err(nom::Err::Error(BerError::InvalidTag));
84
31.7k
    }
85
29.1k
    let (i, content) =
86
31.7k
        der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), MAX_RECURSION)?;
87
29.1k
    Ok((i, DerObject::from_header_and_content(hdr, content)))
88
78.1k
}
der_parser::der::parser::parse_der_with_tag::<der_parser::ber::ber::BerTag>
Line
Count
Source
79
341k
pub fn parse_der_with_tag<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> DerResult {
80
341k
    let tag = tag.into();
81
341k
    let (i, hdr) = der_read_element_header(i)?;
82
281k
    if hdr.tag != tag {
83
3.53k
        return Err(nom::Err::Error(BerError::InvalidTag));
84
277k
    }
85
272k
    let (i, content) =
86
277k
        der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), MAX_RECURSION)?;
87
272k
    Ok((i, DerObject::from_header_and_content(hdr, content)))
88
341k
}
der_parser::der::parser::parse_der_with_tag::<der_parser::ber::ber::BerTag>
Line
Count
Source
79
399k
pub fn parse_der_with_tag<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> DerResult {
80
399k
    let tag = tag.into();
81
399k
    let (i, hdr) = der_read_element_header(i)?;
82
394k
    if hdr.tag != tag {
83
1.44k
        return Err(nom::Err::Error(BerError::InvalidTag));
84
392k
    }
85
386k
    let (i, content) =
86
392k
        der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), MAX_RECURSION)?;
87
386k
    Ok((i, DerObject::from_header_and_content(hdr, content)))
88
399k
}
89
90
/// Read end of content marker
91
#[inline]
92
0
pub fn parse_der_endofcontent(i: &[u8]) -> DerResult {
93
0
    parse_der_with_tag(i, DerTag::EndOfContent)
94
0
}
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]
104
0
pub fn parse_der_bool(i: &[u8]) -> DerResult {
105
0
    parse_der_with_tag(i, DerTag::Boolean)
106
0
}
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]
133
501k
pub fn parse_der_integer(i: &[u8]) -> DerResult {
134
501k
    parse_der_with_tag(i, DerTag::Integer)
135
501k
}
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]
154
68.2k
pub fn parse_der_bitstring(i: &[u8]) -> DerResult {
155
68.2k
    parse_der_with_tag(i, DerTag::BitString)
156
68.2k
}
157
158
/// Read an octetstring value
159
#[inline]
160
1.29k
pub fn parse_der_octetstring(i: &[u8]) -> DerResult {
161
1.29k
    parse_der_with_tag(i, DerTag::OctetString)
162
1.29k
}
163
164
/// Read a null value
165
#[inline]
166
0
pub fn parse_der_null(i: &[u8]) -> DerResult {
167
0
    parse_der_with_tag(i, DerTag::Null)
168
0
}
169
170
/// Read an object identifier value
171
#[inline]
172
76.5k
pub fn parse_der_oid(i: &[u8]) -> DerResult {
173
76.5k
    parse_der_with_tag(i, DerTag::Oid)
174
76.5k
}
175
176
/// Read an enumerated value
177
#[inline]
178
0
pub fn parse_der_enum(i: &[u8]) -> DerResult {
179
0
    parse_der_with_tag(i, DerTag::Enumerated)
180
0
}
181
182
/// Read a UTF-8 string value. The encoding is checked.
183
#[inline]
184
0
pub fn parse_der_utf8string(i: &[u8]) -> DerResult {
185
0
    parse_der_with_tag(i, DerTag::Utf8String)
186
0
}
187
188
/// Read a relative object identifier value
189
#[inline]
190
0
pub fn parse_der_relative_oid(i: &[u8]) -> DerResult {
191
0
    parse_der_with_tag(i, DerTag::RelativeOid)
192
0
}
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]
203
1.62k
pub fn parse_der_sequence(i: &[u8]) -> DerResult {
204
1.62k
    parse_der_with_tag(i, DerTag::Sequence)
205
1.62k
}
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]
216
0
pub fn parse_der_set(i: &[u8]) -> DerResult {
217
0
    parse_der_with_tag(i, DerTag::Set)
218
0
}
219
220
/// Read a numeric string value. The content is verified to
221
/// contain only digits and spaces.
222
#[inline]
223
0
pub fn parse_der_numericstring(i: &[u8]) -> DerResult {
224
0
    parse_der_with_tag(i, DerTag::NumericString)
225
0
}
226
227
/// Read a printable string value. The content is verified to
228
/// contain only the allowed characters.
229
#[inline]
230
0
pub fn visiblestring(i: &[u8]) -> DerResult {
231
0
    parse_der_with_tag(i, DerTag::VisibleString)
232
0
}
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, DerTag::PrintableString)
239
0
}
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, DerTag::T61String)
245
0
}
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, DerTag::VideotexString)
251
0
}
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, DerTag::Ia5String)
257
0
}
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, DerTag::UtcTime)
263
0
}
264
265
/// Read a Generalized time value
266
#[inline]
267
72.1k
pub fn parse_der_generalizedtime(i: &[u8]) -> DerResult {
268
72.1k
    parse_der_with_tag(i, DerTag::GeneralizedTime)
269
72.1k
}
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, DerTag::ObjDescriptor)
275
0
}
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, DerTag::GraphicString)
281
0
}
282
283
/// Read a GeneralString value
284
#[inline]
285
97.5k
pub fn parse_der_generalstring(i: &[u8]) -> DerResult {
286
97.5k
    parse_der_with_tag(i, DerTag::GeneralString)
287
97.5k
}
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, DerTag::BmpString)
293
0
}
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, DerTag::UniversalString)
299
0
}
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: DerTag, f: F) -> DerResult
313
0
where
314
0
    F: Fn(&[u8]) -> DerResult,
315
{
316
0
    parse_ber_explicit_optional(i, tag, f)
317
0
}
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]
359
0
pub fn parse_der_implicit<'a, Tag, F>(i: &'a [u8], tag: Tag, f: F) -> DerResult<'a>
360
0
where
361
0
    F: Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>>,
362
0
    Tag: Into<DerTag>,
363
{
364
0
    parse_ber_implicit(i, tag, f)
365
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
    let (rem, der) = parse_der_integer(i)?;
374
0
    let int = der.as_i32().map_err(nom::Err::Error)?;
375
0
    Ok((rem, int))
376
0
}
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]
383
0
pub fn parse_der_i64(i: &[u8]) -> BerResult<i64> {
384
0
    let (rem, der) = parse_der_integer(i)?;
385
0
    let int = der.as_i64().map_err(nom::Err::Error)?;
386
0
    Ok((rem, int))
387
0
}
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.
393
399k
pub fn parse_der_u32(i: &[u8]) -> BerResult<u32> {
394
399k
    let (rem, der) = parse_der_integer(i)?;
395
386k
    let int = der.as_u32().map_err(nom::Err::Error)?;
396
382k
    Ok((rem, int))
397
399k
}
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.
403
0
pub fn parse_der_u64(i: &[u8]) -> BerResult<u64> {
404
0
    let (rem, der) = parse_der_integer(i)?;
405
0
    let int = der.as_u64().map_err(nom::Err::Error)?;
406
0
    Ok((rem, int))
407
0
}
408
409
/// Parse DER object and get content as slice
410
#[inline]
411
0
pub fn parse_der_slice<Tag: Into<DerTag>>(i: &[u8], tag: Tag) -> BerResult<&[u8]> {
412
0
    let tag = tag.into();
413
0
    parse_der_container(move |content, hdr| {
414
0
        if hdr.tag != tag {
415
0
            return Err(Err::Error(BerError::InvalidTag));
416
0
        }
417
0
        Ok((&b""[..], content))
418
0
    })(i)
419
0
}
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
/// ```
446
0
pub fn parse_der_content<'a>(
447
0
    tag: DerTag,
448
0
) -> impl Fn(&'a [u8], &'_ DerObjectHeader, usize) -> BerResult<'a, DerObjectContent<'a>> {
449
0
    move |i: &[u8], hdr: &DerObjectHeader, max_recursion: usize| {
450
0
        der_read_element_content_as(i, tag, hdr.len, hdr.is_constructed(), max_recursion)
451
0
    }
452
0
}
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
/// ```
478
0
pub fn parse_der_content2<'a>(
479
0
    tag: DerTag,
480
0
) -> impl Fn(&'a [u8], DerObjectHeader<'a>, usize) -> BerResult<'a, DerObjectContent<'a>> {
481
0
    move |i: &[u8], hdr: DerObjectHeader, max_recursion: usize| {
482
0
        der_read_element_content_as(i, tag, hdr.len, hdr.is_constructed(), max_recursion)
483
0
    }
484
0
}
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
491
885k
pub fn der_read_element_content_as(
492
885k
    i: &[u8],
493
885k
    tag: DerTag,
494
885k
    len: BerSize,
495
885k
    constructed: bool,
496
885k
    max_depth: usize,
497
885k
) -> BerResult<DerObjectContent> {
498
    // Indefinite lengths are not allowed in DER (X.690 section 10.1)
499
885k
    let l = len.primitive()?;
500
885k
    if i.len() < l {
501
7.61k
        return Err(Err::Incomplete(Needed::new(l)));
502
878k
    }
503
878k
    match tag {
504
        DerTag::Boolean => {
505
7.20k
            custom_check!(i, l != 1, BerError::InvalidLength)?;
506
3.95k
            der_constraint_fail_if!(i, i[0] != 0 && i[0] != 0xff);
507
        }
508
        DerTag::BitString => {
509
85.8k
            der_constraint_fail_if!(i, constructed);
510
            // exception: read and verify padding bits
511
85.1k
            return der_read_content_bitstring(i, l);
512
        }
513
        DerTag::Integer => {
514
            // verify leading zeros
515
454k
            match i[..l] {
516
454k
                [] => return Err(nom::Err::Error(BerError::DerConstraintFailed)),
517
452k
                [0, 0, ..] => return Err(nom::Err::Error(BerError::DerConstraintFailed)),
518
20.5k
                [0, byte, ..] if byte < 0x80 => {
519
1.73k
                    return Err(nom::Err::Error(BerError::DerConstraintFailed));
520
                }
521
447k
                _ => (),
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
123k
            der_constraint_fail_if!(i, constructed);
537
        }
538
        DerTag::UtcTime | DerTag::GeneralizedTime => {
539
75.8k
            if l == 0 || i.get(l - 1).cloned() != Some(b'Z') {
540
3.66k
                return Err(Err::Error(BerError::DerConstraintFailed));
541
72.1k
            }
542
        }
543
131k
        _ => (),
544
    }
545
773k
    ber_read_element_content_as(i, tag, len, constructed, max_depth)
546
885k
}
547
548
/// Parse DER object content recursively
549
///
550
/// *Note: an error is raised if recursion depth exceeds `MAX_RECURSION`.
551
0
pub fn der_read_element_content<'a>(i: &'a [u8], hdr: DerObjectHeader<'a>) -> DerResult<'a> {
552
0
    der_read_element_content_recursive(i, hdr, MAX_RECURSION)
553
0
}
554
555
238k
fn der_read_element_content_recursive<'a>(
556
238k
    i: &'a [u8],
557
238k
    hdr: DerObjectHeader<'a>,
558
238k
    max_depth: usize,
559
238k
) -> DerResult<'a> {
560
238k
    match hdr.class {
561
183k
        BerClass::Universal => (),
562
        BerClass::Private => {
563
6.57k
            let (rem, content) = ber_get_object_content(i, &hdr, max_depth)?;
564
4.34k
            let content = BerObjectContent::Private(hdr.clone(), content);
565
4.34k
            let obj = BerObject::from_header_and_content(hdr, content);
566
4.34k
            return Ok((rem, obj));
567
        }
568
        _ => {
569
48.3k
            let (i, content) = ber_get_object_content(i, &hdr, max_depth)?;
570
38.3k
            let content = DerObjectContent::Unknown(hdr.class, hdr.tag, content);
571
38.3k
            let obj = DerObject::from_header_and_content(hdr, content);
572
38.3k
            return Ok((i, obj));
573
        }
574
    }
575
183k
    match der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), max_depth) {
576
124k
        Ok((rem, content)) => Ok((rem, DerObject::from_header_and_content(hdr, content))),
577
        Err(Err::Error(BerError::UnknownTag)) => {
578
2.93k
            let (rem, content) = ber_get_object_content(i, &hdr, max_depth)?;
579
2.93k
            let content = DerObjectContent::Unknown(hdr.class, hdr.tag, content);
580
2.93k
            let obj = DerObject::from_header_and_content(hdr, content);
581
2.93k
            Ok((rem, obj))
582
        }
583
56.1k
        Err(e) => Err(e),
584
    }
585
238k
}
586
587
85.1k
fn der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent> {
588
85.1k
    let (i, ignored_bits) = be_u8(i)?;
589
83.6k
    if ignored_bits > 7 {
590
1.84k
        return Err(Err::Error(BerError::DerConstraintFailed));
591
81.8k
    }
592
81.8k
    if len == 0 {
593
1.81k
        return Err(Err::Error(BerError::InvalidLength));
594
79.9k
    }
595
79.9k
    let (i, data) = take(len - 1)(i)?;
596
79.9k
    if len > 1 {
597
77.7k
        let mut last_byte = data[len - 2];
598
77.7k
        for _ in 0..ignored_bits as usize {
599
105k
            der_constraint_fail_if!(i, last_byte & 1 != 0);
600
96.5k
            last_byte >>= 1;
601
        }
602
2.19k
    }
603
71.0k
    Ok((
604
71.0k
        i,
605
71.0k
        DerObjectContent::BitString(ignored_bits, BitStringObject { data }),
606
71.0k
    ))
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
85.1k
}
626
627
/// Read an object header (DER)
628
1.10M
pub fn der_read_element_header(i: &[u8]) -> BerResult<DerObjectHeader> {
629
1.10M
    let (i1, el) = parse_identifier(i)?;
630
994k
    let class = match DerClass::try_from(el.0) {
631
994k
        Ok(c) => c,
632
0
        Err(_) => unreachable!(), // Cannot fail, we have read exactly 2 bits
633
    };
634
994k
    let (i2, len) = parse_ber_length_byte(i1)?;
635
988k
    let (i3, len) = match (len.0, len.1) {
636
963k
        (0, l1) => {
637
            // Short form: MSB is 0, the rest encodes the length (which can be 0) (8.1.3.4)
638
963k
            (i2, BerSize::Definite(usize::from(l1)))
639
        }
640
        (_, 0) => {
641
            // Indefinite form is not allowed in DER (10.1)
642
1.33k
            return Err(::nom::Err::Error(BerError::DerConstraintFailed));
643
        }
644
24.4k
        (_, l1) => {
645
            // if len is 0xff -> error (8.1.3.5)
646
24.4k
            if l1 == 0b0111_1111 {
647
5.12k
                return Err(::nom::Err::Error(BerError::InvalidTag));
648
19.3k
            }
649
            // DER(9.1) if len is 0 (indefinite form), obj must be constructed
650
19.3k
            der_constraint_fail_if!(&i[1..], len.1 == 0 && el.1 != 1);
651
19.3k
            let (i3, llen) = take(l1)(i2)?;
652
13.7k
            match bytes_to_u64(llen) {
653
9.44k
                Ok(l) => {
654
                    // DER: should have been encoded in short form (< 127)
655
9.44k
                    der_constraint_fail_if!(i, l < 127);
656
8.34k
                    let l =
657
8.34k
                        usize::try_from(l).or(Err(::nom::Err::Error(BerError::InvalidLength)))?;
658
8.34k
                    (i3, BerSize::Definite(l))
659
                }
660
                Err(_) => {
661
4.30k
                    return Err(::nom::Err::Error(BerError::InvalidTag));
662
                }
663
            }
664
        }
665
    };
666
971k
    let hdr = DerObjectHeader::new(class, el.1, BerTag(el.2), len).with_raw_tag(Some(el.3));
667
971k
    Ok((i3, hdr))
668
1.10M
}