diff --git a/Cargo.lock b/Cargo.lock index 195b42032..3d00952a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -784,6 +784,7 @@ dependencies = [ "serde_json", "sha2", "smallvec", + "smol", "stop-token", "strum", "strum_macros", diff --git a/Cargo.toml b/Cargo.toml index a63cf33b9..c61569fe3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,7 @@ pretty_assertions = "0.6.1" pretty_env_logger = "0.3.0" proptest = "0.9.4" async-std = { version = "1.6.0", features = ["unstable", "attributes"] } +smol = "0.1.10" [workspace] members = [ @@ -98,4 +99,4 @@ vendored = ["async-native-tls/vendored", "async-smtp/native-tls-vendored"] nightly = ["pgp/nightly"] [patch.crates-io] -smol = { git = "https://github.com/dignifiedquire/smol-1", branch = "isolate-nix" } \ No newline at end of file +smol = { git = "https://github.com/dignifiedquire/smol-1", branch = "isolate-nix" } diff --git a/src/e2ee.rs b/src/e2ee.rs index 899f1df23..bb3f985d3 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -87,30 +87,30 @@ impl EncryptHelper { /// Tries to encrypt the passed in `mail`. pub async fn encrypt( - &mut self, + self, context: &Context, min_verified: PeerstateVerifiedStatus, mail_to_encrypt: lettre_email::PartBuilder, - peerstates: &[(Option>, &str)], + peerstates: Vec<(Option>, &str)>, ) -> Result { let mut keyring = Keyring::default(); for (peerstate, addr) in peerstates - .iter() - .filter_map(|(state, addr)| state.as_ref().map(|s| (s, addr))) + .into_iter() + .filter_map(|(state, addr)| state.map(|s| (s, addr))) { - let key = peerstate.peek_key(min_verified).ok_or_else(|| { + let key = peerstate.take_key(min_verified).ok_or_else(|| { format_err!("proper enc-key for {} missing, cannot encrypt", addr) })?; - keyring.add_ref(key); + keyring.add(key); } - let public_key = Key::from(self.public_key.clone()); - keyring.add_ref(&public_key); + let public_key = Key::from(self.public_key); + keyring.add(public_key); let sign_key = Key::from(SignedSecretKey::load_self(context).await?); let raw_message = mail_to_encrypt.build().as_string().into_bytes(); - let ctext = pgp::pk_encrypt(&raw_message, &keyring, Some(&sign_key))?; + let ctext = pgp::pk_encrypt(&raw_message, keyring, Some(sign_key)).await?; Ok(ctext) } @@ -151,39 +151,38 @@ pub async fn try_decrypt( } /* possibly perform decryption */ - let mut private_keyring = Keyring::default(); let mut public_keyring_for_validate = Keyring::default(); let mut out_mail = None; let mut signatures = HashSet::default(); let self_addr = context.get_config(Config::ConfiguredAddr).await; if let Some(self_addr) = self_addr { - if private_keyring - .load_self_private_for_decrypting(context, self_addr, &context.sql) - .await + if let Ok(private_keyring) = + Keyring::load_self_private_for_decrypting(context, self_addr).await { if peerstate.as_ref().map(|p| p.last_seen).unwrap_or_else(|| 0) == 0 { peerstate = Peerstate::from_addr(&context, &from).await; } - if let Some(ref peerstate) = peerstate { + if let Some(peerstate) = peerstate { if peerstate.degrade_event.is_some() { handle_degrade_event(context, &peerstate).await?; } - if let Some(ref key) = peerstate.gossip_key { - public_keyring_for_validate.add_ref(key); + if let Some(key) = peerstate.gossip_key { + public_keyring_for_validate.add(key); } - if let Some(ref key) = peerstate.public_key { - public_keyring_for_validate.add_ref(key); + if let Some(key) = peerstate.public_key { + public_keyring_for_validate.add(key); } } out_mail = decrypt_if_autocrypt_message( context, mail, - &private_keyring, - &public_keyring_for_validate, + private_keyring, + public_keyring_for_validate, &mut signatures, - )?; + ) + .await?; } } Ok((out_mail, signatures)) @@ -216,11 +215,11 @@ fn get_autocrypt_mime<'a, 'b>(mail: &'a ParsedMail<'b>) -> Result<&'a ParsedMail Ok(&mail.subparts[1]) } -fn decrypt_if_autocrypt_message<'a>( +async fn decrypt_if_autocrypt_message<'a>( context: &Context, mail: &ParsedMail<'a>, - private_keyring: &Keyring, - public_keyring_for_validate: &Keyring, + private_keyring: Keyring, + public_keyring_for_validate: Keyring, ret_valid_signatures: &mut HashSet, ) -> Result>> { // The returned bool is true if we detected an Autocrypt-encrypted @@ -240,20 +239,19 @@ fn decrypt_if_autocrypt_message<'a>( info!(context, "Detected Autocrypt-mime message"); decrypt_part( - context, encrypted_data_part, private_keyring, public_keyring_for_validate, ret_valid_signatures, ) + .await } /// Returns Ok(None) if nothing encrypted was found. -fn decrypt_part( - _context: &Context, +async fn decrypt_part( mail: &ParsedMail<'_>, - private_keyring: &Keyring, - public_keyring_for_validate: &Keyring, + private_keyring: Keyring, + public_keyring_for_validate: Keyring, ret_valid_signatures: &mut HashSet, ) -> Result>> { let data = mail.get_body_raw()?; @@ -263,11 +261,12 @@ fn decrypt_part( ensure!(ret_valid_signatures.is_empty(), "corrupt signatures"); let plain = pgp::pk_decrypt( - &data, - &private_keyring, - &public_keyring_for_validate, + data, + private_keyring, + public_keyring_for_validate, Some(ret_valid_signatures), - )?; + ) + .await?; ensure!(!ret_valid_signatures.is_empty(), "no valid signatures"); return Ok(Some(plain)); diff --git a/src/imex.rs b/src/imex.rs index 2c443e846..563b6aa68 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -187,7 +187,7 @@ pub async fn render_setup_file(context: &Context, passphrase: &str) -> Result Some(("Autocrypt-Prefer-Encrypt", "mutual")), }; let private_key_asc = private_key.to_asc(ac_headers); - let encr = pgp::symm_encrypt(&passphrase, private_key_asc.as_bytes())?; + let encr = pgp::symm_encrypt(&passphrase, private_key_asc.as_bytes()).await?; let replacement = format!( concat!( @@ -274,7 +274,7 @@ pub async fn continue_key_transfer( if let Some(filename) = msg.get_file(context) { let file = dc_open_file_std(context, filename)?; let sc = normalize_setup_code(setup_code); - let armored_key = decrypt_setup_file(context, &sc, file)?; + let armored_key = decrypt_setup_file(&sc, file).await?; set_self_key(context, &armored_key, true, true).await?; maybe_add_bcc_self_device_msg(context).await?; @@ -345,12 +345,11 @@ async fn set_self_key( Ok(()) } -fn decrypt_setup_file( - _context: &Context, +async fn decrypt_setup_file( passphrase: &str, file: T, ) -> Result { - let plain_bytes = pgp::symm_decrypt(passphrase, file)?; + let plain_bytes = pgp::symm_decrypt(passphrase, file).await?; let plain_text = std::string::String::from_utf8(plain_bytes)?; Ok(plain_text) @@ -713,7 +712,7 @@ async fn export_self_keys(context: &Context, dir: impl AsRef) -> Result<() for (id, public_key, private_key, is_default) in keys { let id = Some(id).filter(|_| is_default != 0); - if let Some(key) = public_key { + if let Ok(key) = public_key { if export_key_to_asc_file(context, &dir, id, &key) .await .is_err() @@ -723,7 +722,7 @@ async fn export_self_keys(context: &Context, dir: impl AsRef) -> Result<() } else { export_errors += 1; } - if let Some(key) = private_key { + if let Ok(key) = private_key { if export_key_to_asc_file(context, &dir, id, &key) .await .is_err() @@ -852,9 +851,6 @@ mod tests { #[async_std::test] async fn test_split_and_decrypt() { - let ctx = dummy_context().await; - let context = &ctx.ctx; - let buf_1 = S_EM_SETUPFILE.as_bytes().to_vec(); let (typ, headers, base64) = split_armored_data(&buf_1).unwrap(); assert_eq!(typ, BlockType::Message); @@ -864,12 +860,10 @@ mod tests { assert!(!base64.is_empty()); let setup_file = S_EM_SETUPFILE.to_string(); - let decrypted = decrypt_setup_file( - context, - S_EM_SETUPCODE, - std::io::Cursor::new(setup_file.as_bytes()), - ) - .unwrap(); + let decrypted = + decrypt_setup_file(S_EM_SETUPCODE, std::io::Cursor::new(setup_file.as_bytes())) + .await + .unwrap(); let (typ, headers, _base64) = split_armored_data(decrypted.as_bytes()).unwrap(); diff --git a/src/key.rs b/src/key.rs index 28df79dbe..c00f77486 100644 --- a/src/key.rs +++ b/src/key.rs @@ -38,6 +38,8 @@ pub enum Error { NoConfiguredAddr, #[error("Configured address is invalid: {}", _0)] InvalidConfiguredAddr(#[from] InvalidEmailError), + #[error("no data provided")] + Empty, } pub type Result = std::result::Result; @@ -260,22 +262,17 @@ impl Key { !self.is_public() } - pub fn from_slice(bytes: &[u8], key_type: KeyType) -> Option { + pub fn from_slice(bytes: &[u8], key_type: KeyType) -> Result { if bytes.is_empty() { - return None; + return Err(Error::Empty); } - let res: std::result::Result = match key_type { - KeyType::Public => SignedPublicKey::from_bytes(Cursor::new(bytes)).map(Into::into), - KeyType::Private => SignedSecretKey::from_bytes(Cursor::new(bytes)).map(Into::into), + + let res = match key_type { + KeyType::Public => SignedPublicKey::from_bytes(Cursor::new(bytes))?.into(), + KeyType::Private => SignedSecretKey::from_bytes(Cursor::new(bytes))?.into(), }; - match res { - Ok(key) => Some(key), - Err(err) => { - eprintln!("Invalid key bytes: {:?}", err); - None - } - } + Ok(res) } pub fn from_armored_string( @@ -625,7 +622,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD KeyType::Private }, ); - assert!(bad_key.is_none()); + assert!(bad_key.is_err()); } } diff --git a/src/keyring.rs b/src/keyring.rs index f1da55e13..c962e3fbd 100644 --- a/src/keyring.rs +++ b/src/keyring.rs @@ -1,46 +1,47 @@ -use std::borrow::Cow; +use anyhow::Result; use crate::constants::KeyType; use crate::context::Context; use crate::key::Key; -use crate::sql::Sql; #[derive(Default, Clone, Debug)] -pub struct Keyring<'a> { - keys: Vec>, +pub struct Keyring { + keys: Vec, } -impl<'a> Keyring<'a> { - pub fn add_owned(&mut self, key: Key) { - self.add(Cow::Owned(key)) +impl Keyring { + pub fn add(&mut self, key: Key) { + self.keys.push(key) } - pub fn add_ref(&mut self, key: &'a Key) { - self.add(Cow::Borrowed(key)) + pub fn len(&self) -> usize { + self.keys.len() } - fn add(&mut self, key: Cow<'a, Key>) { - self.keys.push(key); + pub fn is_empty(&self) -> bool { + self.keys.is_empty() } - pub fn keys(&self) -> &[Cow<'a, Key>] { + pub fn keys(&self) -> &[Key] { &self.keys } pub async fn load_self_private_for_decrypting( - &mut self, context: &Context, self_addr: impl AsRef, - sql: &Sql, - ) -> bool { - sql.query_get_value( - context, - "SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;", - paramsv![self_addr.as_ref().to_string()], - ) - .await - .and_then(|blob: Vec| Key::from_slice(&blob, KeyType::Private)) - .map(|key| self.add_owned(key)) - .is_some() + ) -> Result { + let blob: Vec = context + .sql + .query_get_value_result( + "SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;", + paramsv![self_addr.as_ref().to_string()], + ) + .await? + .unwrap_or_default(); + + let key = async_std::task::spawn_blocking(move || Key::from_slice(&blob, KeyType::Private)) + .await?; + + Ok(Self { keys: vec![key] }) } } diff --git a/src/mimefactory.rs b/src/mimefactory.rs index ceb87d134..e17cf668e 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -463,7 +463,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> { let force_plaintext = self.should_force_plaintext(); let subject_str = self.subject_str().await; let e2ee_guaranteed = self.is_e2ee_guaranteed(); - let mut encrypt_helper = EncryptHelper::new(self.context).await?; + let encrypt_helper = EncryptHelper::new(self.context).await?; let subject = encode_words(&subject_str); @@ -560,7 +560,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> { } let encrypted = encrypt_helper - .encrypt(self.context, min_verified, message, &peerstates) + .encrypt(self.context, min_verified, message, peerstates) .await?; outer_message = outer_message diff --git a/src/peerstate.rs b/src/peerstate.rs index beec1bbf5..fc36020a6 100644 --- a/src/peerstate.rs +++ b/src/peerstate.rs @@ -220,15 +220,15 @@ impl<'a> Peerstate<'a> { res.public_key = row .get(4) .ok() - .and_then(|blob: Vec| Key::from_slice(&blob, KeyType::Public)); + .and_then(|blob: Vec| Key::from_slice(&blob, KeyType::Public).ok()); res.gossip_key = row .get(6) .ok() - .and_then(|blob: Vec| Key::from_slice(&blob, KeyType::Public)); + .and_then(|blob: Vec| Key::from_slice(&blob, KeyType::Public).ok()); res.verified_key = row .get(9) .ok() - .and_then(|blob: Vec| Key::from_slice(&blob, KeyType::Public)); + .and_then(|blob: Vec| Key::from_slice(&blob, KeyType::Public).ok()); Ok(res) }) @@ -367,6 +367,15 @@ impl<'a> Peerstate<'a> { } } + pub fn take_key(mut self, min_verified: PeerstateVerifiedStatus) -> Option { + match min_verified { + PeerstateVerifiedStatus::BidirectVerified => self.verified_key.take(), + PeerstateVerifiedStatus::Unverified => { + self.public_key.take().or_else(|| self.gossip_key.take()) + } + } + } + pub fn peek_key(&self, min_verified: PeerstateVerifiedStatus) -> Option<&Key> { match min_verified { PeerstateVerifiedStatus::BidirectVerified => self.verified_key.as_ref(), diff --git a/src/pgp.rs b/src/pgp.rs index 287c7b0bf..fef20379d 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -238,124 +238,140 @@ fn select_pk_for_encryption(key: &SignedPublicKey) -> Option, + public_keys_for_encryption: Keyring, + private_key_for_signing: Option, ) -> Result { let lit_msg = Message::new_literal_bytes("", plain); - let pkeys: Vec = public_keys_for_encryption - .keys() - .iter() - .filter_map(|key| { - key.as_ref() + + async_std::task::spawn_blocking(move || { + let pkeys: Vec = public_keys_for_encryption + .keys() + .iter() + .filter_map(|key| key.try_into().ok().and_then(select_pk_for_encryption)) + .collect(); + let pkeys_refs: Vec<&SignedPublicKeyOrSubkey> = pkeys.iter().collect(); + + let mut rng = thread_rng(); + + // TODO: measure time + let encrypted_msg = if let Some(ref private_key) = private_key_for_signing { + let skey: &SignedSecretKey = private_key .try_into() - .ok() - .and_then(select_pk_for_encryption) - }) - .collect(); - let pkeys_refs: Vec<&SignedPublicKeyOrSubkey> = pkeys.iter().collect(); + .map_err(|_| format_err!("Invalid private key"))?; - let mut rng = thread_rng(); + lit_msg + .sign(skey, || "".into(), Default::default()) + .and_then(|msg| msg.compress(CompressionAlgorithm::ZLIB)) + .and_then(|msg| msg.encrypt_to_keys(&mut rng, Default::default(), &pkeys_refs)) + } else { + lit_msg.encrypt_to_keys(&mut rng, Default::default(), &pkeys_refs) + }; - // TODO: measure time - let encrypted_msg = if let Some(private_key) = private_key_for_signing { - let skey: &SignedSecretKey = private_key - .try_into() - .map_err(|_| format_err!("Invalid private key"))?; + let msg = encrypted_msg?; + let encoded_msg = msg.to_armored_string(None)?; - lit_msg - .sign(skey, || "".into(), Default::default()) - .and_then(|msg| msg.compress(CompressionAlgorithm::ZLIB)) - .and_then(|msg| msg.encrypt_to_keys(&mut rng, Default::default(), &pkeys_refs)) - } else { - lit_msg.encrypt_to_keys(&mut rng, Default::default(), &pkeys_refs) - }; - - let msg = encrypted_msg?; - let encoded_msg = msg.to_armored_string(None)?; - - Ok(encoded_msg) + Ok(encoded_msg) + }) + .await } #[allow(clippy::implicit_hasher)] -pub fn pk_decrypt( - ctext: &[u8], - private_keys_for_decryption: &Keyring, - public_keys_for_validation: &Keyring, +pub async fn pk_decrypt( + ctext: Vec, + private_keys_for_decryption: Keyring, + public_keys_for_validation: Keyring, ret_signature_fingerprints: Option<&mut HashSet>, ) -> Result> { - let (msg, _) = Message::from_armor_single(Cursor::new(ctext))?; - let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption - .keys() - .iter() - .filter_map(|key| { - let k: &Key = &key; - k.try_into().ok() - }) - .collect(); + let msgs = async_std::task::spawn_blocking(move || { + let cursor = Cursor::new(ctext); + let (msg, _) = Message::from_armor_single(cursor)?; + + let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption + .keys() + .iter() + .filter_map(|key| key.try_into().ok()) + .collect(); + + let (decryptor, _) = msg.decrypt(|| "".into(), || "".into(), &skeys[..])?; + decryptor.collect::>>() + }) + .await?; - let (decryptor, _) = msg.decrypt(|| "".into(), || "".into(), &skeys[..])?; - let msgs = decryptor.collect::>>()?; ensure!(!msgs.is_empty(), "No valid messages found"); - let dec_msg = &msgs[0]; + let content = match msgs[0].get_content()? { + Some(content) => content, + None => bail!("Decrypted message is empty"), + }; if let Some(ret_signature_fingerprints) = ret_signature_fingerprints { - if !public_keys_for_validation.keys().is_empty() { - let pkeys: Vec<&SignedPublicKey> = public_keys_for_validation - .keys() - .iter() - .filter_map(|key| { - let k: &Key = &key; - k.try_into().ok() - }) - .collect(); + if !public_keys_for_validation.is_empty() { + let fingerprints = async_std::task::spawn_blocking(move || { + let dec_msg = &msgs[0]; - for pkey in &pkeys { - if dec_msg.verify(&pkey.primary_key).is_ok() { - let fp = hex::encode_upper(pkey.fingerprint()); - ret_signature_fingerprints.insert(fp); + let pkeys = public_keys_for_validation + .keys() + .iter() + .filter_map(|key| -> Option<&SignedPublicKey> { key.try_into().ok() }); + + let mut fingerprints = Vec::new(); + for pkey in pkeys { + if dec_msg.verify(&pkey.primary_key).is_ok() { + let fp = hex::encode_upper(pkey.fingerprint()); + fingerprints.push(fp); + } } - } + fingerprints + }) + .await; + + ret_signature_fingerprints.extend(fingerprints); } } - match dec_msg.get_content()? { - Some(content) => Ok(content), - None => bail!("Decrypted message is empty"), - } + Ok(content) } /// Symmetric encryption. -pub fn symm_encrypt(passphrase: &str, plain: &[u8]) -> Result { - let mut rng = thread_rng(); +pub async fn symm_encrypt(passphrase: &str, plain: &[u8]) -> Result { let lit_msg = Message::new_literal_bytes("", plain); + let passphrase = passphrase.to_string(); - let s2k = StringToKey::new_default(&mut rng); - let msg = - lit_msg.encrypt_with_password(&mut rng, s2k, Default::default(), || passphrase.into())?; + async_std::task::spawn_blocking(move || { + let mut rng = thread_rng(); + let s2k = StringToKey::new_default(&mut rng); + let msg = + lit_msg.encrypt_with_password(&mut rng, s2k, Default::default(), || passphrase)?; - let encoded_msg = msg.to_armored_string(None)?; + let encoded_msg = msg.to_armored_string(None)?; - Ok(encoded_msg) + Ok(encoded_msg) + }) + .await } /// Symmetric decryption. -pub fn symm_decrypt( +pub async fn symm_decrypt( passphrase: &str, ctext: T, ) -> Result> { let (enc_msg, _) = Message::from_armor_single(ctext)?; - let decryptor = enc_msg.decrypt_with_password(|| passphrase.into())?; - let msgs = decryptor.collect::>>()?; - ensure!(!msgs.is_empty(), "No valid messages found"); + let passphrase = passphrase.to_string(); + async_std::task::spawn_blocking(move || { + let decryptor = enc_msg.decrypt_with_password(|| passphrase)?; - match msgs[0].get_content()? { - Some(content) => Ok(content), - None => bail!("Decrypted message is empty"), - } + let msgs = decryptor.collect::>>()?; + ensure!(!msgs.is_empty(), "No valid messages found"); + + match msgs[0].get_content()? { + Some(content) => Ok(content), + None => bail!("Decrypted message is empty"), + } + }) + .await } #[cfg(test)] @@ -437,17 +453,17 @@ mod tests { /// A cyphertext encrypted to Alice & Bob, signed by Alice. static ref CTEXT_SIGNED: String = { let mut keyring = Keyring::default(); - keyring.add_owned(KEYS.alice_public.clone()); - keyring.add_ref(&KEYS.bob_public); - pk_encrypt(CLEARTEXT, &keyring, Some(&KEYS.alice_secret)).unwrap() + keyring.add(KEYS.alice_public.clone()); + keyring.add(KEYS.bob_public.clone()); + smol::block_on(pk_encrypt(CLEARTEXT, keyring, Some(KEYS.alice_secret.clone()))).unwrap() }; /// A cyphertext encrypted to Alice & Bob, not signed. static ref CTEXT_UNSIGNED: String = { let mut keyring = Keyring::default(); - keyring.add_owned(KEYS.alice_public.clone()); - keyring.add_ref(&KEYS.bob_public); - pk_encrypt(CLEARTEXT, &keyring, None).unwrap() + keyring.add(KEYS.alice_public.clone()); + keyring.add(KEYS.bob_public.clone()); + smol::block_on(pk_encrypt(CLEARTEXT, keyring, None)).unwrap() }; } @@ -463,20 +479,21 @@ mod tests { assert!(CTEXT_UNSIGNED.starts_with("-----BEGIN PGP MESSAGE-----")); } - #[test] - fn test_decrypt_singed() { + #[async_std::test] + async fn test_decrypt_singed() { // Check decrypting as Alice let mut decrypt_keyring = Keyring::default(); - decrypt_keyring.add_ref(&KEYS.alice_secret); + decrypt_keyring.add(KEYS.alice_secret.clone()); let mut sig_check_keyring = Keyring::default(); - sig_check_keyring.add_ref(&KEYS.alice_public); + sig_check_keyring.add(KEYS.alice_public.clone()); let mut valid_signatures: HashSet = Default::default(); let plain = pk_decrypt( - CTEXT_SIGNED.as_bytes(), - &decrypt_keyring, - &sig_check_keyring, + CTEXT_SIGNED.as_bytes().to_vec(), + decrypt_keyring, + sig_check_keyring, Some(&mut valid_signatures), ) + .await .map_err(|err| println!("{:?}", err)) .unwrap(); assert_eq!(plain, CLEARTEXT); @@ -484,89 +501,94 @@ mod tests { // Check decrypting as Bob let mut decrypt_keyring = Keyring::default(); - decrypt_keyring.add_ref(&KEYS.bob_secret); + decrypt_keyring.add(KEYS.bob_secret.clone()); let mut sig_check_keyring = Keyring::default(); - sig_check_keyring.add_ref(&KEYS.alice_public); + sig_check_keyring.add(KEYS.alice_public.clone()); let mut valid_signatures: HashSet = Default::default(); let plain = pk_decrypt( - CTEXT_SIGNED.as_bytes(), - &decrypt_keyring, - &sig_check_keyring, + CTEXT_SIGNED.as_bytes().to_vec(), + decrypt_keyring, + sig_check_keyring, Some(&mut valid_signatures), ) + .await .map_err(|err| println!("{:?}", err)) .unwrap(); assert_eq!(plain, CLEARTEXT); assert_eq!(valid_signatures.len(), 1); } - #[test] - fn test_decrypt_no_sig_check() { + #[async_std::test] + async fn test_decrypt_no_sig_check() { let mut keyring = Keyring::default(); - keyring.add_ref(&KEYS.alice_secret); + keyring.add(KEYS.alice_secret.clone()); let empty_keyring = Keyring::default(); let mut valid_signatures: HashSet = Default::default(); let plain = pk_decrypt( - CTEXT_SIGNED.as_bytes(), - &keyring, - &empty_keyring, + CTEXT_SIGNED.as_bytes().to_vec(), + keyring, + empty_keyring, Some(&mut valid_signatures), ) + .await .unwrap(); assert_eq!(plain, CLEARTEXT); assert_eq!(valid_signatures.len(), 0); } - #[test] - fn test_decrypt_signed_no_key() { + #[async_std::test] + async fn test_decrypt_signed_no_key() { // The validation does not have the public key of the signer. let mut decrypt_keyring = Keyring::default(); - decrypt_keyring.add_ref(&KEYS.bob_secret); + decrypt_keyring.add(KEYS.bob_secret.clone()); let mut sig_check_keyring = Keyring::default(); - sig_check_keyring.add_ref(&KEYS.bob_public); + sig_check_keyring.add(KEYS.bob_public.clone()); let mut valid_signatures: HashSet = Default::default(); let plain = pk_decrypt( - CTEXT_SIGNED.as_bytes(), - &decrypt_keyring, - &sig_check_keyring, + CTEXT_SIGNED.as_bytes().to_vec(), + decrypt_keyring, + sig_check_keyring, Some(&mut valid_signatures), ) + .await .unwrap(); assert_eq!(plain, CLEARTEXT); assert_eq!(valid_signatures.len(), 0); } - #[test] - fn test_decrypt_unsigned() { + #[async_std::test] + async fn test_decrypt_unsigned() { let mut decrypt_keyring = Keyring::default(); - decrypt_keyring.add_ref(&KEYS.bob_secret); + decrypt_keyring.add(KEYS.bob_secret.clone()); let sig_check_keyring = Keyring::default(); - decrypt_keyring.add_ref(&KEYS.alice_public); + decrypt_keyring.add(KEYS.alice_public.clone()); let mut valid_signatures: HashSet = Default::default(); let plain = pk_decrypt( - CTEXT_UNSIGNED.as_bytes(), - &decrypt_keyring, - &sig_check_keyring, + CTEXT_UNSIGNED.as_bytes().to_vec(), + decrypt_keyring, + sig_check_keyring, Some(&mut valid_signatures), ) + .await .unwrap(); assert_eq!(plain, CLEARTEXT); assert_eq!(valid_signatures.len(), 0); } - #[test] - fn test_decrypt_signed_no_sigret() { + #[async_std::test] + async fn test_decrypt_signed_no_sigret() { // Check decrypting signed cyphertext without providing the HashSet for signatures. let mut decrypt_keyring = Keyring::default(); - decrypt_keyring.add_ref(&KEYS.bob_secret); + decrypt_keyring.add(KEYS.bob_secret.clone()); let mut sig_check_keyring = Keyring::default(); - sig_check_keyring.add_ref(&KEYS.alice_public); + sig_check_keyring.add(KEYS.alice_public.clone()); let plain = pk_decrypt( - CTEXT_SIGNED.as_bytes(), - &decrypt_keyring, - &sig_check_keyring, + CTEXT_SIGNED.as_bytes().to_vec(), + decrypt_keyring, + sig_check_keyring, None, ) + .await .unwrap(); assert_eq!(plain, CLEARTEXT); }