der/asn1/
integer.rs

1//! ASN.1 `INTEGER` support.
2
3pub(super) mod bigint;
4mod int;
5mod uint;
6
7use crate::{
8    asn1::Any, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, FixedTag, Length,
9    Result, Tag, ValueOrd,
10};
11use core::{cmp::Ordering, mem};
12
13macro_rules! impl_int_encoding {
14    ($($int:ty => $uint:ty),+) => {
15        $(
16            impl<'a> DecodeValue<'a> for $int {
17                fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
18                    let bytes = ByteSlice::decode_value(decoder, length)?.as_bytes();
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 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, encoder: &mut Encoder<'_>) -> Result<()> {
45                    if *self < 0 {
46                        int::encode_bytes(encoder, &(*self as $uint).to_be_bytes())
47                    } else {
48                        uint::encode_bytes(encoder, &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<Any<'_>> for $int {
64                type Error = Error;
65
66                fn try_from(any: Any<'_>) -> Result<Self> {
67                    any.decode_into()
68                }
69            }
70        )+
71    };
72}
73
74macro_rules! impl_uint_encoding {
75    ($($uint:ty),+) => {
76        $(
77            impl<'a> DecodeValue<'a> for $uint {
78                fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
79                    let bytes = ByteSlice::decode_value(decoder, length)?.as_bytes();
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 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, encoder: &mut Encoder<'_>) -> Result<()> {
97                    uint::encode_bytes(encoder, &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<Any<'_>> for $uint {
112                type Error = Error;
113
114                fn try_from(any: Any<'_>) -> Result<Self> {
115                    any.decode_into()
116                }
117            }
118        )+
119    };
120}
121
122impl_int_encoding!(i8 => u8, i16 => u16, i32 => u32, i64 => u64, i128 => u128);
123impl_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]
127fn 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
135fn value_cmp<T>(a: T, b: T) -> Result<Ordering>
136where
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 = Encoder::new(&mut buf1);
144    a.encode_value(&mut encoder1)?;
145
146    let mut buf2 = [0u8; MAX_INT_SIZE];
147    let mut encoder2 = Encoder::new(&mut buf2);
148    b.encode_value(&mut encoder2)?;
149
150    Ok(encoder1.finish()?.cmp(encoder2.finish()?))
151}
152
153#[cfg(test)]
154pub(crate) mod tests {
155    use crate::{Decodable, Encodable};
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]
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]
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]
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]
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]
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]
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]
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]
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]
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}