diff --git a/Cargo.toml b/Cargo.toml index afe0922..09a9278 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ default = ["reqwest", "rustls-tls"] pkce-plain = [] native-tls = ["reqwest/native-tls"] rustls-tls = ["reqwest/rustls-tls"] +timing-resistant-secret-traits = [] [dependencies] base64 = "0.13" diff --git a/src/types.rs b/src/types.rs index b11d827..398353f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,8 @@ use std::convert::Into; use std::fmt::Error as FormatterError; use std::fmt::{Debug, Formatter}; +#[cfg(feature = "timing-resistant-secret-traits")] +use std::hash::{Hash, Hasher}; use std::ops::Deref; use rand::{thread_rng, Rng}; @@ -148,6 +150,7 @@ macro_rules! new_secret_type { $( #[$attr] )* + #[cfg_attr(feature = "timing-resistant-secret-traits", derive(Eq))] pub struct $name($type); impl $name { $($item)* @@ -170,6 +173,21 @@ macro_rules! new_secret_type { write!(f, concat!(stringify!($name), "([redacted])")) } } + + #[cfg(feature = "timing-resistant-secret-traits")] + impl PartialEq for $name { + fn eq(&self, other: &Self) -> bool { + Sha256::digest(&self.0) == Sha256::digest(&other.0) + } + } + + #[cfg(feature = "timing-resistant-secret-traits")] + impl Hash for $name { + fn hash(&self, state: &mut H) { + Sha256::digest(&self.0).hash(state) + } + } + }; }