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
16 changes: 11 additions & 5 deletions der/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ use alloc::boxed::Box;
#[cfg(feature = "ber")]
use crate::EncodingRules;

/// Decoding trait.
/// Decode trait parses a complete TLV (Tag-Length-Value) structure.
///
/// This trait provides the core abstraction upon which all decoding operations
/// are based.
///
/// When decoding fails, a [`Decode::Error`] type is thrown.
/// Most ASN.1 DER objects return a builtin der [`Error`] type as [`Decode::Error`], which can be made from [`ErrorKind`].
#[diagnostic::on_unimplemented(
note = "Consider adding impls of `DecodeValue` and `FixedTag` to `{Self}`"
)]
pub trait Decode<'a>: Sized + 'a {
/// Type returned in the event of a decoding error.
type Error: From<Error> + 'static;

/// Attempt to decode this message using the provided decoder.
/// Attempt to decode this TLV message using the provided decoder.
fn decode<R: Reader<'a>>(decoder: &mut R) -> Result<Self, Self::Error>;

/// Parse `Self` from the provided BER-encoded byte slice.
Expand Down Expand Up @@ -127,13 +130,16 @@ impl<T: DecodeOwned<Error = Error> + PemLabel> DecodePem for T {
}
}

/// Decode the value part of a Tag-Length-Value encoded field, sans the [`Tag`]
/// and [`Length`].
/// DecodeValue trait parses the value part of a Tag-Length-Value object,
/// sans the [`Tag`] and [`Length`].
///
/// As opposed to [`Decode`], implementer is expected to read the inner content only,
/// without the [`Header`], which was decoded beforehand.
pub trait DecodeValue<'a>: Sized {
/// Type returned in the event of a decoding error.
type Error: From<Error> + 'static;

/// Attempt to decode this message using the provided [`Reader`].
/// Attempt to decode this value using the provided [`Reader`].
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self, Self::Error>;
}

Expand Down
26 changes: 17 additions & 9 deletions der/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,30 @@ use {
use crate::ErrorKind;

#[cfg(doc)]
use crate::Tag;
use crate::{FixedTag, Tag};

/// Encoding trait.
/// Encode trait produces a complete TLV (Tag-Length-Value) structure.
///
/// As opposed to [`EncodeValue`], implementer is expected to write ASN.1 DER tag and length header before value.
#[diagnostic::on_unimplemented(
note = "Consider adding impls of `EncodeValue` and `FixedTag` to `{Self}`"
)]
pub trait Encode {
/// Compute the length of this value in bytes when encoded as ASN.1 DER.
/// Compute the length of this TLV object in bytes when encoded as ASN.1 DER.
fn encoded_len(&self) -> Result<Length>;

/// Encode this value as ASN.1 DER using the provided [`Writer`].
/// Encode this TLV object as ASN.1 DER using the provided [`Writer`].
fn encode(&self, encoder: &mut impl Writer) -> Result<()>;

/// Encode this value to the provided byte slice, returning a sub-slice
/// Encode this TLV object to the provided byte slice, returning a sub-slice
/// containing the encoded message.
fn encode_to_slice<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> {
let mut writer = SliceWriter::new(buf);
self.encode(&mut writer)?;
writer.finish()
}

/// Encode this message as ASN.1 DER, appending it to the provided
/// Encode this TLV object as ASN.1 DER, appending it to the provided
/// byte vector.
#[cfg(feature = "alloc")]
fn encode_to_vec(&self, buf: &mut Vec<u8>) -> Result<Length> {
Expand All @@ -60,7 +62,7 @@ pub trait Encode {
actual_len.try_into()
}

/// Encode this type as DER, returning a byte vector.
/// Encode this TLV object as ASN.1 DER, returning a byte vector.
#[cfg(feature = "alloc")]
fn to_der(&self) -> Result<Vec<u8>> {
let mut buf = Vec::new();
Expand All @@ -73,12 +75,12 @@ impl<T> Encode for T
where
T: EncodeValue + Tagged + ?Sized,
{
/// Compute the length of this value in bytes when encoded as ASN.1 DER.
/// Compute the length of this TLV object in bytes when encoded as ASN.1 DER.
fn encoded_len(&self) -> Result<Length> {
self.value_len().and_then(|len| len.for_tlv(self.tag()))
}

/// Encode this value as ASN.1 DER using the provided [`Writer`].
/// Encode this TLV object as ASN.1 DER using the provided [`Writer`].
fn encode(&self, writer: &mut impl Writer) -> Result<()> {
self.header()?.encode(writer)?;
self.encode_value(writer)
Expand Down Expand Up @@ -134,6 +136,12 @@ where

/// Encode the value part of a Tag-Length-Value encoded field, sans the [`Tag`]
/// and [`Length`].
///
/// As opposed to [`Encode`], implementer is expected to write the inner content only,
/// without the [`Header`].
///
/// When [`EncodeValue`] is paired with [`FixedTag`],
/// it produces a complete TLV ASN.1 DER encoding as [`Encode`] trait.
pub trait EncodeValue {
/// Get the [`Header`] used to encode this value.
fn header(&self) -> Result<Header>
Expand Down