mirror of
https://github.com/chatmail/core.git
synced 2026-04-21 15:36:30 +03:00
refactor: use slices and vectors instead of Keyring wrapper
This change removes all traces of dc_keyring_t, which was a C implementation of dynamically sized array.
This commit is contained in:
76
src/pgp.rs
76
src/pgp.rs
@@ -20,7 +20,6 @@ use tokio::runtime::Handle;
|
||||
|
||||
use crate::constants::KeyGenType;
|
||||
use crate::key::{DcKey, Fingerprint};
|
||||
use crate::keyring::Keyring;
|
||||
use crate::tools::EmailAddress;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
@@ -229,7 +228,7 @@ fn select_pk_for_encryption(key: &SignedPublicKey) -> Option<SignedPublicKeyOrSu
|
||||
/// and signs it using `private_key_for_signing`.
|
||||
pub async fn pk_encrypt(
|
||||
plain: &[u8],
|
||||
public_keys_for_encryption: Keyring<SignedPublicKey>,
|
||||
public_keys_for_encryption: Vec<SignedPublicKey>,
|
||||
private_key_for_signing: Option<SignedSecretKey>,
|
||||
) -> Result<String> {
|
||||
let lit_msg = Message::new_literal_bytes("", plain);
|
||||
@@ -237,7 +236,6 @@ pub async fn pk_encrypt(
|
||||
Handle::current()
|
||||
.spawn_blocking(move || {
|
||||
let pkeys: Vec<SignedPublicKeyOrSubkey> = public_keys_for_encryption
|
||||
.keys()
|
||||
.iter()
|
||||
.filter_map(select_pk_for_encryption)
|
||||
.collect();
|
||||
@@ -288,15 +286,15 @@ pub fn pk_calc_signature(
|
||||
#[allow(clippy::implicit_hasher)]
|
||||
pub fn pk_decrypt(
|
||||
ctext: Vec<u8>,
|
||||
private_keys_for_decryption: &Keyring<SignedSecretKey>,
|
||||
public_keys_for_validation: &Keyring<SignedPublicKey>,
|
||||
private_keys_for_decryption: &[SignedSecretKey],
|
||||
public_keys_for_validation: &[SignedPublicKey],
|
||||
) -> Result<(Vec<u8>, HashSet<Fingerprint>)> {
|
||||
let mut ret_signature_fingerprints: HashSet<Fingerprint> = Default::default();
|
||||
|
||||
let cursor = Cursor::new(ctext);
|
||||
let (msg, _) = Message::from_armor_single(cursor)?;
|
||||
|
||||
let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption.keys().iter().collect();
|
||||
let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption.iter().collect();
|
||||
|
||||
let (decryptor, _) = msg.decrypt(|| "".into(), &skeys[..])?;
|
||||
let msgs = decryptor.collect::<pgp::errors::Result<Vec<_>>>()?;
|
||||
@@ -311,20 +309,13 @@ pub fn pk_decrypt(
|
||||
None => bail!("The decrypted message is empty"),
|
||||
};
|
||||
|
||||
if !public_keys_for_validation.is_empty() {
|
||||
let pkeys = public_keys_for_validation.keys();
|
||||
|
||||
let mut fingerprints: Vec<Fingerprint> = Vec::new();
|
||||
if let signed_msg @ pgp::composed::Message::Signed { .. } = msg {
|
||||
for pkey in pkeys {
|
||||
if signed_msg.verify(&pkey.primary_key).is_ok() {
|
||||
let fp = DcKey::fingerprint(pkey);
|
||||
fingerprints.push(fp);
|
||||
}
|
||||
if let signed_msg @ pgp::composed::Message::Signed { .. } = msg {
|
||||
for pkey in public_keys_for_validation {
|
||||
if signed_msg.verify(&pkey.primary_key).is_ok() {
|
||||
let fp = DcKey::fingerprint(pkey);
|
||||
ret_signature_fingerprints.insert(fp);
|
||||
}
|
||||
}
|
||||
|
||||
ret_signature_fingerprints.extend(fingerprints);
|
||||
}
|
||||
Ok((content, ret_signature_fingerprints))
|
||||
} else {
|
||||
@@ -336,12 +327,11 @@ pub fn pk_decrypt(
|
||||
pub fn pk_validate(
|
||||
content: &[u8],
|
||||
signature: &[u8],
|
||||
public_keys_for_validation: &Keyring<SignedPublicKey>,
|
||||
public_keys_for_validation: &[SignedPublicKey],
|
||||
) -> Result<HashSet<Fingerprint>> {
|
||||
let mut ret: HashSet<Fingerprint> = Default::default();
|
||||
|
||||
let standalone_signature = StandaloneSignature::from_armor_single(Cursor::new(signature))?.0;
|
||||
let pkeys = public_keys_for_validation.keys();
|
||||
|
||||
// Remove trailing CRLF before the delimiter.
|
||||
// According to RFC 3156 it is considered to be part of the MIME delimiter for the purpose of
|
||||
@@ -350,7 +340,7 @@ pub fn pk_validate(
|
||||
.get(..content.len().saturating_sub(2))
|
||||
.context("index is out of range")?;
|
||||
|
||||
for pkey in pkeys {
|
||||
for pkey in public_keys_for_validation {
|
||||
if standalone_signature.verify(pkey, content).is_ok() {
|
||||
let fp = DcKey::fingerprint(pkey);
|
||||
ret.insert(fp);
|
||||
@@ -485,9 +475,7 @@ mod tests {
|
||||
async fn ctext_signed() -> &'static String {
|
||||
CTEXT_SIGNED
|
||||
.get_or_init(|| async {
|
||||
let mut keyring = Keyring::new();
|
||||
keyring.add(KEYS.alice_public.clone());
|
||||
keyring.add(KEYS.bob_public.clone());
|
||||
let keyring = vec![KEYS.alice_public.clone(), KEYS.bob_public.clone()];
|
||||
|
||||
pk_encrypt(CLEARTEXT, keyring, Some(KEYS.alice_secret.clone()))
|
||||
.await
|
||||
@@ -500,9 +488,7 @@ mod tests {
|
||||
async fn ctext_unsigned() -> &'static String {
|
||||
CTEXT_UNSIGNED
|
||||
.get_or_init(|| async {
|
||||
let mut keyring = Keyring::new();
|
||||
keyring.add(KEYS.alice_public.clone());
|
||||
keyring.add(KEYS.bob_public.clone());
|
||||
let keyring = vec![KEYS.alice_public.clone(), KEYS.bob_public.clone()];
|
||||
pk_encrypt(CLEARTEXT, keyring, None).await.unwrap()
|
||||
})
|
||||
.await
|
||||
@@ -527,10 +513,8 @@ mod tests {
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_decrypt_singed() {
|
||||
// Check decrypting as Alice
|
||||
let mut decrypt_keyring: Keyring<SignedSecretKey> = Keyring::new();
|
||||
decrypt_keyring.add(KEYS.alice_secret.clone());
|
||||
let mut sig_check_keyring: Keyring<SignedPublicKey> = Keyring::new();
|
||||
sig_check_keyring.add(KEYS.alice_public.clone());
|
||||
let decrypt_keyring = vec![KEYS.alice_secret.clone()];
|
||||
let sig_check_keyring = vec![KEYS.alice_public.clone()];
|
||||
let (plain, valid_signatures) = pk_decrypt(
|
||||
ctext_signed().await.as_bytes().to_vec(),
|
||||
&decrypt_keyring,
|
||||
@@ -541,10 +525,8 @@ mod tests {
|
||||
assert_eq!(valid_signatures.len(), 1);
|
||||
|
||||
// Check decrypting as Bob
|
||||
let mut decrypt_keyring = Keyring::new();
|
||||
decrypt_keyring.add(KEYS.bob_secret.clone());
|
||||
let mut sig_check_keyring = Keyring::new();
|
||||
sig_check_keyring.add(KEYS.alice_public.clone());
|
||||
let decrypt_keyring = vec![KEYS.bob_secret.clone()];
|
||||
let sig_check_keyring = vec![KEYS.alice_public.clone()];
|
||||
let (plain, valid_signatures) = pk_decrypt(
|
||||
ctext_signed().await.as_bytes().to_vec(),
|
||||
&decrypt_keyring,
|
||||
@@ -557,15 +539,9 @@ mod tests {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_decrypt_no_sig_check() {
|
||||
let mut keyring = Keyring::new();
|
||||
keyring.add(KEYS.alice_secret.clone());
|
||||
let empty_keyring = Keyring::new();
|
||||
let (plain, valid_signatures) = pk_decrypt(
|
||||
ctext_signed().await.as_bytes().to_vec(),
|
||||
&keyring,
|
||||
&empty_keyring,
|
||||
)
|
||||
.unwrap();
|
||||
let keyring = vec![KEYS.alice_secret.clone()];
|
||||
let (plain, valid_signatures) =
|
||||
pk_decrypt(ctext_signed().await.as_bytes().to_vec(), &keyring, &[]).unwrap();
|
||||
assert_eq!(plain, CLEARTEXT);
|
||||
assert_eq!(valid_signatures.len(), 0);
|
||||
}
|
||||
@@ -573,10 +549,8 @@ mod tests {
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_decrypt_signed_no_key() {
|
||||
// The validation does not have the public key of the signer.
|
||||
let mut decrypt_keyring = Keyring::new();
|
||||
decrypt_keyring.add(KEYS.bob_secret.clone());
|
||||
let mut sig_check_keyring = Keyring::new();
|
||||
sig_check_keyring.add(KEYS.bob_public.clone());
|
||||
let decrypt_keyring = vec![KEYS.bob_secret.clone()];
|
||||
let sig_check_keyring = vec![KEYS.bob_public.clone()];
|
||||
let (plain, valid_signatures) = pk_decrypt(
|
||||
ctext_signed().await.as_bytes().to_vec(),
|
||||
&decrypt_keyring,
|
||||
@@ -589,13 +563,11 @@ mod tests {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_decrypt_unsigned() {
|
||||
let mut decrypt_keyring = Keyring::new();
|
||||
decrypt_keyring.add(KEYS.bob_secret.clone());
|
||||
let sig_check_keyring = Keyring::new();
|
||||
let decrypt_keyring = vec![KEYS.bob_secret.clone()];
|
||||
let (plain, valid_signatures) = pk_decrypt(
|
||||
ctext_unsigned().await.as_bytes().to_vec(),
|
||||
&decrypt_keyring,
|
||||
&sig_check_keyring,
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(plain, CLEARTEXT);
|
||||
|
||||
Reference in New Issue
Block a user