diff options
Diffstat (limited to 'crates/secd/src/util/crypter.rs')
| -rw-r--r-- | crates/secd/src/util/crypter.rs | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/crates/secd/src/util/crypter.rs b/crates/secd/src/util/crypter.rs index 1717377..e5ec796 100644 --- a/crates/secd/src/util/crypter.rs +++ b/crates/secd/src/util/crypter.rs @@ -3,8 +3,8 @@ use aes_gcm::{ Aes256Gcm, Nonce, }; use argon2::{ - password_hash::{self, SaltString}, - Argon2, PasswordHasher, + password_hash::{Salt, SaltString}, + Argon2, PasswordHash, PasswordHasher, }; use derive_more::Display; use rand::Rng; @@ -13,10 +13,10 @@ use thiserror::Error; #[derive(Debug, Display, Error)] pub enum CrypterError { - EncryptError(String), - DecryptError(String), - DecodeError(String), - HashError(String), + Encrypt(String), + Decrypt(String), + Decode(String), + Hash(String), } pub struct Crypter { @@ -37,8 +37,8 @@ impl Crypter { let rbs = rand::thread_rng().gen::<[u8; 12]>(); let iv = Nonce::from_slice(&rbs); let crypt = cipher - .encrypt(&iv, data) - .map_err(|e| CrypterError::EncryptError(e.to_string()))?; + .encrypt(iv, data) + .map_err(|e| CrypterError::Encrypt(e.to_string()))?; let mut msg = iv.to_vec(); msg.extend_from_slice(&crypt); @@ -53,19 +53,36 @@ impl Crypter { let iv = Nonce::from_slice(&data[0..=11]); let data = &data[12..]; - Ok(cipher - .decrypt(&iv, data) - .map_err(|e| CrypterError::DecryptError(e.to_string()))?) + cipher + .decrypt(iv, data) + .map_err(|e| CrypterError::Decrypt(e.to_string())) } - pub fn hash(&self, data: &[u8]) -> Result<String, CrypterError> { - let salt = SaltString::generate(&mut OsRng); + /// Hash data. + /// If a candidate is provided, then use that candidate's salt, passed as a full phc string. + pub fn hash(&self, data: &[u8], phc_candidate: Option<&str>) -> Result<String, CrypterError> { + let salt = match phc_candidate { + None => SaltString::generate(&mut OsRng).as_str().to_owned(), + Some(phc) => PasswordHash::new(phc) + .map_err(|e| CrypterError::Hash(e.to_string()))? + .salt.expect("unreachable fbacabb8-082a-423a-abff-06a961dc5828 [no salt found means a forced error since all resources, even those of high entropy, are salted]").as_str().to_owned(), + }; + let hasher = Argon2::default(); Ok(hasher - .hash_password(data, &salt) - .map_err(|e| CrypterError::HashError(e.to_string()))? + .hash_password( + data, + Salt::from_b64(&salt).map_err(|e| CrypterError::Hash(e.to_string()))?, + ) + .map_err(|e| CrypterError::Hash(e.to_string()))? .to_string()) } + + pub fn weak_hash(&self, data: &[u8]) -> Result<String, CrypterError> { + let mut hasher = Sha256::new(); + hasher.update(data); + Ok(hex::encode(hasher.finalize())) + } } #[cfg(test)] |
