Skip to content

Commit 293efc9

Browse files
authored
der: refactor Int*/Uint* types (#881)
Factors these types out of the (now-removed) `bigint` module into the `int` and `uint` modules respectively, avoiding other code changes and preserving all tests.
1 parent ff3c9be commit 293efc9

File tree

6 files changed

+673
-666
lines changed

6 files changed

+673
-666
lines changed

der/src/asn1.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub use self::{
3535
context_specific::{ContextSpecific, ContextSpecificRef},
3636
generalized_time::GeneralizedTime,
3737
ia5_string::Ia5StringRef,
38-
integer::bigint::{IntRef, UintRef},
38+
integer::{int::IntRef, uint::UintRef},
3939
null::Null,
4040
octet_string::OctetStringRef,
4141
printable_string::PrintableStringRef,
@@ -54,7 +54,7 @@ pub use self::{
5454
any::Any,
5555
bit_string::BitString,
5656
ia5_string::Ia5String,
57-
integer::bigint::{Int, Uint},
57+
integer::{int::Int, uint::Uint},
5858
octet_string::OctetString,
5959
printable_string::PrintableString,
6060
set_of::SetOfVec,

der/src/asn1/integer.rs

Lines changed: 2 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,13 @@
11
//! ASN.1 `INTEGER` support.
22
3-
pub(super) mod bigint;
43
pub(super) mod int;
54
pub(super) mod uint;
65

76
use core::{cmp::Ordering, mem};
87

9-
use crate::{
10-
asn1::AnyRef, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader, Result,
11-
SliceWriter, Tag, ValueOrd, Writer,
12-
};
8+
use crate::{EncodeValue, Result, SliceWriter};
139

14-
macro_rules! impl_int_encoding {
15-
($($int:ty => $uint:ty),+) => {
16-
$(
17-
impl<'a> DecodeValue<'a> for $int {
18-
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
19-
let mut buf = [0u8; Self::BITS as usize / 8];
20-
let max_length = u32::from(header.length) as usize;
21-
22-
if max_length > buf.len() {
23-
return Err(Self::TAG.non_canonical_error());
24-
}
25-
26-
let bytes = reader.read_into(&mut buf[..max_length])?;
27-
28-
let result = if is_highest_bit_set(bytes) {
29-
<$uint>::from_be_bytes(int::decode_to_array(bytes)?) as $int
30-
} else {
31-
Self::from_be_bytes(uint::decode_to_array(bytes)?)
32-
};
33-
34-
// Ensure we compute the same encoded length as the original any value
35-
if header.length != result.value_len()? {
36-
return Err(Self::TAG.non_canonical_error());
37-
}
38-
39-
Ok(result)
40-
}
41-
}
42-
43-
impl EncodeValue for $int {
44-
fn value_len(&self) -> Result<Length> {
45-
if *self < 0 {
46-
int::negative_encoded_len(&(*self as $uint).to_be_bytes())
47-
} else {
48-
uint::encoded_len(&self.to_be_bytes())
49-
}
50-
}
51-
52-
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
53-
if *self < 0 {
54-
int::encode_bytes(writer, &(*self as $uint).to_be_bytes())
55-
} else {
56-
uint::encode_bytes(writer, &self.to_be_bytes())
57-
}
58-
}
59-
}
60-
61-
impl FixedTag for $int {
62-
const TAG: Tag = Tag::Integer;
63-
}
64-
65-
impl ValueOrd for $int {
66-
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
67-
value_cmp(*self, *other)
68-
}
69-
}
70-
71-
impl TryFrom<AnyRef<'_>> for $int {
72-
type Error = Error;
73-
74-
fn try_from(any: AnyRef<'_>) -> Result<Self> {
75-
any.decode_as()
76-
}
77-
}
78-
)+
79-
};
80-
}
81-
82-
macro_rules! impl_uint_encoding {
83-
($($uint:ty),+) => {
84-
$(
85-
impl<'a> DecodeValue<'a> for $uint {
86-
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
87-
// Integers always encodes as a signed value, unsigned gets a leading 0x00 that
88-
// needs to be stripped off. We need to provide room for it.
89-
const UNSIGNED_HEADROOM: usize = 1;
90-
91-
let mut buf = [0u8; (Self::BITS as usize / 8) + UNSIGNED_HEADROOM];
92-
let max_length = u32::from(header.length) as usize;
93-
94-
if max_length > buf.len() {
95-
return Err(Self::TAG.non_canonical_error());
96-
}
97-
98-
let bytes = reader.read_into(&mut buf[..max_length])?;
99-
100-
let result = Self::from_be_bytes(uint::decode_to_array(bytes)?);
101-
102-
// Ensure we compute the same encoded length as the original any value
103-
if header.length != result.value_len()? {
104-
return Err(Self::TAG.non_canonical_error());
105-
}
106-
107-
Ok(result)
108-
}
109-
}
110-
111-
impl EncodeValue for $uint {
112-
fn value_len(&self) -> Result<Length> {
113-
uint::encoded_len(&self.to_be_bytes())
114-
}
115-
116-
fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
117-
uint::encode_bytes(writer, &self.to_be_bytes())
118-
}
119-
}
120-
121-
impl FixedTag for $uint {
122-
const TAG: Tag = Tag::Integer;
123-
}
124-
125-
impl ValueOrd for $uint {
126-
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
127-
value_cmp(*self, *other)
128-
}
129-
}
130-
131-
impl TryFrom<AnyRef<'_>> for $uint {
132-
type Error = Error;
133-
134-
fn try_from(any: AnyRef<'_>) -> Result<Self> {
135-
any.decode_as()
136-
}
137-
}
138-
)+
139-
};
140-
}
141-
142-
impl_int_encoding!(i8 => u8, i16 => u16, i32 => u32, i64 => u64, i128 => u128);
143-
impl_uint_encoding!(u8, u16, u32, u64, u128);
144-
145-
/// Is the highest bit of the first byte in the slice 1? (if present)
10+
/// Is the highest bit of the first byte in the slice set to `1`? (if present)
14611
#[inline]
14712
fn is_highest_bit_set(bytes: &[u8]) -> bool {
14813
bytes

0 commit comments

Comments
 (0)