Skip to content

Commit 858f3af

Browse files
authored
Negative test case for constructed, definite-length octet string (#1931)
Ensure octet strings with constructed, definite-length method return an error, rather than an incorrect decoding.
1 parent 98480d8 commit 858f3af

26 files changed

+158
-82
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,5 @@ tls_codec_derive = { path = "./tls_codec/derive" }
5959
x509-tsp = { path = "./x509-tsp" }
6060
x509-cert = { path = "./x509-cert" }
6161
x509-ocsp = { path = "./x509-ocsp" }
62+
63+
ecdsa = { git = "https://github.com/dwhjames/RustCrypto-signatures", branch = "tmp_der_header_refactor" }

der/src/asn1/any.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,7 @@ impl<'a> AnyRef<'a> {
5656

5757
/// Returns [`Tag`] and [`Length`] of self.
5858
pub fn header(&self) -> Header {
59-
Header {
60-
tag: self.tag,
61-
length: self.value.len(),
62-
}
59+
Header::new(self.tag, self.value.len())
6360
}
6461

6562
/// Attempt to decode this [`AnyRef`] type into the inner value.
@@ -128,7 +125,7 @@ impl<'a> DecodeValue<'a> for AnyRef<'a> {
128125

129126
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Error> {
130127
Ok(Self {
131-
tag: header.tag,
128+
tag: header.tag(),
132129
value: <&'a BytesRef>::decode_value(reader, header)?,
133130
})
134131
}
@@ -207,10 +204,7 @@ mod allocating {
207204

208205
/// Returns [`Tag`] and [`Length`] of self.
209206
pub fn header(&self) -> Header {
210-
Header {
211-
tag: self.tag,
212-
length: self.value.len(),
213-
}
207+
Header::new(self.tag, self.value.len())
214208
}
215209

216210
/// Attempt to decode this [`Any`] type into the inner value.
@@ -290,7 +284,7 @@ mod allocating {
290284

291285
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Error> {
292286
Ok(Self {
293-
tag: header.tag,
287+
tag: header.tag(),
294288
value: BytesOwned::decode_value(reader, header)?,
295289
})
296290
}

der/src/asn1/bit_string.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,7 @@ impl<'a> DecodeValue<'a> for BitStringRef<'a> {
139139
type Error = Error;
140140

141141
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
142-
let header = Header {
143-
tag: header.tag,
144-
length: (header.length - Length::ONE)?,
145-
};
142+
let header = header.with_length((header.length() - Length::ONE)?);
146143

147144
let unused_bits = reader.read_byte()?;
148145
let inner = <&'a BytesRef>::decode_value(reader, header)?;
@@ -354,7 +351,7 @@ mod allocating {
354351
type Error = Error;
355352

356353
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
357-
let inner_len = (header.length - Length::ONE)?;
354+
let inner_len = (header.length() - Length::ONE)?;
358355
let unused_bits = reader.read_byte()?;
359356
let inner = reader.read_vec(inner_len)?;
360357
Self::new(unused_bits, inner)

der/src/asn1/bmp_string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl<'a> DecodeValue<'a> for BmpString {
9393
type Error = Error;
9494

9595
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
96-
Self::from_ucs2(reader.read_vec(header.length)?)
96+
Self::from_ucs2(reader.read_vec(header.length())?)
9797
}
9898
}
9999

der/src/asn1/boolean.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl<'a> DecodeValue<'a> for bool {
1818
type Error = Error;
1919

2020
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
21-
if header.length != Length::ONE {
21+
if header.length() != Length::ONE {
2222
return Err(reader.error(ErrorKind::Length { tag: Self::TAG }));
2323
}
2424

der/src/asn1/generalized_time.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl<'a> DecodeValue<'a> for GeneralizedTime {
7878
type Error = Error;
7979

8080
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
81-
if Self::LENGTH != usize::try_from(header.length)? {
81+
if Self::LENGTH != usize::try_from(header.length())? {
8282
return Err(reader.error(Self::TAG.value_error()));
8383
}
8484

der/src/asn1/integer/int.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ macro_rules! impl_encoding_traits {
1818

1919
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> $crate::Result<Self> {
2020
let mut buf = [0u8; Self::BITS as usize / 8];
21-
let max_length = u32::from(header.length) as usize;
21+
let max_length = u32::from(header.length()) as usize;
2222

2323
if max_length == 0 {
2424
return Err(reader.error(Tag::Integer.length_error()));
@@ -39,7 +39,7 @@ macro_rules! impl_encoding_traits {
3939
};
4040

4141
// Ensure we compute the same encoded length as the original any value
42-
if header.length != result.value_len()? {
42+
if header.length() != result.value_len()? {
4343
return Err(reader.error(Self::TAG.non_canonical_error()));
4444
}
4545

@@ -143,7 +143,7 @@ impl<'a> DecodeValue<'a> for IntRef<'a> {
143143
let result = Self::new(bytes.as_slice())?;
144144

145145
// Ensure we compute the same encoded length as the original any value.
146-
if result.value_len()? != header.length {
146+
if result.value_len()? != header.length() {
147147
return Err(reader.error(Self::TAG.non_canonical_error()));
148148
}
149149

@@ -237,7 +237,7 @@ mod allocating {
237237
let result = Self::new(bytes.as_slice())?;
238238

239239
// Ensure we compute the same encoded length as the original any value.
240-
if result.value_len()? != header.length {
240+
if result.value_len()? != header.length() {
241241
return Err(reader.error(Self::TAG.non_canonical_error()));
242242
}
243243

der/src/asn1/integer/uint.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ macro_rules! impl_encoding_traits {
2222
const UNSIGNED_HEADROOM: usize = 1;
2323

2424
let mut buf = [0u8; (Self::BITS as usize / 8) + UNSIGNED_HEADROOM];
25-
let max_length = u32::from(header.length) as usize;
25+
let max_length = u32::from(header.length()) as usize;
2626

2727
if max_length == 0 {
2828
return Err(reader.error(Tag::Integer.length_error()));
@@ -36,7 +36,7 @@ macro_rules! impl_encoding_traits {
3636
let result = Self::from_be_bytes(decode_to_array(bytes)?);
3737

3838
// Ensure we compute the same encoded length as the original any value
39-
if header.length != result.value_len()? {
39+
if header.length() != result.value_len()? {
4040
return Err(reader.error(Self::TAG.non_canonical_error()));
4141
}
4242

@@ -126,7 +126,7 @@ impl<'a> DecodeValue<'a> for UintRef<'a> {
126126
let result = Self::new(decode_to_slice(bytes)?)?;
127127

128128
// Ensure we compute the same encoded length as the original any value.
129-
if result.value_len()? != header.length {
129+
if result.value_len()? != header.length() {
130130
return Err(reader.error(Self::TAG.non_canonical_error()));
131131
}
132132

@@ -221,7 +221,7 @@ mod allocating {
221221
let result = Self::new(decode_to_slice(bytes.as_slice())?)?;
222222

223223
// Ensure we compute the same encoded length as the original any value.
224-
if result.value_len()? != header.length {
224+
if result.value_len()? != header.length() {
225225
return Err(reader.error(Self::TAG.non_canonical_error()));
226226
}
227227

der/src/asn1/internal_macros.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ macro_rules! impl_custom_class {
148148
let header = Header::decode(reader)?;
149149

150150
// the encoding shall be constructed if the base encoding is constructed
151-
if header.tag.is_constructed() != T::CONSTRUCTED
151+
if header.tag().is_constructed() != T::CONSTRUCTED
152152
&& reader.encoding_rules().is_der() {
153-
return Err(reader.error(header.tag.non_canonical_error()).into());
153+
return Err(reader.error(header.tag().non_canonical_error()).into());
154154
}
155155

156156
// read_value checks if header matches decoded length
@@ -184,10 +184,10 @@ macro_rules! impl_custom_class {
184184
let header = Header::decode(reader)?;
185185

186186
// encoding shall be constructed
187-
if !header.tag.is_constructed() {
188-
return Err(reader.error(header.tag.non_canonical_error()).into());
187+
if !header.tag().is_constructed() {
188+
return Err(reader.error(header.tag().non_canonical_error()).into());
189189
}
190-
match header.tag {
190+
match header.tag() {
191191
Tag::$class_enum_name { number, .. } => Ok(Self {
192192
tag_number: number,
193193
tag_mode: TagMode::default(),

0 commit comments

Comments
 (0)