1 //! Unsigned integer decoders/encoders.
2 
3 use super::value_cmp;
4 use crate::{
5     ord::OrdIsValueOrd, AnyRef, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag,
6     Header, Length, Reader, Result, Tag, ValueOrd, Writer,
7 };
8 use core::cmp::Ordering;
9 
10 #[cfg(feature = "alloc")]
11 pub use allocating::Uint;
12 
13 macro_rules! impl_encoding_traits {
14     ($($uint:ty),+) => {
15         $(
16             impl<'a> DecodeValue<'a> for $uint {
17                 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
18                     // Integers always encodes as a signed value, unsigned gets a leading 0x00 that
19                     // needs to be stripped off. We need to provide room for it.
20                     const UNSIGNED_HEADROOM: usize = 1;
21 
22                     let mut buf = [0u8; (Self::BITS as usize / 8) + UNSIGNED_HEADROOM];
23                     let max_length = u32::from(header.length) as usize;
24 
25                     if max_length > buf.len() {
26                         return Err(Self::TAG.non_canonical_error());
27                     }
28 
29                     let bytes = reader.read_into(&mut buf[..max_length])?;
30 
31                     let result = Self::from_be_bytes(decode_to_array(bytes)?);
32 
33                     // Ensure we compute the same encoded length as the original any value
34                     if header.length != result.value_len()? {
35                         return Err(Self::TAG.non_canonical_error());
36                     }
37 
38                     Ok(result)
39                 }
40             }
41 
42             impl EncodeValue for $uint {
43                 fn value_len(&self) -> Result<Length> {
44                     encoded_len(&self.to_be_bytes())
45                 }
46 
47                 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
48                     encode_bytes(writer, &self.to_be_bytes())
49                 }
50             }
51 
52             impl FixedTag for $uint {
53                 const TAG: Tag = Tag::Integer;
54             }
55 
56             impl ValueOrd for $uint {
57                 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
58                     value_cmp(*self, *other)
59                 }
60             }
61 
62             impl TryFrom<AnyRef<'_>> for $uint {
63                 type Error = Error;
64 
65                 fn try_from(any: AnyRef<'_>) -> Result<Self> {
66                     any.decode_as()
67                 }
68             }
69         )+
70     };
71 }
72 
73 impl_encoding_traits!(u8, u16, u32, u64, u128);
74 
75 /// Unsigned arbitrary precision ASN.1 `INTEGER` reference type.
76 ///
77 /// Provides direct access to the underlying big endian bytes which comprise an
78 /// unsigned integer value.
79 ///
80 /// Intended for use cases like very large integers that are used in
81 /// cryptographic applications (e.g. keys, signatures).
82 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
83 pub struct UintRef<'a> {
84     /// Inner value
85     inner: BytesRef<'a>,
86 }
87 
88 impl<'a> UintRef<'a> {
89     /// Create a new [`UintRef`] from a byte slice.
new(bytes: &'a [u8]) -> Result<Self>90     pub fn new(bytes: &'a [u8]) -> Result<Self> {
91         let inner = BytesRef::new(strip_leading_zeroes(bytes))
92             .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
93 
94         Ok(Self { inner })
95     }
96 
97     /// Borrow the inner byte slice which contains the least significant bytes
98     /// of a big endian integer value with all leading zeros stripped.
as_bytes(&self) -> &'a [u8]99     pub fn as_bytes(&self) -> &'a [u8] {
100         self.inner.as_slice()
101     }
102 
103     /// Get the length of this [`UintRef`] in bytes.
len(&self) -> Length104     pub fn len(&self) -> Length {
105         self.inner.len()
106     }
107 
108     /// Is the inner byte slice empty?
is_empty(&self) -> bool109     pub fn is_empty(&self) -> bool {
110         self.inner.is_empty()
111     }
112 }
113 
114 impl_any_conversions!(UintRef<'a>, 'a);
115 
116 impl<'a> DecodeValue<'a> for UintRef<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>117     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
118         let bytes = BytesRef::decode_value(reader, header)?.as_slice();
119         let result = Self::new(decode_to_slice(bytes)?)?;
120 
121         // Ensure we compute the same encoded length as the original any value.
122         if result.value_len()? != header.length {
123             return Err(Self::TAG.non_canonical_error());
124         }
125 
126         Ok(result)
127     }
128 }
129 
130 impl<'a> EncodeValue for UintRef<'a> {
value_len(&self) -> Result<Length>131     fn value_len(&self) -> Result<Length> {
132         encoded_len(self.inner.as_slice())
133     }
134 
encode_value(&self, writer: &mut impl Writer) -> Result<()>135     fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
136         // Add leading `0x00` byte if required
137         if self.value_len()? > self.len() {
138             writer.write_byte(0)?;
139         }
140 
141         writer.write(self.as_bytes())
142     }
143 }
144 
145 impl<'a> From<&UintRef<'a>> for UintRef<'a> {
from(value: &UintRef<'a>) -> UintRef<'a>146     fn from(value: &UintRef<'a>) -> UintRef<'a> {
147         *value
148     }
149 }
150 
151 impl<'a> FixedTag for UintRef<'a> {
152     const TAG: Tag = Tag::Integer;
153 }
154 
155 impl<'a> OrdIsValueOrd for UintRef<'a> {}
156 
157 #[cfg(feature = "alloc")]
158 mod allocating {
159     use super::{decode_to_slice, encoded_len, strip_leading_zeroes, UintRef};
160     use crate::{
161         ord::OrdIsValueOrd,
162         referenced::{OwnedToRef, RefToOwned},
163         BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result,
164         Tag, Writer,
165     };
166 
167     /// Unsigned arbitrary precision ASN.1 `INTEGER` type.
168     ///
169     /// Provides heap-allocated storage for big endian bytes which comprise an
170     /// unsigned integer value.
171     ///
172     /// Intended for use cases like very large integers that are used in
173     /// cryptographic applications (e.g. keys, signatures).
174     #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
175     pub struct Uint {
176         /// Inner value
177         inner: BytesOwned,
178     }
179 
180     impl Uint {
181         /// Create a new [`Uint`] from a byte slice.
new(bytes: &[u8]) -> Result<Self>182         pub fn new(bytes: &[u8]) -> Result<Self> {
183             let inner = BytesOwned::new(strip_leading_zeroes(bytes))
184                 .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
185 
186             Ok(Self { inner })
187         }
188 
189         /// Borrow the inner byte slice which contains the least significant bytes
190         /// of a big endian integer value with all leading zeros stripped.
as_bytes(&self) -> &[u8]191         pub fn as_bytes(&self) -> &[u8] {
192             self.inner.as_slice()
193         }
194 
195         /// Get the length of this [`Uint`] in bytes.
len(&self) -> Length196         pub fn len(&self) -> Length {
197             self.inner.len()
198         }
199 
200         /// Is the inner byte slice empty?
is_empty(&self) -> bool201         pub fn is_empty(&self) -> bool {
202             self.inner.is_empty()
203         }
204     }
205 
206     impl_any_conversions!(Uint);
207 
208     impl<'a> DecodeValue<'a> for Uint {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>209         fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
210             let bytes = BytesOwned::decode_value(reader, header)?;
211             let result = Self::new(decode_to_slice(bytes.as_slice())?)?;
212 
213             // Ensure we compute the same encoded length as the original any value.
214             if result.value_len()? != header.length {
215                 return Err(Self::TAG.non_canonical_error());
216             }
217 
218             Ok(result)
219         }
220     }
221 
222     impl EncodeValue for Uint {
value_len(&self) -> Result<Length>223         fn value_len(&self) -> Result<Length> {
224             encoded_len(self.inner.as_slice())
225         }
226 
encode_value(&self, writer: &mut impl Writer) -> Result<()>227         fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
228             // Add leading `0x00` byte if required
229             if self.value_len()? > self.len() {
230                 writer.write_byte(0)?;
231             }
232 
233             writer.write(self.as_bytes())
234         }
235     }
236 
237     impl<'a> From<&UintRef<'a>> for Uint {
from(value: &UintRef<'a>) -> Uint238         fn from(value: &UintRef<'a>) -> Uint {
239             let inner = BytesOwned::new(value.as_bytes()).expect("Invalid Uint");
240             Uint { inner }
241         }
242     }
243 
244     impl FixedTag for Uint {
245         const TAG: Tag = Tag::Integer;
246     }
247 
248     impl OrdIsValueOrd for Uint {}
249 
250     impl<'a> RefToOwned<'a> for UintRef<'a> {
251         type Owned = Uint;
ref_to_owned(&self) -> Self::Owned252         fn ref_to_owned(&self) -> Self::Owned {
253             let inner = self.inner.ref_to_owned();
254 
255             Uint { inner }
256         }
257     }
258 
259     impl OwnedToRef for Uint {
260         type Borrowed<'a> = UintRef<'a>;
owned_to_ref(&self) -> Self::Borrowed<'_>261         fn owned_to_ref(&self) -> Self::Borrowed<'_> {
262             let inner = self.inner.owned_to_ref();
263 
264             UintRef { inner }
265         }
266     }
267 }
268 
269 /// Decode an unsigned integer into a big endian byte slice with all leading
270 /// zeroes removed.
271 ///
272 /// Returns a byte array of the requested size containing a big endian integer.
decode_to_slice(bytes: &[u8]) -> Result<&[u8]>273 pub(crate) fn decode_to_slice(bytes: &[u8]) -> Result<&[u8]> {
274     // The `INTEGER` type always encodes a signed value, so for unsigned
275     // values the leading `0x00` byte may need to be removed.
276     //
277     // We also disallow a leading byte which would overflow a signed ASN.1
278     // integer (since we're decoding an unsigned integer).
279     // We expect all such cases to have a leading `0x00` byte.
280     match bytes {
281         [] => Err(Tag::Integer.non_canonical_error()),
282         [0] => Ok(bytes),
283         [0, byte, ..] if *byte < 0x80 => Err(Tag::Integer.non_canonical_error()),
284         [0, rest @ ..] => Ok(rest),
285         [byte, ..] if *byte >= 0x80 => Err(Tag::Integer.value_error()),
286         _ => Ok(bytes),
287     }
288 }
289 
290 /// Decode an unsigned integer into a byte array of the requested size
291 /// containing a big endian integer.
decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]>292 pub(super) fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
293     let input = decode_to_slice(bytes)?;
294 
295     // Compute number of leading zeroes to add
296     let num_zeroes = N
297         .checked_sub(input.len())
298         .ok_or_else(|| Tag::Integer.length_error())?;
299 
300     // Copy input into `N`-sized output buffer with leading zeroes
301     let mut output = [0u8; N];
302     output[num_zeroes..].copy_from_slice(input);
303     Ok(output)
304 }
305 
306 /// Encode the given big endian bytes representing an integer as ASN.1 DER.
encode_bytes<W>(encoder: &mut W, bytes: &[u8]) -> Result<()> where W: Writer + ?Sized,307 pub(crate) fn encode_bytes<W>(encoder: &mut W, bytes: &[u8]) -> Result<()>
308 where
309     W: Writer + ?Sized,
310 {
311     let bytes = strip_leading_zeroes(bytes);
312 
313     if needs_leading_zero(bytes) {
314         encoder.write_byte(0)?;
315     }
316 
317     encoder.write(bytes)
318 }
319 
320 /// Get the encoded length for the given unsigned integer serialized as bytes.
321 #[inline]
encoded_len(bytes: &[u8]) -> Result<Length>322 pub(crate) fn encoded_len(bytes: &[u8]) -> Result<Length> {
323     let bytes = strip_leading_zeroes(bytes);
324     Length::try_from(bytes.len())? + u8::from(needs_leading_zero(bytes))
325 }
326 
327 /// Strip the leading zeroes from the given byte slice
strip_leading_zeroes(mut bytes: &[u8]) -> &[u8]328 pub(crate) fn strip_leading_zeroes(mut bytes: &[u8]) -> &[u8] {
329     while let Some((byte, rest)) = bytes.split_first() {
330         if *byte == 0 && !rest.is_empty() {
331             bytes = rest;
332         } else {
333             break;
334         }
335     }
336 
337     bytes
338 }
339 
340 /// Does the given integer need a leading zero?
needs_leading_zero(bytes: &[u8]) -> bool341 fn needs_leading_zero(bytes: &[u8]) -> bool {
342     matches!(bytes.first(), Some(byte) if *byte >= 0x80)
343 }
344 
345 #[cfg(test)]
346 mod tests {
347     use super::{decode_to_array, UintRef};
348     use crate::{asn1::integer::tests::*, AnyRef, Decode, Encode, ErrorKind, SliceWriter, Tag};
349 
350     #[test]
decode_to_array_no_leading_zero()351     fn decode_to_array_no_leading_zero() {
352         let arr = decode_to_array::<4>(&[1, 2]).unwrap();
353         assert_eq!(arr, [0, 0, 1, 2]);
354     }
355 
356     #[test]
decode_to_array_leading_zero()357     fn decode_to_array_leading_zero() {
358         let arr = decode_to_array::<4>(&[0x00, 0xFF, 0xFE]).unwrap();
359         assert_eq!(arr, [0x00, 0x00, 0xFF, 0xFE]);
360     }
361 
362     #[test]
decode_to_array_extra_zero()363     fn decode_to_array_extra_zero() {
364         let err = decode_to_array::<4>(&[0, 1, 2]).err().unwrap();
365         assert_eq!(err.kind(), ErrorKind::Noncanonical { tag: Tag::Integer });
366     }
367 
368     #[test]
decode_to_array_missing_zero()369     fn decode_to_array_missing_zero() {
370         // We're decoding an unsigned integer, but this value would be signed
371         let err = decode_to_array::<4>(&[0xFF, 0xFE]).err().unwrap();
372         assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
373     }
374 
375     #[test]
decode_to_array_oversized_input()376     fn decode_to_array_oversized_input() {
377         let err = decode_to_array::<1>(&[1, 2, 3]).err().unwrap();
378         assert_eq!(err.kind(), ErrorKind::Length { tag: Tag::Integer });
379     }
380 
381     #[test]
decode_uintref()382     fn decode_uintref() {
383         assert_eq!(&[0], UintRef::from_der(I0_BYTES).unwrap().as_bytes());
384         assert_eq!(&[127], UintRef::from_der(I127_BYTES).unwrap().as_bytes());
385         assert_eq!(&[128], UintRef::from_der(I128_BYTES).unwrap().as_bytes());
386         assert_eq!(&[255], UintRef::from_der(I255_BYTES).unwrap().as_bytes());
387 
388         assert_eq!(
389             &[0x01, 0x00],
390             UintRef::from_der(I256_BYTES).unwrap().as_bytes()
391         );
392 
393         assert_eq!(
394             &[0x7F, 0xFF],
395             UintRef::from_der(I32767_BYTES).unwrap().as_bytes()
396         );
397     }
398 
399     #[test]
encode_uintref()400     fn encode_uintref() {
401         for &example in &[
402             I0_BYTES,
403             I127_BYTES,
404             I128_BYTES,
405             I255_BYTES,
406             I256_BYTES,
407             I32767_BYTES,
408         ] {
409             let uint = UintRef::from_der(example).unwrap();
410 
411             let mut buf = [0u8; 128];
412             let mut encoder = SliceWriter::new(&mut buf);
413             uint.encode(&mut encoder).unwrap();
414 
415             let result = encoder.finish().unwrap();
416             assert_eq!(example, result);
417         }
418     }
419 
420     #[test]
reject_oversize_without_extra_zero()421     fn reject_oversize_without_extra_zero() {
422         let err = UintRef::try_from(AnyRef::new(Tag::Integer, &[0x81]).unwrap())
423             .err()
424             .unwrap();
425 
426         assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
427     }
428 }
429