• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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