Coverage Report

Created: 2025-07-14 07:05

/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.23.29/src/x509.rs
Line
Count
Source (jump to first uncovered line)
1
// Additional x509/asn1 functions to those provided in webpki/ring.
2
3
use alloc::vec::Vec;
4
5
/// Prepend stuff to `bytes` to put it in a DER SEQUENCE.
6
0
pub(crate) fn wrap_in_sequence(bytes: &[u8]) -> Vec<u8> {
7
0
    asn1_wrap(DER_SEQUENCE_TAG, bytes, &[])
8
0
}
Unexecuted instantiation: rustls::x509::wrap_in_sequence
Unexecuted instantiation: rustls::x509::wrap_in_sequence
9
10
/// Prepend stuff to `bytes_a` + `bytes_b` to put it in a DER SEQUENCE.
11
#[cfg_attr(not(feature = "ring"), allow(dead_code))]
12
0
pub(crate) fn wrap_concat_in_sequence(bytes_a: &[u8], bytes_b: &[u8]) -> Vec<u8> {
13
0
    asn1_wrap(DER_SEQUENCE_TAG, bytes_a, bytes_b)
14
0
}
Unexecuted instantiation: rustls::x509::wrap_concat_in_sequence
Unexecuted instantiation: rustls::x509::wrap_concat_in_sequence
15
16
/// Prepend stuff to `bytes` to put it in a DER BIT STRING.
17
0
pub(crate) fn wrap_in_bit_string(bytes: &[u8]) -> Vec<u8> {
18
0
    asn1_wrap(DER_BIT_STRING_TAG, &[0u8], bytes)
19
0
}
Unexecuted instantiation: rustls::x509::wrap_in_bit_string
Unexecuted instantiation: rustls::x509::wrap_in_bit_string
20
21
/// Prepend stuff to `bytes` to put it in a DER OCTET STRING.
22
#[cfg_attr(not(feature = "ring"), allow(dead_code))]
23
0
pub(crate) fn wrap_in_octet_string(bytes: &[u8]) -> Vec<u8> {
24
0
    asn1_wrap(DER_OCTET_STRING_TAG, bytes, &[])
25
0
}
Unexecuted instantiation: rustls::x509::wrap_in_octet_string
Unexecuted instantiation: rustls::x509::wrap_in_octet_string
26
27
0
fn asn1_wrap(tag: u8, bytes_a: &[u8], bytes_b: &[u8]) -> Vec<u8> {
28
0
    let len = bytes_a.len() + bytes_b.len();
29
0
30
0
    if len <= 0x7f {
31
        // Short form
32
0
        let mut ret = Vec::with_capacity(2 + len);
33
0
        ret.push(tag);
34
0
        ret.push(len as u8);
35
0
        ret.extend_from_slice(bytes_a);
36
0
        ret.extend_from_slice(bytes_b);
37
0
        ret
38
    } else {
39
        // Long form
40
0
        let size = len.to_be_bytes();
41
0
        let leading_zero_bytes = size
42
0
            .iter()
43
0
            .position(|&x| x != 0)
Unexecuted instantiation: rustls::x509::asn1_wrap::{closure#0}
Unexecuted instantiation: rustls::x509::asn1_wrap::{closure#0}
44
0
            .unwrap_or(size.len());
45
0
        assert!(leading_zero_bytes < size.len());
46
0
        let encoded_bytes = size.len() - leading_zero_bytes;
47
0
48
0
        let mut ret = Vec::with_capacity(2 + encoded_bytes + len);
49
0
        ret.push(tag);
50
0
51
0
        ret.push(0x80 + encoded_bytes as u8);
52
0
        ret.extend_from_slice(&size[leading_zero_bytes..]);
53
0
54
0
        ret.extend_from_slice(bytes_a);
55
0
        ret.extend_from_slice(bytes_b);
56
0
        ret
57
    }
58
0
}
Unexecuted instantiation: rustls::x509::asn1_wrap
Unexecuted instantiation: rustls::x509::asn1_wrap
59
60
const DER_SEQUENCE_TAG: u8 = 0x30;
61
const DER_BIT_STRING_TAG: u8 = 0x03;
62
const DER_OCTET_STRING_TAG: u8 = 0x04;
63
64
#[cfg(test)]
65
mod tests {
66
    use std::vec;
67
68
    use super::*;
69
70
    #[test]
71
    fn test_empty() {
72
        assert_eq!(vec![0x30, 0x00], wrap_in_sequence(&[]));
73
    }
74
75
    #[test]
76
    fn test_small() {
77
        assert_eq!(
78
            vec![0x30, 0x04, 0x00, 0x11, 0x22, 0x33],
79
            wrap_in_sequence(&[0x00, 0x11, 0x22, 0x33])
80
        );
81
    }
82
83
    #[test]
84
    fn test_medium() {
85
        let mut val = Vec::new();
86
        val.resize(255, 0x12);
87
        assert_eq!(
88
            vec![0x30, 0x81, 0xff, 0x12, 0x12, 0x12],
89
            wrap_in_sequence(&val)[..6]
90
        );
91
    }
92
93
    #[test]
94
    fn test_large() {
95
        let mut val = Vec::new();
96
        val.resize(4660, 0x12);
97
        wrap_in_sequence(&val);
98
        assert_eq!(
99
            vec![0x30, 0x82, 0x12, 0x34, 0x12, 0x12],
100
            wrap_in_sequence(&val)[..6]
101
        );
102
    }
103
104
    #[test]
105
    fn test_huge() {
106
        let mut val = Vec::new();
107
        val.resize(0xffff, 0x12);
108
        let result = wrap_in_sequence(&val);
109
        assert_eq!(vec![0x30, 0x82, 0xff, 0xff, 0x12, 0x12], result[..6]);
110
        assert_eq!(result.len(), 0xffff + 4);
111
    }
112
113
    #[test]
114
    fn test_gigantic() {
115
        let mut val = Vec::new();
116
        val.resize(0x100000, 0x12);
117
        let result = wrap_in_sequence(&val);
118
        assert_eq!(vec![0x30, 0x83, 0x10, 0x00, 0x00, 0x12, 0x12], result[..7]);
119
        assert_eq!(result.len(), 0x100000 + 5);
120
    }
121
122
    #[test]
123
    fn test_ludicrous() {
124
        let mut val = Vec::new();
125
        val.resize(0x1000000, 0x12);
126
        let result = wrap_in_sequence(&val);
127
        assert_eq!(
128
            vec![0x30, 0x84, 0x01, 0x00, 0x00, 0x00, 0x12, 0x12],
129
            result[..8]
130
        );
131
        assert_eq!(result.len(), 0x1000000 + 6);
132
    }
133
134
    #[test]
135
    fn test_wrap_in_bit_string() {
136
        // The BIT STRING encoding starts with a single octet on
137
        // the front saying how many bits to disregard from the
138
        // last octet. So this zero means "no bits" unused, which
139
        // is correct because our input is an string of octets.
140
        //
141
        // So if we encode &[0x55u8] with this function, we should get:
142
        //
143
        // 0x03    0x02    0x00                0x55
144
        // ^ tag   ^ len   ^ no unused bits    ^ value
145
        assert_eq!(wrap_in_bit_string(&[0x55u8]), vec![0x03, 0x02, 0x00, 0x55]);
146
    }
147
}