from err
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
shimunn 2019-09-18 19:38:00 +02:00
parent 579851315a
commit 03cc5c70fd
Signed by: shimun
GPG Key ID: E81D8382DC2F971B
5 changed files with 76 additions and 41 deletions

View File

@ -71,22 +71,21 @@ pub fn setup() -> Fido2LuksResult<()> {
println!("Config saved to: fido2luks.json"); println!("Config saved to: fido2luks.json");
let slot = add_key_to_luks(&config).expect("Failed to add key to device"); //let slot = add_key_to_luks(&config).expect("Failed to add key to device");
println!("Added key to slot: {}", slot); //println!("Added key to slot: {}", slot);
Ok(()) Ok(())
} }
pub fn add_key_to_luks(conf: &Config) -> Fido2LuksResult<u8> { pub fn add_key_to_luks(device: PathBuf, secret: &[u8; 32]) -> Fido2LuksResult<u8> {
fn offer_format( fn offer_format(
_dev: CryptDeviceOpenBuilder, _dev: CryptDeviceOpenBuilder,
) -> Fido2LuksResult<CryptDeviceHandle<Luks1Params>> { ) -> Fido2LuksResult<CryptDeviceHandle<Luks1Params>> {
unimplemented!() unimplemented!()
} }
let dev = || -> luks::device::Result<CryptDeviceOpenBuilder> { let dev =
luks::open(&conf.device.canonicalize()?) || -> luks::device::Result<CryptDeviceOpenBuilder> { luks::open(&device.canonicalize()?) };
};
let prev_key_info = rpassword::read_password_from_tty(Some( let prev_key_info = rpassword::read_password_from_tty(Some(
"Please enter your current password or path to a keyfile in order to add a new key: ", "Please enter your current password or path to a keyfile in order to add a new key: ",
@ -113,13 +112,7 @@ pub fn add_key_to_luks(conf: &Config) -> Fido2LuksResult<u8> {
} //TODO: find correct errorno and offer to format as luks } //TODO: find correct errorno and offer to format as luks
err => err?, err => err?,
}; };
let slot = handle.add_keyslot(secret, prev_key.as_ref().map(|b| b.as_slice()), None)?;
let secret = {
let salt = conf.input_salt.obtain(&conf.password_helper)?;
assemble_secret(&perform_challenge(&conf.credential_id, &salt)?, &salt)
};
let slot = handle.add_keyslot(&secret, prev_key.as_ref().map(|b| b.as_slice()), None)?;
Ok(slot) Ok(slot)
} }

View File

@ -5,6 +5,7 @@ use crypto::sha2::Sha256;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryInto;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
@ -13,28 +14,31 @@ use std::process::Command;
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub struct EnvConfig { pub struct EnvConfig {
credential_id: String, pub credential_id: String,
device: String, pub device: Option<String>,
salt: String, pub salt: String,
mapper_name: String, pub mapper_name: Option<String>,
password_helper: String, pub password_helper: String,
} }
impl Into<Config> for EnvConfig { impl TryInto<Config> for EnvConfig {
fn into(self) -> Config { type Error = Fido2LuksError;
Config {
fn try_into(self) -> Fido2LuksResult<Config> {
Ok(Config {
credential_id: self.credential_id, credential_id: self.credential_id,
device: self.device.into(), device: self
mapper_name: self.mapper_name, .device
.ok_or(Fido2LuksError::ConfigurationError {
cause: ConfigurationError::MissingField("DEVICE".into()),
})?
.into(),
mapper_name: self.mapper_name.ok_or(Fido2LuksError::ConfigurationError {
cause: ConfigurationError::MissingField("DEVICE_MAPPER".into()),
})?,
password_helper: PasswordHelper::Script(self.password_helper), password_helper: PasswordHelper::Script(self.password_helper),
input_salt: if PathBuf::from(&self.salt).exists() && &self.salt != "Ask" { input_salt: self.salt.as_str().into(),
InputSalt::File { })
path: self.salt.into(),
}
} else {
InputSalt::AskPassword
},
}
} }
} }
@ -93,6 +97,16 @@ impl Default for InputSalt {
} }
} }
impl From<&str> for InputSalt {
fn from(s: &str) -> Self {
if PathBuf::from(s).exists() && s != "Ask" {
InputSalt::File { path: s.into() }
} else {
InputSalt::AskPassword
}
}
}
impl InputSalt { impl InputSalt {
pub fn obtain(&self, password_helper: &PasswordHelper) -> Fido2LuksResult<[u8; 32]> { pub fn obtain(&self, password_helper: &PasswordHelper) -> Fido2LuksResult<[u8; 32]> {
let mut digest = Sha256::new(); let mut digest = Sha256::new();
@ -139,6 +153,15 @@ impl Default for PasswordHelper {
} }
} }
impl From<&str> for PasswordHelper {
fn from(s: &str) -> Self {
match s {
"stdin" => PasswordHelper::Stdin,
s => PasswordHelper::Script(s.into()),
}
}
}
impl PasswordHelper { impl PasswordHelper {
pub fn obtain(&self) -> Fido2LuksResult<String> { pub fn obtain(&self) -> Fido2LuksResult<String> {
use PasswordHelper::*; use PasswordHelper::*;

View File

@ -5,7 +5,7 @@ use ctap::extensions::hmac::{FidoHmacCredential, HmacExtension};
use ctap::{FidoDevice, FidoError, FidoErrorKind}; use ctap::{FidoDevice, FidoError, FidoErrorKind};
pub fn make_credential_id() -> Fido2LuksResult<FidoHmacCredential> { pub fn make_credential_id() -> Fido2LuksResult<FidoHmacCredential> {
let mut errs = Vec::new(); let mut errs = Vec::new();
match get_devices()? { match get_devices()? {
ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?, ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?,
devs => { devs => {

View File

@ -18,13 +18,36 @@ pub enum Fido2LuksError {
#[fail(display = "no authenticator found, please ensure you device is plugged in")] #[fail(display = "no authenticator found, please ensure you device is plugged in")]
IoError { cause: io::Error }, IoError { cause: io::Error },
#[fail(display = "failed to parse config, please check formatting and contents")] #[fail(display = "failed to parse config, please check formatting and contents")]
ConfigurationError { cause: serde_json::error::Error }, ConfigurationError { cause: ConfigurationError },
#[fail(display = "the submitted secret is not applicable to this luks device")] #[fail(display = "the submitted secret is not applicable to this luks device")]
WrongSecret, WrongSecret,
#[fail(display = "not an utf8 string")] #[fail(display = "not an utf8 string")]
StringEncodingError { cause: FromUtf8Error }, StringEncodingError { cause: FromUtf8Error },
} }
#[derive(Debug)]
pub enum ConfigurationError {
Json(serde_json::error::Error),
Env(envy::Error),
MissingField(String),
}
impl From<serde_json::error::Error> for Fido2LuksError {
fn from(e: serde_json::error::Error) -> Self {
Fido2LuksError::ConfigurationError {
cause: ConfigurationError::Json(e),
}
}
}
impl From<envy::Error> for Fido2LuksError {
fn from(e: envy::Error) -> Self {
Fido2LuksError::ConfigurationError {
cause: ConfigurationError::Env(e),
}
}
}
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use Fido2LuksError::*; use Fido2LuksError::*;
@ -46,12 +69,6 @@ impl From<io::Error> for Fido2LuksError {
} }
} }
impl From<serde_json::error::Error> for Fido2LuksError {
fn from(e: serde_json::error::Error) -> Self {
ConfigurationError { cause: e }
}
}
impl From<FromUtf8Error> for Fido2LuksError { impl From<FromUtf8Error> for Fido2LuksError {
fn from(e: FromUtf8Error) -> Self { fn from(e: FromUtf8Error) -> Self {
StringEncodingError { cause: e } StringEncodingError { cause: e }

View File

@ -150,13 +150,15 @@ fn main() -> Fido2LuksResult<()> {
Ok(()) Ok(())
} }
_ => { _ => {
println!("Usage:\n println!(
"Usage:\n
fido2luks open <device> [name]\n fido2luks open <device> [name]\n
fido2luks addkey <device>\n\n fido2luks addkey <device>\n\n
Environment variables:\n Environment variables:\n
<FIDO2LUKS_CREDENTIAL_ID>\n <FIDO2LUKS_CREDENTIAL_ID>\n
<FIDO2LUKS_SALT>\n <FIDO2LUKS_SALT>\n
"); "
);
Ok(()) Ok(())
} }
} }