/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 | | } |