1 //! ASN.1 `INTEGER` support.
2 
3 pub(super) mod int;
4 pub(super) mod uint;
5 
6 use core::{cmp::Ordering, mem};
7 
8 use crate::{EncodeValue, Result, SliceWriter};
9 
10 /// Is the highest bit of the first byte in the slice set to `1`? (if present)
11 #[inline]
is_highest_bit_set(bytes: &[u8]) -> bool12 fn is_highest_bit_set(bytes: &[u8]) -> bool {
13     bytes
14         .first()
15         .map(|byte| byte & 0b10000000 != 0)
16         .unwrap_or(false)
17 }
18 
19 /// Compare two integer values
value_cmp<T>(a: T, b: T) -> Result<Ordering> where T: Copy + EncodeValue + Sized,20 fn value_cmp<T>(a: T, b: T) -> Result<Ordering>
21 where
22     T: Copy + EncodeValue + Sized,
23 {
24     const MAX_INT_SIZE: usize = 16;
25     debug_assert!(mem::size_of::<T>() <= MAX_INT_SIZE);
26 
27     let mut buf1 = [0u8; MAX_INT_SIZE];
28     let mut encoder1 = SliceWriter::new(&mut buf1);
29     a.encode_value(&mut encoder1)?;
30 
31     let mut buf2 = [0u8; MAX_INT_SIZE];
32     let mut encoder2 = SliceWriter::new(&mut buf2);
33     b.encode_value(&mut encoder2)?;
34 
35     Ok(encoder1.finish()?.cmp(encoder2.finish()?))
36 }
37 
38 #[cfg(test)]
39 pub(crate) mod tests {
40     use crate::{Decode, Encode};
41 
42     // Vectors from Section 5.7 of:
43     // https://luca.ntop.org/Teaching/Appunti/asn1.html
44     pub(crate) const I0_BYTES: &[u8] = &[0x02, 0x01, 0x00];
45     pub(crate) const I127_BYTES: &[u8] = &[0x02, 0x01, 0x7F];
46     pub(crate) const I128_BYTES: &[u8] = &[0x02, 0x02, 0x00, 0x80];
47     pub(crate) const I256_BYTES: &[u8] = &[0x02, 0x02, 0x01, 0x00];
48     pub(crate) const INEG128_BYTES: &[u8] = &[0x02, 0x01, 0x80];
49     pub(crate) const INEG129_BYTES: &[u8] = &[0x02, 0x02, 0xFF, 0x7F];
50 
51     // Additional vectors
52     pub(crate) const I255_BYTES: &[u8] = &[0x02, 0x02, 0x00, 0xFF];
53     pub(crate) const I32767_BYTES: &[u8] = &[0x02, 0x02, 0x7F, 0xFF];
54     pub(crate) const I65535_BYTES: &[u8] = &[0x02, 0x03, 0x00, 0xFF, 0xFF];
55     pub(crate) const INEG32768_BYTES: &[u8] = &[0x02, 0x02, 0x80, 0x00];
56 
57     #[test]
decode_i8()58     fn decode_i8() {
59         assert_eq!(0, i8::from_der(I0_BYTES).unwrap());
60         assert_eq!(127, i8::from_der(I127_BYTES).unwrap());
61         assert_eq!(-128, i8::from_der(INEG128_BYTES).unwrap());
62     }
63 
64     #[test]
decode_i16()65     fn decode_i16() {
66         assert_eq!(0, i16::from_der(I0_BYTES).unwrap());
67         assert_eq!(127, i16::from_der(I127_BYTES).unwrap());
68         assert_eq!(128, i16::from_der(I128_BYTES).unwrap());
69         assert_eq!(255, i16::from_der(I255_BYTES).unwrap());
70         assert_eq!(256, i16::from_der(I256_BYTES).unwrap());
71         assert_eq!(32767, i16::from_der(I32767_BYTES).unwrap());
72         assert_eq!(-128, i16::from_der(INEG128_BYTES).unwrap());
73         assert_eq!(-129, i16::from_der(INEG129_BYTES).unwrap());
74         assert_eq!(-32768, i16::from_der(INEG32768_BYTES).unwrap());
75     }
76 
77     #[test]
decode_u8()78     fn decode_u8() {
79         assert_eq!(0, u8::from_der(I0_BYTES).unwrap());
80         assert_eq!(127, u8::from_der(I127_BYTES).unwrap());
81         assert_eq!(255, u8::from_der(I255_BYTES).unwrap());
82     }
83 
84     #[test]
decode_u16()85     fn decode_u16() {
86         assert_eq!(0, u16::from_der(I0_BYTES).unwrap());
87         assert_eq!(127, u16::from_der(I127_BYTES).unwrap());
88         assert_eq!(255, u16::from_der(I255_BYTES).unwrap());
89         assert_eq!(256, u16::from_der(I256_BYTES).unwrap());
90         assert_eq!(32767, u16::from_der(I32767_BYTES).unwrap());
91         assert_eq!(65535, u16::from_der(I65535_BYTES).unwrap());
92     }
93 
94     #[test]
encode_i8()95     fn encode_i8() {
96         let mut buffer = [0u8; 3];
97 
98         assert_eq!(I0_BYTES, 0i8.encode_to_slice(&mut buffer).unwrap());
99         assert_eq!(I127_BYTES, 127i8.encode_to_slice(&mut buffer).unwrap());
100 
101         assert_eq!(
102             INEG128_BYTES,
103             (-128i8).encode_to_slice(&mut buffer).unwrap()
104         );
105     }
106 
107     #[test]
encode_i16()108     fn encode_i16() {
109         let mut buffer = [0u8; 4];
110         assert_eq!(I0_BYTES, 0i16.encode_to_slice(&mut buffer).unwrap());
111         assert_eq!(I127_BYTES, 127i16.encode_to_slice(&mut buffer).unwrap());
112         assert_eq!(I128_BYTES, 128i16.encode_to_slice(&mut buffer).unwrap());
113         assert_eq!(I255_BYTES, 255i16.encode_to_slice(&mut buffer).unwrap());
114         assert_eq!(I256_BYTES, 256i16.encode_to_slice(&mut buffer).unwrap());
115         assert_eq!(I32767_BYTES, 32767i16.encode_to_slice(&mut buffer).unwrap());
116 
117         assert_eq!(
118             INEG128_BYTES,
119             (-128i16).encode_to_slice(&mut buffer).unwrap()
120         );
121 
122         assert_eq!(
123             INEG129_BYTES,
124             (-129i16).encode_to_slice(&mut buffer).unwrap()
125         );
126 
127         assert_eq!(
128             INEG32768_BYTES,
129             (-32768i16).encode_to_slice(&mut buffer).unwrap()
130         );
131     }
132 
133     #[test]
encode_u8()134     fn encode_u8() {
135         let mut buffer = [0u8; 4];
136         assert_eq!(I0_BYTES, 0u8.encode_to_slice(&mut buffer).unwrap());
137         assert_eq!(I127_BYTES, 127u8.encode_to_slice(&mut buffer).unwrap());
138         assert_eq!(I255_BYTES, 255u8.encode_to_slice(&mut buffer).unwrap());
139     }
140 
141     #[test]
encode_u16()142     fn encode_u16() {
143         let mut buffer = [0u8; 5];
144         assert_eq!(I0_BYTES, 0u16.encode_to_slice(&mut buffer).unwrap());
145         assert_eq!(I127_BYTES, 127u16.encode_to_slice(&mut buffer).unwrap());
146         assert_eq!(I128_BYTES, 128u16.encode_to_slice(&mut buffer).unwrap());
147         assert_eq!(I255_BYTES, 255u16.encode_to_slice(&mut buffer).unwrap());
148         assert_eq!(I256_BYTES, 256u16.encode_to_slice(&mut buffer).unwrap());
149         assert_eq!(I32767_BYTES, 32767u16.encode_to_slice(&mut buffer).unwrap());
150         assert_eq!(I65535_BYTES, 65535u16.encode_to_slice(&mut buffer).unwrap());
151     }
152 
153     /// Integers must be encoded with a minimum number of octets
154     #[test]
reject_non_canonical()155     fn reject_non_canonical() {
156         assert!(i8::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
157         assert!(i16::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
158         assert!(u8::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
159         assert!(u16::from_der(&[0x02, 0x02, 0x00, 0x00]).is_err());
160     }
161 }
162