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/asn1-rs-0.6.2/src/ber/parser.rs
Line
Count
Source
1
use crate::error::*;
2
use crate::header::*;
3
use crate::{BerParser, DerParser, FromBer, Length, Tag};
4
use nom::bytes::streaming::take;
5
use nom::{Err, Needed, Offset};
6
use rusticata_macros::custom_check;
7
8
/// Default maximum recursion limit
9
pub const MAX_RECURSION: usize = 50;
10
11
/// Default maximum object size (2^32)
12
// pub const MAX_OBJECT_SIZE: usize = 4_294_967_295;
13
14
pub trait GetObjectContent {
15
    /// Return the raw content (bytes) of the next ASN.1 encoded object
16
    ///
17
    /// Note: if using BER and length is indefinite, terminating End-Of-Content is NOT included
18
    fn get_object_content<'a>(
19
        i: &'a [u8],
20
        hdr: &'_ Header,
21
        max_depth: usize,
22
    ) -> ParseResult<'a, &'a [u8]>;
23
}
24
25
impl GetObjectContent for BerParser {
26
10.6M
    fn get_object_content<'a>(
27
10.6M
        i: &'a [u8],
28
10.6M
        hdr: &'_ Header,
29
10.6M
        max_depth: usize,
30
10.6M
    ) -> ParseResult<'a, &'a [u8]> {
31
10.6M
        let start_i = i;
32
10.6M
        let (i, _) = ber_skip_object_content(i, hdr, max_depth)?;
33
10.5M
        let len = start_i.offset(i);
34
10.5M
        let (content, i) = start_i.split_at(len);
35
        // if len is indefinite, there are 2 extra bytes for EOC
36
10.5M
        if hdr.length == Length::Indefinite {
37
88.3k
            let len = content.len();
38
88.3k
            assert!(len >= 2);
39
88.3k
            Ok((i, &content[..len - 2]))
40
        } else {
41
10.4M
            Ok((i, content))
42
        }
43
10.6M
    }
<asn1_rs::traits::BerParser as asn1_rs::ber::parser::GetObjectContent>::get_object_content
Line
Count
Source
26
2.89M
    fn get_object_content<'a>(
27
2.89M
        i: &'a [u8],
28
2.89M
        hdr: &'_ Header,
29
2.89M
        max_depth: usize,
30
2.89M
    ) -> ParseResult<'a, &'a [u8]> {
31
2.89M
        let start_i = i;
32
2.89M
        let (i, _) = ber_skip_object_content(i, hdr, max_depth)?;
33
2.86M
        let len = start_i.offset(i);
34
2.86M
        let (content, i) = start_i.split_at(len);
35
        // if len is indefinite, there are 2 extra bytes for EOC
36
2.86M
        if hdr.length == Length::Indefinite {
37
37.9k
            let len = content.len();
38
37.9k
            assert!(len >= 2);
39
37.9k
            Ok((i, &content[..len - 2]))
40
        } else {
41
2.82M
            Ok((i, content))
42
        }
43
2.89M
    }
<asn1_rs::traits::BerParser as asn1_rs::ber::parser::GetObjectContent>::get_object_content
Line
Count
Source
26
7.70M
    fn get_object_content<'a>(
27
7.70M
        i: &'a [u8],
28
7.70M
        hdr: &'_ Header,
29
7.70M
        max_depth: usize,
30
7.70M
    ) -> ParseResult<'a, &'a [u8]> {
31
7.70M
        let start_i = i;
32
7.70M
        let (i, _) = ber_skip_object_content(i, hdr, max_depth)?;
33
7.66M
        let len = start_i.offset(i);
34
7.66M
        let (content, i) = start_i.split_at(len);
35
        // if len is indefinite, there are 2 extra bytes for EOC
36
7.66M
        if hdr.length == Length::Indefinite {
37
50.3k
            let len = content.len();
38
50.3k
            assert!(len >= 2);
39
50.3k
            Ok((i, &content[..len - 2]))
40
        } else {
41
7.61M
            Ok((i, content))
42
        }
43
7.70M
    }
