simplify argon init

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-06-25 00:03:05 +00:00
parent bd19fac4c5
commit 06f01d384f
2 changed files with 20 additions and 31 deletions

View file

@ -1,4 +1,4 @@
use std::sync::Mutex; use std::sync::OnceLock;
use argon2::{ use argon2::{
password_hash, password_hash::SaltString, Algorithm, Argon2, Params, PasswordHash, PasswordHasher, password_hash, password_hash::SaltString, Algorithm, Argon2, Params, PasswordHash, PasswordHasher,
@ -9,10 +9,24 @@ const M_COST: u32 = Params::DEFAULT_M_COST; // memory size in 1 KiB blocks
const T_COST: u32 = Params::DEFAULT_T_COST; // nr of iterations const T_COST: u32 = Params::DEFAULT_T_COST; // nr of iterations
const P_COST: u32 = Params::DEFAULT_P_COST; // parallelism const P_COST: u32 = Params::DEFAULT_P_COST; // parallelism
static STATE: Mutex<Option<Argon2<'static>>> = Mutex::new(None); static ARGON: OnceLock<Argon2<'static>> = OnceLock::new();
#[allow(clippy::let_underscore_must_use)] pub fn password(password: &str) -> Result<String, password_hash::Error> {
pub fn init() { let salt = SaltString::generate(rand::thread_rng());
ARGON
.get_or_init(init_argon)
.hash_password(password.as_bytes(), &salt)
.map(|it| it.to_string())
}
pub fn verify_password(password: &str, password_hash: &str) -> Result<(), password_hash::Error> {
let password_hash = PasswordHash::new(password_hash)?;
ARGON
.get_or_init(init_argon)
.verify_password(password.as_bytes(), &password_hash)
}
fn init_argon() -> Argon2<'static> {
// 19456 Kib blocks, iterations = 2, parallelism = 1 // 19456 Kib blocks, iterations = 2, parallelism = 1
// * <https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id> // * <https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id>
debug_assert!(M_COST == 19_456, "M_COST default changed"); debug_assert!(M_COST == 19_456, "M_COST default changed");
@ -23,29 +37,7 @@ pub fn init() {
let version = Version::default(); let version = Version::default();
let out_len: Option<usize> = None; let out_len: Option<usize> = None;
let params = Params::new(M_COST, T_COST, P_COST, out_len).expect("valid parameters"); let params = Params::new(M_COST, T_COST, P_COST, out_len).expect("valid parameters");
let state = Argon2::new(algorithm, version, params); Argon2::new(algorithm, version, params)
_ = STATE.lock().expect("hashing state locked").insert(state);
}
pub fn password(password: &str) -> Result<String, password_hash::Error> {
let salt = SaltString::generate(rand::thread_rng());
STATE
.lock()
.expect("hashing state locked")
.as_ref()
.expect("hashing state initialized")
.hash_password(password.as_bytes(), &salt)
.map(|it| it.to_string())
}
pub fn verify_password(password: &str, password_hash: &str) -> Result<(), password_hash::Error> {
let password_hash = PasswordHash::new(password_hash)?;
STATE
.lock()
.expect("hashing state locked")
.as_ref()
.expect("hashing state initialized")
.verify_password(password.as_bytes(), &password_hash)
} }
#[cfg(test)] #[cfg(test)]
@ -53,7 +45,6 @@ mod tests {
#[test] #[test]
fn password_hash_and_verify() { fn password_hash_and_verify() {
use crate::utils::hash; use crate::utils::hash;
hash::init();
let preimage = "temp123"; let preimage = "temp123";
let digest = hash::password(preimage).expect("digest"); let digest = hash::password(preimage).expect("digest");
hash::verify_password(preimage, &digest).expect("verified"); hash::verify_password(preimage, &digest).expect("verified");
@ -63,7 +54,6 @@ mod tests {
#[should_panic(expected = "unverified")] #[should_panic(expected = "unverified")]
fn password_hash_and_verify_fail() { fn password_hash_and_verify_fail() {
use crate::utils::hash; use crate::utils::hash;
hash::init();
let preimage = "temp123"; let preimage = "temp123";
let fakeimage = "temp321"; let fakeimage = "temp321";
let digest = hash::password(preimage).expect("digest"); let digest = hash::password(preimage).expect("digest");

View file

@ -4,7 +4,7 @@ use conduit::{
config::Config, config::Config,
info, info,
log::{self}, log::{self},
utils::{hash, sys}, utils::sys,
Error, Result, Error, Result,
}; };
use tokio::runtime; use tokio::runtime;
@ -39,7 +39,6 @@ impl Server {
#[cfg(unix)] #[cfg(unix)]
sys::maximize_fd_limit().expect("Unable to increase maximum soft and hard file descriptor limit"); sys::maximize_fd_limit().expect("Unable to increase maximum soft and hard file descriptor limit");
hash::init();
info!( info!(
server_name = %config.server_name, server_name = %config.server_name,