blob: 107136063d92c94f74d5e7d1244c5a2bbe86dc37 [file] [log] [blame]
//! Tests for `PasswordHash` encoding/decoding.
//!
//! Each test implements a different permutation of the possible combinations
//! of the string encoding, and ensures password hashes round trip under each
//! of the conditions.
use core::convert::{TryFrom, TryInto};
use password_hash::{Ident, ParamsString, PasswordHash, Salt};
const EXAMPLE_ALGORITHM: Ident = Ident::new("argon2d");
const EXAMPLE_SALT: &str = "saltsaltsaltsaltsalt";
const EXAMPLE_HASH: &[u8] = &[
0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85,
0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab,
];
/// Example parameters
fn example_params() -> ParamsString {
let mut params = ParamsString::new();
params.add_decimal("a", 1).unwrap();
params.add_decimal("b", 2).unwrap();
params.add_decimal("c", 3).unwrap();
params
}
#[test]
fn algorithm_alone() {
let ph = PasswordHash::new("$argon2d").unwrap();
assert_eq!(ph.algorithm, EXAMPLE_ALGORITHM);
let s = ph.to_string();
assert_eq!(s, "$argon2d");
let ph2 = PasswordHash::try_from(s.as_str()).unwrap();
assert_eq!(ph, ph2);
}
#[test]
fn params() {
let ph = PasswordHash {
algorithm: EXAMPLE_ALGORITHM,
version: None,
params: example_params(),
salt: None,
hash: None,
};
let s = ph.to_string();
assert_eq!(s, "$argon2d$a=1,b=2,c=3");
let ph2 = PasswordHash::try_from(s.as_str()).unwrap();
assert_eq!(ph, ph2);
}
#[test]
fn salt() {
let ph = PasswordHash {
algorithm: EXAMPLE_ALGORITHM,
version: None,
params: ParamsString::new(),
salt: Some(Salt::new(EXAMPLE_SALT).unwrap()),
hash: None,
};
let s = ph.to_string();
assert_eq!(s, "$argon2d$saltsaltsaltsaltsalt");
let ph2 = PasswordHash::try_from(s.as_str()).unwrap();
assert_eq!(ph, ph2);
}
#[test]
fn one_param_and_salt() {
let mut params = ParamsString::new();
params.add_decimal("a", 1).unwrap();
let ph = PasswordHash {
algorithm: EXAMPLE_ALGORITHM,
version: None,
params,
salt: Some(Salt::new(EXAMPLE_SALT).unwrap()),
hash: None,
};
let s = ph.to_string();
assert_eq!(s, "$argon2d$a=1$saltsaltsaltsaltsalt");
let ph2 = PasswordHash::try_from(s.as_str()).unwrap();
assert_eq!(ph, ph2);
}
#[test]
fn params_and_salt() {
let ph = PasswordHash {
algorithm: EXAMPLE_ALGORITHM,
version: None,
params: example_params(),
salt: Some(Salt::new(EXAMPLE_SALT).unwrap()),
hash: None,
};
let s = ph.to_string();
assert_eq!(s, "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt");
let ph2 = PasswordHash::try_from(s.as_str()).unwrap();
assert_eq!(ph, ph2);
}
#[test]
fn salt_and_hash() {
let ph = PasswordHash {
algorithm: EXAMPLE_ALGORITHM,
version: None,
params: ParamsString::default(),
salt: Some(Salt::new(EXAMPLE_SALT).unwrap()),
hash: Some(EXAMPLE_HASH.try_into().unwrap()),
};
let s = ph.to_string();
assert_eq!(
s,
"$argon2d$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas"
);
let ph2 = PasswordHash::try_from(s.as_str()).unwrap();
assert_eq!(ph, ph2);
}
#[test]
fn all_fields() {
let ph = PasswordHash {
algorithm: EXAMPLE_ALGORITHM,
version: None,
params: example_params(),
salt: Some(Salt::new(EXAMPLE_SALT).unwrap()),
hash: Some(EXAMPLE_HASH.try_into().unwrap()),
};
let s = ph.to_string();
assert_eq!(
s,
"$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas"
);
let ph2 = PasswordHash::try_from(s.as_str()).unwrap();
assert_eq!(ph, ph2);
}