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
46 changes: 32 additions & 14 deletions der/src/asn1/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//! `SEQUENCE`s to Rust structs.

use crate::{
BytesRef, DecodeValue, EncodeValue, Error, FixedTag, Header, Length, Reader, Result, Tag,
Writer,
BytesRef, DecodeValue, EncodeValue, Error, ErrorKind, FixedTag, Header, Length, Reader, Result,
Tag, Writer,
};

#[cfg(feature = "alloc")]
Expand All @@ -12,7 +12,7 @@ use alloc::boxed::Box;
/// Marker trait for ASN.1 `SEQUENCE`s.
///
/// This is mainly used for custom derive.
pub trait Sequence<'a>: DecodeValue<'a> + EncodeValue {}
pub trait Sequence<'a> {}

impl<'a, S> FixedTag for S
where
Expand All @@ -28,35 +28,53 @@ impl<'a, T> Sequence<'a> for Box<T> where T: Sequence<'a> {}
/// DER-encoded `SEQUENCE`.
///
/// This is a zero-copy reference type which borrows from the input data.
pub struct SequenceRef<'a> {
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct SequenceRef {
/// Body of the `SEQUENCE`.
body: &'a BytesRef,
body: BytesRef,
}

impl<'a> SequenceRef<'a> {
impl SequenceRef {
/// Create a new ASN.1 `OCTET STRING` from a byte slice.
pub fn new(slice: &[u8]) -> Result<&Self> {
BytesRef::new(slice)
.map(Self::from_bytes_ref)
.map_err(|_| ErrorKind::Length { tag: Tag::Sequence }.into())
}

/// Create a [`SequenceRef`] from a [`BytesRef`].
///
/// Implemented as an inherent method to keep [`BytesRef`] out of the public API.
fn from_bytes_ref(bytes_ref: &BytesRef) -> &Self {
// SAFETY: `Self` is a `repr(transparent)` newtype for `BytesRef`
#[allow(unsafe_code)]
unsafe {
&*(bytes_ref.as_ptr() as *const Self)
}
}

/// Borrow the inner byte slice.
pub fn as_bytes(&self) -> &'a [u8] {
pub fn as_bytes(&self) -> &[u8] {
self.body.as_slice()
}
}

impl AsRef<[u8]> for SequenceRef<'_> {
impl AsRef<[u8]> for SequenceRef {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}

impl<'a> DecodeValue<'a> for SequenceRef<'a> {
impl<'a> DecodeValue<'a> for &'a SequenceRef {
type Error = Error;

fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
Ok(Self {
body: <&'a BytesRef>::decode_value(reader, header)?,
})
<&'a BytesRef>::decode_value(reader, header).map(SequenceRef::from_bytes_ref)
}
}

impl EncodeValue for SequenceRef<'_> {
impl EncodeValue for SequenceRef {
fn value_len(&self) -> Result<Length> {
Ok(self.body.len())
}
Expand All @@ -66,4 +84,4 @@ impl EncodeValue for SequenceRef<'_> {
}
}

impl<'a> Sequence<'a> for SequenceRef<'a> {}
impl<'a> Sequence<'a> for &'a SequenceRef {}
2 changes: 1 addition & 1 deletion pkcs8/src/private_key_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ where
let private_key = Key::decode(reader)?;

let _attributes =
reader.context_specific::<SequenceRef<'_>>(ATTRIBUTES_TAG, TagMode::Implicit)?;
reader.context_specific::<&SequenceRef>(ATTRIBUTES_TAG, TagMode::Implicit)?;

let public_key = reader.context_specific::<PubKey>(PUBLIC_KEY_TAG, TagMode::Implicit)?;

Expand Down