1 use crate::error::*;
2
3 /// Decode an unsigned integer into a big endian byte slice with all leading
4 /// zeroes removed.
5 ///
6 /// Returns a byte array of the requested size containing a big endian integer.
remove_zeroes(bytes: &[u8]) -> Result<&[u8], BerError>7 fn remove_zeroes(bytes: &[u8]) -> Result<&[u8], BerError> {
8 // skip leading 0s
9 match bytes {
10 // [] => Err(BerError::DerConstraintFailed),
11 [0] => Ok(bytes),
12 // [0, byte, ..] if *byte < 0x80 => Err(BerError::DerConstraintFailed),
13 // [0, rest @ ..] => Ok(&rest),
14 [0, rest @ ..] => remove_zeroes(rest),
15 // [byte, ..] if *byte >= 0x80 => Err(BerError::IntegerTooLarge),
16 _ => Ok(bytes),
17 }
18 }
19
20 // XXX const generics require rustc >= 1.51
21 // /// Decode an unsigned integer into a byte array of the requested size
22 // /// containing a big endian integer.
23 // pub(crate) fn decode_array_uint<const N: usize>(bytes: &[u8]) -> Result<[u8; N], BerError> {
24 // // Check if MSB is set *before* leading zeroes
25 // if is_highest_bit_set(bytes) {
26 // return Err(BerError::IntegerNegative);
27 // }
28 // let input = remove_zeroes(bytes)?;
29
30 // if input.len() > N {
31 // return Err(BerError::IntegerTooLarge);
32 // }
33
34 // // Input has leading zeroes removed, so we need to add them back
35 // let mut output = [0u8; N];
36 // assert!(input.len() <= N);
37 // output[N.saturating_sub(input.len())..].copy_from_slice(input);
38 // Ok(output)
39 // }
40
decode_array_uint8(bytes: &[u8]) -> Result<[u8; 8], BerError>41 pub(crate) fn decode_array_uint8(bytes: &[u8]) -> Result<[u8; 8], BerError> {
42 // Check if MSB is set *before* leading zeroes
43 if is_highest_bit_set(bytes) {
44 return Err(BerError::IntegerNegative);
45 }
46 let input = remove_zeroes(bytes)?;
47
48 if input.len() > 8 {
49 return Err(BerError::IntegerTooLarge);
50 }
51
52 // Input has leading zeroes removed, so we need to add them back
53 let mut output = [0u8; 8];
54 assert!(input.len() <= 8);
55 output[8_usize.saturating_sub(input.len())..].copy_from_slice(input);
56 Ok(output)
57 }
58
decode_array_uint4(bytes: &[u8]) -> Result<[u8; 4], BerError>59 pub(crate) fn decode_array_uint4(bytes: &[u8]) -> Result<[u8; 4], BerError> {
60 // Check if MSB is set *before* leading zeroes
61 if is_highest_bit_set(bytes) {
62 return Err(BerError::IntegerNegative);
63 }
64 let input = remove_zeroes(bytes)?;
65
66 if input.len() > 4 {
67 return Err(BerError::IntegerTooLarge);
68 }
69
70 // Input has leading zeroes removed, so we need to add them back
71 let mut output = [0u8; 4];
72 assert!(input.len() <= 4);
73 output[4_usize.saturating_sub(input.len())..].copy_from_slice(input);
74 Ok(output)
75 }
76
77 // XXX const generics require rustc >= 1.51
78 // /// Decode an unsigned integer of the specified size.
79 // ///
80 // /// Returns a byte array of the requested size containing a big endian integer.
81 // pub(crate) fn decode_array_int<const N: usize>(input: &[u8]) -> Result<[u8; N], BerError> {
82 // let input = remove_zeroes(input)?;
83
84 // if input.len() > N {
85 // return Err(BerError::IntegerTooLarge);
86 // }
87
88 // // any.tag().assert_eq(Tag::Integer)?;
89 // let mut output = [0xFFu8; N];
90 // let offset = N.saturating_sub(input.len());
91 // output[offset..].copy_from_slice(input);
92 // Ok(output)
93 // }
94
decode_array_int8(input: &[u8]) -> Result<[u8; 8], BerError>95 pub(crate) fn decode_array_int8(input: &[u8]) -> Result<[u8; 8], BerError> {
96 let input = remove_zeroes(input)?;
97
98 if input.len() > 8 {
99 return Err(BerError::IntegerTooLarge);
100 }
101
102 // any.tag().assert_eq(Tag::Integer)?;
103 let mut output = [0xFFu8; 8];
104 let offset = 8_usize.saturating_sub(input.len());
105 output[offset..].copy_from_slice(input);
106 Ok(output)
107 }
108
decode_array_int4(input: &[u8]) -> Result<[u8; 4], BerError>109 pub(crate) fn decode_array_int4(input: &[u8]) -> Result<[u8; 4], BerError> {
110 let input = remove_zeroes(input)?;
111
112 if input.len() > 4 {
113 return Err(BerError::IntegerTooLarge);
114 }
115
116 // any.tag().assert_eq(Tag::Integer)?;
117 let mut output = [0xFFu8; 4];
118 let offset = 4_usize.saturating_sub(input.len());
119 output[offset..].copy_from_slice(input);
120 Ok(output)
121 }
122
123 /// Is the highest bit of the first byte in the slice 1? (if present)
124 #[inline]
is_highest_bit_set(bytes: &[u8]) -> bool125 pub(crate) fn is_highest_bit_set(bytes: &[u8]) -> bool {
126 bytes
127 .get(0)
128 .map(|byte| byte & 0b10000000 != 0)
129 .unwrap_or(false)
130 }
131