1 //! Support for encoding signed integers
2 
3 use super::{is_highest_bit_set, uint, 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::Int;
12 
13 macro_rules! impl_encoding_traits {
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 mut buf = [0u8; Self::BITS as usize / 8];
19                     let max_length = u32::from(header.length) as usize;
20 
21                     if max_length > buf.len() {
22                         return Err(Self::TAG.non_canonical_error());
23                     }
24 
25                     let bytes = reader.read_into(&mut buf[..max_length])?;
26 
27                     let result = if is_highest_bit_set(bytes) {
28                         <$uint>::from_be_bytes(decode_to_array(bytes)?) as $int
29                     } else {
30                         Self::from_be_bytes(uint::decode_to_array(bytes)?)
31                     };
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 $int {
43                 fn value_len(&self) -> Result<Length> {
44                     if *self < 0 {
45                         negative_encoded_len(&(*self as $uint).to_be_bytes())
46                     } else {
47                         uint::encoded_len(&self.to_be_bytes())
48                     }
49                 }
50 
51                 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
52                     if *self < 0 {
53                         encode_bytes(writer, &(*self as $uint).to_be_bytes())
54                     } else {
55                         uint::encode_bytes(writer, &self.to_be_bytes())
56                     }
57                 }
58             }
59 
60             impl FixedTag for $int {
61                 const TAG: Tag = Tag::Integer;
62             }
63 
64             impl ValueOrd for $int {
65                 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
66                     value_cmp(*self, *other)
67                 }
68             }
69 
70             impl TryFrom<AnyRef<'_>> for $int {
71                 type Error = Error;
72 
73                 fn try_from(any: AnyRef<'_>) -> Result<Self> {
74                     any.decode_as()
75                 }
76             }
77         )+
78     };
79 }
80 
81 impl_encoding_traits!(i8 => u8, i16 => u16, i32 => u32, i64 => u64, i128 => u128);
82 
83 /// Signed arbitrary precision ASN.1 `INTEGER` reference type.
84 ///
85 /// Provides direct access to the underlying big endian bytes which comprise
86 /// an signed integer value.
87 ///
88 /// Intended for use cases like very large integers that are used in
89 /// cryptographic applications (e.g. keys, signatures).
90 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
91 pub struct IntRef<'a> {
92     /// Inner value
93     inner: BytesRef<'a>,
94 }
95 
96 impl<'a> IntRef<'a> {
97     /// Create a new [`IntRef`] from a byte slice.
new(bytes: &'a [u8]) -> Result<Self>98     pub fn new(bytes: &'a [u8]) -> Result<Self> {
99         let inner = BytesRef::new(strip_leading_ones(bytes))
100             .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
101 
102         Ok(Self { inner })
103     }
104 
105     /// Borrow the inner byte slice which contains the least significant bytes
106     /// of a big endian integer value with all leading ones stripped.
as_bytes(&self) -> &'a [u8]107     pub fn as_bytes(&self) -> &'a [u8] {
108         self.inner.as_slice()
109     }
110 
111     /// Get the length of this [`IntRef`] in bytes.
len(&self) -> Length112     pub fn len(&self) -> Length {
113         self.inner.len()
114     }
115 
116     /// Is the inner byte slice empty?
is_empty(&self) -> bool117     pub fn is_empty(&self) -> bool {
118         self.inner.is_empty()
119     }
120 }
121 
122 impl_any_conversions!(IntRef<'a>, 'a);
123 
124 impl<'a> DecodeValue<'a> for IntRef<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>125     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
126         let bytes = BytesRef::decode_value(reader, header)?;
127         validate_canonical(bytes.as_slice())?;
128 
129         let result = Self::new(bytes.as_slice())?;
130 
131         // Ensure we compute the same encoded length as the original any value.
132         if result.value_len()? != header.length {
133             return Err(Self::TAG.non_canonical_error());
134         }
135 
136         Ok(result)
137     }
138 }
139 
140 impl<'a> EncodeValue for IntRef<'a> {
value_len(&self) -> Result<Length>141     fn value_len(&self) -> Result<Length> {
142         // Signed integers always hold their full encoded form.
143         Ok(self.inner.len())
144     }
145 
encode_value(&self, writer: &mut impl Writer) -> Result<()>146     fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
147         writer.write(self.as_bytes())
148     }
149 }
150 
151 impl<'a> From<&IntRef<'a>> for IntRef<'a> {
from(value: &IntRef<'a>) -> IntRef<'a>152     fn from(value: &IntRef<'a>) -> IntRef<'a> {
153         *value
154     }
155 }
156 
157 impl<'a> FixedTag for IntRef<'a> {
158     const TAG: Tag = Tag::Integer;
159 }
160 
161 impl<'a> OrdIsValueOrd for IntRef<'a> {}
162 
163 #[cfg(feature = "alloc")]
164 mod allocating {
165     use super::{strip_leading_ones, validate_canonical, IntRef};
166     use crate::{
167         asn1::Uint,
168         ord::OrdIsValueOrd,
169         referenced::{OwnedToRef, RefToOwned},
170         BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result,
171         Tag, Writer,
172     };
173     use alloc::vec::Vec;
174 
175     /// Signed arbitrary precision ASN.1 `INTEGER` type.
176     ///
177     /// Provides heap-allocated storage for big endian bytes which comprise an
178     /// signed integer value.
179     ///
180     /// Intended for use cases like very large integers that are used in
181     /// cryptographic applications (e.g. keys, signatures).
182     #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
183     pub struct Int {
184         /// Inner value
185         inner: BytesOwned,
186     }
187 
188     impl Int {
189         /// Create a new [`Int`] from a byte slice.
new(bytes: &[u8]) -> Result<Self>190         pub fn new(bytes: &[u8]) -> Result<Self> {
191             let inner = BytesOwned::new(strip_leading_ones(bytes))
192                 .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
193 
194             Ok(Self { inner })
195         }
196 
197         /// Borrow the inner byte slice which contains the least significant bytes
198         /// of a big endian integer value with all leading ones stripped.
as_bytes(&self) -> &[u8]199         pub fn as_bytes(&self) -> &[u8] {
200             self.inner.as_slice()
201         }
202 
203         /// Get the length of this [`Int`] in bytes.
len(&self) -> Length204         pub fn len(&self) -> Length {
205             self.inner.len()
206         }
207 
208         /// Is the inner byte slice empty?
is_empty(&self) -> bool209         pub fn is_empty(&self) -> bool {
210             self.inner.is_empty()
211         }
212     }
213 
214     impl_any_conversions!(Int);
215 
216     impl<'a> DecodeValue<'a> for Int {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>217         fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
218             let bytes = BytesOwned::decode_value(reader, header)?;
219             validate_canonical(bytes.as_slice())?;
220 
221             let result = Self::new(bytes.as_slice())?;
222 
223             // Ensure we compute the same encoded length as the original any value.
224             if result.value_len()? != header.length {
225                 return Err(Self::TAG.non_canonical_error());
226             }
227 
228             Ok(result)
229         }
230     }
231 
232     impl EncodeValue for Int {
value_len(&self) -> Result<Length>233         fn value_len(&self) -> Result<Length> {
234             // Signed integers always hold their full encoded form.
235             Ok(self.inner.len())
236         }
237 
encode_value(&self, writer: &mut impl Writer) -> Result<()>238         fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
239             writer.write(self.as_bytes())
240         }
241     }
242 
243     impl<'a> From<&IntRef<'a>> for Int {
from(value: &IntRef<'a>) -> Int244         fn from(value: &IntRef<'a>) -> Int {
245             let inner = BytesOwned::new(value.as_bytes()).expect("Invalid Int");
246             Int { inner }
247         }
248     }
249 
250     impl From<Uint> for Int {
from(value: Uint) -> Self251         fn from(value: Uint) -> Self {
252             let mut inner: Vec<u8> = Vec::new();
253 
254             // Add leading `0x00` byte if required
255             if value.value_len().expect("invalid Uint") > value.len() {
256                 inner.push(0x00);
257             }
258 
259             inner.extend_from_slice(value.as_bytes());
260             let inner = BytesOwned::new(inner).expect("invalid Uint");
261 
262             Int { inner }
263         }
264     }
265 
266     impl FixedTag for Int {
267         const TAG: Tag = Tag::Integer;
268     }
269 
270     impl OrdIsValueOrd for Int {}
271 
272     impl<'a> RefToOwned<'a> for IntRef<'a> {
273         type Owned = Int;
ref_to_owned(&self) -> Self::Owned274         fn ref_to_owned(&self) -> Self::Owned {
275             let inner = self.inner.ref_to_owned();
276 
277             Int { inner }
278         }
279     }
280 
281     impl OwnedToRef for Int {
282         type Borrowed<'a> = IntRef<'a>;
owned_to_ref(&self) -> Self::Borrowed<'_>283         fn owned_to_ref(&self) -> Self::Borrowed<'_> {
284             let inner = self.inner.owned_to_ref();
285 
286             IntRef { inner }
287         }
288     }
289 }
290 
291 /// Ensure `INTEGER` is canonically encoded.
validate_canonical(bytes: &[u8]) -> Result<()>292 fn validate_canonical(bytes: &[u8]) -> Result<()> {
293     // The `INTEGER` type always encodes a signed value and we're decoding
294     // as signed here, so we allow a zero extension or sign extension byte,
295     // but only as permitted under DER canonicalization.
296     match bytes {
297         [] => Err(Tag::Integer.non_canonical_error()),
298         [0x00, byte, ..] if *byte < 0x80 => Err(Tag::Integer.non_canonical_error()),
299         [0xFF, byte, ..] if *byte >= 0x80 => Err(Tag::Integer.non_canonical_error()),
300         _ => Ok(()),
301     }
302 }
303 
304 /// Decode an signed integer of the specified size.
305 ///
306 /// Returns a byte array of the requested size containing a big endian integer.
decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]>307 fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
308     match N.checked_sub(bytes.len()) {
309         Some(offset) => {
310             let mut output = [0xFFu8; N];
311             output[offset..].copy_from_slice(bytes);
312             Ok(output)
313         }
314         None => {
315             let expected_len = Length::try_from(N)?;
316             let actual_len = Length::try_from(bytes.len())?;
317 
318             Err(ErrorKind::Incomplete {
319                 expected_len,
320                 actual_len,
321             }
322             .into())
323         }
324     }
325 }
326 
327 /// Encode the given big endian bytes representing an integer as ASN.1 DER.
encode_bytes<W>(writer: &mut W, bytes: &[u8]) -> Result<()> where W: Writer + ?Sized,328 fn encode_bytes<W>(writer: &mut W, bytes: &[u8]) -> Result<()>
329 where
330     W: Writer + ?Sized,
331 {
332     writer.write(strip_leading_ones(bytes))
333 }
334 
335 /// Get the encoded length for the given **negative** integer serialized as bytes.
336 #[inline]
negative_encoded_len(bytes: &[u8]) -> Result<Length>337 fn negative_encoded_len(bytes: &[u8]) -> Result<Length> {
338     Length::try_from(strip_leading_ones(bytes).len())
339 }
340 
341 /// Strip the leading all-ones bytes from the given byte slice.
strip_leading_ones(mut bytes: &[u8]) -> &[u8]342 pub(crate) fn strip_leading_ones(mut bytes: &[u8]) -> &[u8] {
343     while let Some((byte, rest)) = bytes.split_first() {
344         if *byte == 0xFF && is_highest_bit_set(rest) {
345             bytes = rest;
346             continue;
347         }
348 
349         break;
350     }
351 
352     bytes
353 }
354 
355 #[cfg(test)]
356 mod tests {
357     use super::{validate_canonical, IntRef};
358     use crate::{asn1::integer::tests::*, Decode, Encode, SliceWriter};
359 
360     #[test]
validate_canonical_ok()361     fn validate_canonical_ok() {
362         assert_eq!(validate_canonical(&[0x00]), Ok(()));
363         assert_eq!(validate_canonical(&[0x01]), Ok(()));
364         assert_eq!(validate_canonical(&[0x00, 0x80]), Ok(()));
365         assert_eq!(validate_canonical(&[0xFF, 0x00]), Ok(()));
366     }
367 
368     #[test]
validate_canonical_err()369     fn validate_canonical_err() {
370         // Empty integers are always non-canonical.
371         assert!(validate_canonical(&[]).is_err());
372 
373         // Positives with excessive zero extension are non-canonical.
374         assert!(validate_canonical(&[0x00, 0x00]).is_err());
375 
376         // Negatives with excessive sign extension are non-canonical.
377         assert!(validate_canonical(&[0xFF, 0x80]).is_err());
378     }
379 
380     #[test]
decode_intref()381     fn decode_intref() {
382         // Positive numbers decode, but have zero extensions as necessary
383         // (to distinguish them from negative representations).
384         assert_eq!(&[0], IntRef::from_der(I0_BYTES).unwrap().as_bytes());
385         assert_eq!(&[127], IntRef::from_der(I127_BYTES).unwrap().as_bytes());
386         assert_eq!(&[0, 128], IntRef::from_der(I128_BYTES).unwrap().as_bytes());
387         assert_eq!(&[0, 255], IntRef::from_der(I255_BYTES).unwrap().as_bytes());
388 
389         assert_eq!(
390             &[0x01, 0x00],
391             IntRef::from_der(I256_BYTES).unwrap().as_bytes()
392         );
393 
394         assert_eq!(
395             &[0x7F, 0xFF],
396             IntRef::from_der(I32767_BYTES).unwrap().as_bytes()
397         );
398 
399         // Negative integers decode.
400         assert_eq!(&[128], IntRef::from_der(INEG128_BYTES).unwrap().as_bytes());
401         assert_eq!(
402             &[255, 127],
403             IntRef::from_der(INEG129_BYTES).unwrap().as_bytes()
404         );
405         assert_eq!(
406             &[128, 0],
407             IntRef::from_der(INEG32768_BYTES).unwrap().as_bytes()
408         );
409     }
410 
411     #[test]
encode_intref()412     fn encode_intref() {
413         for &example in &[
414             I0_BYTES,
415             I127_BYTES,
416             I128_BYTES,
417             I255_BYTES,
418             I256_BYTES,
419             I32767_BYTES,
420         ] {
421             let uint = IntRef::from_der(example).unwrap();
422 
423             let mut buf = [0u8; 128];
424             let mut encoder = SliceWriter::new(&mut buf);
425             uint.encode(&mut encoder).unwrap();
426 
427             let result = encoder.finish().unwrap();
428             assert_eq!(example, result);
429         }
430 
431         for &example in &[INEG128_BYTES, INEG129_BYTES, INEG32768_BYTES] {
432             let uint = IntRef::from_der(example).unwrap();
433 
434             let mut buf = [0u8; 128];
435             let mut encoder = SliceWriter::new(&mut buf);
436             uint.encode(&mut encoder).unwrap();
437 
438             let result = encoder.finish().unwrap();
439             assert_eq!(example, result);
440         }
441     }
442 }
443