switch to RustCrypto's argon2 crate

This commit is contained in:
Charles Hall 2024-06-02 17:52:43 -07:00
parent 60d32ddf48
commit aa4cd8b1e1
No known key found for this signature in database
GPG key ID: 7B8E0645816E07CF
6 changed files with 58 additions and 58 deletions

View file

@ -113,11 +113,7 @@ pub(crate) async fn login_route(
));
}
let hash_matches =
argon2::verify_encoded(&hash, password.as_bytes())
.unwrap_or(false);
if !hash_matches {
if !utils::verify_password_hash(hash, password) {
return Err(Error::BadRequest(
ErrorKind::forbidden(),
"Wrong username or password.",

View file

@ -584,10 +584,9 @@ impl KeyValueDatabase {
for (userid, password) in db.userid_password.iter() {
let password = utils::string_from_bytes(&password);
let empty_hashed_password =
password.map_or(false, |password| {
argon2::verify_encoded(&password, b"")
.unwrap_or(false)
let empty_hashed_password = password
.map_or(false, |password| {
utils::verify_password_hash("", password)
});
if empty_hashed_password {

View file

@ -87,11 +87,7 @@ impl Service {
// Check if password is correct
if let Some(hash) = services().users.password_hash(&user_id)? {
let hash_matches =
argon2::verify_encoded(&hash, password.as_bytes())
.unwrap_or(false);
if !hash_matches {
if !utils::verify_password_hash(hash, password) {
uiaainfo.auth_error =
Some(ruma::api::client::error::StandardErrorBody {
kind: ErrorKind::forbidden(),

View file

@ -7,9 +7,9 @@ use std::{
time::{SystemTime, UNIX_EPOCH},
};
use argon2::{Config, Variant};
use argon2::{password_hash, Argon2, PasswordHasher, PasswordVerifier};
use cmp::Ordering;
use rand::prelude::*;
use rand::{prelude::*, rngs::OsRng};
use ring::digest;
use ruma::{
canonical_json::try_from_json_map, CanonicalJsonError, CanonicalJsonObject,
@ -72,16 +72,33 @@ pub(crate) fn random_string(length: usize) -> String {
}
/// Calculate a new hash for the given password
pub(crate) fn calculate_password_hash(
password: &str,
) -> Result<String, argon2::Error> {
let hashing_config = Config {
variant: Variant::Argon2id,
..Default::default()
pub(crate) fn calculate_password_hash<B>(
password: B,
) -> Result<password_hash::PasswordHashString, password_hash::Error>
where
B: AsRef<[u8]>,
{
Argon2::default()
.hash_password(
password.as_ref(),
&password_hash::SaltString::generate(&mut OsRng),
)
.map(|x| x.serialize())
}
/// Compare a password to a hash
///
/// Returns `true` if the password matches the hash, `false` otherwise.
pub(crate) fn verify_password_hash<S, B>(hash: S, password: B) -> bool
where
S: AsRef<str>,
B: AsRef<[u8]>,
{
let Ok(hash) = password_hash::PasswordHash::new(hash.as_ref()) else {
return false;
};
let salt = random_string(32);
argon2::hash_encoded(password.as_bytes(), salt.as_bytes(), &hashing_config)
Argon2::default().verify_password(password.as_ref(), &hash).is_ok()
}
#[tracing::instrument(skip(keys))]