Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkcs5: Make storage generic #1193

Closed
wants to merge 1 commit into from
Closed
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
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
Loading