Coverage Report

Created: 2025-10-29 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/der-parser-10.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};
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
0
pub fn parse_der(i: &[u8]) -> DerResult {
30
0
    parse_der_recursive(i, MAX_RECURSION)
31
0
}
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
0
pub fn parse_der_recursive(i: &[u8], max_depth: usize) -> DerResult {
48
0
    let (i, hdr) = der_read_element_header(i)?;
49
    // safety check: length cannot be more than 2^32 bytes
50
0
    if let Length::Definite(l) = hdr.length() {
51
0
        custom_check!(i, l > MAX_OBJECT_SIZE, BerError::InvalidLength)?;
52
0
    }
53
0
    der_read_element_content_recursive(i, hdr, max_depth)
54
0
}
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
0
pub fn parse_der_with_tag<T: Into<Tag>>(i: &[u8], tag: T) -> DerResult {
71
0
    let tag = tag.into();
72
0
    let (i, hdr) = der_read_element_header(i)?;
73
0
    hdr.assert_tag(tag)?;
74
0
    let (i, content) = der_read_element_content_as(
75
0
        i,
76
0
        hdr.tag(),
77
0
        hdr.length(),
78
0
        hdr.is_constructed(),
79
        MAX_RECURSION,
80
0
    )?;
81
0
    Ok((i, DerObject::from_header_and_content(hdr, content)))
82
0
}
Unexecuted instantiation: der_parser::der::parser::parse_der_with_tag::<asn1_rs::tag::Tag>
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
}
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
}
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
0
pub fn parse_der_bitstring(i: &[u8]) -> DerResult {
149
0
    parse_der_with_tag(i, Tag::BitString)
150
0
}
Unexecuted instantiation: der_parser::der::parser::parse_der_bitstring
Unexecuted instantiation: der_parser::der::parser::parse_der_bitstring
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
}
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
}
163
164
/// Read an object identifier value
165
#[inline]
166
0
pub fn parse_der_oid(i: &[u8]) -> DerResult {
167
0
    parse_der_with_tag(i, Tag::Oid)
168
0
}
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
}
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
0
pub fn parse_der_sequence(i: &[u8]) -> DerResult {
198
0
    parse_der_with_tag(i, Tag::Sequence)
199
0
}
Unexecuted instantiation: der_parser::der::parser::parse_der_sequence
Unexecuted instantiation: der_parser::der::parser::parse_der_sequence
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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::<u32, der_parser::der::parser::parse_der_content::{closure#0}>
Unexecuted instantiation: der_parser::der::parser::parse_der_implicit::<_, _>
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
}
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
}
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
}
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
}
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)
409
0
}
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
0
    move |i: &[u8], hdr: &Header, max_recursion: usize| {
440
0
        der_read_element_content_as(i, tag, hdr.length(), hdr.is_constructed(), max_recursion)
441
0
    }
Unexecuted instantiation: der_parser::der::parser::parse_der_content::{closure#0}
Unexecuted instantiation: der_parser::der::parser::parse_der_content::{closure#0}
442
0
}
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
    }
