summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-11-14 17:56:42 +0100
committerJustus Winter <justus@sequoia-pgp.org>2023-11-14 17:56:42 +0100
commit2560383bf9c71cdaf025dd583ba8e28b25bbfb52 (patch)
treee02f6e03170af9da86c6ef0e64b6f673150e5100
parent54318d2d26d4a63cd62d980594ef2f122ac33104 (diff)
openpgp: Add functions to encrypt keys with the new type.
- Same should be done for decryption.
-rw-r--r--openpgp/src/packet/key.rs56
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(&params)
+ }
+
+ /// 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()))
}
}