mirror of
https://github.com/chatmail/core.git
synced 2026-04-29 11:26:29 +03:00
WIP: Start with decryption, and a test for it. Next TODO: SQL table migartion.
This commit is contained in:
51
src/pgp.rs
51
src/pgp.rs
@@ -236,9 +236,10 @@ pub fn pk_calc_signature(
|
||||
///
|
||||
/// Receiver private keys are provided in
|
||||
/// `private_keys_for_decryption`.
|
||||
pub fn pk_decrypt(
|
||||
pub fn decrypt(
|
||||
ctext: Vec<u8>,
|
||||
private_keys_for_decryption: &[SignedSecretKey],
|
||||
symmetric_secrets: &[&str],
|
||||
) -> Result<pgp::composed::Message<'static>> {
|
||||
let cursor = Cursor::new(ctext);
|
||||
let (msg, _headers) = Message::from_armor(cursor)?;
|
||||
@@ -246,10 +247,17 @@ pub fn pk_decrypt(
|
||||
let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption.iter().collect();
|
||||
let empty_pw = Password::empty();
|
||||
|
||||
// TODO it may degrade performance that we always try out all passwords here
|
||||
let message_password: Vec<Password> = symmetric_secrets
|
||||
.iter()
|
||||
.map(|p| Password::from(*p))
|
||||
.collect();
|
||||
let message_password: Vec<&Password> = message_password.iter().collect();
|
||||
|
||||
let ring = TheRing {
|
||||
secret_keys: skeys,
|
||||
key_passwords: vec![&empty_pw],
|
||||
message_password: vec![],
|
||||
message_password,
|
||||
session_keys: vec![],
|
||||
allow_legacy: false,
|
||||
};
|
||||
@@ -327,7 +335,7 @@ pub async fn symm_encrypt(passphrase: &str, plain: Vec<u8>) -> Result<String> {
|
||||
pub async fn encrypt_for_broadcast(
|
||||
plain: Vec<u8>,
|
||||
passphrase: &str,
|
||||
private_key_for_signing: Option<SignedSecretKey>,
|
||||
private_key_for_signing: SignedSecretKey,
|
||||
compress: bool,
|
||||
) -> Result<String> {
|
||||
let passphrase = Password::from(passphrase.to_string());
|
||||
@@ -344,11 +352,9 @@ pub async fn encrypt_for_broadcast(
|
||||
);
|
||||
msg.encrypt_with_password(&mut rng, s2k, &passphrase)?;
|
||||
|
||||
if let Some(ref skey) = private_key_for_signing {
|
||||
msg.sign(&**skey, Password::empty(), HASH_ALGORITHM);
|
||||
if compress {
|
||||
msg.compression(CompressionAlgorithm::ZLIB);
|
||||
}
|
||||
msg.sign(&*private_key_for_signing, Password::empty(), HASH_ALGORITHM);
|
||||
if compress {
|
||||
msg.compression(CompressionAlgorithm::ZLIB);
|
||||
}
|
||||
|
||||
let encoded_msg = msg.to_armored_string(&mut rng, Default::default())?;
|
||||
@@ -381,7 +387,10 @@ mod tests {
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
use super::*;
|
||||
use crate::test_utils::{alice_keypair, bob_keypair};
|
||||
use crate::{
|
||||
key::load_self_secret_key,
|
||||
test_utils::{TestContext, TestContextManager, alice_keypair, bob_keypair},
|
||||
};
|
||||
|
||||
fn pk_decrypt_and_validate<'a>(
|
||||
ctext: &'a [u8],
|
||||
@@ -392,7 +401,7 @@ mod tests {
|
||||
HashSet<Fingerprint>,
|
||||
Vec<u8>,
|
||||
)> {
|
||||
let mut msg = pk_decrypt(ctext.to_vec(), private_keys_for_decryption)?;
|
||||
let mut msg = decrypt(ctext.to_vec(), private_keys_for_decryption)?;
|
||||
let content = msg.as_data_vec()?;
|
||||
let ret_signature_fingerprints =
|
||||
valid_signature_fingerprints(&msg, public_keys_for_validation);
|
||||
@@ -578,4 +587,26 @@ mod tests {
|
||||
assert_eq!(content, CLEARTEXT);
|
||||
assert_eq!(valid_signatures.len(), 0);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_encrypt_decrypt_broadcast() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
|
||||
let plain = Vec::from(b"this is the secret message");
|
||||
let shared_secret = "shared secret";
|
||||
let ctext = encrypt_for_broadcast(
|
||||
plain,
|
||||
shared_secret,
|
||||
load_self_secret_key(alice).await?,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let bob_private_keyring = crate::key::load_self_secret_keyring(bob).await?;
|
||||
let decrypted = decrypt(ctext.into(), &bob_private_keyring)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user