Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

secrecy: Allow opting in to PartialEq/Eq implementations for secrets for testing #632

Open
steven-joruk opened this issue Feb 5, 2021 · 3 comments

Comments

@steven-joruk
Copy link

I would find it useful when unit testing equivalence of values which contain secrets.

I can work around it by manually implementing the traits for my structs which contain secrets, but maybe others would find this useful as well.

Perhaps it should be an opt-in feature flag so that it could support more test project configurations?

@tony-iqlusion
Copy link
Member

How about subtle::ConstantTimeEq as a safe alternative?

It's slightly more cumbersome in that you have to import a trait and use Into to coerce subtle::Choice into a boolean, but it would avoid exposing unsafe APIs just for testing.

@marccarre
Copy link

@steven-joruk, which workaround did you end up using? Mind sharing an example? 🙇🏻‍♂️
@tony-iqlusion, could you share an example of what you'd have in mind for the case of implementing PartialEq/Eq using subtle::Choice? 🙇🏻‍♂️

@Bauxitedev
Copy link

Unfortunately, due to the orphan trait rule, I couldn't find a nice workaround for this, so I just made my own wrapper type and used that instead.

use secrecy::{
    ExposeSecret, Secret, Zeroize,
};

/// Secret<T> wrapper that impls PartialEq and Eq (so you can use it in BTreeSets and such)
pub struct SecretWrapper<T>(pub Secret<T>)
where
    T: Zeroize;

impl<T> SecretWrapper<T>
where
    T: Zeroize,
{
    pub fn new(value: T) -> Self {
        Self(Secret::new(value))
    }
}

impl<T> Eq for SecretWrapper<T> where T: Zeroize + Eq {}
impl<T> PartialEq for SecretWrapper<T>
where
    T: Zeroize + PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.expose_secret() == other.expose_secret()
    }
}

You'll need to impl any other traits you may need (Clone/Debug/etc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants