1 | // Additional x509/asn1 functions to those provided in webpki/ring. |
2 | |
3 | use alloc::vec::Vec; |
4 | |
5 | pub(crate) fn asn1_wrap(tag: u8, bytes: &[u8]) -> Vec<u8> { |
6 | let len = bytes.len(); |
7 | |
8 | if len <= 0x7f { |
9 | // Short form |
10 | let mut ret = Vec::with_capacity(2 + len); |
11 | ret.push(tag); |
12 | ret.push(len as u8); |
13 | ret.extend_from_slice(bytes); |
14 | ret |
15 | } else { |
16 | // Long form |
17 | let size = len.to_be_bytes(); |
18 | let leading_zero_bytes = size |
19 | .iter() |
20 | .position(|&x| x != 0) |
21 | .unwrap_or(size.len()); |
22 | assert!(leading_zero_bytes < size.len()); |
23 | let encoded_bytes = size.len() - leading_zero_bytes; |
24 | |
25 | let mut ret = Vec::with_capacity(2 + encoded_bytes + len); |
26 | ret.push(tag); |
27 | |
28 | ret.push(0x80 + encoded_bytes as u8); |
29 | ret.extend_from_slice(&size[leading_zero_bytes..]); |
30 | |
31 | ret.extend_from_slice(bytes); |
32 | ret |
33 | } |
34 | } |
35 | |
36 | /// Prepend stuff to `bytes` to put it in a DER SEQUENCE. |
37 | pub(crate) fn wrap_in_sequence(bytes: &[u8]) -> Vec<u8> { |
38 | asn1_wrap(DER_SEQUENCE_TAG, bytes) |
39 | } |
40 | |
41 | const DER_SEQUENCE_TAG: u8 = 0x30; |
42 | |
43 | #[cfg (test)] |
44 | mod tests { |
45 | use super::*; |
46 | |
47 | #[test ] |
48 | fn test_empty() { |
49 | assert_eq!(vec![0x30, 0x00], wrap_in_sequence(&[])); |
50 | } |
51 | |
52 | #[test ] |
53 | fn test_small() { |
54 | assert_eq!( |
55 | vec![0x30, 0x04, 0x00, 0x11, 0x22, 0x33], |
56 | wrap_in_sequence(&[0x00, 0x11, 0x22, 0x33]) |
57 | ); |
58 | } |
59 | |
60 | #[test ] |
61 | fn test_medium() { |
62 | let mut val = Vec::new(); |
63 | val.resize(255, 0x12); |
64 | assert_eq!( |
65 | vec![0x30, 0x81, 0xff, 0x12, 0x12, 0x12], |
66 | wrap_in_sequence(&val)[..6] |
67 | ); |
68 | } |
69 | |
70 | #[test ] |
71 | fn test_large() { |
72 | let mut val = Vec::new(); |
73 | val.resize(4660, 0x12); |
74 | wrap_in_sequence(&val); |
75 | assert_eq!( |
76 | vec![0x30, 0x82, 0x12, 0x34, 0x12, 0x12], |
77 | wrap_in_sequence(&val)[..6] |
78 | ); |
79 | } |
80 | |
81 | #[test ] |
82 | fn test_huge() { |
83 | let mut val = Vec::new(); |
84 | val.resize(0xffff, 0x12); |
85 | let result = wrap_in_sequence(&val); |
86 | assert_eq!(vec![0x30, 0x82, 0xff, 0xff, 0x12, 0x12], result[..6]); |
87 | assert_eq!(result.len(), 0xffff + 4); |
88 | } |
89 | |
90 | #[test ] |
91 | fn test_gigantic() { |
92 | let mut val = Vec::new(); |
93 | val.resize(0x100000, 0x12); |
94 | let result = wrap_in_sequence(&val); |
95 | assert_eq!(vec![0x30, 0x83, 0x10, 0x00, 0x00, 0x12, 0x12], result[..7]); |
96 | assert_eq!(result.len(), 0x100000 + 5); |
97 | } |
98 | |
99 | #[test ] |
100 | fn test_ludicrous() { |
101 | let mut val = Vec::new(); |
102 | val.resize(0x1000000, 0x12); |
103 | let result = wrap_in_sequence(&val); |
104 | assert_eq!( |
105 | vec![0x30, 0x84, 0x01, 0x00, 0x00, 0x00, 0x12, 0x12], |
106 | result[..8] |
107 | ); |
108 | assert_eq!(result.len(), 0x1000000 + 6); |
109 | } |
110 | } |
111 | |