1use super::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::Uint;
12
13macro_rules! impl_encoding_traits {
14 ($($uint:ty),+) => {
15 $(
16 impl<'a> DecodeValue<'a> for $uint {
17 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
18 const UNSIGNED_HEADROOM: usize = 1;
21
22 let mut buf = [0u8; (Self::BITS as usize / 8) + UNSIGNED_HEADROOM];
23 let max_length = u32::from(header.length) as usize;
24
25 if max_length > buf.len() {
26 return Err(Self::TAG.non_canonical_error());
27 }
28
29 let bytes = reader.read_into(&mut buf[..max_length])?;
30
31 let result = Self::from_be_bytes(decode_to_array(bytes)?);
32
33 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 $uint {
43 fn value_len(&self) -> Result<Length> {
44 encoded_len(&self.to_be_bytes())
45 }
46
47 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
48 encode_bytes(writer, &self.to_be_bytes())
49 }
50 }
51
52 impl FixedTag for $uint {
53 const TAG: Tag = Tag::Integer;
54 }
55
56 impl ValueOrd for $uint {
57 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
58 value_cmp(*self, *other)
59 }
60 }
61
62 impl TryFrom<AnyRef<'_>> for $uint {
63 type Error = Error;
64
65 fn try_from(any: AnyRef<'_>) -> Result<Self> {
66 any.decode_as()
67 }
68 }
69 )+
70 };
71}
72
73impl_encoding_traits!(u8, u16, u32, u64, u128);
74
75#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
83pub struct UintRef<'a> {
84 inner: BytesRef<'a>,
86}
87
88impl<'a> UintRef<'a> {
89 pub fn new(bytes: &'a [u8]) -> Result<Self> {
91 let inner = BytesRef::new(strip_leading_zeroes(bytes))
92 .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
93
94 Ok(Self { inner })
95 }
96
97 pub fn as_bytes(&self) -> &'a [u8] {
100 self.inner.as_slice()
101 }
102
103 pub fn len(&self) -> Length {
105 self.inner.len()
106 }
107
108 pub fn is_empty(&self) -> bool {
110 self.inner.is_empty()
111 }
112}
113
114impl_any_conversions!(UintRef<'a>, 'a);
115
116impl<'a> DecodeValue<'a> for UintRef<'a> {
117 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
118 let bytes = BytesRef::decode_value(reader, header)?.as_slice();
119 let result = Self::new(decode_to_slice(bytes)?)?;
120
121 if result.value_len()? != header.length {
123 return Err(Self::TAG.non_canonical_error());
124 }
125
126 Ok(result)
127 }
128}
129
130impl<'a> EncodeValue for UintRef<'a> {
131 fn value_len(&self) -> Result<Length> {
132 encoded_len(self.inner.as_slice())
133 }
134
135 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
136 if self.value_len()? > self.len() {
138 writer.write_byte(0)?;
139 }
140
141 writer.write(self.as_bytes())
142 }
143}
144
145impl<'a> From<&UintRef<'a>> for UintRef<'a> {
146 fn from(value: &UintRef<'a>) -> UintRef<'a> {
147 *value
148 }
149}
150
151impl<'a> FixedTag for UintRef<'a> {
152 const TAG: Tag = Tag::Integer;
153}
154
155impl<'a> OrdIsValueOrd for UintRef<'a> {}
156
157#[cfg(feature = "alloc")]
158mod allocating {
159 use super::{decode_to_slice, encoded_len, strip_leading_zeroes, UintRef};
160 use crate::{
161 ord::OrdIsValueOrd,
162 referenced::{OwnedToRef, RefToOwned},
163 BytesOwned, DecodeValue, EncodeValue, ErrorKind, FixedTag, Header, Length, Reader, Result,
164 Tag, Writer,
165 };
166
167 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
175 pub struct Uint {
176 inner: BytesOwned,
178 }
179
180 impl Uint {
181 pub fn new(bytes: &[u8]) -> Result<Self> {
183 let inner = BytesOwned::new(strip_leading_zeroes(bytes))
184 .map_err(|_| ErrorKind::Length { tag: Self::TAG })?;
185
186 Ok(Self { inner })
187 }
188
189 pub fn as_bytes(&self) -> &[u8] {
192 self.inner.as_slice()
193 }
194
195 pub fn len(&self) -> Length {
197 self.inner.len()
198 }
199
200 pub fn is_empty(&self) -> bool {
202 self.inner.is_empty()
203 }
204 }
205
206 impl_any_conversions!(Uint);
207
208 impl<'a> DecodeValue<'a> for Uint {
209 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
210 let bytes = BytesOwned::decode_value(reader, header)?;
211 let result = Self::new(decode_to_slice(bytes.as_slice())?)?;
212
213 if result.value_len()? != header.length {
215 return Err(Self::TAG.non_canonical_error());
216 }
217
218 Ok(result)
219 }
220 }
221
222 impl EncodeValue for Uint {
223 fn value_len(&self) -> Result<Length> {
224 encoded_len(self.inner.as_slice())
225 }
226
227 fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
228 if self.value_len()? > self.len() {
230 writer.write_byte(0)?;
231 }
232
233 writer.write(self.as_bytes())
234 }
235 }
236
237 impl<'a> From<&UintRef<'a>> for Uint {
238 fn from(value: &UintRef<'a>) -> Uint {
239 let inner = BytesOwned::new(value.as_bytes()).expect("Invalid Uint");
240 Uint { inner }
241 }
242 }
243
244 impl FixedTag for Uint {
245 const TAG: Tag = Tag::Integer;
246 }
247
248 impl OrdIsValueOrd for Uint {}
249
250 impl<'a> RefToOwned<'a> for UintRef<'a> {
251 type Owned = Uint;
252 fn ref_to_owned(&self) -> Self::Owned {
253 let inner = self.inner.ref_to_owned();
254
255 Uint { inner }
256 }
257 }
258
259 impl OwnedToRef for Uint {
260 type Borrowed<'a> = UintRef<'a>;
261 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
262 let inner = self.inner.owned_to_ref();
263
264 UintRef { inner }
265 }
266 }
267}
268
269pub(crate) fn decode_to_slice(bytes: &[u8]) -> Result<&[u8]> {
274 match bytes {
281 [] => Err(Tag::Integer.non_canonical_error()),
282 [0] => Ok(bytes),
283 [0, byte, ..] if *byte < 0x80 => Err(Tag::Integer.non_canonical_error()),
284 [0, rest @ ..] => Ok(rest),
285 [byte, ..] if *byte >= 0x80 => Err(Tag::Integer.value_error()),
286 _ => Ok(bytes),
287 }
288}
289
290pub(super) fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {
293 let input = decode_to_slice(bytes)?;
294
295 let num_zeroes = N
297 .checked_sub(input.len())
298 .ok_or_else(|| Tag::Integer.length_error())?;
299
300 let mut output = [0u8; N];
302 output[num_zeroes..].copy_from_slice(input);
303 Ok(output)
304}
305
306pub(crate) fn encode_bytes<W>(encoder: &mut W, bytes: &[u8]) -> Result<()>
308where
309 W: Writer + ?Sized,
310{
311 let bytes = strip_leading_zeroes(bytes);
312
313 if needs_leading_zero(bytes) {
314 encoder.write_byte(0)?;
315 }
316
317 encoder.write(bytes)
318}
319
320#[inline]
322pub(crate) fn encoded_len(bytes: &[u8]) -> Result<Length> {
323 let bytes = strip_leading_zeroes(bytes);
324 Length::try_from(bytes.len())? + u8::from(needs_leading_zero(bytes))
325}
326
327pub(crate) fn strip_leading_zeroes(mut bytes: &[u8]) -> &[u8] {
329 while let Some((byte, rest)) = bytes.split_first() {
330 if *byte == 0 && !rest.is_empty() {
331 bytes = rest;
332 } else {
333 break;
334 }
335 }
336
337 bytes
338}
339
340fn needs_leading_zero(bytes: &[u8]) -> bool {
342 matches!(bytes.first(), Some(byte) if *byte >= 0x80)
343}
344
345#[cfg(test)]
346mod tests {
347 use super::{decode_to_array, UintRef};
348 use crate::{asn1::integer::tests::*, AnyRef, Decode, Encode, ErrorKind, SliceWriter, Tag};
349
350 #[test]
351 fn decode_to_array_no_leading_zero() {
352 let arr = decode_to_array::<4>(&[1, 2]).unwrap();
353 assert_eq!(arr, [0, 0, 1, 2]);
354 }
355
356 #[test]
357 fn decode_to_array_leading_zero() {
358 let arr = decode_to_array::<4>(&[0x00, 0xFF, 0xFE]).unwrap();
359 assert_eq!(arr, [0x00, 0x00, 0xFF, 0xFE]);
360 }
361
362 #[test]
363 fn decode_to_array_extra_zero() {
364 let err = decode_to_array::<4>(&[0, 1, 2]).err().unwrap();
365 assert_eq!(err.kind(), ErrorKind::Noncanonical { tag: Tag::Integer });
366 }
367
368 #[test]
369 fn decode_to_array_missing_zero() {
370 let err = decode_to_array::<4>(&[0xFF, 0xFE]).err().unwrap();
372 assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
373 }
374
375 #[test]
376 fn decode_to_array_oversized_input() {
377 let err = decode_to_array::<1>(&[1, 2, 3]).err().unwrap();
378 assert_eq!(err.kind(), ErrorKind::Length { tag: Tag::Integer });
379 }
380
381 #[test]
382 fn decode_uintref() {
383 assert_eq!(&[0], UintRef::from_der(I0_BYTES).unwrap().as_bytes());
384 assert_eq!(&[127], UintRef::from_der(I127_BYTES).unwrap().as_bytes());
385 assert_eq!(&[128], UintRef::from_der(I128_BYTES).unwrap().as_bytes());
386 assert_eq!(&[255], UintRef::from_der(I255_BYTES).unwrap().as_bytes());
387
388 assert_eq!(
389 &[0x01, 0x00],
390 UintRef::from_der(I256_BYTES).unwrap().as_bytes()
391 );
392
393 assert_eq!(
394 &[0x7F, 0xFF],
395 UintRef::from_der(I32767_BYTES).unwrap().as_bytes()
396 );
397 }
398
399 #[test]
400 fn encode_uintref() {
401 for &example in &[
402 I0_BYTES,
403 I127_BYTES,
404 I128_BYTES,
405 I255_BYTES,
406 I256_BYTES,
407 I32767_BYTES,
408 ] {
409 let uint = UintRef::from_der(example).unwrap();
410
411 let mut buf = [0u8; 128];
412 let mut encoder = SliceWriter::new(&mut buf);
413 uint.encode(&mut encoder).unwrap();
414
415 let result = encoder.finish().unwrap();
416 assert_eq!(example, result);
417 }
418 }
419
420 #[test]
421 fn reject_oversize_without_extra_zero() {
422 let err = UintRef::try_from(AnyRef::new(Tag::Integer, &[0x81]).unwrap())
423 .err()
424 .unwrap();
425
426 assert_eq!(err.kind(), ErrorKind::Value { tag: Tag::Integer });
427 }
428}