der/asn1/integer/
int.rs

1//! Support for encoding negative integers
2
3use super::is_highest_bit_set;
4use crate::{ErrorKind, Length, Result, Writer};
5
6/// Decode an unsigned integer of the specified size.
7///
8/// Returns a byte array of the requested size containing a big endian integer.
9pub(super) fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
10    match N.checked_sub(bytes.len()) {
11        Some(offset) => {
12            let mut output = [0xFFu8; N];
13            output[offset..].copy_from_slice(bytes);
14            Ok(output)
15        }
16        None => {
17            let expected_len = Length::try_from(N)?;
18            let actual_len = Length::try_from(bytes.len())?;
19
20            Err(ErrorKind::Incomplete {
21                expected_len,
22                actual_len,
23            }
24            .into())
25        }
26    }
27}
28
29/// Encode the given big endian bytes representing an integer as ASN.1 DER.
30pub(super) fn encode_bytes<W>(writer: &mut W, bytes: &[u8]) -> Result<()>
31where
32    W: Writer + ?Sized,
33{
34    writer.write(strip_leading_ones(bytes))
35}
36
37/// Get the encoded length for the given unsigned integer serialized as bytes.
38#[inline]
39pub(super) fn encoded_len(bytes: &[u8]) -> Result<Length> {
40    Length::try_from(strip_leading_ones(bytes).len())
41}
42
43/// Strip the leading all-ones bytes from the given byte slice.
44fn strip_leading_ones(mut bytes: &[u8]) -> &[u8] {
45    while let Some((byte, rest)) = bytes.split_first() {
46        if *byte == 0xFF && is_highest_bit_set(rest) {
47            bytes = rest;
48            continue;
49        }
50
51        break;
52    }
53
54    bytes
55}