@@ -9,6 +9,10 @@ pub enum ParseErrorKind {
9
9
/// Something about the tag was invalid. This refers to a syntax error,
10
10
/// not a tag's value being unexpected.
11
11
InvalidTag ,
12
+ /// Something about the length was invalid. This can mean either a invalid
13
+ /// encoding, or that a TLV was longer than 65535, which is the maximum
14
+ /// length that rust-asn1 supports.
15
+ InvalidLength ,
12
16
/// An unexpected tag was encountered.
13
17
UnexpectedTag { actual : Tag } ,
14
18
/// There was not enough data available to complete parsing.
@@ -112,6 +116,7 @@ impl fmt::Display for ParseError {
112
116
match self . kind {
113
117
ParseErrorKind :: InvalidValue => write ! ( f, "invalid value" ) ,
114
118
ParseErrorKind :: InvalidTag => write ! ( f, "invalid tag" ) ,
119
+ ParseErrorKind :: InvalidLength => write ! ( f, "invalid length" ) ,
115
120
ParseErrorKind :: UnexpectedTag { actual } => {
116
121
write ! ( f, "unexpected tag (got {:?})" , actual)
117
122
}
@@ -201,34 +206,29 @@ impl<'a> Parser<'a> {
201
206
}
202
207
203
208
fn read_length ( & mut self ) -> ParseResult < usize > {
204
- let b = self . read_u8 ( ) ?;
205
- if b & 0x80 == 0 {
206
- return Ok ( b as usize ) ;
207
- }
208
- let num_bytes = b & 0x7f ;
209
- // Indefinite length form is not valid DER
210
- if num_bytes == 0 {
211
- return Err ( ParseError :: new ( ParseErrorKind :: InvalidValue ) ) ;
212
- }
213
-
214
- let mut length = 0 ;
215
- for _ in 0 ..num_bytes {
216
- let b = self . read_u8 ( ) ?;
217
- if length > ( usize:: max_value ( ) >> 8 ) {
218
- return Err ( ParseError :: new ( ParseErrorKind :: IntegerOverflow ) ) ;
209
+ match self . read_u8 ( ) ? {
210
+ n if ( n & 0x80 ) == 0 => Ok ( usize:: from ( n) ) ,
211
+ 0x81 => {
212
+ let length = usize:: from ( self . read_u8 ( ) ?) ;
213
+ // Do not allow values <0x80 to be encoded using the long form
214
+ if length < 0x80 {
215
+ return Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) ;
216
+ }
217
+ Ok ( length)
219
218
}
220
- length <<= 8 ;
221
- length |= b as usize ;
222
- // Disallow leading 0s
223
- if length == 0 {
224
- return Err ( ParseError :: new ( ParseErrorKind :: InvalidValue ) ) ;
219
+ 0x82 => {
220
+ let length = usize:: from ( self . read_u8 ( ) ?) << 8 | usize:: from ( self . read_u8 ( ) ?) ;
221
+ // Enforce that we're not using long form for values <0x80,
222
+ // and that the first byte of the length is not zero (i.e.
223
+ // that we're minimally encoded)
224
+ if length < 0x100 {
225
+ return Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) ;
226
+ }
227
+ Ok ( length)
225
228
}
229
+ // We only support two-byte lengths
230
+ _ => Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) ,
226
231
}
227
- // Do not allow values <0x80 to be encoded using the long form
228
- if length < 0x80 {
229
- return Err ( ParseError :: new ( ParseErrorKind :: InvalidValue ) ) ;
230
- }
231
- Ok ( length)
232
232
}
233
233
234
234
#[ inline]
@@ -404,6 +404,10 @@ mod tests {
404
404
ParseError :: new ( ParseErrorKind :: InvalidTag ) ,
405
405
"ASN.1 parsing error: invalid tag"
406
406
) ,
407
+ (
408
+ ParseError :: new ( ParseErrorKind :: InvalidLength ) ,
409
+ "ASN.1 parsing error: invalid length"
410
+ ) ,
407
411
(
408
412
ParseError :: new ( ParseErrorKind :: IntegerOverflow ) ,
409
413
"ASN.1 parsing error: integer overflow"
@@ -619,15 +623,16 @@ mod tests {
619
623
Ok ( b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ) ,
620
624
b"\x04 \x81 \x81 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
621
625
) ,
622
- ( Err ( ParseError :: new ( ParseErrorKind :: InvalidValue ) ) , b"\x04 \x80 " ) ,
623
- ( Err ( ParseError :: new ( ParseErrorKind :: InvalidValue ) ) , b"\x04 \x81 \x00 " ) ,
624
- ( Err ( ParseError :: new ( ParseErrorKind :: InvalidValue ) ) , b"\x04 \x81 \x01 \x09 " ) ,
626
+ ( Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) , b"\x04 \x80 " ) ,
627
+ ( Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) , b"\x04 \x81 \x00 " ) ,
628
+ ( Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) , b"\x04 \x81 \x01 \x09 " ) ,
629
+ ( Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) , b"\x04 \x82 \x00 \x80 " ) ,
625
630
(
626
- Err ( ParseError :: new ( ParseErrorKind :: IntegerOverflow ) ) ,
631
+ Err ( ParseError :: new ( ParseErrorKind :: InvalidLength ) ) ,
627
632
b"\x04 \x89 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 "
628
633
) ,
629
634
( Err ( ParseError :: new ( ParseErrorKind :: ShortData ) ) , b"\x04 \x03 \x01 \x02 " ) ,
630
- ( Err ( ParseError :: new ( ParseErrorKind :: ShortData ) ) , b"\x04 \x83 \xff \xff \xff \xff \xff \xff " ) ,
635
+ ( Err ( ParseError :: new ( ParseErrorKind :: ShortData ) ) , b"\x04 \x82 \xff \xff \xff \xff \xff \xff " ) ,
631
636
] ) ;
632
637
}
633
638
0 commit comments