Cache pgp signature verification results
parent
6086a3789d
commit
13fe64a027
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue