1
1
//! Length calculations for encoded ASN.1 DER values
2
2
3
3
use crate :: {
4
- Decode , DerOrd , Encode , EncodingRules , Error , ErrorKind , Reader , Result , SliceWriter , Tag ,
5
- Writer ,
4
+ Decode , DerOrd , Encode , EncodingRules , Error , ErrorKind , Header , Reader , Result , SliceWriter ,
5
+ Tag , Writer ,
6
6
} ;
7
7
use core:: {
8
8
cmp:: Ordering ,
@@ -347,6 +347,8 @@ fn decode_indefinite_length<'a, R: Reader<'a>>(reader: &mut R) -> Result<Length>
347
347
let start_pos = reader. position ( ) ;
348
348
349
349
loop {
350
+ let current_pos = reader. position ( ) ;
351
+
350
352
// Look for the end-of-contents marker
351
353
if reader. peek_byte ( ) == Some ( EOC_TAG ) {
352
354
// Drain the end-of-contents tag
@@ -355,15 +357,14 @@ fn decode_indefinite_length<'a, R: Reader<'a>>(reader: &mut R) -> Result<Length>
355
357
// Read the length byte and ensure it's zero (i.e. the full EOC is `00 00`)
356
358
let length_byte = reader. read_byte ( ) ?;
357
359
if length_byte == 0 {
358
- return reader . position ( ) - start_pos;
360
+ return current_pos - start_pos;
359
361
} else {
360
362
return Err ( reader. error ( ErrorKind :: IndefiniteLength ) ) ;
361
363
}
362
364
}
363
365
364
- let _tag = Tag :: decode ( reader) ?;
365
- let inner_length = Length :: decode ( reader) ?;
366
- reader. drain ( inner_length) ?;
366
+ let header = Header :: decode ( reader) ?;
367
+ reader. drain ( header. length ) ?;
367
368
}
368
369
}
369
370
@@ -470,6 +471,9 @@ mod tests {
470
471
/// Length of example in octets.
471
472
const EXAMPLE_LEN : usize = 68 ;
472
473
474
+ /// Length of end-of-content octets (i.e. `00 00`).
475
+ const EOC_LEN : usize = 2 ;
476
+
473
477
/// Test vector from: <https://github.com/RustCrypto/formats/issues/779#issuecomment-2902948789>
474
478
///
475
479
/// Notably this example contains nested indefinite lengths to ensure the decoder handles
@@ -496,7 +500,30 @@ mod tests {
496
500
let pos = usize:: try_from ( reader. position ( ) ) . unwrap ( ) ;
497
501
assert_eq ! ( pos, 2 ) ;
498
502
499
- // The first two bytes are the header and the rest is the length of the message
500
- assert_eq ! ( usize :: try_from( length) . unwrap( ) , EXAMPLE_LEN - pos) ;
503
+ // The first two bytes are the header and the rest is the length of the message.
504
+ // The last four are two end-of-content markers (2 * 2 bytes).
505
+ assert_eq ! (
506
+ usize :: try_from( length) . unwrap( ) ,
507
+ EXAMPLE_LEN - pos - ( EOC_LEN * 2 )
508
+ ) ;
509
+
510
+ // Read OID
511
+ reader. tlv_bytes ( ) . unwrap ( ) ;
512
+ // Read SEQUENCE
513
+ reader. tlv_bytes ( ) . unwrap ( ) ;
514
+
515
+ // We're now at the next indefinite length record
516
+ let tag = Tag :: decode ( & mut reader) . unwrap ( ) ;
517
+ assert_eq ! (
518
+ tag,
519
+ Tag :: ContextSpecific {
520
+ constructed: true ,
521
+ number: 0u32 . into( )
522
+ }
523
+ ) ;
524
+
525
+ // Parse the inner indefinite length
526
+ let length = Length :: decode ( & mut reader) . unwrap ( ) ;
527
+ assert_eq ! ( usize :: try_from( length) . unwrap( ) , 18 ) ;
501
528
}
502
529
}
0 commit comments