44
}
45
46
impl GetObjectContent for DerParser {
47
    /// Skip object content, accepting only DER
48
    ///
49
    /// This this function is for DER only, it cannot go into recursion (no indefinite length)
50
2.06M
    fn get_object_content<'a>(
51
2.06M
        i: &'a [u8],
52
2.06M
        hdr: &'_ Header,
53
2.06M
        _max_depth: usize,
54
2.06M
    ) -> ParseResult<'a, &'a [u8]> {
55
2.06M
        match hdr.length {
56
2.06M
            Length::Definite(l) => take(l)(i),
57
0
            Length::Indefinite => Err(Err::Error(Error::DerConstraintFailed(
58
0
                DerConstraint::IndefiniteLength,
59
0
            ))),
60
        }
61
2.06M
    }
<asn1_rs::traits::DerParser as asn1_rs::ber::parser::GetObjectContent>::get_object_content
Line
Count
Source
50
408k
    fn get_object_content<'a>(
51
408k
        i: &'a [u8],
52
408k
        hdr: &'_ Header,
53
408k
        _max_depth: usize,
54
408k
    ) -> ParseResult<'a, &'a [u8]> {
55
408k
        match hdr.length {
56
408k
            Length::Definite(l) => take(l)(i),
57
0
            Length::Indefinite => Err(Err::Error(Error::DerConstraintFailed(
58
0
                DerConstraint::IndefiniteLength,
59
0
            ))),
60
        }
61
408k
    }
<asn1_rs::traits::DerParser as asn1_rs::ber::parser::GetObjectContent>::get_object_content
Line
Count
Source
50
1.65M
    fn get_object_content<'a>(
51
1.65M
        i: &'a [u8],
52
1.65M
        hdr: &'_ Header,
53
1.65M
        _max_depth: usize,
54
1.65M
    ) -> ParseResult<'a, &'a [u8]> {
55
1.65M
        match hdr.length {
56
1.65M
            Length::Definite(l) => take(l)(i),
57
0
            Length::Indefinite => Err(Err::Error(Error::DerConstraintFailed(
58
0
                DerConstraint::IndefiniteLength,
59
0
            ))),
60
        }
61
1.65M
    }
62
}
63
64
/// Skip object content, and return true if object was End-Of-Content
65
22.5M
fn ber_skip_object_content<'a>(
66
22.5M
    i: &'a [u8],
67
22.5M
    hdr: &Header,
68
22.5M
    max_depth: usize,
69
22.5M
) -> ParseResult<'a, bool> {
70
22.5M
    if max_depth == 0 {
71
403
        return Err(Err::Error(Error::BerMaxDepth));
72
22.5M
    }
73
22.5M
    match hdr.length {
74
21.9M
        Length::Definite(l) => {
75
21.9M
            if l == 0 && hdr.tag == Tag::EndOfContent {
76
2.28M
                return Ok((i, true));
77
19.6M
            }
78
19.6M
            let (i, _) = take(l)(i)?;
79
19.6M
            Ok((i, false))
80
        }
81
        Length::Indefinite => {
82
557k
            hdr.assert_constructed()?;
83
            // read objects until EndOfContent (00 00)
84
            // this is recursive
85
557k
            let mut i = i;
86
            loop {
87
11.9M
                let (i2, header2) = Header::from_ber(i)?;
88
11.9M
                let (i3, eoc) = ber_skip_object_content(i2, &header2, max_depth - 1)?;
89
11.8M
                if eoc {
90
                    // return false, since top object was not EndOfContent
91
515k
                    return Ok((i3, false));
92
11.3M
                }
93
11.3M
                i = i3;
94
            }
95
        }
96
    }
