|
|
@ -49,6 +49,8 @@ pub struct RegisterData { |
|
|
|
Email: String, |
|
|
|
Kdf: Option<i32>, |
|
|
|
KdfIterations: Option<i32>, |
|
|
|
KdfMemory: Option<i32>, |
|
|
|
KdfParallelism: Option<i32>, |
|
|
|
Key: String, |
|
|
|
Keys: Option<KeysData>, |
|
|
|
MasterPasswordHash: String, |
|
|
@ -153,13 +155,16 @@ pub async fn _register(data: JsonUpcase<RegisterData>, mut conn: DbConn) -> Json |
|
|
|
// Make sure we don't leave a lingering invitation.
|
|
|
|
Invitation::take(&email, &mut conn).await; |
|
|
|
|
|
|
|
if let Some(client_kdf_type) = data.Kdf { |
|
|
|
user.client_kdf_type = client_kdf_type; |
|
|
|
} |
|
|
|
|
|
|
|
if let Some(client_kdf_iter) = data.KdfIterations { |
|
|
|
user.client_kdf_iter = client_kdf_iter; |
|
|
|
} |
|
|
|
|
|
|
|
if let Some(client_kdf_type) = data.Kdf { |
|
|
|
user.client_kdf_type = client_kdf_type; |
|
|
|
} |
|
|
|
user.client_kdf_parallelism = data.KdfMemory; |
|
|
|
user.client_kdf_memory = data.KdfParallelism; |
|
|
|
|
|
|
|
user.set_password(&data.MasterPasswordHash, Some(data.Key), true, None); |
|
|
|
user.password_hint = password_hint; |
|
|
@ -337,6 +342,8 @@ async fn post_password( |
|
|
|
struct ChangeKdfData { |
|
|
|
Kdf: i32, |
|
|
|
KdfIterations: i32, |
|
|
|
KdfMemory: Option<i32>, |
|
|
|
KdfParallelism: Option<i32>, |
|
|
|
|
|
|
|
MasterPasswordHash: String, |
|
|
|
NewMasterPasswordHash: String, |
|
|
@ -352,10 +359,31 @@ async fn post_kdf(data: JsonUpcase<ChangeKdfData>, headers: Headers, mut conn: D |
|
|
|
err!("Invalid password") |
|
|
|
} |
|
|
|
|
|
|
|
if data.KdfIterations < 100_000 { |
|
|
|
err!("KDF iterations lower then 100000 are not allowed.") |
|
|
|
if data.Kdf == UserKdfType::Pbkdf2 as i32 && data.KdfIterations < 100_000 { |
|
|
|
err!("PBKDF2 KDF iterations must be at least 100000.") |
|
|
|
} |
|
|
|
|
|
|
|
if data.Kdf == UserKdfType::Argon2id as i32 { |
|
|
|
if data.KdfIterations < 1 { |
|
|
|
err!("Argon2 KDF iterations must be at least 1.") |
|
|
|
} |
|
|
|
if let Some(m) = data.KdfMemory { |
|
|
|
if !(15..=1024).contains(&m) { |
|
|
|
err!("Argon2 memory must be between 15 MB and 1024 MB.") |
|
|
|
} |
|
|
|
user.client_kdf_memory = data.KdfMemory; |
|
|
|
} else { |
|
|
|
err!("Argon2 memory parameter is required.") |
|
|
|
} |
|
|
|
if let Some(p) = data.KdfParallelism { |
|
|
|
if !(1..=16).contains(&p) { |
|
|
|
err!("Argon2 parallelism must be between 1 and 16.") |
|
|
|
} |
|
|
|
user.client_kdf_parallelism = data.KdfParallelism; |
|
|
|
} else { |
|
|
|
err!("Argon2 parallelism parameter is required.") |
|
|
|
} |
|
|
|
} |
|
|
|
user.client_kdf_iter = data.KdfIterations; |
|
|
|
user.client_kdf_type = data.Kdf; |
|
|
|
user.set_password(&data.NewMasterPasswordHash, Some(data.Key), true, None); |
|
|
@ -770,15 +798,22 @@ async fn prelogin(data: JsonUpcase<PreloginData>, conn: DbConn) -> Json<Value> { |
|
|
|
pub async fn _prelogin(data: JsonUpcase<PreloginData>, mut conn: DbConn) -> Json<Value> { |
|
|
|
let data: PreloginData = data.into_inner().data; |
|
|
|
|
|
|
|
let (kdf_type, kdf_iter) = match User::find_by_mail(&data.Email, &mut conn).await { |
|
|
|
Some(user) => (user.client_kdf_type, user.client_kdf_iter), |
|
|
|
None => (User::CLIENT_KDF_TYPE_DEFAULT, User::CLIENT_KDF_ITER_DEFAULT), |
|
|
|
let (kdf_type, kdf_iter, kdf_mem, kdf_para) = match User::find_by_mail(&data.Email, &mut conn).await { |
|
|
|
Some(user) => (user.client_kdf_type, user.client_kdf_iter, user.client_kdf_memory, user.client_kdf_parallelism), |
|
|
|
None => (User::CLIENT_KDF_TYPE_DEFAULT, User::CLIENT_KDF_ITER_DEFAULT, None, None), |
|
|
|
}; |
|
|
|
|
|
|
|
Json(json!({ |
|
|
|
let mut result = json!({ |
|
|
|
"Kdf": kdf_type, |
|
|
|
"KdfIterations": kdf_iter |
|
|
|
})) |
|
|
|
"KdfIterations": kdf_iter, |
|
|
|
}); |
|
|
|
|
|
|
|
if kdf_type == UserKdfType::Argon2id as i32 { |
|
|
|
result["KdfMemory"] = Value::Number(kdf_mem.expect("Argon2 memory parameter is required.").into()); |
|
|
|
result["KdfParallelism"] = Value::Number(kdf_para.expect("Argon2 parallelism parameter is required.").into()); |
|
|
|
} |
|
|
|
|
|
|
|
Json(result) |
|
|
|
} |
|
|
|
|
|
|
|
// https://github.com/bitwarden/server/blob/master/src/Api/Models/Request/Accounts/SecretVerificationRequestModel.cs
|
|
|
|