Skip to content

Commit

Permalink
pkcs5: Make storage generic
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Gautier <[email protected]>
  • Loading branch information
baloo committed Aug 8, 2023
1 parent bb80aa0 commit a44febb
Show file tree
Hide file tree
Showing 5 changed files with 383 additions and 173 deletions.
19 changes: 19 additions & 0 deletions der/src/referenced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ where
}
}

impl<'a, T, const N: usize> RefToOwned<'a> for &'a [T; N]
where
T: Clone,
{
type Owned = [T; N];

fn ref_to_owned(&self) -> Self::Owned {
self.clone().clone()
}
}

impl<T, const N: usize> OwnedToRef for [T; N] {
type Borrowed<'a> = &'a [T; N] where T:'a;

fn owned_to_ref(&self) -> Self::Borrowed<'_> {
&self
}
}

#[cfg(feature = "alloc")]
mod allocating {
use super::{OwnedToRef, RefToOwned};
Expand Down
76 changes: 60 additions & 16 deletions pkcs5/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,17 @@ pub use scrypt;
#[cfg(all(feature = "alloc", feature = "pbes2"))]
use alloc::vec::Vec;

pub type EncryptionScheme<'a> = EncryptionSchemeInner<
&'a [u8; pbes2::AES_BLOCK_SIZE],
&'a [u8; pbes2::DES_BLOCK_SIZE],
&'a [u8],
>;

/// Supported PKCS#5 password-based encryption schemes.
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
#[allow(clippy::large_enum_variant)]
pub enum EncryptionScheme<'a> {
pub enum EncryptionSchemeInner<AesBlock, DesBlock, Salt> {
/// Password-Based Encryption Scheme 1 as defined in [RFC 8018 Section 6.1].
///
/// [RFC 8018 Section 6.1]: https://tools.ietf.org/html/rfc8018#section-6.1
Expand All @@ -58,10 +64,15 @@ pub enum EncryptionScheme<'a> {
/// Password-Based Encryption Scheme 2 as defined in [RFC 8018 Section 6.2].
///
/// [RFC 8018 Section 6.2]: https://tools.ietf.org/html/rfc8018#section-6.2
Pbes2(pbes2::Parameters<'a>),
Pbes2(pbes2::ParametersInner<AesBlock, DesBlock, Salt>),
}

impl<'a> EncryptionScheme<'a> {
impl<AesBlock, DesBlock, Salt> EncryptionSchemeInner<AesBlock, DesBlock, Salt>
where
Salt: AsRef<[u8]>,
AesBlock: AsRef<[u8]>,
DesBlock: AsRef<[u8]>,
{
/// Attempt to decrypt the given ciphertext, allocating and returning a
/// byte vector containing the plaintext.
#[cfg(all(feature = "alloc", feature = "pbes2"))]
Expand Down Expand Up @@ -132,21 +143,32 @@ impl<'a> EncryptionScheme<'a> {
}

/// Get [`pbes2::Parameters`] if it is the selected algorithm.
pub fn pbes2(&self) -> Option<&pbes2::Parameters<'a>> {
pub fn pbes2(&self) -> Option<&pbes2::ParametersInner<AesBlock, DesBlock, Salt>> {
match self {
Self::Pbes2(params) => Some(params),
_ => None,
}
}
}

impl<'a> DecodeValue<'a> for EncryptionScheme<'a> {
impl<'a, AesBlock, DesBlock, Salt> DecodeValue<'a>
for EncryptionSchemeInner<AesBlock, DesBlock, Salt>
where
Salt: AsRef<[u8]> + From<&'a [u8]>,
AesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
DesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
{
fn decode_value<R: Reader<'a>>(decoder: &mut R, header: Header) -> der::Result<Self> {
AlgorithmIdentifierRef::decode_value(decoder, header)?.try_into()
}
}

impl EncodeValue for EncryptionScheme<'_> {
impl<'a, AesBlock, DesBlock, Salt> EncodeValue for EncryptionSchemeInner<AesBlock, DesBlock, Salt>
where
Salt: AsRef<[u8]> + From<&'a [u8]>,
AesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
DesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
{
fn value_len(&self) -> der::Result<Length> {
match self {
Self::Pbes1(pbes1) => pbes1.oid().encoded_len()? + pbes1.parameters.encoded_len()?,
Expand All @@ -170,27 +192,43 @@ impl EncodeValue for EncryptionScheme<'_> {
}
}

impl<'a> Sequence<'a> for EncryptionScheme<'a> {}
impl<'a, AesBlock, DesBlock, Salt> Sequence<'a> for EncryptionSchemeInner<AesBlock, DesBlock, Salt>
where
Salt: AsRef<[u8]> + From<&'a [u8]>,
AesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
DesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
{
}

impl<'a> From<pbes1::Algorithm> for EncryptionScheme<'a> {
fn from(alg: pbes1::Algorithm) -> EncryptionScheme<'a> {
impl<AesBlock, DesBlock, Salt> From<pbes1::Algorithm>
for EncryptionSchemeInner<AesBlock, DesBlock, Salt>
{
fn from(alg: pbes1::Algorithm) -> Self {
Self::Pbes1(alg)
}
}

impl<'a> From<pbes2::Parameters<'a>> for EncryptionScheme<'a> {
fn from(params: pbes2::Parameters<'a>) -> EncryptionScheme<'a> {
impl<AesBlock, DesBlock, Salt> From<pbes2::ParametersInner<AesBlock, DesBlock, Salt>>
for EncryptionSchemeInner<AesBlock, DesBlock, Salt>
{
fn from(params: pbes2::ParametersInner<AesBlock, DesBlock, Salt>) -> Self {
Self::Pbes2(params)
}
}

impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
impl<'a, AesBlock, DesBlock, Salt> TryFrom<AlgorithmIdentifierRef<'a>>
for EncryptionSchemeInner<AesBlock, DesBlock, Salt>
where
Salt: AsRef<[u8]> + From<&'a [u8]>,
AesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
DesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
{
type Error = der::Error;

fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<EncryptionScheme<'_>> {
fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
if alg.oid == pbes2::PBES2_OID {
match alg.parameters {
Some(params) => pbes2::Parameters::try_from(params).map(Into::into),
Some(params) => pbes2::ParametersInner::try_from(params).map(Into::into),
None => Err(Tag::OctetString.value_error()),
}
} else {
Expand All @@ -199,10 +237,16 @@ impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
}
}

impl<'a> TryFrom<&'a [u8]> for EncryptionScheme<'a> {
impl<'a, AesBlock, DesBlock, Salt> TryFrom<&'a [u8]>
for EncryptionSchemeInner<AesBlock, DesBlock, Salt>
where
Salt: AsRef<[u8]> + From<&'a [u8]>,
AesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
DesBlock: AsRef<[u8]> + TryFrom<&'a [u8]>,
{
type Error = der::Error;

fn try_from(bytes: &'a [u8]) -> der::Result<EncryptionScheme<'a>> {
fn try_from(bytes: &'a [u8]) -> der::Result<Self> {
AlgorithmIdentifierRef::from_der(bytes)?.try_into()
}
}
Loading

0 comments on commit a44febb

Please sign in to comment.