diff options
Diffstat (limited to 'src/identity.rs')
-rw-r--r-- | src/identity.rs | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/src/identity.rs b/src/identity.rs index 90d4fad..fd46b85 100644 --- a/src/identity.rs +++ b/src/identity.rs @@ -1,5 +1,7 @@ use crate::prelude::*; +use sha1::Digest as _; + pub struct Identity { pub email: String, pub keys: crate::locked::Keys, @@ -10,8 +12,13 @@ impl Identity { pub fn new( email: &str, password: &crate::locked::Password, + kdf: crate::api::KdfType, iterations: u32, + memory: Option<u32>, + parallelism: Option<u32>, ) -> Result<Self> { + let email = email.trim().to_lowercase(); + let iterations = std::num::NonZeroU32::new(iterations) .ok_or(Error::Pbkdf2ZeroIterations)?; @@ -19,12 +26,43 @@ impl Identity { keys.extend(std::iter::repeat(0).take(64)); let enc_key = &mut keys.data_mut()[0..32]; - pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>( - password.password(), - email.as_bytes(), - iterations.get(), - enc_key, - ); + + match kdf { + crate::api::KdfType::Pbkdf2 => { + pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>( + password.password(), + email.as_bytes(), + iterations.get(), + enc_key, + ) + .map_err(|_| Error::Pbkdf2)?; + } + + crate::api::KdfType::Argon2id => { + let mut hasher = sha2::Sha256::new(); + hasher.update(email.as_bytes()); + let salt = hasher.finalize(); + + let argon2_config = argon2::Argon2::new( + argon2::Algorithm::Argon2id, + argon2::Version::V0x13, + argon2::Params::new( + memory.unwrap() * 1024, + iterations.get(), + parallelism.unwrap(), + Some(32), + ) + .unwrap(), + ); + argon2::Argon2::hash_password_into( + &argon2_config, + password.password(), + &salt, + enc_key, + ) + .map_err(|_| Error::Argon2)?; + } + }; let mut hash = crate::locked::Vec::new(); hash.extend(std::iter::repeat(0).take(32)); @@ -33,7 +71,8 @@ impl Identity { password.password(), 1, hash.data_mut(), - ); + ) + .map_err(|_| Error::Pbkdf2)?; let hkdf = hkdf::Hkdf::<sha2::Sha256>::from_prk(enc_key) .map_err(|_| Error::HkdfExpand)?; |