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