initial
This commit is contained in:
commit
abb3eab559
16 changed files with 1035 additions and 0 deletions
71
native/argon2/src/lib.rs
Normal file
71
native/argon2/src/lib.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use argon2::Algorithm;
|
||||
use argon2::Version;
|
||||
use argon2::{
|
||||
password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
||||
Argon2, Params,
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
use rustler::Error;
|
||||
|
||||
const MIN_PASSWORD_LENGTH: usize = 8;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ConfigType {
|
||||
Owasp,
|
||||
Strong,
|
||||
TestUnsafe,
|
||||
}
|
||||
|
||||
impl ConfigType {
|
||||
fn params(&self) -> Params {
|
||||
match self {
|
||||
ConfigType::Owasp => Params::new(19456, 2, 1, None).expect("Invalid OWASP config"),
|
||||
ConfigType::Strong => Params::new(65540, 3, 4, None).expect("Invalid strong config"),
|
||||
ConfigType::TestUnsafe => Params::new(1024, 1, 1, None).expect("Invalid test config"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustler::nif]
|
||||
fn hash_password(password: String, config_type: Option<String>) -> Result<String, Error> {
|
||||
if password.len() < MIN_PASSWORD_LENGTH {
|
||||
return Err(Error::Term(Box::new(format!(
|
||||
"Password must be at least {} characters long",
|
||||
MIN_PASSWORD_LENGTH
|
||||
))));
|
||||
}
|
||||
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
|
||||
let config_type = match config_type.as_deref() {
|
||||
Some("strong") => ConfigType::Strong,
|
||||
Some("test_unsafe") => ConfigType::TestUnsafe,
|
||||
_ => ConfigType::Owasp,
|
||||
};
|
||||
|
||||
let argon2 = Argon2::new(Algorithm::Argon2i, Version::V0x13, config_type.params());
|
||||
|
||||
argon2
|
||||
.hash_password(password.as_bytes(), &salt)
|
||||
.map(|hash| hash.to_string())
|
||||
.map_err(|e| Error::Term(Box::new(format!("Hashing error: {}", e))))
|
||||
}
|
||||
|
||||
#[rustler::nif]
|
||||
fn verify_password(password: String, hash: String) -> Result<bool, Error> {
|
||||
if password.len() < MIN_PASSWORD_LENGTH {
|
||||
return Err(Error::Term(Box::new(format!(
|
||||
"Password must be at least {} characters long",
|
||||
MIN_PASSWORD_LENGTH
|
||||
))));
|
||||
}
|
||||
|
||||
let parsed_hash = PasswordHash::new(&hash)
|
||||
.map_err(|e| Error::Term(Box::new(format!("Invalid hash format: {}", e))))?;
|
||||
|
||||
Ok(Argon2::default()
|
||||
.verify_password(password.as_bytes(), &parsed_hash)
|
||||
.is_ok())
|
||||
}
|
||||
|
||||
rustler::init!("Elixir.Argon2.Native");
|
Loading…
Add table
Add a link
Reference in a new issue