From addaf087abfaa9fd41f75ce0c2181a2df48a972a Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 20 May 2022 11:45:13 +0200 Subject: [PATCH] implement hash_password and verify_password --- Cargo.lock | 80 +++++++++++++++++++++++++++++++++--- Cargo.toml | 1 + src/login/static_provider.rs | 27 +++++++++--- src/main.rs | 5 ++- 4 files changed, 101 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0925486..39a6fa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,17 @@ version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +[[package]] +name = "argon2" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25df3c03f1040d0069fcd3907e24e36d59f9b6fa07ba49be0eb25a794f036ba7" +dependencies = [ + "base64ct", + "blake2", + "password-hash", +] + [[package]] name = "async-trait" version = "0.1.53" @@ -42,6 +53,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64ct" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" + [[package]] name = "bitflags" version = "1.3.2" @@ -57,6 +74,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "blake2" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +dependencies = [ + "digest 0.10.3", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -66,6 +92,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + [[package]] name = "byteorder" version = "1.4.3" @@ -179,6 +214,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "crypto-mac" version = "0.11.1" @@ -198,6 +243,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", + "subtle", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -427,7 +483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ "crypto-mac", - "digest", + "digest 0.9.0", ] [[package]] @@ -612,6 +668,7 @@ name = "mailrage" version = "0.0.1" dependencies = [ "anyhow", + "argon2", "async-trait", "base64", "clap", @@ -639,8 +696,8 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" dependencies = [ - "block-buffer", - "digest", + "block-buffer 0.9.0", + "digest 0.9.0", "opaque-debug", ] @@ -772,6 +829,17 @@ version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029d8d0b2f198229de29dca79676f2738ff952edf3fde542eb8bf94d8c21b435" +[[package]] +name = "password-hash" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + [[package]] name = "paste" version = "1.0.7" @@ -1017,7 +1085,7 @@ dependencies = [ "base64", "bytes", "chrono", - "digest", + "digest 0.9.0", "futures", "hex", "hmac", @@ -1134,10 +1202,10 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest", + "digest 0.9.0", "opaque-debug", ] diff --git a/Cargo.toml b/Cargo.toml index 16f619b..0205f10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ description = "Encrypted mail storage over Garage" [dependencies] anyhow = "1.0.28" +argon2 = "0.3" async-trait = "0.1" base64 = "0.13" clap = { version = "3.1.18", features = ["derive", "env"] } diff --git a/src/login/static_provider.rs b/src/login/static_provider.rs index cc0c8cb..74a6c14 100644 --- a/src/login/static_provider.rs +++ b/src/login/static_provider.rs @@ -32,7 +32,7 @@ impl LoginProvider for StaticLoginProvider { match self.users.get(username) { None => bail!("User {} does not exist", username), Some(u) => { - if !verify_password(password, &u.password) { + if !verify_password(password, &u.password)? { bail!("Wrong password"); } let bucket = u @@ -71,10 +71,27 @@ impl LoginProvider for StaticLoginProvider { } } -pub fn hash_password(password: &str) -> String { - unimplemented!() +pub fn hash_password(password: &str) -> Result { + use argon2::{ + password_hash::{rand_core::OsRng, PasswordHasher, SaltString}, + Argon2, + }; + let salt = SaltString::generate(&mut OsRng); + let argon2 = Argon2::default(); + Ok(argon2 + .hash_password(password.as_bytes(), &salt) + .map_err(|e| anyhow!("Argon2 error: {}", e))? + .to_string()) } -pub fn verify_password(password: &str, hash: &str) -> bool { - unimplemented!() +pub fn verify_password(password: &str, hash: &str) -> Result { + use argon2::{ + password_hash::{rand_core::OsRng, PasswordHash, PasswordVerifier}, + Argon2, + }; + let parsed_hash = + PasswordHash::new(&hash).map_err(|e| anyhow!("Invalid hashed password: {}", e))?; + Ok(Argon2::default() + .verify_password(password.as_bytes(), &parsed_hash) + .is_ok()) } diff --git a/src/main.rs b/src/main.rs index 04c0705..dcdd335 100644 --- a/src/main.rs +++ b/src/main.rs @@ -222,7 +222,10 @@ fn make_storage_creds(c: StorageCredsArgs) -> StorageCredentials { fn dump_config(password: &str, creds: &StorageCredentials) { println!("[login_static.users.]"); - println!("password = \"{}\"", hash_password(password)); //TODO + println!( + "password = \"{}\"", + hash_password(password).expect("unable to hash password") + ); println!("aws_access_key_id = \"{}\"", creds.aws_access_key_id); println!( "aws_secret_access_key = \"{}\"",