• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! ASN.1 `INTEGER` support.
2 
3 pub(super) mod bigint;
4 pub(super) mod int;
5 pub(super) mod uint;
6 
7 use crate::{
8     asn1::AnyRef, ByteSlice, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader,
9     Result, SliceWriter, Tag, ValueOrd, Writer,
10 };
11 use core::{cmp::Ordering, mem};
12 
13 macro_rules! impl_int_encoding {
14     ($($int:ty => $uint:ty),+) => {
15         $(
16             impl<'a> DecodeValue<'a> for $int {
17                 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
18                     let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
19 
20                     let result = if is_highest_bit_set(bytes) {
21                         <$uint>::from_be_bytes(int::decode_to_array(bytes)?) as $int
22                     } else {
23                         Self::from_be_bytes(uint::decode_to_array(bytes)?)
24                     };
25 
26                     // Ensure we compute the same encoded length as the original any value
27                     if header.length != result.value_len()? {
28                         return Err(Self::TAG.non_canonical_error());
29                     }
30 
31                     Ok(result)
32                 }
33             }
34 
35             impl EncodeValue for $int {
36                 fn value_len(&self) -> Result<Length> {
37                     if *self < 0 {
38                         int::encoded_len(&(*self as $uint).to_be_bytes())
39                     } else {
40                         uint::encoded_len(&self.to_be_bytes())
41                     }
42                 }
43 
44                 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
45                     if *self < 0 {
46                         int::encode_bytes(writer, &(*self as $uint).to_be_bytes())
47                     } else {
48                         uint::encode_bytes(writer, &self.to_be_bytes())
49                     }
50                 }
51             }
52 
53             impl FixedTag for $int {
54                 const TAG: Tag = Tag::Integer;
55             }
56 
57             impl ValueOrd for $int {
58                 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
59                     value_cmp(*self, *other)
60                 }
61             }
62 
63             impl TryFrom<AnyRef<'_>> for $int {
64                 type Error = Error;
65 
66                 fn try_from(any: AnyRef<'_>) -> Result<Self> {
67                     any.decode_into()
68                 }
69             }
70         )+
71     };
72 }
73 
74 macro_rules! impl_uint_encoding {
75     ($($uint:ty),+) => {
76         $(
77             impl<'a> DecodeValue<'a> for $uint {
78                 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
79                     let bytes = ByteSlice::decode_value(reader, header)?.as_slice();
80                     let result = Self::from_be_bytes(uint::decode_to_array(bytes)?);
81 
82                     // Ensure we compute the same encoded length as the original any value
83                     if header.length != result.value_len()? {
84                         return Err(Self::TAG.non_canonical_error());
85                     }
86 
87                     Ok(result)
88                 }
89             }
90 
91             impl EncodeValue for $uint {
92                 fn value_len(&self) -> Result<Length> {
93                     uint::encoded_len(&self.to_be_bytes())
94                 }
95 
96                 fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
97                     uint::encode_bytes(writer, &self.to_be_bytes())
98                 }
99             }
100 
101             impl FixedTag for $uint {
102                 const TAG: Tag = Tag::Integer;
103             }
104 
105             impl ValueOrd for $uint {
106                 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
107                     value_cmp(*self, *other)
108                 }
109             }
110 
111             impl TryFrom<AnyRef<'_>> for $uint {
112                 type Error = Error;
113 
114                 fn try_from(any: AnyRef<'_>) -> Result<Self> {
115                     any.decode_into()
116                 }
117             }
118         )+
119     };
120 }
121 
122 impl_int_encoding!(i8 => u8, i16 => u16, i32 => u32, i64 => u64, i128 => u128);
123 impl_uint_encoding!(u8, u16, u32, u64, u128);
124 
125 /// Is the highest bit of the first byte in the slice 1? (if present)
126 #[inline]
is_highest_bit_set(bytes: &[u8]) -> bool127 fn is_highest_bit_set(bytes: &[u8]) -> bool {
128     bytes
129         .get(0)
130         .map(|byte| byte & 0b10000000 != 0)
131         .unwrap_or(false)
132 }
133 
134 /// Compare two integer values
value_cmp<T>(a: T, b: T) -> Result<Ordering> where T: Copy + EncodeValue + Sized,135 fn value_cmp<T>(a: T, b: T) -> Result<Ordering>
136 where
137     T: Copy + EncodeValue + Sized,
138 {
139     const MAX_INT_SIZE: usize = 16;
140     debug_assert!(mem::size_of::<T>() <= MAX_INT_SIZE);
141 
142     let mut buf1 = [0u8; MAX_INT_SIZE];
143     let mut encoder1 = SliceWriter::new(&mut buf1);
144     a.encode_value(&mut encoder1)?;
145 
146     let mut buf2 = [0u8; MAX_INT_SIZE];
147     let mut encoder2 = SliceWriter::new(&mut buf2);
148     b.encode_value(&mut encoder2)?;
149 
150     Ok(encoder1.finish()?.cmp(encoder2.finish()?))
151 }
152 
153 #[cfg(test)]
154 pub(crate) mod tests {
155     use crate::{Decode, Encode};
156 
157     // Vectors from Section 5.7 of:
158     // https://luca.ntop.org/Teaching/Appunti/asn1.html
159     pub(crate) const I0_BYTES: &[u8] = &[0x02, 0x01, 0x00];
160     pub(crate) const I127_BYTES: &[u8] = &[0x02, 0x01, 0x7F];
161     pub(crate) const I128_BYTES: &[u8] = &[0x02, 0x02, 0x00, 0x80];
162     pub(crate) const I256_BYTES: &[u8] = &[0x02, 0x02, 0x01, 0x00];
163     pub(crate) const INEG128_BYTES: &[u8] = &[0x02, 0x01, 0x80];
164     pub(crate) const INEG129_BYTES: &[u8] = &[0x02, 0x02, 0xFF, 0x7F];
165 
166     // Additional vectors
167     pub(crate) const I255_BYTES: &[u8] = &[0x02, 0x02, 0x00, 0xFF];
168     pub(crate) const I32767_BYTES: &[u8] = &[0x02, 0x02, 0x7F, 0xFF];
169     pub(crate) const I65535_BYTES: &[u8] = &[0x02, 0x03, 0x00, 0xFF, 0xFF];
170     pub(crate) const INEG32768_BYTES: &[u8] = &[0x02, 0x02, 0x80, 0x00];
171 
172     #[test]
decode_i8()173     fn decode_i8() {
174         assert_eq!(0, i8::from_der(I0_BYTES).unwrap());
175         assert_eq!(127, i8::from_der(I127_BYTES).unwrap());
176         assert_eq!(-128, i8::from_der(INEG128_BYTES).unwrap());
177     }
178 
179     #[test]
decode_i16()180     fn decode_i16() {
181         assert_eq!(0, i16::from_der(I0_BYTES).unwrap());
182         assert_eq!(127, i16::from_der(I127_BYTES).unwrap());
183         assert_eq!(128, i16::from_der(I128_BYTES).unwrap());
184         assert_eq!(255, i16::from_der(I255_BYTES).unwrap());
185         assert_eq!(256, i16::from_der(I256_BYTES).unwrap());
186         assert_eq!(32767, i16::from_der(I32767_BYTES).unwrap());
187         assert_eq!(-128, i16::from_der(INEG128_BYTES).unwrap());
188         assert_eq!(-129, i16::from_der(INEG129_BYTES).unwrap());
189         assert_eq!(-32768, i16::from_der(INEG32768_BYTES).unwrap());
190     }
191 
192     #[test]
decode_u8()193     fn decode_u8() {
194         assert_eq!(0, u8::from_der(I0_BYTES).unwrap());
195         assert_eq!(127, u8::from_der(I127_BYTES).unwrap());
196         assert_eq!(255, u8::from_der(I255_BYTES).unwrap());
197     }
198 
199     #[test]
decode_u16()200     fn decode_u16() {
201         assert_eq!(0, u16::from_der(I0_BYTES).unwrap());
202         assert_eq!(127, u16::from_der(I127_BYTES).unwrap());
203         assert_eq!(255, u16::from_der(I255_BYTES).unwrap());
204         assert_eq!(256, u16::from_der(I256_BYTES).unwrap());
205         assert_eq!(32767, u16::from_der(I32767_BYTES).unwrap());
206         assert_eq!(65535, u16::from_der(I65535_BYTES).unwrap());
207     }
208 
209     #[test]
encode_i8()210     fn encode_i8() {
211         let mut buffer = [0u8; 3];
212 
213         assert_eq!(I0_BYTES, 0i8.encode_to_slice(&mut buffer).unwrap());
214         assert_eq!(I127_BYTES, 127i8.encode_to_slice(&mut buffer).unwrap());
215 
216         assert_eq!(
217             INEG128_BYTES,
218             (-128i8).encode_to_slice(&mut buffer).unwrap()
219         );
220     }
221 
222     #[test]
encode_i16()223     fn encode_i16() {
224         let mut buffer = [0u8; 4];
225         assert_eq!(I0_BYTES, 0i16.encode_to_slice(&mut buffer).unwrap());
226         assert_eq!(I127_BYTES, 127i16.encode_to_slice(&mut buffer).unwrap());
227         assert_eq!(I128_BYTES, 128i16.encode_to_slice(&mut buffer).unwrap());
228         assert_eq!(I255_BYTES, 255i16.encode_to_slice(&mut buffer).unwrap());
229         assert_eq!(I256_BYTES, 256i16.encode_to_slice(&mut buffer).unwrap());
230         assert_eq!(I32767_BYTES, 32767i16.encode_to_slice(&mut buffer).unwrap());
231 
232         assert_eq!(
233             INEG128_BYTES,
234             (-128i16).encode_to_slice(&mut buffer).unwrap()
235         );
236 
237         assert_eq!(
238             INEG129_BYTES,
239             (-129i16).encode_to_slice(&mut buffer).unwrap()
240         );
241 
242         assert_eq!(
243             INEG32768_BYTES,
244             (-32768i16).encode_to_slice(&mut buffer).unwrap()
245         );
246     }
247 
248     #[test]
encode_u8()249     fn encode_u8() {
250         let mut buffer = [0u8; 4];
251         assert_eq!(I0_BYTES, 0u8.encode_to_slice(&mut buffer).unwrap());
252         assert_eq!(I127_BYTES, 127u8.encode_to_slice(&mut buffer).unwrap());
253         assert_eq!(I255_BYTES, 255u8.encode_to_slice(&mut buffer).unwrap());
254     }
255 
256     #[test]
encode_u16()257     fn encode_u16() {
258         let mut buffer = [0u8; 5];
259         assert_eq!(I0_BYTES, 0u16.encode_to_slice(&mut buffer).unwrap());
260         assert_eq!(I127_BYTES, 127u16.encode_to_slice(&mut buffer).unwrap());
261         assert_eq!(I128_BYTES, 128u16.encode_to_slice(&mut buffer).unwrap());
262         assert_eq!(I255_BYTES, 255u16.encode_to_slice(&mut buffer).unwrap());
263         assert_eq!(I256_BYTES, 256u16.encode_to_slice(&mut buffer).unwrap());
264         assert_eq!(I32767_BYTES, 32767u16.encode_to_slice(&mut buffer).unwrap());
265         assert_eq!(I65535_BYTES, 65535u16.encode_to_slice(&mut buffer).unwrap());
266     }
267 
268     /// Integers must be encoded with a minimum number of octets
269     #[test]
reject_non_canonical()270     fn reject_non_canonical() {
271         assert!(i8::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
272         assert!(i16::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
273         assert!(u8::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
274         assert!(u16::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
275     }
276 }
277