474
0
}
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
0
pub fn der_read_element_content_as(
482
0
    i: &[u8],
483
0
    tag: Tag,
484
0
    length: Length,
485
0
    constructed: bool,
486
0
    max_depth: usize,
487
0
) -> BerResult<DerObjectContent> {
488
    // Indefinite lengths are not allowed in DER (X.690 section 10.1)
489
0
    let l = length.definite()?;
490
0
    if i.len() < l {
491
0
        return Err(Err::Incomplete(Needed::new(l)));
492
0
    }
493
0
    match tag {
494
        Tag::Boolean => {
495
0
            custom_check!(i, l != 1, BerError::InvalidLength)?;
496
0
            der_constraint_fail_if!(i, i[0] != 0 && i[0] != 0xff, DerConstraint::InvalidBoolean);
497
        }
498
        Tag::BitString => {
499
0
            der_constraint_fail_if!(i, constructed, DerConstraint::Constructed);
500
            // exception: read and verify padding bits
501
0
            return der_read_content_bitstring(i, l);
502
        }
503
        Tag::Integer => {
504
            // verify leading zeros
505
0
            match i[..l] {
506
0
                [] => {
507
0
                    return Err(Err::Error(BerError::DerConstraintFailed(
508
0
                        DerConstraint::IntegerEmpty,
509
0
                    )))
510
                }
511
0
                [0, 0, ..] => {
512
0
                    return Err(Err::Error(BerError::DerConstraintFailed(
513
0
                        DerConstraint::IntegerLeadingZeroes,
514
0
                    )))
515
                }
516
0
                [0, byte, ..] if byte < 0x80 => {
517
0
                    return Err(Err::Error(BerError::DerConstraintFailed(
518
0
                        DerConstraint::IntegerLeadingZeroes,
519
0
                    )));
520
                }
521
0
                _ => (),
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
0
            der_constraint_fail_if!(i, constructed, DerConstraint::Constructed);
537
        }
538
        Tag::UtcTime | Tag::GeneralizedTime => {
539
0
            if l == 0 || i.get(l - 1).cloned() != Some(b'Z') {
540
0
                return Err(Err::Error(BerError::DerConstraintFailed(
541
0
                    DerConstraint::MissingTimeZone,
542
0
                )));
543
0
            }
544
        }
545
0
        _ => (),
546
    }
547
0
    ber_read_element_content_as(i, tag, length, constructed, max_depth)
548
0
}
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
}
556
557
0
fn der_read_element_content_recursive<'a>(
558
0
    i: &'a [u8],
559
0
    hdr: Header<'a>,
560
0
    max_depth: usize,
561
0
) -> DerResult<'a> {
562
0
    match hdr.class() {
563
0
        Class::Universal => (),
564
        _ => {
565
0
            let (i, data) = ber_get_object_content(i, &hdr, max_depth)?;
566
0
            let any = Any::new(hdr.clone(), data);
567
0
            let content = DerObjectContent::Unknown(any);
568
0
            let obj = DerObject::from_header_and_content(hdr, content);
569
0
            return Ok((i, obj));
570
        }
571
    }
572
0
    match der_read_element_content_as(i, hdr.tag(), hdr.length(), hdr.is_constructed(), max_depth) {
573
0
        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
0
        Err(e) => Err(e),
582
    }
583
0
}
584
585
0
fn der_read_content_bitstring(i: &[u8], len: usize) -> BerResult<DerObjectContent> {
586
0
    let (i, ignored_bits) = be_u8(i)?;
587
0
    if ignored_bits > 7 {
588
0
        return Err(Err::Error(BerError::invalid_value(
589
0
            Tag::BitString,
590
0
            "More than 7 unused bits".to_owned(),
591
0
        )));
592
0
    }
593
0
    if len == 0 {
594
0
        return Err(Err::Error(BerError::InvalidLength));
595
0
    }
596
0
    let (i, data) = take(len - 1)(i)?;
597
0
    if len > 1 {
598
0
        let mut last_byte = data[len - 2];
599
0
        for _ in 0..ignored_bits as usize {
600
0
            der_constraint_fail_if!(i, last_byte & 1 != 0, DerConstraint::UnusedBitsNotZero);
601
0
            last_byte >>= 1;
602
        }
603
0
    }
604
0
    Ok((
605
0
        i,
606
0
        DerObjectContent::BitString(ignored_bits, BitStringObject { data }),
607
0
    ))
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
0
}
627
628
/// Read an object header (DER)
629
#[inline]
630
0
pub fn der_read_element_header(i: &[u8]) -> BerResult<Header> {
631
0
    Header::from_der(i)
632
0
}
Unexecuted instantiation: der_parser::der::parser::der_read_element_header
Unexecuted instantiation: der_parser::der::parser::der_read_element_header