97
22.5M
}
asn1_rs::ber::parser::ber_skip_object_content
Line
Count
Source
65
3.37M
fn ber_skip_object_content<'a>(
66
3.37M
    i: &'a [u8],
67
3.37M
    hdr: &Header,
68
3.37M
    max_depth: usize,
69
3.37M
) -> ParseResult<'a, bool> {
70
3.37M
    if max_depth == 0 {
71
4
        return Err(Err::Error(Error::BerMaxDepth));
72
3.37M
    }
73
3.37M
    match hdr.length {
74
3.19M
        Length::Definite(l) => {
75
3.19M
            if l == 0 && hdr.tag == Tag::EndOfContent {
76
658k
                return Ok((i, true));
77
2.53M
            }
78
2.53M
            let (i, _) = take(l)(i)?;
79
2.51M
            Ok((i, false))
80
        }
81
        Length::Indefinite => {
82
180k
            hdr.assert_constructed()?;
83
            // read objects until EndOfContent (00 00)
84
            // this is recursive
85
180k
            let mut i = i;
86
            loop {
87
483k
                let (i2, header2) = Header::from_ber(i)?;
88
478k
                let (i3, eoc) = ber_skip_object_content(i2, &header2, max_depth - 1)?;
89
473k
                if eoc {
90
                    // return false, since top object was not EndOfContent
91
170k
                    return Ok((i3, false));
92
303k
                }
93
303k
                i = i3;
94
            }
95
        }
96
    }
97
3.37M
}
asn1_rs::ber::parser::ber_skip_object_content
Line
Count
Source
65
19.1M
fn ber_skip_object_content<'a>(
66
19.1M
    i: &'a [u8],
67
19.1M
    hdr: &Header,
68
19.1M
    max_depth: usize,
69
19.1M
) -> ParseResult<'a, bool> {
70
19.1M
    if max_depth == 0 {
71
399
        return Err(Err::Error(Error::BerMaxDepth));
72
19.1M
    }
73
19.1M
    match hdr.length {
74
18.7M
        Length::Definite(l) => {
75
18.7M
            if l == 0 && hdr.tag == Tag::EndOfContent {
76
1.63M
                return Ok((i, true));
77
17.1M
            }
78
17.1M
            let (i, _) = take(l)(i)?;
79
17.0M
            Ok((i, false))
80
        }
81
        Length::Indefinite => {
82
376k
            hdr.assert_constructed()?;
83
            // read objects until EndOfContent (00 00)
84
            // this is recursive
85
376k
            let mut i = i;
86
            loop {
87
11.4M
                let (i2, header2) = Header::from_ber(i)?;
88
11.4M
                let (i3, eoc) = ber_skip_object_content(i2, &header2, max_depth - 1)?;
89
11.3M
                if eoc {
90
                    // return false, since top object was not EndOfContent
91
345k
                    return Ok((i3, false));
92
11.0M
                }
93
11.0M
                i = i3;
94
            }
95
        }
96
    }
