1pub(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 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 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#[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
134fn 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 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 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 #[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}