aboutsummaryrefslogtreecommitdiff
path: root/crates/secd/src/util/crypter.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/secd/src/util/crypter.rs')
-rw-r--r--crates/secd/src/util/crypter.rs47
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)]