vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

commit 75615bb5c809054b4926e6162f65e18fe9cf0480
parent 6378d96d1ab26d84bc78d3e0e17294db9bf0a13b
Author: Daniel GarcĂ­a <dani-garcia@users.noreply.github.com>
Date:   Fri, 13 Jul 2018 12:28:35 +0200

Ignore U2F challenge if not provided. Also checked that error_code has to be 0 for a successfull registration

Diffstat:
Msrc/api/core/two_factor.rs | 40+++++++++++++++++++++++++++++++++++++---
Msrc/api/mod.rs | 2+-
2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/src/api/core/two_factor.rs b/src/api/core/two_factor.rs @@ -254,6 +254,29 @@ struct EnableU2FData { DeviceResponse: String, } +// This struct is copied from the U2F lib +// because challenge is not always sent +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RegisterResponseCopy { + pub registration_data: String, + pub version: String, + pub challenge: Option<String>, + pub error_code: Option<NumberOrString>, + pub client_data: String, +} + +impl RegisterResponseCopy { + fn into_response(self, challenge: String) -> RegisterResponse { + RegisterResponse { + registration_data: self.registration_data, + version: self.version, + challenge: challenge, + client_data: self.client_data, + } + } +} + #[post("/two-factor/u2f", data = "<data>")] fn activate_u2f(data: JsonUpcase<EnableU2FData>, headers: Headers, conn: DbConn) -> JsonResult { let data: EnableU2FData = data.into_inner().data; @@ -278,8 +301,19 @@ fn activate_u2f(data: JsonUpcase<EnableU2FData>, headers: Headers, conn: DbConn) println!("RegisterResponse {:#?}", &data.DeviceResponse); - let response: RegisterResponse = - serde_json::from_str(&data.DeviceResponse).expect("Can't parse DeviceResponse data"); + let response_copy: RegisterResponseCopy = + serde_json::from_str(&data.DeviceResponse).expect("Can't parse RegisterResponse data"); + + let error_code = response_copy + .error_code + .clone() + .map_or("0".into(), NumberOrString::into_string); + + if error_code != "0" { + err!("Error registering U2F token") + } + + let response = response_copy.into_response(challenge.challenge.clone()); match U2F.register_response(challenge.clone(), response) { Ok(registration) => { @@ -337,7 +371,7 @@ fn _create_u2f_challenge(user_uuid: &str, type_: TwoFactorType, conn: &DbConn) - // because it doesn't implement Deserialize #[derive(Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] -pub struct RegistrationCopy { +struct RegistrationCopy { pub key_handle: Vec<u8>, pub pub_key: Vec<u8>, pub attestation_cert: Option<Vec<u8>>, diff --git a/src/api/mod.rs b/src/api/mod.rs @@ -26,7 +26,7 @@ struct PasswordData { MasterPasswordHash: String } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] #[serde(untagged)] enum NumberOrString { Number(i32),