diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-11-14 17:56:42 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-11-14 17:56:42 +0100 |
commit | 2560383bf9c71cdaf025dd583ba8e28b25bbfb52 (patch) | |
tree | e02f6e03170af9da86c6ef0e64b6f673150e5100 | |
parent | 54318d2d26d4a63cd62d980594ef2f122ac33104 (diff) |
openpgp: Add functions to encrypt keys with the new type.
- Same should be done for decryption.
-rw-r--r-- | openpgp/src/packet/key.rs | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/openpgp/src/packet/key.rs b/openpgp/src/packet/key.rs index d0e62a5a..110f98c4 100644 --- a/openpgp/src/packet/key.rs +++ b/openpgp/src/packet/key.rs @@ -99,7 +99,7 @@ use crate::seal; use crate::SymmetricAlgorithm; use crate::HashAlgorithm; use crate::types::{Curve, Timestamp}; -use crate::crypto::S2K; +use crate::crypto::{S2K, EncryptionParameters}; use crate::Result; use crate::crypto::Password; use crate::crypto::SessionKey; @@ -1578,6 +1578,18 @@ impl SecretKeyMaterial { Ok(self) } + /// Encrypts the secret key material using the given parameters. + /// + /// This returns an error if the secret key material is encrypted. + /// + /// See [`Unencrypted::encrypt_with`] for details. + pub fn encrypt_with(mut self, params: &EncryptionParameters) + -> Result<Self> + { + self.encrypt_in_place_with(params)?; + Ok(self) + } + /// Encrypts the secret key material using `password`. /// /// This returns an error if the secret key material is encrypted. @@ -1596,6 +1608,26 @@ impl SecretKeyMaterial { } } + /// Encrypts the secret key material using the given parameters. + /// + /// This returns an error if the secret key material is encrypted. + /// + /// See [`Unencrypted::encrypt_with`] for details. + pub fn encrypt_in_place_with(&mut self, params: &EncryptionParameters) + -> Result<()> + { + match self { + SecretKeyMaterial::Unencrypted(ref u) => { + *self = SecretKeyMaterial::Encrypted( + u.encrypt_with(params)?); + Ok(()) + } + SecretKeyMaterial::Encrypted(_) => + Err(Error::InvalidArgument( + "secret key is encrypted".into()).into()), + } + } + /// Returns whether the secret key material is encrypted. pub fn is_encrypted(&self) -> bool { match self { @@ -1669,27 +1701,35 @@ impl Unencrypted { pub fn encrypt(&self, password: &Password) -> Result<Encrypted> { - use std::io::Write; - use crate::crypto::symmetric::Encryptor; - let s2k = S2K::default(); let algo = SymmetricAlgorithm::AES256; - let key = s2k.derive_key(password, algo.key_size()?)?; + let params = s2k.make_encryption_parameters(password, algo)?; + self.encrypt_with(¶ms) + } + + /// Encrypts the secret key material using the given parameters. + pub fn encrypt_with(&self, params: &EncryptionParameters) + -> Result<Encrypted> + { + use std::io::Write; + use crate::crypto::symmetric::Encryptor; // Ciphertext is preceded by a random block. - let mut trash = vec![0u8; algo.block_size()?]; + let mut trash = vec![0u8; params.algo().block_size()?]; crypto::random(&mut trash); let checksum = Default::default(); let mut esk = Vec::new(); { - let mut encryptor = Encryptor::new(algo, &key, &mut esk)?; + let mut encryptor = + Encryptor::new(params.algo(), params.key(), &mut esk)?; encryptor.write_all(&trash)?; self.map(|mpis| mpis.serialize_with_checksum(&mut encryptor, checksum))?; } - Ok(Encrypted::new(s2k, algo, Some(checksum), esk.into_boxed_slice())) + Ok(Encrypted::new(params.s2k().clone(), params.algo(), Some(checksum), + esk.into_boxed_slice())) } } |