Skip to content

Commit

Permalink
[WIP] pkcs5: remove lifetimes
Browse files Browse the repository at this point in the history
Removes lifetimes from all types in the `pkcs5` crate, making them own
their data.
  • Loading branch information
tarcieri committed Aug 9, 2023
1 parent 3e65c66 commit 057cee0
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 149 deletions.
42 changes: 21 additions & 21 deletions pkcs5/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use alloc::vec::Vec;
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
#[allow(clippy::large_enum_variant)]
pub enum EncryptionScheme<'a> {
pub enum EncryptionScheme {
/// 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 +58,10 @@ 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::Parameters),
}

impl<'a> EncryptionScheme<'a> {
impl EncryptionScheme {
/// Attempt to decrypt the given ciphertext, allocating and returning a
/// byte vector containing the plaintext.
#[cfg(all(feature = "alloc", feature = "pbes2"))]
Expand All @@ -79,11 +79,11 @@ impl<'a> EncryptionScheme<'a> {
/// is unsupported, or if the ciphertext is malformed (e.g. not a multiple
/// of a block mode's padding)
#[cfg(feature = "pbes2")]
pub fn decrypt_in_place<'b>(
pub fn decrypt_in_place<'a>(
&self,
password: impl AsRef<[u8]>,
buffer: &'b mut [u8],
) -> Result<&'b [u8]> {
buffer: &'a mut [u8],
) -> Result<&'a [u8]> {
match self {
Self::Pbes2(params) => params.decrypt_in_place(password, buffer),
Self::Pbes1(_) => Err(Error::NoPbes1CryptSupport),
Expand All @@ -103,12 +103,12 @@ impl<'a> EncryptionScheme<'a> {
/// Encrypt the given ciphertext in-place using a key derived from the
/// provided password and this scheme's parameters.
#[cfg(feature = "pbes2")]
pub fn encrypt_in_place<'b>(
pub fn encrypt_in_place<'a>(
&self,
password: impl AsRef<[u8]>,
buffer: &'b mut [u8],
buffer: &'a mut [u8],
pos: usize,
) -> Result<&'b [u8]> {
) -> Result<&'a [u8]> {
match self {
Self::Pbes2(params) => params.encrypt_in_place(password, buffer, pos),
Self::Pbes1(_) => Err(Error::NoPbes1CryptSupport),
Expand All @@ -132,21 +132,21 @@ 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::Parameters> {
match self {
Self::Pbes2(params) => Some(params),
_ => None,
}
}
}

impl<'a> DecodeValue<'a> for EncryptionScheme<'a> {
impl<'a> DecodeValue<'a> for EncryptionScheme {
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 EncodeValue for EncryptionScheme {
fn value_len(&self) -> der::Result<Length> {
match self {
Self::Pbes1(pbes1) => pbes1.oid().encoded_len()? + pbes1.parameters.encoded_len()?,
Expand All @@ -170,24 +170,24 @@ impl EncodeValue for EncryptionScheme<'_> {
}
}

impl<'a> Sequence<'a> for EncryptionScheme<'a> {}
impl Sequence<'_> for EncryptionScheme {}

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

impl<'a> From<pbes2::Parameters<'a>> for EncryptionScheme<'a> {
fn from(params: pbes2::Parameters<'a>) -> EncryptionScheme<'a> {
impl From<pbes2::Parameters> for EncryptionScheme {
fn from(params: pbes2::Parameters) -> EncryptionScheme {
Self::Pbes2(params)
}
}

impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
impl TryFrom<AlgorithmIdentifierRef<'_>> for EncryptionScheme {
type Error = der::Error;

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

impl<'a> TryFrom<&'a [u8]> for EncryptionScheme<'a> {
impl TryFrom<&[u8]> for EncryptionScheme {
type Error = der::Error;

fn try_from(bytes: &'a [u8]) -> der::Result<EncryptionScheme<'a>> {
fn try_from(bytes: &[u8]) -> der::Result<EncryptionScheme> {
AlgorithmIdentifierRef::from_der(bytes)?.try_into()
}
}
90 changes: 45 additions & 45 deletions pkcs5/src/pbes2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod kdf;
mod encryption;

pub use self::kdf::{
Kdf, Pbkdf2Params, Pbkdf2Prf, ScryptParams, HMAC_WITH_SHA1_OID, HMAC_WITH_SHA256_OID,
Kdf, Pbkdf2Params, Pbkdf2Prf, Salt, ScryptParams, HMAC_WITH_SHA1_OID, HMAC_WITH_SHA256_OID,
PBKDF2_OID, SCRYPT_OID,
};

Expand Down Expand Up @@ -66,21 +66,21 @@ const DES_BLOCK_SIZE: usize = 8;
///
/// [RFC 8018 Appendix A.4]: https://tools.ietf.org/html/rfc8018#appendix-A.4
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Parameters<'a> {
pub struct Parameters {
/// Key derivation function
pub kdf: Kdf<'a>,
pub kdf: Kdf,

/// Encryption scheme
pub encryption: EncryptionScheme<'a>,
pub encryption: EncryptionScheme,
}

impl<'a> Parameters<'a> {
impl Parameters {
/// Initialize PBES2 parameters using PBKDF2-SHA256 as the password-based
/// key derivation function and AES-128-CBC as the symmetric cipher.
pub fn pbkdf2_sha256_aes128cbc(
pbkdf2_iterations: u32,
pbkdf2_salt: &'a [u8],
aes_iv: &'a [u8; AES_BLOCK_SIZE],
pbkdf2_salt: &[u8],
aes_iv: [u8; AES_BLOCK_SIZE],
) -> Result<Self> {
let kdf = Pbkdf2Params::hmac_with_sha256(pbkdf2_iterations, pbkdf2_salt)?.into();
let encryption = EncryptionScheme::Aes128Cbc { iv: aes_iv };
Expand All @@ -91,8 +91,8 @@ impl<'a> Parameters<'a> {
/// key derivation function and AES-256-CBC as the symmetric cipher.
pub fn pbkdf2_sha256_aes256cbc(
pbkdf2_iterations: u32,
pbkdf2_salt: &'a [u8],
aes_iv: &'a [u8; AES_BLOCK_SIZE],
pbkdf2_salt: &[u8],
aes_iv: [u8; AES_BLOCK_SIZE],
) -> Result<Self> {
let kdf = Pbkdf2Params::hmac_with_sha256(pbkdf2_iterations, pbkdf2_salt)?.into();
let encryption = EncryptionScheme::Aes256Cbc { iv: aes_iv };
Expand All @@ -108,8 +108,8 @@ impl<'a> Parameters<'a> {
#[cfg(feature = "pbes2")]
pub fn scrypt_aes128cbc(
params: scrypt::Params,
salt: &'a [u8],
aes_iv: &'a [u8; AES_BLOCK_SIZE],
salt: &[u8],
aes_iv: [u8; AES_BLOCK_SIZE],
) -> Result<Self> {
let kdf = ScryptParams::from_params_and_salt(params, salt)?.into();
let encryption = EncryptionScheme::Aes128Cbc { iv: aes_iv };
Expand All @@ -128,8 +128,8 @@ impl<'a> Parameters<'a> {
#[cfg(feature = "pbes2")]
pub fn scrypt_aes256cbc(
params: scrypt::Params,
salt: &'a [u8],
aes_iv: &'a [u8; AES_BLOCK_SIZE],
salt: &[u8],
aes_iv: [u8; AES_BLOCK_SIZE],
) -> Result<Self> {
let kdf = ScryptParams::from_params_and_salt(params, salt)?.into();
let encryption = EncryptionScheme::Aes256Cbc { iv: aes_iv };
Expand All @@ -153,11 +153,11 @@ impl<'a> Parameters<'a> {
/// is unsupported, or if the ciphertext is malformed (e.g. not a multiple
/// of a block mode's padding)
#[cfg(feature = "pbes2")]
pub fn decrypt_in_place<'b>(
pub fn decrypt_in_place<'a>(
&self,
password: impl AsRef<[u8]>,
buffer: &'b mut [u8],
) -> Result<&'b [u8]> {
buffer: &'a mut [u8],
) -> Result<&'a [u8]> {
encryption::decrypt_in_place(self, password, buffer)
}

Expand All @@ -182,23 +182,23 @@ impl<'a> Parameters<'a> {
/// provided password and this scheme's parameters, writing the ciphertext
/// into the same buffer.
#[cfg(feature = "pbes2")]
pub fn encrypt_in_place<'b>(
pub fn encrypt_in_place<'a>(
&self,
password: impl AsRef<[u8]>,
buffer: &'b mut [u8],
buffer: &'a mut [u8],
pos: usize,
) -> Result<&'b [u8]> {
) -> Result<&'a [u8]> {
encryption::encrypt_in_place(self, password, buffer, pos)
}
}

impl<'a> DecodeValue<'a> for Parameters<'a> {
impl<'a> DecodeValue<'a> for Parameters {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: der::Header) -> der::Result<Self> {
AnyRef::decode_value(reader, header)?.try_into()
}
}

impl EncodeValue for Parameters<'_> {
impl EncodeValue for Parameters {
fn value_len(&self) -> der::Result<Length> {
self.kdf.encoded_len()? + self.encryption.encoded_len()?
}
Expand All @@ -210,12 +210,12 @@ impl EncodeValue for Parameters<'_> {
}
}

impl<'a> Sequence<'a> for Parameters<'a> {}
impl Sequence<'_> for Parameters {}

impl<'a> TryFrom<AnyRef<'a>> for Parameters<'a> {
impl TryFrom<AnyRef<'_>> for Parameters {
type Error = der::Error;

fn try_from(any: AnyRef<'a>) -> der::Result<Self> {
fn try_from(any: AnyRef<'_>) -> der::Result<Self> {
any.sequence(|params| {
let kdf = AlgorithmIdentifierRef::decode(params)?;
let encryption = AlgorithmIdentifierRef::decode(params)?;
Expand All @@ -231,41 +231,41 @@ impl<'a> TryFrom<AnyRef<'a>> for Parameters<'a> {
/// Symmetric encryption scheme used by PBES2.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum EncryptionScheme<'a> {
pub enum EncryptionScheme {
/// AES-128 in CBC mode
Aes128Cbc {
/// Initialization vector
iv: &'a [u8; AES_BLOCK_SIZE],
iv: [u8; AES_BLOCK_SIZE],
},

/// AES-192 in CBC mode
Aes192Cbc {
/// Initialization vector
iv: &'a [u8; AES_BLOCK_SIZE],
iv: [u8; AES_BLOCK_SIZE],
},

/// AES-256 in CBC mode
Aes256Cbc {
/// Initialization vector
iv: &'a [u8; AES_BLOCK_SIZE],
iv: [u8; AES_BLOCK_SIZE],
},

/// 3-Key Triple DES in CBC mode
#[cfg(feature = "3des")]
DesEde3Cbc {
/// Initialisation vector
iv: &'a [u8; DES_BLOCK_SIZE],
iv: [u8; DES_BLOCK_SIZE],
},

/// DES in CBC mode
#[cfg(feature = "des-insecure")]
DesCbc {
/// Initialisation vector
iv: &'a [u8; DES_BLOCK_SIZE],
iv: [u8; DES_BLOCK_SIZE],
},
}

impl<'a> EncryptionScheme<'a> {
impl EncryptionScheme {
/// Get the size of a key used by this algorithm in bytes.
pub fn key_size(&self) -> usize {
match self {
Expand Down Expand Up @@ -300,19 +300,19 @@ impl<'a> EncryptionScheme<'a> {
}
}

impl<'a> Decode<'a> for EncryptionScheme<'a> {
impl<'a> Decode<'a> for EncryptionScheme {
fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
AlgorithmIdentifierRef::decode(reader).and_then(TryInto::try_into)
}
}

impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
impl TryFrom<AlgorithmIdentifierRef<'_>> for EncryptionScheme {
type Error = der::Error;

fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
fn try_from(alg: AlgorithmIdentifierRef<'_>) -> der::Result<Self> {
// TODO(tarcieri): support for non-AES algorithms?
let iv = match alg.parameters {
Some(params) => params.decode_as::<OctetStringRef<'a>>()?.as_bytes(),
Some(params) => params.decode_as::<OctetStringRef<'_>>()?.as_bytes(),
None => return Err(Tag::OctetString.value_error()),
};

Expand Down Expand Up @@ -349,18 +349,18 @@ impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
}
}

impl<'a> TryFrom<EncryptionScheme<'a>> for AlgorithmIdentifierRef<'a> {
impl<'a> TryFrom<&'a EncryptionScheme> for AlgorithmIdentifierRef<'a> {
type Error = der::Error;

fn try_from(scheme: EncryptionScheme<'a>) -> der::Result<Self> {
fn try_from(scheme: &'a EncryptionScheme) -> der::Result<Self> {
let parameters = OctetStringRef::new(match scheme {
EncryptionScheme::Aes128Cbc { iv } => iv,
EncryptionScheme::Aes192Cbc { iv } => iv,
EncryptionScheme::Aes256Cbc { iv } => iv,
EncryptionScheme::Aes128Cbc { iv } => iv.as_slice(),
EncryptionScheme::Aes192Cbc { iv } => iv.as_slice(),
EncryptionScheme::Aes256Cbc { iv } => iv.as_slice(),
#[cfg(feature = "des-insecure")]
EncryptionScheme::DesCbc { iv } => iv,
EncryptionScheme::DesCbc { iv } => iv.as_slice(),
#[cfg(feature = "3des")]
EncryptionScheme::DesEde3Cbc { iv } => iv,
EncryptionScheme::DesEde3Cbc { iv } => iv.as_slice(),
})?;

Ok(AlgorithmIdentifierRef {
Expand All @@ -370,12 +370,12 @@ impl<'a> TryFrom<EncryptionScheme<'a>> for AlgorithmIdentifierRef<'a> {
}
}

impl<'a> Encode for EncryptionScheme<'a> {
impl Encode for EncryptionScheme {
fn encoded_len(&self) -> der::Result<Length> {
AlgorithmIdentifierRef::try_from(*self)?.encoded_len()
AlgorithmIdentifierRef::try_from(self)?.encoded_len()
}

fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
AlgorithmIdentifierRef::try_from(*self)?.encode(writer)
AlgorithmIdentifierRef::try_from(self)?.encode(writer)
}
}
Loading

0 comments on commit 057cee0

Please sign in to comment.