From e524ef5fbc97c0c54b8144aed81c383faa099173 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Mon, 23 Nov 2020 14:31:47 +0100 Subject: openpgp: Make Digest Send + Sync. --- openpgp/src/crypto/backend/cng/hash.rs | 32 +++++++++++++++++++++++++------- openpgp/src/crypto/hash.rs | 2 +- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/openpgp/src/crypto/backend/cng/hash.rs b/openpgp/src/crypto/backend/cng/hash.rs index 22d8ae77..a88c1524 100644 --- a/openpgp/src/crypto/backend/cng/hash.rs +++ b/openpgp/src/crypto/backend/cng/hash.rs @@ -1,4 +1,5 @@ use core::convert::TryFrom; +use std::sync::Mutex; use crate::crypto::hash::Digest; use crate::types::HashAlgorithm; @@ -6,27 +7,44 @@ use crate::{Error, Result}; use win_crypto_ng::hash as cng; -impl Digest for cng::Hash { +struct Hash(Mutex); + +impl From for Hash { + fn from(h: cng::Hash) -> Self { + Hash(Mutex::new(h)) + } +} + +impl Clone for Hash { + fn clone(&self) -> Self { + self.0.lock().expect("Mutex not to be poisoned").clone().into() + } +} + +impl Digest for Hash { fn digest_size(&self) -> usize { - self.hash_size().expect("CNG to not fail internally") + self.0.lock().expect("Mutex not to be poisoned") + .hash_size().expect("CNG to not fail internally") } fn update(&mut self, data: &[u8]) { - let _ = self.hash(data); + let _ = self.0.lock().expect("Mutex not to be poisoned").hash(data); } fn digest(&mut self, digest: &mut [u8]) -> Result<()> { // TODO: Replace with CNG reusable hash objects, supported from Windows 8 // This would allow us to not re-create the CNG hash object each time we // want to finish digest calculation - let algorithm = self.hash_algorithm() + let algorithm = self.0.lock().expect("Mutex not to be poisoned") + .hash_algorithm() .expect("CNG hash object to know its algorithm"); let new = cng::HashAlgorithm::open(algorithm) .expect("CNG to open a new correct hash provider") .new_hash() .expect("Failed to create a new CNG hash object"); - let old = std::mem::replace(self, new); + let old = std::mem::replace( + self.0.get_mut().expect("Mutex not to be poisoned"), new); let buffer = old.finish() .expect("CNG to not fail internally"); @@ -76,8 +94,8 @@ impl HashAlgorithm { let algo = cng::HashAlgorithmId::try_from(self)?; let algo = cng::HashAlgorithm::open(algo)?; - Ok(Box::new(algo.new_hash().expect( + Ok(Box::new(Hash::from(algo.new_hash().expect( "CNG to always create a hasher object for valid algo", - ))) + )))) } } diff --git a/openpgp/src/crypto/hash.rs b/openpgp/src/crypto/hash.rs index e3311b52..8f594e99 100644 --- a/openpgp/src/crypto/hash.rs +++ b/openpgp/src/crypto/hash.rs @@ -31,7 +31,7 @@ use std::io::{self, Write}; const DUMP_HASHED_VALUES: Option<&str> = None; /// Hasher capable of calculating a digest for the input byte stream. -pub(crate) trait Digest: DynClone { +pub(crate) trait Digest: DynClone + Send + Sync { /// Size of the digest in bytes fn digest_size(&self) -> usize; -- cgit v1.2.3