This commit is contained in:
parent
579851315a
commit
03cc5c70fd
19
src/cli.rs
19
src/cli.rs
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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::*;
|
||||||
|
@ -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 => {
|
||||||
|
31
src/error.rs
31
src/error.rs
@ -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 }
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user