2023-06-01 11:42:35 +00:00
|
|
|
use entity::master_pass;
|
2023-06-11 10:05:20 +00:00
|
|
|
use once_cell::sync::Lazy;
|
2023-06-01 11:42:35 +00:00
|
|
|
use rand::{rngs::OsRng, RngCore};
|
|
|
|
use scrypt::{scrypt, Params};
|
|
|
|
use sea_orm::ActiveValue::Set;
|
2023-06-06 17:04:39 +00:00
|
|
|
use subtle::ConstantTimeEq;
|
2023-06-01 11:42:35 +00:00
|
|
|
|
2023-06-11 10:05:20 +00:00
|
|
|
static PARAMS: Lazy<Params> = Lazy::new(|| Params::new(14, 8, 1, 64).unwrap());
|
|
|
|
|
2023-06-01 11:42:35 +00:00
|
|
|
/// Hashes the password with Scrypt with the given salt
|
|
|
|
#[inline]
|
|
|
|
fn hash_password(password: &[u8], salt: &[u8]) -> [u8; 64] {
|
|
|
|
let mut password_hash = [0; 64];
|
2023-06-11 10:05:20 +00:00
|
|
|
scrypt(password, salt, &PARAMS, &mut password_hash).unwrap();
|
2023-06-01 11:42:35 +00:00
|
|
|
password_hash
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait VerifyMasterPassExt {
|
|
|
|
fn verify(&self, password: &str) -> bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VerifyMasterPassExt for master_pass::Model {
|
|
|
|
/// Checks that the given password hash matches the one of the model
|
|
|
|
#[inline]
|
|
|
|
fn verify(&self, password: &str) -> bool {
|
|
|
|
let hashed = hash_password(password.as_bytes(), &self.salt);
|
2023-06-06 17:04:39 +00:00
|
|
|
hashed.ct_eq(&self.password_hash).into()
|
2023-06-01 11:42:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait MasterPassFromUnencryptedExt {
|
|
|
|
fn from_unencrypted(user_id: u64, password: &str) -> master_pass::ActiveModel;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MasterPassFromUnencryptedExt for master_pass::ActiveModel {
|
|
|
|
/// Hashes the password and creates an ActiveModel with all fields set to Set variant
|
|
|
|
#[inline]
|
|
|
|
fn from_unencrypted(user_id: u64, password: &str) -> Self {
|
|
|
|
let mut salt = vec![0; 64];
|
|
|
|
OsRng.fill_bytes(&mut salt);
|
|
|
|
let password_hash = Set(hash_password(password.as_bytes(), &salt).to_vec());
|
|
|
|
Self {
|
|
|
|
user_id: Set(user_id),
|
|
|
|
salt: Set(salt),
|
|
|
|
password_hash,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|