1 //! Length calculations for encoded ASN.1 DER values 2 3 use crate::{Decode, DerOrd, Encode, Error, ErrorKind, Reader, Result, SliceWriter, Writer}; 4 use core::{ 5 cmp::Ordering, 6 fmt, 7 ops::{Add, Sub}, 8 }; 9 10 /// Maximum number of octets in a DER encoding of a [`Length`] using the 11 /// rules implemented by this crate. 12 const MAX_DER_OCTETS: usize = 5; 13 14 /// Maximum length as a `u32` (256 MiB). 15 const MAX_U32: u32 = 0xfff_ffff; 16 17 /// ASN.1-encoded length. 18 /// 19 /// Maximum length is defined by the [`Length::MAX`] constant (256 MiB). 20 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] 21 pub struct Length(u32); 22 23 impl Length { 24 /// Length of `0` 25 pub const ZERO: Self = Self(0); 26 27 /// Length of `1` 28 pub const ONE: Self = Self(1); 29 30 /// Maximum length currently supported: 256 MiB 31 pub const MAX: Self = Self(MAX_U32); 32 33 /// Create a new [`Length`] for any value which fits inside of a [`u16`]. 34 /// 35 /// This function is const-safe and therefore useful for [`Length`] constants. new(value: u16) -> Self36 pub const fn new(value: u16) -> Self { 37 Self(value as u32) 38 } 39 40 /// Is this length equal to zero? is_zero(self) -> bool41 pub fn is_zero(self) -> bool { 42 self == Self::ZERO 43 } 44 45 /// Get the length of DER Tag-Length-Value (TLV) encoded data if `self` 46 /// is the length of the inner "value" portion of the message. for_tlv(self) -> Result<Self>47 pub fn for_tlv(self) -> Result<Self> { 48 Self::ONE + self.encoded_len()? + self 49 } 50 51 /// Perform saturating addition of two lengths. saturating_add(self, rhs: Self) -> Self52 pub fn saturating_add(self, rhs: Self) -> Self { 53 Self(self.0.saturating_add(rhs.0)) 54 } 55 56 /// Perform saturating subtraction of two lengths. saturating_sub(self, rhs: Self) -> Self57 pub fn saturating_sub(self, rhs: Self) -> Self { 58 Self(self.0.saturating_sub(rhs.0)) 59 } 60 61 /// Get initial octet of the encoded length (if one is required). 62 /// 63 /// From X.690 Section 8.1.3.5: 64 /// > In the long form, the length octets shall consist of an initial octet 65 /// > and one or more subsequent octets. The initial octet shall be encoded 66 /// > as follows: 67 /// > 68 /// > a) bit 8 shall be one; 69 /// > b) bits 7 to 1 shall encode the number of subsequent octets in the 70 /// > length octets, as an unsigned binary integer with bit 7 as the 71 /// > most significant bit; 72 /// > c) the value 11111111₂ shall not be used. initial_octet(self) -> Option<u8>73 fn initial_octet(self) -> Option<u8> { 74 match self.0 { 75 0x80..=0xFF => Some(0x81), 76 0x100..=0xFFFF => Some(0x82), 77 0x10000..=0xFFFFFF => Some(0x83), 78 0x1000000..=MAX_U32 => Some(0x84), 79 _ => None, 80 } 81 } 82 } 83 84 impl Add for Length { 85 type Output = Result<Self>; 86 add(self, other: Self) -> Result<Self>87 fn add(self, other: Self) -> Result<Self> { 88 self.0 89 .checked_add(other.0) 90 .ok_or_else(|| ErrorKind::Overflow.into()) 91 .and_then(TryInto::try_into) 92 } 93 } 94 95 impl Add<u8> for Length { 96 type Output = Result<Self>; 97 add(self, other: u8) -> Result<Self>98 fn add(self, other: u8) -> Result<Self> { 99 self + Length::from(other) 100 } 101 } 102 103 impl Add<u16> for Length { 104 type Output = Result<Self>; 105 add(self, other: u16) -> Result<Self>106 fn add(self, other: u16) -> Result<Self> { 107 self + Length::from(other) 108 } 109 } 110 111 impl Add<u32> for Length { 112 type Output = Result<Self>; 113 add(self, other: u32) -> Result<Self>114 fn add(self, other: u32) -> Result<Self> { 115 self + Length::try_from(other)? 116 } 117 } 118 119 impl Add<usize> for Length { 120 type Output = Result<Self>; 121 add(self, other: usize) -> Result<Self>122 fn add(self, other: usize) -> Result<Self> { 123 self + Length::try_from(other)? 124 } 125 } 126 127 impl Add<Length> for Result<Length> { 128 type Output = Self; 129 add(self, other: Length) -> Self130 fn add(self, other: Length) -> Self { 131 self? + other 132 } 133 } 134 135 impl Sub for Length { 136 type Output = Result<Self>; 137 sub(self, other: Length) -> Result<Self>138 fn sub(self, other: Length) -> Result<Self> { 139 self.0 140 .checked_sub(other.0) 141 .ok_or_else(|| ErrorKind::Overflow.into()) 142 .and_then(TryInto::try_into) 143 } 144 } 145 146 impl Sub<Length> for Result<Length> { 147 type Output = Self; 148 sub(self, other: Length) -> Self149 fn sub(self, other: Length) -> Self { 150 self? - other 151 } 152 } 153 154 impl From<u8> for Length { from(len: u8) -> Length155 fn from(len: u8) -> Length { 156 Length(len.into()) 157 } 158 } 159 160 impl From<u16> for Length { from(len: u16) -> Length161 fn from(len: u16) -> Length { 162 Length(len.into()) 163 } 164 } 165 166 impl From<Length> for u32 { from(length: Length) -> u32167 fn from(length: Length) -> u32 { 168 length.0 169 } 170 } 171 172 impl TryFrom<u32> for Length { 173 type Error = Error; 174 try_from(len: u32) -> Result<Length>175 fn try_from(len: u32) -> Result<Length> { 176 if len <= Self::MAX.0 { 177 Ok(Length(len)) 178 } else { 179 Err(ErrorKind::Overflow.into()) 180 } 181 } 182 } 183 184 impl TryFrom<usize> for Length { 185 type Error = Error; 186 try_from(len: usize) -> Result<Length>187 fn try_from(len: usize) -> Result<Length> { 188 u32::try_from(len) 189 .map_err(|_| ErrorKind::Overflow)? 190 .try_into() 191 } 192 } 193 194 impl TryFrom<Length> for usize { 195 type Error = Error; 196 try_from(len: Length) -> Result<usize>197 fn try_from(len: Length) -> Result<usize> { 198 len.0.try_into().map_err(|_| ErrorKind::Overflow.into()) 199 } 200 } 201 202 impl<'a> Decode<'a> for Length { decode<R: Reader<'a>>(reader: &mut R) -> Result<Length>203 fn decode<R: Reader<'a>>(reader: &mut R) -> Result<Length> { 204 match reader.read_byte()? { 205 // Note: per X.690 Section 8.1.3.6.1 the byte 0x80 encodes indefinite 206 // lengths, which are not allowed in DER, so disallow that byte. 207 len if len < 0x80 => Ok(len.into()), 208 // 1-4 byte variable-sized length prefix 209 tag @ 0x81..=0x84 => { 210 let nbytes = tag.checked_sub(0x80).ok_or(ErrorKind::Overlength)? as usize; 211 debug_assert!(nbytes <= 4); 212 213 let mut decoded_len = 0u32; 214 for _ in 0..nbytes { 215 decoded_len = decoded_len.checked_shl(8).ok_or(ErrorKind::Overflow)? 216 | u32::from(reader.read_byte()?); 217 } 218 219 let length = Length::try_from(decoded_len)?; 220 221 // X.690 Section 10.1: DER lengths must be encoded with a minimum 222 // number of octets 223 if length.initial_octet() == Some(tag) { 224 Ok(length) 225 } else { 226 Err(ErrorKind::Overlength.into()) 227 } 228 } 229 _ => { 230 // We specialize to a maximum 4-byte length (including initial octet) 231 Err(ErrorKind::Overlength.into()) 232 } 233 } 234 } 235 } 236 237 impl Encode for Length { encoded_len(&self) -> Result<Length>238 fn encoded_len(&self) -> Result<Length> { 239 match self.0 { 240 0..=0x7F => Ok(Length(1)), 241 0x80..=0xFF => Ok(Length(2)), 242 0x100..=0xFFFF => Ok(Length(3)), 243 0x10000..=0xFFFFFF => Ok(Length(4)), 244 0x1000000..=MAX_U32 => Ok(Length(5)), 245 _ => Err(ErrorKind::Overflow.into()), 246 } 247 } 248 encode(&self, writer: &mut dyn Writer) -> Result<()>249 fn encode(&self, writer: &mut dyn Writer) -> Result<()> { 250 match self.initial_octet() { 251 Some(tag_byte) => { 252 writer.write_byte(tag_byte)?; 253 254 // Strip leading zeroes 255 match self.0.to_be_bytes() { 256 [0, 0, 0, byte] => writer.write_byte(byte), 257 [0, 0, bytes @ ..] => writer.write(&bytes), 258 [0, bytes @ ..] => writer.write(&bytes), 259 bytes => writer.write(&bytes), 260 } 261 } 262 #[allow(clippy::cast_possible_truncation)] 263 None => writer.write_byte(self.0 as u8), 264 } 265 } 266 } 267 268 impl DerOrd for Length { der_cmp(&self, other: &Self) -> Result<Ordering>269 fn der_cmp(&self, other: &Self) -> Result<Ordering> { 270 let mut buf1 = [0u8; MAX_DER_OCTETS]; 271 let mut buf2 = [0u8; MAX_DER_OCTETS]; 272 273 let mut encoder1 = SliceWriter::new(&mut buf1); 274 encoder1.encode(self)?; 275 276 let mut encoder2 = SliceWriter::new(&mut buf2); 277 encoder2.encode(other)?; 278 279 Ok(encoder1.finish()?.cmp(encoder2.finish()?)) 280 } 281 } 282 283 impl fmt::Display for Length { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result284 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 285 self.0.fmt(f) 286 } 287 } 288 289 #[cfg(test)] 290 mod tests { 291 use super::Length; 292 use crate::{Decode, DerOrd, Encode, ErrorKind}; 293 use core::cmp::Ordering; 294 295 #[test] decode()296 fn decode() { 297 assert_eq!(Length::ZERO, Length::from_der(&[0x00]).unwrap()); 298 299 assert_eq!(Length::from(0x7Fu8), Length::from_der(&[0x7F]).unwrap()); 300 301 assert_eq!( 302 Length::from(0x80u8), 303 Length::from_der(&[0x81, 0x80]).unwrap() 304 ); 305 306 assert_eq!( 307 Length::from(0xFFu8), 308 Length::from_der(&[0x81, 0xFF]).unwrap() 309 ); 310 311 assert_eq!( 312 Length::from(0x100u16), 313 Length::from_der(&[0x82, 0x01, 0x00]).unwrap() 314 ); 315 316 assert_eq!( 317 Length::try_from(0x10000u32).unwrap(), 318 Length::from_der(&[0x83, 0x01, 0x00, 0x00]).unwrap() 319 ); 320 } 321 322 #[test] encode()323 fn encode() { 324 let mut buffer = [0u8; 4]; 325 326 assert_eq!(&[0x00], Length::ZERO.encode_to_slice(&mut buffer).unwrap()); 327 328 assert_eq!( 329 &[0x7F], 330 Length::from(0x7Fu8).encode_to_slice(&mut buffer).unwrap() 331 ); 332 333 assert_eq!( 334 &[0x81, 0x80], 335 Length::from(0x80u8).encode_to_slice(&mut buffer).unwrap() 336 ); 337 338 assert_eq!( 339 &[0x81, 0xFF], 340 Length::from(0xFFu8).encode_to_slice(&mut buffer).unwrap() 341 ); 342 343 assert_eq!( 344 &[0x82, 0x01, 0x00], 345 Length::from(0x100u16).encode_to_slice(&mut buffer).unwrap() 346 ); 347 348 assert_eq!( 349 &[0x83, 0x01, 0x00, 0x00], 350 Length::try_from(0x10000u32) 351 .unwrap() 352 .encode_to_slice(&mut buffer) 353 .unwrap() 354 ); 355 } 356 357 #[test] reject_indefinite_lengths()358 fn reject_indefinite_lengths() { 359 assert!(Length::from_der(&[0x80]).is_err()); 360 } 361 362 #[test] add_overflows_when_max_length_exceeded()363 fn add_overflows_when_max_length_exceeded() { 364 let result = Length::MAX + Length::ONE; 365 assert_eq!( 366 result.err().map(|err| err.kind()), 367 Some(ErrorKind::Overflow) 368 ); 369 } 370 371 #[test] der_ord()372 fn der_ord() { 373 assert_eq!(Length::ONE.der_cmp(&Length::MAX).unwrap(), Ordering::Less); 374 } 375 } 376