1 //! Length calculations for encoded ASN.1 DER values
2 
3 use crate::{Decode, DerOrd, Encode, Error, ErrorKind, Reader, Result, SliceWriter, Writer};
4 use core::{
5     cmp::Ordering,
6     fmt,
7     ops::{Add, Sub},
8 };
9 
10 /// Maximum number of octets in a DER encoding of a [`Length`] using the
11 /// rules implemented by this crate.
12 const MAX_DER_OCTETS: usize = 5;
13 
14 /// Maximum length as a `u32` (256 MiB).
15 const MAX_U32: u32 = 0xfff_ffff;
16 
17 /// Octet identifying an indefinite length as described in X.690 Section
18 /// 8.1.3.6.1:
19 ///
20 /// > The single octet shall have bit 8 set to one, and bits 7 to
21 /// > 1 set to zero.
22 const INDEFINITE_LENGTH_OCTET: u8 = 0b10000000; // 0x80
23 
24 /// ASN.1-encoded length.
25 ///
26 /// Maximum length is defined by the [`Length::MAX`] constant (256 MiB).
27 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
28 pub struct Length(u32);
29 
30 impl Length {
31     /// Length of `0`
32     pub const ZERO: Self = Self(0);
33 
34     /// Length of `1`
35     pub const ONE: Self = Self(1);
36 
37     /// Maximum length currently supported: 256 MiB
38     pub const MAX: Self = Self(MAX_U32);
39 
40     /// Create a new [`Length`] for any value which fits inside of a [`u16`].
41     ///
42     /// This function is const-safe and therefore useful for [`Length`] constants.
new(value: u16) -> Self43     pub const fn new(value: u16) -> Self {
44         Self(value as u32)
45     }
46 
47     /// Is this length equal to zero?
is_zero(self) -> bool48     pub fn is_zero(self) -> bool {
49         self == Self::ZERO
50     }
51 
52     /// Get the length of DER Tag-Length-Value (TLV) encoded data if `self`
53     /// is the length of the inner "value" portion of the message.
for_tlv(self) -> Result<Self>54     pub fn for_tlv(self) -> Result<Self> {
55         Self::ONE + self.encoded_len()? + self
56     }
57 
58     /// Perform saturating addition of two lengths.
saturating_add(self, rhs: Self) -> Self59     pub fn saturating_add(self, rhs: Self) -> Self {
60         Self(self.0.saturating_add(rhs.0))
61     }
62 
63     /// Perform saturating subtraction of two lengths.
saturating_sub(self, rhs: Self) -> Self64     pub fn saturating_sub(self, rhs: Self) -> Self {
65         Self(self.0.saturating_sub(rhs.0))
66     }
67 
68     /// Get initial octet of the encoded length (if one is required).
69     ///
70     /// From X.690 Section 8.1.3.5:
71     /// > In the long form, the length octets shall consist of an initial octet
72     /// > and one or more subsequent octets. The initial octet shall be encoded
73     /// > as follows:
74     /// >
75     /// > a) bit 8 shall be one;
76     /// > b) bits 7 to 1 shall encode the number of subsequent octets in the
77     /// >    length octets, as an unsigned binary integer with bit 7 as the
78     /// >    most significant bit;
79     /// > c) the value 11111111₂ shall not be used.
initial_octet(self) -> Option<u8>80     fn initial_octet(self) -> Option<u8> {
81         match self.0 {
82             0x80..=0xFF => Some(0x81),
83             0x100..=0xFFFF => Some(0x82),
84             0x10000..=0xFFFFFF => Some(0x83),
85             0x1000000..=MAX_U32 => Some(0x84),
86             _ => None,
87         }
88     }
89 }
90 
91 impl Add for Length {
92     type Output = Result<Self>;
93 
add(self, other: Self) -> Result<Self>94     fn add(self, other: Self) -> Result<Self> {
95         self.0
96             .checked_add(other.0)
97             .ok_or_else(|| ErrorKind::Overflow.into())
98             .and_then(TryInto::try_into)
99     }
100 }
101 
102 impl Add<u8> for Length {
103     type Output = Result<Self>;
104 
add(self, other: u8) -> Result<Self>105     fn add(self, other: u8) -> Result<Self> {
106         self + Length::from(other)
107     }
108 }
109 
110 impl Add<u16> for Length {
111     type Output = Result<Self>;
112 
add(self, other: u16) -> Result<Self>113     fn add(self, other: u16) -> Result<Self> {
114         self + Length::from(other)
115     }
116 }
117 
118 impl Add<u32> for Length {
119     type Output = Result<Self>;
120 
add(self, other: u32) -> Result<Self>121     fn add(self, other: u32) -> Result<Self> {
122         self + Length::try_from(other)?
123     }
124 }
125 
126 impl Add<usize> for Length {
127     type Output = Result<Self>;
128 
add(self, other: usize) -> Result<Self>129     fn add(self, other: usize) -> Result<Self> {
130         self + Length::try_from(other)?
131     }
132 }
133 
134 impl Add<Length> for Result<Length> {
135     type Output = Self;
136 
add(self, other: Length) -> Self137     fn add(self, other: Length) -> Self {
138         self? + other
139     }
140 }
141 
142 impl Sub for Length {
143     type Output = Result<Self>;
144 
sub(self, other: Length) -> Result<Self>145     fn sub(self, other: Length) -> Result<Self> {
146         self.0
147             .checked_sub(other.0)
148             .ok_or_else(|| ErrorKind::Overflow.into())
149             .and_then(TryInto::try_into)
150     }
151 }
152 
153 impl Sub<Length> for Result<Length> {
154     type Output = Self;
155 
sub(self, other: Length) -> Self156     fn sub(self, other: Length) -> Self {
157         self? - other
158     }
159 }
160 
161 impl From<u8> for Length {
from(len: u8) -> Length162     fn from(len: u8) -> Length {
163         Length(len.into())
164     }
165 }
166 
167 impl From<u16> for Length {
from(len: u16) -> Length168     fn from(len: u16) -> Length {
169         Length(len.into())
170     }
171 }
172 
173 impl From<Length> for u32 {
from(length: Length) -> u32174     fn from(length: Length) -> u32 {
175         length.0
176     }
177 }
178 
179 impl TryFrom<u32> for Length {
180     type Error = Error;
181 
try_from(len: u32) -> Result<Length>182     fn try_from(len: u32) -> Result<Length> {
183         if len <= Self::MAX.0 {
184             Ok(Length(len))
185         } else {
186             Err(ErrorKind::Overflow.into())
187         }
188     }
189 }
190 
191 impl TryFrom<usize> for Length {
192     type Error = Error;
193 
try_from(len: usize) -> Result<Length>194     fn try_from(len: usize) -> Result<Length> {
195         u32::try_from(len)
196             .map_err(|_| ErrorKind::Overflow)?
197             .try_into()
198     }
199 }
200 
201 impl TryFrom<Length> for usize {
202     type Error = Error;
203 
try_from(len: Length) -> Result<usize>204     fn try_from(len: Length) -> Result<usize> {
205         len.0.try_into().map_err(|_| ErrorKind::Overflow.into())
206     }
207 }
208 
209 impl<'a> Decode<'a> for Length {
decode<R: Reader<'a>>(reader: &mut R) -> Result<Length>210     fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Length> {
211         match reader.read_byte()? {
212             // Note: per X.690 Section 8.1.3.6.1 the byte 0x80 encodes indefinite
213             // lengths, which are not allowed in DER, so disallow that byte.
214             len if len < INDEFINITE_LENGTH_OCTET => Ok(len.into()),
215             INDEFINITE_LENGTH_OCTET => Err(ErrorKind::IndefiniteLength.into()),
216             // 1-4 byte variable-sized length prefix
217             tag @ 0x81..=0x84 => {
218                 let nbytes = tag.checked_sub(0x80).ok_or(ErrorKind::Overlength)? as usize;
219                 debug_assert!(nbytes <= 4);
220 
221                 let mut decoded_len = 0u32;
222                 for _ in 0..nbytes {
223                     decoded_len = decoded_len.checked_shl(8).ok_or(ErrorKind::Overflow)?
224                         | u32::from(reader.read_byte()?);
225                 }
226 
227                 let length = Length::try_from(decoded_len)?;
228 
229                 // X.690 Section 10.1: DER lengths must be encoded with a minimum
230                 // number of octets
231                 if length.initial_octet() == Some(tag) {
232                     Ok(length)
233                 } else {
234                     Err(ErrorKind::Overlength.into())
235                 }
236             }
237             _ => {
238                 // We specialize to a maximum 4-byte length (including initial octet)
239                 Err(ErrorKind::Overlength.into())
240             }
241         }
242     }
243 }
244 
245 impl Encode for Length {
encoded_len(&self) -> Result<Length>246     fn encoded_len(&self) -> Result<Length> {
247         match self.0 {
248             0..=0x7F => Ok(Length(1)),
249             0x80..=0xFF => Ok(Length(2)),
250             0x100..=0xFFFF => Ok(Length(3)),
251             0x10000..=0xFFFFFF => Ok(Length(4)),
252             0x1000000..=MAX_U32 => Ok(Length(5)),
253             _ => Err(ErrorKind::Overflow.into()),
254         }
255     }
256 
encode(&self, writer: &mut impl Writer) -> Result<()>257     fn encode(&self, writer: &mut impl Writer) -> Result<()> {
258         match self.initial_octet() {
259             Some(tag_byte) => {
260                 writer.write_byte(tag_byte)?;
261 
262                 // Strip leading zeroes
263                 match self.0.to_be_bytes() {
264                     [0, 0, 0, byte] => writer.write_byte(byte),
265                     [0, 0, bytes @ ..] => writer.write(&bytes),
266                     [0, bytes @ ..] => writer.write(&bytes),
267                     bytes => writer.write(&bytes),
268                 }
269             }
270             #[allow(clippy::cast_possible_truncation)]
271             None => writer.write_byte(self.0 as u8),
272         }
273     }
274 }
275 
276 impl DerOrd for Length {
der_cmp(&self, other: &Self) -> Result<Ordering>277     fn der_cmp(&self, other: &Self) -> Result<Ordering> {
278         let mut buf1 = [0u8; MAX_DER_OCTETS];
279         let mut buf2 = [0u8; MAX_DER_OCTETS];
280 
281         let mut encoder1 = SliceWriter::new(&mut buf1);
282         encoder1.encode(self)?;
283 
284         let mut encoder2 = SliceWriter::new(&mut buf2);
285         encoder2.encode(other)?;
286 
287         Ok(encoder1.finish()?.cmp(encoder2.finish()?))
288     }
289 }
290 
291 impl fmt::Display for Length {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result292     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293         self.0.fmt(f)
294     }
295 }
296 
297 // Implement by hand because the derive would create invalid values.
298 // Generate a u32 with a valid range.
299 #[cfg(feature = "arbitrary")]
300 impl<'a> arbitrary::Arbitrary<'a> for Length {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>301     fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
302         Ok(Self(u.int_in_range(0..=MAX_U32)?))
303     }
304 
size_hint(depth: usize) -> (usize, Option<usize>)305     fn size_hint(depth: usize) -> (usize, Option<usize>) {
306         u32::size_hint(depth)
307     }
308 }
309 
310 /// Length type with support for indefinite lengths as used by ASN.1 BER,
311 /// as described in X.690 Section 8.1.3.6:
312 ///
313 /// > 8.1.3.6 For the indefinite form, the length octets indicate that the
314 /// > contents octets are terminated by end-of-contents
315 /// > octets (see 8.1.5), and shall consist of a single octet.
316 /// >
317 /// > 8.1.3.6.1 The single octet shall have bit 8 set to one, and bits 7 to
318 /// > 1 set to zero.
319 /// >
320 /// > 8.1.3.6.2 If this form of length is used, then end-of-contents octets
321 /// > (see 8.1.5) shall be present in the encoding following the contents
322 /// > octets.
323 ///
324 /// Indefinite lengths are non-canonical and therefore invalid DER, however
325 /// there are interoperability corner cases where we have little choice but to
326 /// tolerate some BER productions where this is helpful.
327 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
328 pub struct IndefiniteLength(Option<Length>);
329 
330 impl IndefiniteLength {
331     /// Length of `0`.
332     pub const ZERO: Self = Self(Some(Length::ZERO));
333 
334     /// Length of `1`.
335     pub const ONE: Self = Self(Some(Length::ONE));
336 
337     /// Indefinite length.
338     pub const INDEFINITE: Self = Self(None);
339 }
340 
341 impl IndefiniteLength {
342     /// Create a definite length from a type which can be converted into a
343     /// `Length`.
new(length: impl Into<Length>) -> Self344     pub fn new(length: impl Into<Length>) -> Self {
345         Self(Some(length.into()))
346     }
347 
348     /// Is this length definite?
is_definite(self) -> bool349     pub fn is_definite(self) -> bool {
350         self.0.is_some()
351     }
352     /// Is this length indefinite?
is_indefinite(self) -> bool353     pub fn is_indefinite(self) -> bool {
354         self.0.is_none()
355     }
356 }
357 
358 impl<'a> Decode<'a> for IndefiniteLength {
decode<R: Reader<'a>>(reader: &mut R) -> Result<IndefiniteLength>359     fn decode<R: Reader<'a>>(reader: &mut R) -> Result<IndefiniteLength> {
360         if reader.peek_byte() == Some(INDEFINITE_LENGTH_OCTET) {
361             // Consume the byte we already peeked at.
362             let byte = reader.read_byte()?;
363             debug_assert_eq!(byte, INDEFINITE_LENGTH_OCTET);
364 
365             Ok(Self::INDEFINITE)
366         } else {
367             Length::decode(reader).map(Into::into)
368         }
369     }
370 }
371 
372 impl Encode for IndefiniteLength {
encoded_len(&self) -> Result<Length>373     fn encoded_len(&self) -> Result<Length> {
374         match self.0 {
375             Some(length) => length.encoded_len(),
376             None => Ok(Length::ONE),
377         }
378     }
379 
encode(&self, writer: &mut impl Writer) -> Result<()>380     fn encode(&self, writer: &mut impl Writer) -> Result<()> {
381         match self.0 {
382             Some(length) => length.encode(writer),
383             None => writer.write_byte(INDEFINITE_LENGTH_OCTET),
384         }
385     }
386 }
387 
388 impl From<Length> for IndefiniteLength {
from(length: Length) -> IndefiniteLength389     fn from(length: Length) -> IndefiniteLength {
390         Self(Some(length))
391     }
392 }
393 
394 impl From<Option<Length>> for IndefiniteLength {
from(length: Option<Length>) -> IndefiniteLength395     fn from(length: Option<Length>) -> IndefiniteLength {
396         IndefiniteLength(length)
397     }
398 }
399 
400 impl From<IndefiniteLength> for Option<Length> {
from(length: IndefiniteLength) -> Option<Length>401     fn from(length: IndefiniteLength) -> Option<Length> {
402         length.0
403     }
404 }
405 
406 impl TryFrom<IndefiniteLength> for Length {
407     type Error = Error;
408 
try_from(length: IndefiniteLength) -> Result<Length>409     fn try_from(length: IndefiniteLength) -> Result<Length> {
410         length.0.ok_or_else(|| ErrorKind::IndefiniteLength.into())
411     }
412 }
413 
414 #[cfg(test)]
415 mod tests {
416     use super::{IndefiniteLength, Length};
417     use crate::{Decode, DerOrd, Encode, ErrorKind};
418     use core::cmp::Ordering;
419 
420     #[test]
decode()421     fn decode() {
422         assert_eq!(Length::ZERO, Length::from_der(&[0x00]).unwrap());
423 
424         assert_eq!(Length::from(0x7Fu8), Length::from_der(&[0x7F]).unwrap());
425 
426         assert_eq!(
427             Length::from(0x80u8),
428             Length::from_der(&[0x81, 0x80]).unwrap()
429         );
430 
431         assert_eq!(
432             Length::from(0xFFu8),
433             Length::from_der(&[0x81, 0xFF]).unwrap()
434         );
435 
436         assert_eq!(
437             Length::from(0x100u16),
438             Length::from_der(&[0x82, 0x01, 0x00]).unwrap()
439         );
440 
441         assert_eq!(
442             Length::try_from(0x10000u32).unwrap(),
443             Length::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap()
444         );
445     }
446 
447     #[test]
encode()448     fn encode() {
449         let mut buffer = [0u8; 4];
450 
451         assert_eq!(&[0x00], Length::ZERO.encode_to_slice(&mut buffer).unwrap());
452 
453         assert_eq!(
454             &[0x7F],
455             Length::from(0x7Fu8).encode_to_slice(&mut buffer).unwrap()
456         );
457 
458         assert_eq!(
459             &[0x81, 0x80],
460             Length::from(0x80u8).encode_to_slice(&mut buffer).unwrap()
461         );
462 
463         assert_eq!(
464             &[0x81, 0xFF],
465             Length::from(0xFFu8).encode_to_slice(&mut buffer).unwrap()
466         );
467 
468         assert_eq!(
469             &[0x82, 0x01, 0x00],
470             Length::from(0x100u16).encode_to_slice(&mut buffer).unwrap()
471         );
472 
473         assert_eq!(
474             &[0x83, 0x01, 0x00, 0x00],
475             Length::try_from(0x10000u32)
476                 .unwrap()
477                 .encode_to_slice(&mut buffer)
478                 .unwrap()
479         );
480     }
481 
482     #[test]
indefinite_lengths()483     fn indefinite_lengths() {
484         // DER disallows indefinite lengths
485         assert!(Length::from_der(&[0x80]).is_err());
486 
487         // The `IndefiniteLength` type supports them
488         let indefinite_length = IndefiniteLength::from_der(&[0x80]).unwrap();
489         assert!(indefinite_length.is_indefinite());
490         assert_eq!(indefinite_length, IndefiniteLength::INDEFINITE);
491 
492         // It also supports definite lengths.
493         let length = IndefiniteLength::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap();
494         assert!(length.is_definite());
495         assert_eq!(
496             Length::try_from(0x10000u32).unwrap(),
497             length.try_into().unwrap()
498         );
499     }
500 
501     #[test]
add_overflows_when_max_length_exceeded()502     fn add_overflows_when_max_length_exceeded() {
503         let result = Length::MAX + Length::ONE;
504         assert_eq!(
505             result.err().map(|err| err.kind()),
506             Some(ErrorKind::Overflow)
507         );
508     }
509 
510     #[test]
der_ord()511     fn der_ord() {
512         assert_eq!(Length::ONE.der_cmp(&Length::MAX).unwrap(), Ordering::Less);
513     }
514 }
515