diff --git a/Cargo.lock b/Cargo.lock index bb592eee..a89928f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,13 +124,13 @@ dependencies = [ [[package]] name = "argon2" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +checksum = "134c52ddac6d63c576bef8168db10c83c49c26444ecbc68060fef078925a901c" dependencies = [ "base64ct", "blake2", - "cpufeatures 0.2.17", + "cpufeatures 0.3.0", "password-hash", ] @@ -766,11 +766,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +checksum = "5b5d4d889834ee8ecfc0f8426ad30faf7cdcb10f741a8e6d7224d95325479f6f" dependencies = [ - "digest 0.10.7", + "digest 0.11.3", ] [[package]] @@ -4560,13 +4560,12 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +checksum = "aab41826031698d6ffcd9cff78ef56ef998e39dc7e5067cdfebe373842d4723b" dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", + "getrandom 0.4.3", + "phc", ] [[package]] @@ -4585,6 +4584,17 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phc" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44dc769b75f93afdddd8c7fa12d685292ddeff1e66f7f0f3a234cf1818afe892" +dependencies = [ + "base64ct", + "ctutils", + "getrandom 0.4.3", +] + [[package]] name = "phf" version = "0.13.1" diff --git a/crates/crypto/Cargo.toml b/crates/crypto/Cargo.toml index 0d261bd1..3d047036 100644 --- a/crates/crypto/Cargo.toml +++ b/crates/crypto/Cargo.toml @@ -17,7 +17,7 @@ blake3 = "1.8.5" hex = "0.4.3" thiserror = "2.0.18" ed25519-dalek = "3.0.0" -argon2 = "0.5" +argon2 = "0.6" [dev-dependencies] rand_chacha = "0.3" diff --git a/crates/crypto/src/credentials.rs b/crates/crypto/src/credentials.rs index 735353be..7589662a 100644 --- a/crates/crypto/src/credentials.rs +++ b/crates/crypto/src/credentials.rs @@ -2,7 +2,8 @@ //! generation and hashing, constant-time comparison. Lives here because //! RustCrypto (argon2, blake3) and the RNG stay quarantined in this crate. -use argon2::password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString}; +use argon2::password_hash::phc::PasswordHash; +use argon2::password_hash::{PasswordHasher, PasswordVerifier}; use argon2::Argon2; use std::sync::OnceLock; @@ -11,11 +12,10 @@ pub fn hash_password(password: &str) -> String { use rand_core::{OsRng, RngCore}; let mut salt = [0u8; 16]; OsRng.fill_bytes(&mut salt); - let salt = SaltString::encode_b64(&salt).expect("16 bytes is a valid salt length"); - Argon2::default() - .hash_password(password.as_bytes(), &salt) - .expect("argon2 hashing with default parameters cannot fail") - .to_string() + let hash: PasswordHash = Argon2::default() + .hash_password_with_salt(password.as_bytes(), &salt) + .expect("argon2 hashing with default parameters cannot fail"); + hash.to_string() } static DUMMY: OnceLock = OnceLock::new(); @@ -102,6 +102,18 @@ mod tests { ); } + #[test] + fn hash_from_argon2_0_5_still_verifies() { + // Made by argon2 0.5.3 (the version before 0.6): rows stored by older + // sc-forge builds must keep verifying after the upgrade. + let legacy = concat!( + "$argon2id$v=19$m=19456,t=2,p=1$12Jq/QaZmfBGlN6TfZu3Rg", + "$nVEPZmM6n6sSG8yZfXvFF5E00aLDJTCVu7bpGnEhDyU" + ); + assert!(verify_password("legacy-0.5-fixture-pw", Some(legacy))); + assert!(!verify_password("legacy-0.5-fixture-px", Some(legacy))); + } + #[test] fn same_password_hashes_differently() { let p = pw();