|
|
@ -254,6 +254,29 @@ struct EnableU2FData {
|
|
|
|
DeviceResponse: String,
|
|
|
|
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>")]
|
|
|
|
#[post("/two-factor/u2f", data = "<data>")]
|
|
|
|
fn activate_u2f(data: JsonUpcase<EnableU2FData>, headers: Headers, conn: DbConn) -> JsonResult {
|
|
|
|
fn activate_u2f(data: JsonUpcase<EnableU2FData>, headers: Headers, conn: DbConn) -> JsonResult {
|
|
|
|
let data: EnableU2FData = data.into_inner().data;
|
|
|
|
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);
|
|
|
|
println!("RegisterResponse {:#?}", &data.DeviceResponse);
|
|
|
|
|
|
|
|
|
|
|
|
let response: RegisterResponse =
|
|
|
|
let response_copy: RegisterResponseCopy =
|
|
|
|
serde_json::from_str(&data.DeviceResponse).expect("Can't parse DeviceResponse data");
|
|
|
|
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) {
|
|
|
|
match U2F.register_response(challenge.clone(), response) {
|
|
|
|
Ok(registration) => {
|
|
|
|
Ok(registration) => {
|
|
|
@ -337,7 +371,7 @@ fn _create_u2f_challenge(user_uuid: &str, type_: TwoFactorType, conn: &DbConn) -
|
|
|
|
// because it doesn't implement Deserialize
|
|
|
|
// because it doesn't implement Deserialize
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
pub struct RegistrationCopy {
|
|
|
|
struct RegistrationCopy {
|
|
|
|
pub key_handle: Vec<u8>,
|
|
|
|
pub key_handle: Vec<u8>,
|
|
|
|
pub pub_key: Vec<u8>,
|
|
|
|
pub pub_key: Vec<u8>,
|
|
|
|
pub attestation_cert: Option<Vec<u8>>,
|
|
|
|
pub attestation_cert: Option<Vec<u8>>,
|
|
|
|