Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions der/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub struct Header {
}

impl Header {
/// Maximum number of DER octets a header can be in this crate.
pub(crate) const MAX_SIZE: usize = 1 + Length::MAX_SIZE;

/// Create a new [`Header`] from a [`Tag`] and a specified length.
///
/// Returns an error if the length exceeds the limits of [`Length`].
Expand Down
12 changes: 6 additions & 6 deletions der/src/length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ use core::{
ops::{Add, Sub},
};

/// Maximum number of octets in a DER encoding of a [`Length`] using the
/// rules implemented by this crate.
const MAX_DER_OCTETS: usize = 5;

/// Maximum length as a `u32` (256 MiB).
const MAX_U32: u32 = 0xfff_ffff;

Expand All @@ -37,6 +33,10 @@ impl Length {
/// Maximum length currently supported: 256 MiB
pub const MAX: Self = Self(MAX_U32);

/// Maximum number of octets in a DER encoding of a [`Length`] using the
/// rules implemented by this crate.
pub(crate) const MAX_SIZE: usize = 5;

/// Create a new [`Length`] for any value which fits inside of a [`u16`].
///
/// This function is const-safe and therefore useful for [`Length`] constants.
Expand Down Expand Up @@ -277,8 +277,8 @@ impl Encode for Length {

impl DerOrd for Length {
fn der_cmp(&self, other: &Self) -> Result<Ordering> {
let mut buf1 = [0u8; MAX_DER_OCTETS];
let mut buf2 = [0u8; MAX_DER_OCTETS];
let mut buf1 = [0u8; Self::MAX_SIZE];
let mut buf2 = [0u8; Self::MAX_SIZE];

let mut encoder1 = SliceWriter::new(&mut buf1);
encoder1.encode(self)?;
Expand Down
36 changes: 29 additions & 7 deletions der/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@ pub trait Reader<'r>: Sized {
/// Get the length of the input.
fn input_len(&self) -> Length;

/// Peek at the next byte of input without modifying the cursor.
fn peek_byte(&self) -> Option<u8>;

/// Peek forward in the input data, attempting to decode a [`Header`] from
/// the data at the current position in the decoder.
/// Peek at the decoded PEM without updating the internal state, writing into the provided
/// output buffer.
///
/// Does not modify the decoder's state.
fn peek_header(&self) -> Result<Header, Error>;
/// Attempts to fill the entire buffer, returning an error if there is not enough data.
fn peek_into(&self, buf: &mut [u8]) -> crate::Result<()>;

/// Get the position within the buffer.
fn position(&self) -> Length;
Expand Down Expand Up @@ -103,6 +100,31 @@ pub trait Reader<'r>: Sized {
self.position()
}

/// Peek at the next byte of input without modifying the cursor.
fn peek_byte(&self) -> Option<u8> {
let mut byte = [0];
self.peek_into(&mut byte).ok().map(|_| byte[0])
}

/// Peek forward in the input data, attempting to decode a [`Header`] from
/// the data at the current position in the decoder.
///
/// Does not modify the decoder's state.
fn peek_header(&self) -> Result<Header, Error> {
let mut buf = [0u8; Header::MAX_SIZE];

for i in 2..Header::MAX_SIZE {
let slice = &mut buf[0..i];
if self.peek_into(slice).is_ok() {
if let Ok(header) = Header::from_der(slice) {
return Ok(header);
}
}
}

Header::from_der(&buf)
}

/// Peek at the next byte in the decoder and attempt to decode it as a
/// [`Tag`] value.
///
Expand Down
21 changes: 4 additions & 17 deletions der/src/reader/pem.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Streaming PEM reader.

use super::Reader;
use crate::{Decode, EncodingRules, Error, ErrorKind, Header, Length};
use crate::{EncodingRules, Error, ErrorKind, Length};
use pem_rfc7468::Decoder;

/// `Reader` type which decodes PEM on-the-fly.
Expand Down Expand Up @@ -45,15 +45,6 @@ impl<'i> PemReader<'i> {
pub fn type_label(&self) -> &'i str {
self.decoder.type_label()
}

/// Peek at the decoded PEM without updating the internal state, writing into the provided
/// output buffer.
///
/// Attempts to fill the entire buffer, returning an error if there is not enough data.
pub fn peek_into(&self, buf: &mut [u8]) -> crate::Result<()> {
self.clone().read_into(buf)?;
Ok(())
}
}

#[cfg(feature = "pem")]
Expand All @@ -67,13 +58,9 @@ impl<'i> Reader<'i> for PemReader<'i> {
self.input_len
}

fn peek_byte(&self) -> Option<u8> {
let mut byte = [0];
self.peek_into(&mut byte).ok().map(|_| byte[0])
}

fn peek_header(&self) -> crate::Result<Header> {
Header::decode(&mut self.clone())
fn peek_into(&self, buf: &mut [u8]) -> crate::Result<()> {
self.clone().read_into(buf)?;
Ok(())
}

fn position(&self) -> Length {
Expand Down
13 changes: 4 additions & 9 deletions der/src/reader/slice.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Slice reader.

use crate::{BytesRef, Decode, EncodingRules, Error, ErrorKind, Header, Length, Reader, Tag};
use crate::{BytesRef, Decode, EncodingRules, Error, ErrorKind, Length, Reader, Tag};

/// [`Reader`] which consumes an input byte slice.
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -77,14 +77,9 @@ impl<'a> Reader<'a> for SliceReader<'a> {
self.bytes.len()
}

fn peek_byte(&self) -> Option<u8> {
self.remaining()
.ok()
.and_then(|bytes| bytes.first().cloned())
}

fn peek_header(&self) -> Result<Header, Error> {
Header::decode(&mut self.clone())
fn peek_into(&self, buf: &mut [u8]) -> crate::Result<()> {
self.clone().read_into(buf)?;
Ok(())
}

fn position(&self) -> Length {
Expand Down