Skip to content

Commit 47a1cd9

Browse files
committed
der: add indefinite length as u32::MAX
1 parent 0b029a2 commit 47a1cd9

File tree

2 files changed

+46
-20
lines changed

2 files changed

+46
-20
lines changed

der/src/header.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ mod tests {
103103

104104
#[test]
105105
fn peek_max_header() {
106-
const MAX_HEADER: [u8; 11] = hex!("BF8FFFFFFF7F 84FFFFFFFF");
106+
const MAX_HEADER: [u8; 11] = hex!("BF8FFFFFFF7F 84FFFFFFFE");
107107
let reader = SliceReader::new(&MAX_HEADER).expect("slice to be valid length");
108108

109109
let header = Header::peek(&reader).expect("peeked tag");
@@ -116,14 +116,14 @@ mod tests {
116116
);
117117
assert_eq!(
118118
header.length,
119-
Length::new_usize(0xFFFFFFFF).expect("u32 to fit")
119+
Length::new_usize(0xFFFFFFFE).expect("u32 to fit")
120120
);
121121
assert_eq!(header.encoded_len(), Ok(Length::new(11)));
122122
assert_eq!(reader.position(), Length::ZERO); // Position unchanged
123123
}
124124
#[test]
125125
fn negative_peek_overlength_header() {
126-
const MAX_HEADER: [u8; 12] = hex!("BF8FFFFFFFFF7F 84FFFFFFFF");
126+
const MAX_HEADER: [u8; 12] = hex!("BF8FFFFFFFFF7F 84FFFFFFFE");
127127
let reader = SliceReader::new(&MAX_HEADER).expect("slice to be valid length");
128128
// Should not decode
129129
Header::peek(&reader).expect_err("overlength error");

der/src/length.rs

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ use core::{
1010
ops::{Add, Sub},
1111
};
1212

13+
/// Maximum length as a `u32`.
14+
const MAX_U32: u32 = u32::MAX - 1;
15+
1316
/// Octet identifying an indefinite length as described in X.690 Section
1417
/// 8.1.3.6.1:
1518
///
@@ -29,7 +32,7 @@ impl Length {
2932
pub const ONE: Self = Self(1);
3033

3134
/// Maximum length (`u32::MAX` - 1).
32-
pub const MAX: Self = Self(u32::MAX - 1);
35+
pub const MAX: Self = Self(MAX_U32);
3336

3437
/// Maximum number of octets in a DER encoding of a [`Length`] using the
3538
/// rules implemented by this crate.
@@ -47,7 +50,7 @@ impl Length {
4750
/// This function is const-safe and therefore useful for [`Length`] constants.
4851
#[allow(clippy::cast_possible_truncation)]
4952
pub(crate) const fn new_usize(len: usize) -> Result<Self> {
50-
if len > (u32::MAX as usize) - 1 {
53+
if len > Self::MAX.0 as usize {
5154
Err(Error::from_kind(ErrorKind::Overflow))
5255
} else {
5356
Ok(Length(len as u32))
@@ -74,7 +77,12 @@ impl Length {
7477

7578
/// Perform saturating addition of two lengths.
7679
pub fn saturating_add(self, rhs: Self) -> Self {
77-
Self(self.0.saturating_add(rhs.0))
80+
let sum = self.0.saturating_add(rhs.0);
81+
if sum < Self::MAX.0 {
82+
Self(sum)
83+
} else {
84+
Self::MAX
85+
}
7886
}
7987

8088
/// Perform saturating subtraction of two lengths.
@@ -99,7 +107,7 @@ impl Length {
99107
0x80..=0xFF => Some(0x81),
100108
0x100..=0xFFFF => Some(0x82),
101109
0x10000..=0xFFFFFF => Some(0x83),
102-
0x1000000..=0xFFFFFFFE => Some(0x84),
110+
0x1000000..=MAX_U32 => Some(0x84),
103111
_ => None,
104112
}
105113
}
@@ -112,7 +120,7 @@ impl Add for Length {
112120
self.0
113121
.checked_add(other.0)
114122
.ok_or_else(|| ErrorKind::Overflow.into())
115-
.map(Self)
123+
.and_then(TryInto::try_into)
116124
}
117125
}
118126

@@ -136,7 +144,7 @@ impl Add<u32> for Length {
136144
type Output = Result<Self>;
137145

138146
fn add(self, other: u32) -> Result<Self> {
139-
self + Length::from(other)
147+
self + Length::try_from(other)?
140148
}
141149
}
142150

@@ -187,9 +195,21 @@ impl From<u16> for Length {
187195
}
188196
}
189197

190-
impl From<u32> for Length {
191-
fn from(len: u32) -> Length {
192-
Length(len)
198+
// impl From<u32> for Length {
199+
// fn from(len: u32) -> Length {
200+
// Length(len)
201+
// }
202+
// }
203+
204+
impl TryFrom<u32> for Length {
205+
type Error = Error;
206+
207+
fn try_from(len: u32) -> Result<Length> {
208+
if len <= Self::MAX.0 {
209+
Ok(Length(len))
210+
} else {
211+
Err(ErrorKind::Overflow.into())
212+
}
193213
}
194214
}
195215

@@ -238,7 +258,7 @@ impl<'a> Decode<'a> for Length {
238258
| u32::from(reader.read_byte()?);
239259
}
240260

241-
let length = Length::from(decoded_len);
261+
let length = Length::try_from(decoded_len)?;
242262

243263
// X.690 Section 10.1: DER lengths must be encoded with a minimum
244264
// number of octets
@@ -312,7 +332,7 @@ impl fmt::Display for Length {
312332
#[cfg(feature = "arbitrary")]
313333
impl<'a> arbitrary::Arbitrary<'a> for Length {
314334
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
315-
Ok(Self(u.arbitrary()?))
335+
Ok(Self(u.int_in_range(0..=MAX_U32)?))
316336
}
317337

318338
fn size_hint(depth: usize) -> (usize, Option<usize>) {
@@ -349,12 +369,16 @@ mod tests {
349369
);
350370

351371
assert_eq!(
352-
Length::from(0x10000u32),
372+
Length::try_from(0x10000u32).unwrap(),
353373
Length::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap()
354374
);
355375
assert_eq!(
356-
Length::from(0xFFFFFFFFu32),
357-
Length::from_der(&[0x84, 0xFF, 0xFF, 0xFF, 0xFF]).unwrap()
376+
Length::try_from(0xFFFFFFFEu32).unwrap(),
377+
Length::from_der(&[0x84, 0xFF, 0xFF, 0xFF, 0xFE]).unwrap()
378+
);
379+
assert_eq!(
380+
Length::from_der(&[0x84, 0xFF, 0xFF, 0xFF, 0xFF]),
381+
Err(ErrorKind::Overflow.into())
358382
);
359383
}
360384

@@ -386,13 +410,15 @@ mod tests {
386410

387411
assert_eq!(
388412
&[0x83, 0x01, 0x00, 0x00],
389-
Length::from(0x10000u32)
413+
Length::try_from(0x10000u32)
414+
.unwrap()
390415
.encode_to_slice(&mut buffer)
391416
.unwrap()
392417
);
393418
assert_eq!(
394-
&[0x84, 0xFF, 0xFF, 0xFF, 0xFF],
395-
Length::from(0xFFFFFFFFu32)
419+
&[0x84, 0xFF, 0xFF, 0xFF, 0xFE],
420+
Length::try_from(0xFFFFFFFEu32)
421+
.unwrap()
396422
.encode_to_slice(&mut buffer)
397423
.unwrap()
398424
);

0 commit comments

Comments
 (0)