pass_manager/cryptography/src/master_pass.rs

46 lines
1.5 KiB
Rust
Raw Normal View History

use entity::master_pass;
use rand::{rngs::OsRng, RngCore};
use scrypt::{scrypt, Params};
use sea_orm::ActiveValue::Set;
/// Hashes the password with Scrypt with the given salt
#[inline]
fn hash_password(password: &[u8], salt: &[u8]) -> [u8; 64] {
let params = Params::new(14, Params::RECOMMENDED_R, Params::RECOMMENDED_P, 64).unwrap();
let mut password_hash = [0; 64];
scrypt(password, salt, &params, &mut password_hash).unwrap();
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);
hashed == self.password_hash.as_slice()
}
}
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,
}
}
}