From 442e3e3ba91d95be15d2efeefc1bb3e5b15511ef Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Tue, 25 Mar 2025 09:20:31 +0100 Subject: [PATCH 1/2] der: read_nested: check header length matches contents of IMPLICIT --- der/src/asn1/context_specific.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/der/src/asn1/context_specific.rs b/der/src/asn1/context_specific.rs index 129995711..c282d1cda 100644 --- a/der/src/asn1/context_specific.rs +++ b/der/src/asn1/context_specific.rs @@ -63,8 +63,14 @@ impl ContextSpecific { T: DecodeValue<'a> + Tagged, { Self::decode_with::<_, _, T::Error>(reader, tag_number, |reader| { + // Decode IMPLICIT header let header = Header::decode(reader)?; - let value = T::decode_value(reader, header)?; + + // read_nested checks if header matches decoded length + let value = reader.read_nested(header.length, |reader| { + // Decode inner IMPLICIT value + T::decode_value(reader, header) + })?; if header.tag.is_constructed() != value.tag().is_constructed() { return Err(header.tag.non_canonical_error().into()); @@ -119,6 +125,7 @@ where type Error = T::Error; fn decode>(reader: &mut R) -> Result { + // Decode EXPLICIT header let header = Header::decode(reader)?; match header.tag { @@ -128,7 +135,10 @@ where } => Ok(Self { tag_number: number, tag_mode: TagMode::default(), - value: reader.read_nested(header.length, |reader| T::decode(reader))?, + value: reader.read_nested(header.length, |reader| { + // Decode inner tag-length-value of EXPLICIT + T::decode(reader) + })?, }), tag => Err(tag.unexpected_error(None).into()), } From 4ae9dc5914e83f637a00eda92fff688f094966aa Mon Sep 17 00:00:00 2001 From: dishmaker <141624503+dishmaker@users.noreply.github.com> Date: Mon, 21 Apr 2025 02:52:20 +0200 Subject: [PATCH 2/2] x509-cert: fix idp negative test due to der implicit reader fix --- x509-cert/tests/pkix_extensions.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/x509-cert/tests/pkix_extensions.rs b/x509-cert/tests/pkix_extensions.rs index a0aff0d12..fe0082bc9 100644 --- a/x509-cert/tests/pkix_extensions.rs +++ b/x509-cert/tests/pkix_extensions.rs @@ -843,8 +843,6 @@ fn decode_cert() { #[test] fn decode_idp() { - use der::TagNumber; - // IDP from 04A8739769B3C090A11DCDFABA3CF33F4BEF21F3.crl in PKITS 2048 in ficam-scvp-testing repo let idp = IssuingDistributionPoint::from_der(&hex!("30038201FF")).unwrap(); assert_eq!(idp.only_contains_ca_certs, true); @@ -1112,7 +1110,11 @@ fn decode_idp() { panic!("Expected FullName") } } +} +#[test] +fn decode_idp_negative() { + use der::TagNumber; //--------------------------------- // Negative tests //--------------------------------- @@ -1143,7 +1145,7 @@ fn decode_idp() { "3067A060A05EA45C305A310B3009060355040613025553311F301D060355040A131654657374204365727469666963617465732032303137311C301A060355040B13136F6E6C79536F6D65526561736F6E7320434133310C300A0603550403130343524C8304079F80" )); let err = idp.err().unwrap(); - assert_eq!(err.position().unwrap(), 103u8.into()); + assert_eq!(err.position().unwrap(), 105u8.into()); assert_eq!( ErrorKind::Incomplete { expected_len: 106u8.into(), @@ -1197,7 +1199,13 @@ fn decode_idp() { "30820168A0820161A082015DA4753073310B3009060355040613025553311F301D060355040A13165465737420436572746966696361746573203230313731183016060355040B130F696E64697265637443524C204341353129302706035504031320696E6469726563742043524C20666F7220696E64697265637443524C20434136A4753073310B3009060355040613025553311F301D060355040A13165465737420436572746966696361746573203230313731183016060355040B130F696E64697265637443524C204341353129302706035504031320696E6469726563742043524C20666F7220696E64697265637443524C20434137A46D306B310B3009060355040613025553311F301D060355040A13165465737420436572746966696361746573203230313731183016060355040B130F696E64697265637443524C204341353121301F0603550403131843524C3120666F7220696E64697265637443524C204341358402FFFF" )); let err = idp.err().unwrap(); - assert_eq!(ErrorKind::Length { tag: Tag::Boolean }, err.kind()); + assert_eq!( + ErrorKind::Incomplete { + expected_len: Length::new(365), + actual_len: Length::new(364) + }, + err.kind() + ); // Boolean value is neither 0x00 nor 0xFF let idp = IssuingDistributionPoint::from_der(&hex!(