der/asn1/integer/
int.rs

1//! Support for encoding negative integers
2
3use super::is_highest_bit_set;
4use crate::{Encoder, ErrorKind, Length, Result};
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(encoder: &mut Encoder<'_>, bytes: &[u8]) -> Result<()> {
31    encoder.bytes(strip_leading_ones(bytes))
32}
33
34/// Get the encoded length for the given unsigned integer serialized as bytes.
35#[inline]
36pub(super) fn encoded_len(bytes: &[u8]) -> Result<Length> {
37    Length::try_from(strip_leading_ones(bytes).len())
38}
39
40/// Strip the leading all-ones bytes from the given byte slice.
41fn strip_leading_ones(mut bytes: &[u8]) -> &[u8] {
42    while let Some((byte, rest)) = bytes.split_first() {
43        if *byte == 0xFF && is_highest_bit_set(rest) {
44            bytes = rest;
45            continue;
46        }
47
48        break;
49    }
50
51    bytes
52}