Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}