Cache pgp signature verification results

async-cursors
Manos Pitsidianakis 2023-07-13 17:18:13 +03:00
parent 6086a3789d
commit 13fe64a027
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
4 changed files with 45 additions and 12 deletions

View File

@ -19,7 +19,13 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
use std::{future::Future, pin::Pin};
use std::{
collections::{hash_map::DefaultHasher, BTreeMap},
future::Future,
hash::{Hash, Hasher},
pin::Pin,
sync::{Arc, Mutex},
};
use melib::{
email::{
@ -38,13 +44,40 @@ pub async fn decrypt(raw: Vec<u8>) -> Result<(melib_pgp::DecryptionMetadata, Vec
ctx.decrypt(cipher)?.await
}
pub async fn verify(a: Attachment) -> Result<()> {
pub fn verify(a: Attachment) -> impl Future<Output = Result<()>> {
thread_local! {
static CACHE: Arc<Mutex<BTreeMap<u64, Result<()>>>> = Arc::new(Mutex::new(BTreeMap::new()));
}
let hash_mtx = CACHE.with(|cache| cache.clone());
verify_inner(a, hash_mtx)
}
async fn verify_inner(a: Attachment, cache: Arc<Mutex<BTreeMap<u64, Result<()>>>>) -> Result<()> {
let mut hasher = DefaultHasher::new();
a.hash(&mut hasher);
let attachment_hash: u64 = hasher.finish();
{
let lck = cache.lock().unwrap();
let in_cache: bool = lck.contains_key(&attachment_hash);
if in_cache {
return lck[&attachment_hash].clone();
}
}
let (data, sig) =
melib_pgp::verify_signature(&a).chain_err_summary(|| "Could not verify signature.")?;
let mut ctx = Context::new()?;
let sig = ctx.new_data_mem(sig.body().trim())?;
let data = ctx.new_data_mem(&data)?;
ctx.verify(sig, data)?.await
let result = ctx.verify(sig, data)?.await;
{
let mut lck = cache.lock().unwrap();
lck.insert(attachment_hash, result.clone());
}
result
}
pub fn sign_filter(

View File

@ -394,7 +394,7 @@ impl TryFrom<&str> for Address {
}
/// Helper struct to return slices from a struct field on demand.
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq, Eq, Copy)]
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq, Eq, Copy, Hash)]
pub struct StrBuilder {
pub offset: usize,
pub length: usize,

View File

@ -28,7 +28,7 @@ use crate::email::{
parser::BytesExt,
};
#[derive(Clone, Default, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Default, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub enum Charset {
Ascii,
#[default]
@ -197,7 +197,7 @@ impl Display for Charset {
}
}
#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub enum MultipartType {
Alternative,
Digest,
@ -245,7 +245,7 @@ impl From<&[u8]> for MultipartType {
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum ContentType {
Text {
kind: Text,
@ -441,7 +441,7 @@ impl ContentType {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub enum Text {
Plain,
Html,
@ -466,7 +466,7 @@ impl Display for Text {
}
}
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum ContentTransferEncoding {
#[default]
_8Bit,
@ -509,7 +509,7 @@ impl From<&[u8]> for ContentTransferEncoding {
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct ContentDisposition {
pub kind: ContentDispositionKind,
pub filename: Option<String>,
@ -520,7 +520,7 @@ pub struct ContentDisposition {
pub parameter: Vec<String>,
}
#[derive(Clone, Default, Debug, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Default, Debug, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum ContentDispositionKind {
#[default]
Inline,

View File

@ -387,7 +387,7 @@ impl From<AttachmentBuilder> for Attachment {
}
/// Immutable attachment type.
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Serialize, Deserialize, PartialEq, Hash, Eq)]
pub struct Attachment {
pub content_type: ContentType,
pub content_transfer_encoding: ContentTransferEncoding,