1use alloc::vec::Vec;
4
5pub(crate) fn wrap_in_sequence(bytes: &[u8]) -> Vec<u8> {
7 asn1_wrap(DER_SEQUENCE_TAG, bytes, &[])
8}
9
10#[cfg_attr(not(feature = "ring"), allow(dead_code))]
12pub(crate) fn wrap_concat_in_sequence(bytes_a: &[u8], bytes_b: &[u8]) -> Vec<u8> {
13 asn1_wrap(DER_SEQUENCE_TAG, bytes_a, bytes_b)
14}
15
16pub(crate) fn wrap_in_bit_string(bytes: &[u8]) -> Vec<u8> {
18 asn1_wrap(DER_BIT_STRING_TAG, &[0u8], bytes)
19}
20
21#[cfg_attr(not(feature = "ring"), allow(dead_code))]
23pub(crate) fn wrap_in_octet_string(bytes: &[u8]) -> Vec<u8> {
24 asn1_wrap(DER_OCTET_STRING_TAG, bytes, &[])
25}
26
27fn asn1_wrap(tag: u8, bytes_a: &[u8], bytes_b: &[u8]) -> Vec<u8> {
28 let len = bytes_a.len() + bytes_b.len();
29
30 if len <= 0x7f {
31 let mut ret = Vec::with_capacity(2 + len);
33 ret.push(tag);
34 ret.push(len as u8);
35 ret.extend_from_slice(bytes_a);
36 ret.extend_from_slice(bytes_b);
37 ret
38 } else {
39 let size = len.to_be_bytes();
41 let leading_zero_bytes = size
42 .iter()
43 .position(|&x| x != 0)
44 .unwrap_or(size.len());
45 assert!(leading_zero_bytes < size.len());
46 let encoded_bytes = size.len() - leading_zero_bytes;
47
48 let mut ret = Vec::with_capacity(2 + encoded_bytes + len);
49 ret.push(tag);
50
51 ret.push(0x80 + encoded_bytes as u8);
52 ret.extend_from_slice(&size[leading_zero_bytes..]);
53
54 ret.extend_from_slice(bytes_a);
55 ret.extend_from_slice(bytes_b);
56 ret
57 }
58}
59
60const DER_SEQUENCE_TAG: u8 = 0x30;
61const DER_BIT_STRING_TAG: u8 = 0x03;
62const DER_OCTET_STRING_TAG: u8 = 0x04;
63
64#[cfg(test)]
65mod 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 assert_eq!(wrap_in_bit_string(&[0x55u8]), vec![0x03, 0x02, 0x00, 0x55]);
146 }
147}