Skip to main content

ravenrs_app/security/
password.rs

1//! Keeping passwords so that what is kept does not give them away.
2
3use argon2::Argon2;
4use argon2::password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString};
5
6/// The longest password taken, in bytes, so a huge one cannot be used to keep the machine busy.
7const MOST_BYTES: usize = 1024;
8
9/// What is kept for a password: Argon2id, with its parameters and a salt of its own, in the usual
10/// text form. A new v4 UUID is 122 random bits from the system.
11pub fn hash_password(password: &str) -> Result<String, String> {
12    if password.len() > MOST_BYTES {
13        return Err("the password is too long".to_owned());
14    }
15    let salt = SaltString::encode_b64(uuid::Uuid::new_v4().as_bytes()).map_err(|e| e.to_string())?;
16    Argon2::default()
17        .hash_password(password.as_bytes(), &salt)
18        .map(|hash| hash.to_string())
19        .map_err(|e| e.to_string())
20}
21
22/// Whether this password is the one this was made from. Something unreadable matches nothing.
23pub fn verify_password(password: &str, hash: &str) -> bool {
24    if password.len() > MOST_BYTES {
25        return false;
26    }
27    PasswordHash::new(hash)
28        .is_ok_and(|parsed| Argon2::default().verify_password(password.as_bytes(), &parsed).is_ok())
29}