@@ -14,6 +14,13 @@ const MAX_DER_OCTETS: usize = 5;
14
14
/// Maximum length as a `u32` (256 MiB).
15
15
const MAX_U32 : u32 = 0xfff_ffff ;
16
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
+
17
24
/// ASN.1-encoded length.
18
25
///
19
26
/// Maximum length is defined by the [`Length::MAX`] constant (256 MiB).
@@ -204,7 +211,8 @@ impl<'a> Decode<'a> for Length {
204
211
match reader. read_byte ( ) ? {
205
212
// Note: per X.690 Section 8.1.3.6.1 the byte 0x80 encodes indefinite
206
213
// 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 ( ) ) ,
208
216
// 1-4 byte variable-sized length prefix
209
217
tag @ 0x81 ..=0x84 => {
210
218
let nbytes = tag. checked_sub ( 0x80 ) . ok_or ( ErrorKind :: Overlength ) ? as usize ;
@@ -299,9 +307,113 @@ impl<'a> arbitrary::Arbitrary<'a> for Length {
299
307
}
300
308
}
301
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`.
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
+
302
414
#[ cfg( test) ]
303
415
mod tests {
304
- use super :: Length ;
416
+ use super :: { IndefiniteLength , Length } ;
305
417
use crate :: { Decode , DerOrd , Encode , ErrorKind } ;
306
418
use core:: cmp:: Ordering ;
307
419
@@ -368,8 +480,22 @@ mod tests {
368
480
}
369
481
370
482
#[ test]
371
- fn reject_indefinite_lengths ( ) {
483
+ fn indefinite_lengths ( ) {
484
+ // DER disallows indefinite lengths
372
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
+ ) ;
373
499
}
374
500
375
501
#[ test]
0 commit comments