diff --git a/der/src/asn1/octet_string.rs b/der/src/asn1/octet_string.rs index 436777600..af79a1d91 100644 --- a/der/src/asn1/octet_string.rs +++ b/der/src/asn1/octet_string.rs @@ -449,4 +449,25 @@ mod tests { assert_eq!(decoded.as_bytes(), b"Hello, world"); } + + #[test] + #[cfg(feature = "alloc")] + fn decode_ber_recursive_unsupported() { + use crate::{Decode, Error, ErrorKind, Length, asn1::OctetString}; + use hex_literal::hex; + + const EXAMPLE_BER: &[u8] = &hex!( + "2480" // Constructed indefinite length OCTET STRING + "2480" // Constructed indefinite length OCTET STRING + "040648656c6c6f2c" // Segment containing "Hello," + "040620776f726c64" // Segment containing " world" + "0000" // End-of-contents marker + "040620776f726c64" // Segment containing " world" + "0000" // End-of-contents marker + ); + + let err = OctetString::from_ber(EXAMPLE_BER).err().unwrap(); + let expected = Error::new(ErrorKind::IndefiniteLength, Length::new(4)); + assert_eq!(expected, err); + } } diff --git a/der/src/length/indefinite.rs b/der/src/length/indefinite.rs index fc14681d7..f1c20f1fe 100644 --- a/der/src/length/indefinite.rs +++ b/der/src/length/indefinite.rs @@ -97,7 +97,13 @@ pub(crate) fn read_constructed_vec<'r, R: Reader<'r>>( let h = Header::decode(reader)?; h.tag.assert_eq(inner_tag)?; - // Indefinite length headers can't be indefinite + // This constructed string is ‘recursively constructed’ + // as one of its segments is itself encoded with + // constructed, indefinite-length method. + // This is currently chosen to be unsupported. + // + // See discussion: + // - https://github.com/RustCrypto/formats/issues/779#issuecomment-3049589340 if h.length.is_indefinite() { return Err(reader.error(ErrorKind::IndefiniteLength)); }