diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-01-03 12:38:49 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-01-03 12:38:49 +0100 |
commit | 7fd9f46fcc4ffb863b02e493fcbe49295564b741 (patch) | |
tree | a86b8710739a873a5ae02ecc4e636567d60b4eca /openpgp/src/crypto | |
parent | ab726285b21cb5b342e14507ef9177f3dcdde775 (diff) |
openpgp: Explicitly implement Eq and Hash if PartialEq is.
- If we don't derive PartialEq, then deriving hash is unsafe.
- See #92.
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r-- | openpgp/src/crypto/mem.rs | 11 | ||||
-rw-r--r-- | openpgp/src/crypto/mpis.rs | 18 |
2 files changed, 26 insertions, 3 deletions
diff --git a/openpgp/src/crypto/mem.rs b/openpgp/src/crypto/mem.rs index a67cf993..4dfe5457 100644 --- a/openpgp/src/crypto/mem.rs +++ b/openpgp/src/crypto/mem.rs @@ -2,6 +2,7 @@ use std::cmp::{min, Ordering}; use std::fmt; +use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut}; use std::pin::Pin; @@ -11,7 +12,7 @@ use memsec; /// /// The memory is guaranteed not to be copied around, and is cleared /// when the object is dropped. -#[derive(Clone, Eq, Hash)] +#[derive(Clone)] pub struct Protected(Pin<Box<[u8]>>); impl PartialEq for Protected { @@ -20,6 +21,14 @@ impl PartialEq for Protected { } } +impl Eq for Protected {} + +impl Hash for Protected { + fn hash<H: Hasher>(&self, state: &mut H) { + self.0.hash(state); + } +} + impl Protected { /// Converts to a buffer for modification. pub unsafe fn into_vec(self) -> Vec<u8> { diff --git a/openpgp/src/crypto/mpis.rs b/openpgp/src/crypto/mpis.rs index 37f75213..4460cc58 100644 --- a/openpgp/src/crypto/mpis.rs +++ b/openpgp/src/crypto/mpis.rs @@ -20,7 +20,7 @@ use crate::Error; use crate::Result; /// Holds a single MPI. -#[derive(Clone, Hash)] +#[derive(Clone)] pub struct MPI { /// Integer value as big-endian. value: Box<[u8]>, @@ -216,10 +216,16 @@ impl PartialEq for MPI { impl Eq for MPI {} +impl std::hash::Hash for MPI { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.value.hash(state); + } +} + /// Holds a single MPI containing secrets. /// /// The memory will be cleared when the object is dropped. -#[derive(Clone, Hash)] +#[derive(Clone)] pub struct ProtectedMPI { /// Integer value as big-endian. value: Protected, @@ -245,6 +251,12 @@ impl From<MPI> for ProtectedMPI { } } +impl std::hash::Hash for ProtectedMPI { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.value.hash(state); + } +} + impl ProtectedMPI { /// Returns the length of the MPI in bits. pub fn bits(&self) -> usize { @@ -481,6 +493,8 @@ impl Arbitrary for PublicKey { /// /// Provides a typed and structured way of storing multiple MPIs in /// packets. +// Deriving Hash here is okay: PartialEq is manually implemented to +// ensure that secrets are compared in constant-time. #[derive(Clone, Hash)] pub enum SecretKeyMaterial { /// RSA secret key. |