@@ -14,6 +14,13 @@ const MAX_DER_OCTETS: usize = 5;
1414/// Maximum length as a `u32` (256 MiB).
1515const MAX_U32 : u32 = 0xfff_ffff ;
1616
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+
1724/// ASN.1-encoded length.
1825///
1926/// Maximum length is defined by the [`Length::MAX`] constant (256 MiB).
@@ -204,7 +211,8 @@ impl<'a> Decode<'a> for Length {
204211 match reader. read_byte ( ) ? {
205212 // Note: per X.690 Section 8.1.3.6.1 the byte 0x80 encodes indefinite
206213 // lengths, which are not allowed in DER, so disallow that byte.
207- len if len < 0x80 => Ok ( len. into ( ) ) ,
214+ len if len < INDEFINITE_LENGTH_OCTET => Ok ( len. into ( ) ) ,
215+ INDEFINITE_LENGTH_OCTET => Err ( ErrorKind :: IndefiniteLength . into ( ) ) ,
208216 // 1-4 byte variable-sized length prefix
209217 tag @ 0x81 ..=0x84 => {
210218 let nbytes = tag. checked_sub ( 0x80 ) . ok_or ( ErrorKind :: Overlength ) ? as usize ;
@@ -299,9 +307,113 @@ impl<'a> arbitrary::Arbitrary<'a> for Length {
299307 }
300308}
301309
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`.
344+ pub fn new ( length : impl Into < Length > ) -> Self {
345+ Self ( Some ( length. into ( ) ) )
346+ }
347+
348+ /// Is this length definite?
349+ pub fn is_definite ( self ) -> bool {
350+ self . 0 . is_some ( )
351+ }
352+ /// Is this length indefinite?
353+ pub fn is_indefinite ( self ) -> bool {
354+ self . 0 . is_none ( )
355+ }
356+ }
357+
358+ impl < ' a > Decode < ' a > for 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 {
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+
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 {
389+ fn from ( length : Length ) -> IndefiniteLength {
390+ Self ( Some ( length) )
391+ }
392+ }
393+
394+ impl From < Option < Length > > for IndefiniteLength {
395+ fn from ( length : Option < Length > ) -> IndefiniteLength {
396+ IndefiniteLength ( length)
397+ }
398+ }
399+
400+ impl From < IndefiniteLength > for 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+
409+ fn try_from ( length : IndefiniteLength ) -> Result < Length > {
410+ length. 0 . ok_or_else ( || ErrorKind :: IndefiniteLength . into ( ) )
411+ }
412+ }
413+
302414#[ cfg( test) ]
303415mod tests {
304- use super :: Length ;
416+ use super :: { IndefiniteLength , Length } ;
305417 use crate :: { Decode , DerOrd , Encode , ErrorKind } ;
306418 use core:: cmp:: Ordering ;
307419
@@ -368,8 +480,22 @@ mod tests {
368480 }
369481
370482 #[ test]
371- fn reject_indefinite_lengths ( ) {
483+ fn indefinite_lengths ( ) {
484+ // DER disallows indefinite lengths
372485 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+ ) ;
373499 }
374500
375501 #[ test]
0 commit comments