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
10 changes: 10 additions & 0 deletions der/src/bytes_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ impl<'a> BytesRef<'a> {
pub fn is_empty(self) -> bool {
self.len() == Length::ZERO
}

/// Get a prefix of a [`BytesRef`] of the given length.
pub fn prefix(self, length: Length) -> Result<Self> {
let inner = self
.as_slice()
.get(..usize::try_from(length)?)
.ok_or_else(|| Error::incomplete(self.length))?;

Ok(Self { length, inner })
}
}

impl AsRef<[u8]> for BytesRef<'_> {
Expand Down
2 changes: 1 addition & 1 deletion der/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ pub use crate::{
header::Header,
length::{IndefiniteLength, Length},
ord::{DerOrd, ValueOrd},
reader::{nested::NestedReader, slice::SliceReader, Reader},
reader::{slice::SliceReader, Reader},
tag::{Class, FixedTag, Tag, TagMode, TagNumber, Tagged},
writer::{slice::SliceWriter, Writer},
};
Expand Down
24 changes: 8 additions & 16 deletions der/src/reader.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
//! Reader trait.

pub(crate) mod nested;
#[cfg(feature = "pem")]
pub(crate) mod pem;
pub(crate) mod slice;

pub(crate) use nested::NestedReader;

use crate::{
asn1::ContextSpecific, Decode, DecodeValue, Encode, EncodingRules, Error, ErrorKind, FixedTag,
Header, Length, Tag, TagMode, TagNumber,
Expand Down Expand Up @@ -35,6 +32,12 @@ pub trait Reader<'r>: Sized {
/// Get the position within the buffer.
fn position(&self) -> Length;

/// Read nested data of the given length.
fn read_nested<T, F, E>(&mut self, len: Length, f: F) -> Result<T, E>
where
E: From<Error>,
F: FnOnce(&mut Self) -> Result<T, E>;

/// Attempt to read data borrowed directly from the input as a slice,
/// updating the internal cursor position.
///
Expand Down Expand Up @@ -130,17 +133,6 @@ pub trait Reader<'r>: Sized {
Ok(buf)
}

/// Read nested data of the given length.
fn read_nested<'n, T, F, E>(&'n mut self, len: Length, f: F) -> Result<T, E>
where
F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T, E>,
E: From<Error>,
{
let mut reader = NestedReader::new(self, len)?;
let ret = f(&mut reader)?;
Ok(reader.finish(ret)?)
}

/// Read a byte vector of the given length.
#[cfg(feature = "alloc")]
fn read_vec(&mut self, len: Length) -> Result<Vec<u8>, Error> {
Expand All @@ -157,9 +149,9 @@ pub trait Reader<'r>: Sized {

/// Read an ASN.1 `SEQUENCE`, creating a nested [`Reader`] for the body and
/// calling the provided closure with it.
fn sequence<'n, F, T, E>(&'n mut self, f: F) -> Result<T, E>
fn sequence<F, T, E>(&mut self, f: F) -> Result<T, E>
where
F: FnOnce(&mut NestedReader<'n, Self>) -> Result<T, E>,
F: FnOnce(&mut Self) -> Result<T, E>,
E: From<Error>,
{
let header = Header::decode(self)?;
Expand Down
100 changes: 0 additions & 100 deletions der/src/reader/nested.rs

This file was deleted.

52 changes: 36 additions & 16 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, ErrorKind, Header, Length, Result};
use crate::{Decode, EncodingRules, Error, ErrorKind, Header, Length};
use pem_rfc7468::Decoder;

/// `Reader` type which decodes PEM on-the-fly.
Expand All @@ -28,7 +28,7 @@ impl<'i> PemReader<'i> {
/// Create a new PEM reader which decodes data on-the-fly.
///
/// Uses the default 64-character line wrapping.
pub fn new(pem: &'i [u8]) -> Result<Self> {
pub fn new(pem: &'i [u8]) -> crate::Result<Self> {
let decoder = Decoder::new(pem)?;
let input_len = Length::try_from(decoder.remaining_len())?;

Expand All @@ -50,8 +50,8 @@ impl<'i> PemReader<'i> {
/// 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]) -> Result<()> {
self.decoder.clone().decode(buf)?;
pub fn peek_into(&self, buf: &mut [u8]) -> crate::Result<()> {
self.clone().read_into(buf)?;
Ok(())
}
}
Expand All @@ -72,28 +72,48 @@ impl<'i> Reader<'i> for PemReader<'i> {
self.peek_into(&mut byte).ok().map(|_| byte[0])
}

fn peek_header(&self) -> Result<Header> {
fn peek_header(&self) -> crate::Result<Header> {
Header::decode(&mut self.clone())
}

fn position(&self) -> Length {
self.position
}

fn read_slice(&mut self, _len: Length) -> Result<&'i [u8]> {
fn read_nested<T, F, E>(&mut self, len: Length, f: F) -> Result<T, E>
where
F: FnOnce(&mut Self) -> Result<T, E>,
E: From<Error>,
{
let nested_input_len = (self.position + len)?;
if nested_input_len > self.input_len {
return Err(Error::incomplete(self.input_len).into());
}

let orig_input_len = self.input_len;
self.input_len = nested_input_len;
let ret = f(self);
self.input_len = orig_input_len;
ret
}

fn read_slice(&mut self, _len: Length) -> crate::Result<&'i [u8]> {
// Can't borrow from PEM because it requires decoding
Err(ErrorKind::Reader.into())
}

fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> Result<&'o [u8]> {
let bytes = self.decoder.decode(buf)?;
self.position = (self.position + bytes.len())?;

debug_assert_eq!(
self.position,
(self.input_len - Length::try_from(self.decoder.remaining_len())?)?
);

Ok(bytes)
fn read_into<'o>(&mut self, buf: &'o mut [u8]) -> crate::Result<&'o [u8]> {
let new_position = (self.position + buf.len())?;
if new_position > self.input_len {
return Err(ErrorKind::Incomplete {
expected_len: new_position,
actual_len: self.input_len,
}
.at(self.position));
}

self.decoder.decode(buf)?;
self.position = new_position;
Ok(buf)
}
}
22 changes: 22 additions & 0 deletions der/src/reader/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ impl<'a> Reader<'a> for SliceReader<'a> {
self.position
}

/// Read nested data of the given length.
fn read_nested<T, F, E>(&mut self, len: Length, f: F) -> Result<T, E>
where
F: FnOnce(&mut Self) -> Result<T, E>,
E: From<Error>,
{
let prefix_len = (self.position + len)?;
let mut nested_reader = self.clone();
nested_reader.bytes = self.bytes.prefix(prefix_len)?;

let ret = f(&mut nested_reader);
self.position = nested_reader.position;
self.failed = nested_reader.failed;

ret.and_then(|value| {
nested_reader.finish(value).map_err(|e| {
self.failed = true;
e.into()
})
})
}

fn read_slice(&mut self, len: Length) -> Result<&'a [u8], Error> {
if self.is_failed() {
return Err(self.error(ErrorKind::Failed));
Expand Down
1 change: 0 additions & 1 deletion pkcs12/src/safe_bag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ impl<'a> ::der::DecodeValue<'a> for SafeBag {
reader: &mut R,
header: ::der::Header,
) -> ::der::Result<Self> {
use ::der::Reader as _;
reader.read_nested(header.length, |reader| {
let bag_id = reader.decode()?;
let bag_value = match reader.tlv_bytes() {
Expand Down