der/asn1/integer/
int.rs

1//! Support for encoding signed integers
2
3use super::{is_highest_bit_set, uint, value_cmp};
4use crate::{
5    ord::OrdIsValueOrd, AnyRef, BytesRef, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag,
6    Header, Length, Reader, Result, Tag, ValueOrd, Writer,
7};
8use core::cmp::Ordering;
9
10#[cfg(feature = "alloc")]
11pub use allocating::Int;
12
13macro_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
81impl_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)]
91pub struct IntRef<'a> {
92    /// Inner value
93    inner: BytesRef<'a>,
94}
95
96impl<'a> IntRef<'a> {
97    /// Create a new [`IntRef`] from a byte slice.
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.
107    pub fn as_bytes(&self) -> &'a [u8] {
108        self.inner.as_slice()
109    }
110
111    /// Get the length of this [`IntRef`] in bytes.
112    pub fn len(&self) -> Length {
113        self.inner.len()
114    }
115
116    /// Is the inner byte slice empty?
117    pub fn is_empty(&self) -> bool {
118        self.inner.is_empty()
119    }
120}
121
122impl_any_conversions!(IntRef<'a>, 'a);
123
124impl<'a> DecodeValue<'a> for IntRef<'a> {
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
140impl<'a> EncodeValue for IntRef<'a> {
141    fn value_len(&self) -> Result<Length> {
142        // Signed integers always hold their full encoded form.
143        Ok(self.inner.len())
144    }
145
146    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
147        writer.write(self.as_bytes())
148    }
149}
150
151impl<'a> From<&IntRef<'a>> for IntRef<'a> {
152    fn from(value: &IntRef<'a>) -> IntRef<'a> {
153        *value
154    }
155}
156
157impl<'a> FixedTag for IntRef<'a> {
158    const TAG: Tag = Tag::Integer;
159}
160
161impl<'a> OrdIsValueOrd for IntRef<'a> {}
162
163#[cfg(feature = "alloc")]
164mod 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.
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.
199        pub fn as_bytes(&self) -> &[u8] {
200            self.inner.as_slice()
201        }
202
203        /// Get the length of this [`Int`] in bytes.
204        pub fn len(&self) -> Length {
205            self.inner.len()
206        }
207
208        /// Is the inner byte slice empty?
209        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 {
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 {
233        fn value_len(&self) -> Result<Length> {
234            // Signed integers always hold their full encoded form.
235            Ok(self.inner.len())
236        }
237
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 {
244        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 {
251        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;
274        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>;
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.
292fn 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.
307fn 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.
328fn encode_bytes<W>(writer: &mut W, bytes: &[u8]) -> Result<()>
329where
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]
337fn 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.
342pub(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)]
356mod tests {
357    use super::{validate_canonical, IntRef};
358    use crate::{asn1::integer::tests::*, Decode, Encode, SliceWriter};
359
360    #[test]
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]
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]
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]
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}