97
19.1M
}
98
99
/// Try to parse input bytes as u64
100
#[inline]
101
772k
pub(crate) fn bytes_to_u64(s: &[u8]) -> core::result::Result<u64, Error> {
102
772k
    let mut u: u64 = 0;
103
1.82M
    for &c in s {
104
1.06M
        if u & 0xff00_0000_0000_0000 != 0 {
105
16.1k
            return Err(Error::IntegerTooLarge);
106
1.05M
        }
107
1.05M
        u <<= 8;
108
1.05M
        u |= u64::from(c);
109
    }
110
756k
    Ok(u)
111
772k
}
asn1_rs::ber::parser::bytes_to_u64
Line
Count
Source
101
32.9k
pub(crate) fn bytes_to_u64(s: &[u8]) -> core::result::Result<u64, Error> {
102
32.9k
    let mut u: u64 = 0;
103
159k
    for &c in s {
104
131k
        if u & 0xff00_0000_0000_0000 != 0 {
105
5.06k
            return Err(Error::IntegerTooLarge);
106
126k
        }
107
126k
        u <<= 8;
108
126k
        u |= u64::from(c);
109
    }
110
27.9k
    Ok(u)
111
32.9k
}
asn1_rs::ber::parser::bytes_to_u64
Line
Count
Source
101
739k
pub(crate) fn bytes_to_u64(s: &[u8]) -> core::result::Result<u64, Error> {
102
739k
    let mut u: u64 = 0;
103
1.66M
    for &c in s {
104
935k
        if u & 0xff00_0000_0000_0000 != 0 {
105
11.1k
            return Err(Error::IntegerTooLarge);
106
924k
        }
107
924k
        u <<= 8;
108
924k
        u |= u64::from(c);
109
    }
110
728k
    Ok(u)
111
739k
}
112
113
28.8M
pub(crate) fn parse_identifier(i: &[u8]) -> ParseResult<(u8, u8, u32, &[u8])> {
114
28.8M
    if i.is_empty() {
115
215k
        Err(Err::Incomplete(Needed::new(1)))
116
    } else {
117
28.6M
        let a = i[0] >> 6;
118
28.6M
        let b = u8::from(i[0] & 0b0010_0000 != 0);
119
28.6M
        let mut c = u32::from(i[0] & 0b0001_1111);
120
121
28.6M
        let mut tag_byte_count = 1;
122
123
28.6M
        if c == 0x1f {
124
812k
            c = 0;
125
            loop {
126
                // Make sure we don't read past the end of our data.
127
1.22M
                custom_check!(i, tag_byte_count >= i.len(), Error::InvalidTag)?;
128
129
                // With tag defined as u32 the most we can fit in is four tag bytes.
130
                // (X.690 doesn't actually specify maximum tag width.)
131
1.19M
                custom_check!(i, tag_byte_count > 5, Error::InvalidTag)?;
132
133
1.18M
                c = (c << 7) | (u32::from(i[tag_byte_count]) & 0x7f);
134
1.18M
                let done = i[tag_byte_count] & 0x80 == 0;
135
1.18M
                tag_byte_count += 1;
136
1.18M
                if done {
137
767k
                    break;
138
415k
                }
139
            }
140
27.8M
        }
141
142
28.5M
        let (raw_tag, rem) = i.split_at(tag_byte_count);
143
144
28.5M
        Ok((rem, (a, b, c, raw_tag)))
145
    }
146
28.8M
}
asn1_rs::ber::parser::parse_identifier
Line
Count
Source
113
4.82M
pub(crate) fn parse_identifier(i: &[u8]) -> ParseResult<(u8, u8, u32, &[u8])> {
114
4.82M
    if i.is_empty() {
115
43.8k
        Err(Err::Incomplete(Needed::new(1)))
116
    } else {
117
4.78M
        let a = i[0] >> 6;
118
4.78M
        let b = u8::from(i[0] & 0b0010_0000 != 0);
119
4.78M
        let mut c = u32::from(i[0] & 0b0001_1111);
120
121
4.78M
        let mut tag_byte_count = 1;
122
123
4.78M
        if c == 0x1f {
124
701k
            c = 0;
125
            loop {
126
                // Make sure we don't read past the end of our data.
127
933k
                custom_check!(i, tag_byte_count >= i.len(), Error::InvalidTag)?;
128
129
                // With tag defined as u32 the most we can fit in is four tag bytes.
130
                // (X.690 doesn't actually specify maximum tag width.)
131
916k
                custom_check!(i, tag_byte_count > 5, Error::InvalidTag)?;
132
133
911k
                c = (c << 7) | (u32::from(i[tag_byte_count]) & 0x7f);
134
911k
                let done = i[tag_byte_count] & 0x80 == 0;
135
911k
                tag_byte_count += 1;
136
911k
                if done {
137
679k
                    break;
138
232k
                }
139
            }
140
4.08M
        }
141
142
4.76M
        let (raw_tag, rem) = i.split_at(tag_byte_count);
143
144
4.76M
        Ok((rem, (a, b, c, raw_tag)))
145
    }
146
4.82M
}
asn1_rs::ber::parser::parse_identifier
Line
Count
Source
113
24.0M
pub(crate) fn parse_identifier(i: &[u8]) -> ParseResult<(u8, u8, u32, &[u8])> {
114
24.0M
    if i.is_empty() {
115
171k
        Err(Err::Incomplete(Needed::new(1)))
116
    } else {
117
23.8M
        let a = i[0] >> 6;
118
23.8M
        let b = u8::from(i[0] & 0b0010_0000 != 0);
119
23.8M
        let mut c = u32::from(i[0] & 0b0001_1111);
120
121
23.8M
        let mut tag_byte_count = 1;
122
123
23.8M
        if c == 0x1f {
124
111k
            c = 0;
125
            loop {
126
                // Make sure we don't read past the end of our data.
127
294k
                custom_check!(i, tag_byte_count >= i.len(), Error::InvalidTag)?;
128
129
                // With tag defined as u32 the most we can fit in is four tag bytes.
130
                // (X.690 doesn't actually specify maximum tag width.)
131
278k
                custom_check!(i, tag_byte_count > 5, Error::InvalidTag)?;
132
133
271k
                c = (c << 7) | (u32::from(i[tag_byte_count]) & 0x7f);
134
271k
                let done = i[tag_byte_count] & 0x80 == 0;
135
271k
                tag_byte_count += 1;
136
271k
                if done {
137
87.6k
                    break;
138
183k
                }
139
            }
140
23.7M
        }
141
142
23.8M
        let (raw_tag, rem) = i.split_at(tag_byte_count);
143
144
23.8M
        Ok((rem, (a, b, c, raw_tag)))
145
    }
146
24.0M
}
147
148
/// Return the MSB and the rest of the first byte, or an error
149
28.5M
pub(crate) fn parse_ber_length_byte(i: &[u8]) -> ParseResult<(u8, u8)> {
150
28.5M
    if i.is_empty() {
151
23.9k
        Err(Err::Incomplete(Needed::new(1)))
152
    } else {
153
28.5M
        let a = i[0] >> 7;
154
28.5M
        let b = i[0] & 0b0111_1111;
155
28.5M
        Ok((&i[1..], (a, b)))
156
    }
157
28.5M
}
asn1_rs::ber::parser::parse_ber_length_byte
Line
Count
Source
149
4.76M
pub(crate) fn parse_ber_length_byte(i: &[u8]) -> ParseResult<(u8, u8)> {
150
4.76M
    if i.is_empty() {
151
8.19k
        Err(Err::Incomplete(Needed::new(1)))
152
    } else {
153
4.75M
        let a = i[0] >> 7;
154
4.75M
        let b = i[0] & 0b0111_1111;
155
4.75M
        Ok((&i[1..], (a, b)))
156
    }
157
4.76M
}
asn1_rs::ber::parser::parse_ber_length_byte
Line
Count
Source
149
23.8M
pub(crate) fn parse_ber_length_byte(i: &[u8]) -> ParseResult<(u8, u8)> {
150
23.8M
    if i.is_empty() {
151
15.7k
        Err(Err::Incomplete(Needed::new(1)))
152
    } else {
153
23.8M
        let a = i[0] >> 7;
154
23.8M
        let b = i[0] & 0b0111_1111;
155
23.8M
        Ok((&i[1..], (a, b)))
156
    }
157
23.8M
}
158
159
#[doc(hidden)]
160
#[macro_export]
161
macro_rules! der_constraint_fail_if(
162
    ($slice:expr, $cond:expr, $constraint:expr) => (
163
        {
164
            if $cond {
165
                return Err(::nom::Err::Error(Error::DerConstraintFailed($constraint)));
166
            }
167
        }
168
    );
169
);