/rust/registry/src/index.crates.io-1949cf8c6b5b557f/password-hash-0.5.0/src/traits.rs
Line | Count | Source |
1 | | //! Trait definitions. |
2 | | |
3 | | use crate::{Decimal, Error, Ident, ParamsString, PasswordHash, Result, Salt}; |
4 | | use core::fmt::Debug; |
5 | | |
6 | | /// Trait for password hashing functions. |
7 | | pub trait PasswordHasher { |
8 | | /// Algorithm-specific parameters. |
9 | | type Params: Clone |
10 | | + Debug |
11 | | + Default |
12 | | + for<'a> TryFrom<&'a PasswordHash<'a>, Error = Error> |
13 | | + TryInto<ParamsString, Error = Error>; |
14 | | |
15 | | /// Compute a [`PasswordHash`] from the provided password using an |
16 | | /// explicit set of customized algorithm parameters as opposed to the |
17 | | /// defaults. |
18 | | /// |
19 | | /// When in doubt, use [`PasswordHasher::hash_password`] instead. |
20 | | fn hash_password_customized<'a>( |
21 | | &self, |
22 | | password: &[u8], |
23 | | algorithm: Option<Ident<'a>>, |
24 | | version: Option<Decimal>, |
25 | | params: Self::Params, |
26 | | salt: impl Into<Salt<'a>>, |
27 | | ) -> Result<PasswordHash<'a>>; |
28 | | |
29 | | /// Simple API for computing a [`PasswordHash`] from a password and |
30 | | /// salt value. |
31 | | /// |
32 | | /// Uses the default recommended parameters for a given algorithm. |
33 | 0 | fn hash_password<'a>( |
34 | 0 | &self, |
35 | 0 | password: &[u8], |
36 | 0 | salt: impl Into<Salt<'a>>, |
37 | 0 | ) -> Result<PasswordHash<'a>> { |
38 | 0 | self.hash_password_customized(password, None, None, Self::Params::default(), salt) |
39 | 0 | } Unexecuted instantiation: <pbkdf2::simple::Pbkdf2 as password_hash::traits::PasswordHasher>::hash_password::<&password_hash::salt::SaltString> Unexecuted instantiation: <scrypt::simple::Scrypt as password_hash::traits::PasswordHasher>::hash_password::<&password_hash::salt::SaltString> Unexecuted instantiation: <_ as password_hash::traits::PasswordHasher>::hash_password::<_> |
40 | | } |
41 | | |
42 | | /// Trait for password verification. |
43 | | /// |
44 | | /// Automatically impl'd for any type that impls [`PasswordHasher`]. |
45 | | /// |
46 | | /// This trait is object safe and can be used to implement abstractions over |
47 | | /// multiple password hashing algorithms. One such abstraction is provided by |
48 | | /// the [`PasswordHash::verify_password`] method. |
49 | | pub trait PasswordVerifier { |
50 | | /// Compute this password hashing function against the provided password |
51 | | /// using the parameters from the provided password hash and see if the |
52 | | /// computed output matches. |
53 | | fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()>; |
54 | | } |
55 | | |
56 | | impl<T: PasswordHasher> PasswordVerifier for T { |
57 | 0 | fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()> { |
58 | 0 | if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { |
59 | 0 | let computed_hash = self.hash_password_customized( |
60 | 0 | password, |
61 | 0 | Some(hash.algorithm), |
62 | 0 | hash.version, |
63 | 0 | T::Params::try_from(hash)?, |
64 | 0 | *salt, |
65 | 0 | )?; |
66 | | |
67 | 0 | if let Some(computed_output) = &computed_hash.hash { |
68 | | // See notes on `Output` about the use of a constant-time comparison |
69 | 0 | if expected_output == computed_output { |
70 | 0 | return Ok(()); |
71 | 0 | } |
72 | 0 | } |
73 | 0 | } |
74 | | |
75 | 0 | Err(Error::Password) |
76 | 0 | } Unexecuted instantiation: <argon2::Argon2 as password_hash::traits::PasswordVerifier>::verify_password Unexecuted instantiation: <_ as password_hash::traits::PasswordVerifier>::verify_password |
77 | | } |
78 | | |
79 | | /// Trait for password hashing algorithms which support the legacy |
80 | | /// [Modular Crypt Format (MCF)][MCF]. |
81 | | /// |
82 | | /// [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html |
83 | | pub trait McfHasher { |
84 | | /// Upgrade an MCF hash to a PHC hash. MCF follow this rough format: |
85 | | /// |
86 | | /// ```text |
87 | | /// $<id>$<content> |
88 | | /// ``` |
89 | | /// |
90 | | /// MCF hashes are otherwise largely unstructured and parsed according to |
91 | | /// algorithm-specific rules so hashers must parse a raw string themselves. |
92 | | fn upgrade_mcf_hash<'a>(&self, hash: &'a str) -> Result<PasswordHash<'a>>; |
93 | | |
94 | | /// Verify a password hash in MCF format against the provided password. |
95 | 0 | fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<()> |
96 | 0 | where |
97 | 0 | Self: PasswordVerifier, |
98 | | { |
99 | 0 | self.verify_password(password, &self.upgrade_mcf_hash(mcf_hash)?) |
100 | 0 | } |
101 | | } |