reorganised cli
This commit is contained in:
parent
5c0364587e
commit
c3d6425e2d
358
src/cli.rs
358
src/cli.rs
@ -12,7 +12,7 @@ use std::io::Write;
|
|||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use crate::util::read_password;
|
use crate::util::sha256;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
@ -56,6 +56,99 @@ impl<T: Display + FromStr> FromStr for CommaSeparated<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt)]
|
||||||
|
pub struct AuthenticatorParameters {
|
||||||
|
/// FIDO credential ids, seperated by ',' generate using fido2luks credential
|
||||||
|
#[structopt(name = "credential-id", env = "FIDO2LUKS_CREDENTIAL_ID")]
|
||||||
|
pub credential_ids: CommaSeparated<HexEncoded>,
|
||||||
|
|
||||||
|
/// Await for an authenticator to be connected, timeout after n seconds
|
||||||
|
#[structopt(
|
||||||
|
long = "await-dev",
|
||||||
|
name = "await-dev",
|
||||||
|
env = "FIDO2LUKS_DEVICE_AWAIT",
|
||||||
|
default_value = "15"
|
||||||
|
)]
|
||||||
|
pub await_time: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt)]
|
||||||
|
pub struct LuksParameters {
|
||||||
|
#[structopt(env = "FIDO2LUKS_DEVICE")]
|
||||||
|
device: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt, Clone)]
|
||||||
|
pub struct LuksModParameters {
|
||||||
|
/// Number of milliseconds required to derive the volume decryption key
|
||||||
|
/// Defaults to 10ms when using an authenticator or the default by cryptsetup when using a password
|
||||||
|
#[structopt(long = "kdf-time", name = "kdf-time")]
|
||||||
|
kdf_time: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt)]
|
||||||
|
pub struct SecretParameters {
|
||||||
|
/// Salt for secret generation, defaults to 'ask'
|
||||||
|
///
|
||||||
|
/// Options:{n}
|
||||||
|
/// - ask : Prompt user using password helper{n}
|
||||||
|
/// - file:<PATH> : Will read <FILE>{n}
|
||||||
|
/// - string:<STRING> : Will use <STRING>, which will be handled like a password provided to the 'ask' option{n}
|
||||||
|
#[structopt(
|
||||||
|
name = "salt",
|
||||||
|
long = "salt",
|
||||||
|
env = "FIDO2LUKS_SALT",
|
||||||
|
default_value = "ask"
|
||||||
|
)]
|
||||||
|
pub salt: InputSalt,
|
||||||
|
/// Script used to obtain passwords, overridden by --interactive flag
|
||||||
|
#[structopt(
|
||||||
|
name = "password-helper",
|
||||||
|
env = "FIDO2LUKS_PASSWORD_HELPER",
|
||||||
|
default_value = "/usr/bin/env systemd-ask-password 'Please enter second factor for LUKS disk encryption!'"
|
||||||
|
)]
|
||||||
|
pub password_helper: PasswordHelper,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn derive_secret(
|
||||||
|
credentials: &[HexEncoded],
|
||||||
|
salt: &[u8; 32],
|
||||||
|
timeout: u64,
|
||||||
|
) -> Fido2LuksResult<[u8; 32]> {
|
||||||
|
let timeout = Duration::from_secs(timeout);
|
||||||
|
let start = SystemTime::now();
|
||||||
|
|
||||||
|
while let Ok(el) = start.elapsed() {
|
||||||
|
if el > timeout {
|
||||||
|
return Err(error::Fido2LuksError::NoAuthenticatorError);
|
||||||
|
}
|
||||||
|
if get_devices()
|
||||||
|
.map(|devices| !devices.is_empty())
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
thread::sleep(Duration::from_millis(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(sha256(&[
|
||||||
|
&perform_challenge(
|
||||||
|
&credentials
|
||||||
|
.iter()
|
||||||
|
.map(|hex| FidoCredential {
|
||||||
|
id: hex.0.clone(),
|
||||||
|
public_key: None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.iter()
|
||||||
|
.collect::<Vec<_>>()[..],
|
||||||
|
salt,
|
||||||
|
timeout - start.elapsed().unwrap(),
|
||||||
|
)?[..],
|
||||||
|
salt,
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
/// Request passwords via Stdin instead of using the password helper
|
/// Request passwords via Stdin instead of using the password helper
|
||||||
@ -109,70 +202,6 @@ pub struct SecretGeneration {
|
|||||||
pub verify_password: Option<bool>,
|
pub verify_password: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SecretGeneration {
|
|
||||||
pub fn patch(&self, args: &Args, verify_password: Option<bool>) -> Self {
|
|
||||||
let mut me = self.clone();
|
|
||||||
if args.interactive {
|
|
||||||
me.password_helper = PasswordHelper::Stdin;
|
|
||||||
}
|
|
||||||
me.verify_password = me.verify_password.or(verify_password);
|
|
||||||
me
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn obtain_secret(&self, password_query: &str) -> Fido2LuksResult<[u8; 32]> {
|
|
||||||
let mut salt = [0u8; 32];
|
|
||||||
match self.password_helper {
|
|
||||||
PasswordHelper::Stdin if !self.verify_password.unwrap_or(true) => {
|
|
||||||
salt.copy_from_slice(&util::sha256(&[&read_password(
|
|
||||||
password_query,
|
|
||||||
self.verify_password.unwrap_or(true),
|
|
||||||
)?
|
|
||||||
.as_bytes()[..]]));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
salt = self.salt.obtain(&self.password_helper)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let timeout = Duration::from_secs(self.await_authenticator);
|
|
||||||
let start = SystemTime::now();
|
|
||||||
|
|
||||||
while let Ok(el) = start.elapsed() {
|
|
||||||
if el > timeout {
|
|
||||||
return Err(error::Fido2LuksError::NoAuthenticatorError);
|
|
||||||
}
|
|
||||||
if get_devices()
|
|
||||||
.map(|devices| !devices.is_empty())
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
thread::sleep(Duration::from_millis(500));
|
|
||||||
}
|
|
||||||
let credentials = &self
|
|
||||||
.credential_ids
|
|
||||||
.0
|
|
||||||
.iter()
|
|
||||||
.map(|HexEncoded(id)| FidoCredential {
|
|
||||||
id: id.to_vec(),
|
|
||||||
public_key: None,
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let credentials = credentials.iter().collect::<Vec<_>>();
|
|
||||||
Ok(assemble_secret(
|
|
||||||
&perform_challenge(&credentials[..], &salt, timeout - start.elapsed().unwrap())?,
|
|
||||||
&salt,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, StructOpt, Clone)]
|
|
||||||
pub struct LuksSettings {
|
|
||||||
/// Number of milliseconds required to derive the volume decryption key
|
|
||||||
/// Defaults to 10ms when using an authenticator or the default by cryptsetup when using a password
|
|
||||||
#[structopt(long = "kdf-time", name = "kdf-time")]
|
|
||||||
kdf_time: Option<u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, StructOpt, Clone)]
|
#[derive(Debug, StructOpt, Clone)]
|
||||||
pub struct OtherSecret {
|
pub struct OtherSecret {
|
||||||
/// Use a keyfile instead of a password
|
/// Use a keyfile instead of a password
|
||||||
@ -184,24 +213,6 @@ pub struct OtherSecret {
|
|||||||
fido_device: bool,
|
fido_device: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OtherSecret {
|
|
||||||
pub fn obtain(
|
|
||||||
&self,
|
|
||||||
secret_gen: &SecretGeneration,
|
|
||||||
verify_password: bool,
|
|
||||||
password_question: &str,
|
|
||||||
) -> Fido2LuksResult<Vec<u8>> {
|
|
||||||
match &self.keyfile {
|
|
||||||
Some(keyfile) => util::read_keyfile(keyfile.clone()),
|
|
||||||
None if self.fido_device => {
|
|
||||||
Ok(Vec::from(&secret_gen.obtain_secret(password_question)?[..]))
|
|
||||||
}
|
|
||||||
None => util::read_password(password_question, verify_password)
|
|
||||||
.map(|p| p.as_bytes().to_vec()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
#[structopt(name = "print-secret")]
|
#[structopt(name = "print-secret")]
|
||||||
@ -210,49 +221,57 @@ pub enum Command {
|
|||||||
#[structopt(short = "b", long = "bin")]
|
#[structopt(short = "b", long = "bin")]
|
||||||
binary: bool,
|
binary: bool,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
secret_gen: SecretGeneration,
|
authenticator: AuthenticatorParameters,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
secret: SecretParameters,
|
||||||
},
|
},
|
||||||
/// Adds a generated key to the specified LUKS device
|
/// Adds a generated key to the specified LUKS device
|
||||||
#[structopt(name = "add-key")]
|
#[structopt(name = "add-key")]
|
||||||
AddKey {
|
AddKey {
|
||||||
#[structopt(env = "FIDO2LUKS_DEVICE")]
|
#[structopt(flatten)]
|
||||||
device: PathBuf,
|
luks: LuksParameters,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
authenticator: AuthenticatorParameters,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
secret: SecretParameters,
|
||||||
/// Will wipe all other keys
|
/// Will wipe all other keys
|
||||||
#[structopt(short = "e", long = "exclusive")]
|
#[structopt(short = "e", long = "exclusive")]
|
||||||
exclusive: bool,
|
exclusive: bool,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
existing_secret: OtherSecret,
|
existing_secret: OtherSecret,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
secret_gen: SecretGeneration,
|
luks_mod: LuksModParameters,
|
||||||
#[structopt(flatten)]
|
|
||||||
luks_settings: LuksSettings,
|
|
||||||
},
|
},
|
||||||
/// Replace a previously added key with a password
|
/// Replace a previously added key with a password
|
||||||
#[structopt(name = "replace-key")]
|
#[structopt(name = "replace-key")]
|
||||||
ReplaceKey {
|
ReplaceKey {
|
||||||
#[structopt(env = "FIDO2LUKS_DEVICE")]
|
#[structopt(flatten)]
|
||||||
device: PathBuf,
|
luks: LuksParameters,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
authenticator: AuthenticatorParameters,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
secret: SecretParameters,
|
||||||
/// Add the password and keep the key
|
/// Add the password and keep the key
|
||||||
#[structopt(short = "a", long = "add-password")]
|
#[structopt(short = "a", long = "add-password")]
|
||||||
add_password: bool,
|
add_password: bool,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
replacement: OtherSecret,
|
replacement: OtherSecret,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
secret_gen: SecretGeneration,
|
luks_mod: LuksModParameters,
|
||||||
#[structopt(flatten)]
|
|
||||||
luks_settings: LuksSettings,
|
|
||||||
},
|
},
|
||||||
/// Open the LUKS device
|
/// Open the LUKS device
|
||||||
#[structopt(name = "open")]
|
#[structopt(name = "open")]
|
||||||
Open {
|
Open {
|
||||||
#[structopt(env = "FIDO2LUKS_DEVICE")]
|
#[structopt(flatten)]
|
||||||
device: PathBuf,
|
luks: LuksParameters,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
authenticator: AuthenticatorParameters,
|
||||||
|
#[structopt(flatten)]
|
||||||
|
secret: SecretParameters,
|
||||||
#[structopt(env = "FIDO2LUKS_MAPPER_NAME")]
|
#[structopt(env = "FIDO2LUKS_MAPPER_NAME")]
|
||||||
name: String,
|
name: String,
|
||||||
#[structopt(short = "r", long = "max-retries", default_value = "0")]
|
#[structopt(short = "r", long = "max-retries", default_value = "0")]
|
||||||
retries: i32,
|
retries: i32,
|
||||||
#[structopt(flatten)]
|
|
||||||
secret_gen: SecretGeneration,
|
|
||||||
},
|
},
|
||||||
/// Generate a new FIDO credential
|
/// Generate a new FIDO credential
|
||||||
#[structopt(name = "credential")]
|
#[structopt(name = "credential")]
|
||||||
@ -273,6 +292,7 @@ pub fn parse_cmdline() -> Args {
|
|||||||
pub fn run_cli() -> Fido2LuksResult<()> {
|
pub fn run_cli() -> Fido2LuksResult<()> {
|
||||||
let mut stdout = io::stdout();
|
let mut stdout = io::stdout();
|
||||||
let args = parse_cmdline();
|
let args = parse_cmdline();
|
||||||
|
let interactive = args.interactive;
|
||||||
match &args.command {
|
match &args.command {
|
||||||
Command::Credential { name } => {
|
Command::Credential { name } => {
|
||||||
let cred = make_credential_id(name.as_ref().map(|n| n.as_ref()))?;
|
let cred = make_credential_id(name.as_ref().map(|n| n.as_ref()))?;
|
||||||
@ -281,11 +301,19 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
}
|
}
|
||||||
Command::PrintSecret {
|
Command::PrintSecret {
|
||||||
binary,
|
binary,
|
||||||
ref secret_gen,
|
authenticator,
|
||||||
|
secret,
|
||||||
} => {
|
} => {
|
||||||
let secret = secret_gen
|
let salt = if interactive || secret.password_helper == PasswordHelper::Stdin {
|
||||||
.patch(&args, Some(false))
|
util::read_password_hashed("Password", false)
|
||||||
.obtain_secret("Password")?;
|
} else {
|
||||||
|
secret.salt.obtain(&secret.password_helper)
|
||||||
|
}?;
|
||||||
|
let secret = derive_secret(
|
||||||
|
authenticator.credential_ids.0.as_slice(),
|
||||||
|
&salt,
|
||||||
|
authenticator.await_time,
|
||||||
|
)?;
|
||||||
if *binary {
|
if *binary {
|
||||||
stdout.write_all(&secret[..])?;
|
stdout.write_all(&secret[..])?;
|
||||||
} else {
|
} else {
|
||||||
@ -294,72 +322,146 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
Ok(stdout.flush()?)
|
Ok(stdout.flush()?)
|
||||||
}
|
}
|
||||||
Command::AddKey {
|
Command::AddKey {
|
||||||
device,
|
luks,
|
||||||
|
authenticator,
|
||||||
|
secret,
|
||||||
exclusive,
|
exclusive,
|
||||||
existing_secret,
|
existing_secret,
|
||||||
ref secret_gen,
|
luks_mod,
|
||||||
luks_settings,
|
|
||||||
} => {
|
} => {
|
||||||
let secret_gen = secret_gen.patch(&args, None);
|
let salt = |q: &str, verify: bool| -> Fido2LuksResult<[u8; 32]> {
|
||||||
let old_secret = existing_secret.obtain(&secret_gen, false, "Existing password")?;
|
if interactive || secret.password_helper == PasswordHelper::Stdin {
|
||||||
let secret = secret_gen.obtain_secret("Password")?;
|
util::read_password_hashed(q, verify)
|
||||||
|
} else {
|
||||||
|
secret.salt.obtain(&secret.password_helper)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let old_secret = match existing_secret {
|
||||||
|
OtherSecret {
|
||||||
|
keyfile: Some(file),
|
||||||
|
..
|
||||||
|
} => util::read_keyfile(file)?,
|
||||||
|
OtherSecret {
|
||||||
|
fido_device: true, ..
|
||||||
|
} => derive_secret(
|
||||||
|
&authenticator.credential_ids.0,
|
||||||
|
&salt("Existing password", false)?,
|
||||||
|
authenticator.await_time,
|
||||||
|
)?[..]
|
||||||
|
.to_vec(),
|
||||||
|
_ => util::read_password("Existing password", false)?
|
||||||
|
.as_bytes()
|
||||||
|
.to_vec(),
|
||||||
|
};
|
||||||
|
let secret = derive_secret(
|
||||||
|
&authenticator.credential_ids.0,
|
||||||
|
&salt("Password", false)?,
|
||||||
|
authenticator.await_time,
|
||||||
|
)?;
|
||||||
let added_slot = luks::add_key(
|
let added_slot = luks::add_key(
|
||||||
device.clone(),
|
&luks.device,
|
||||||
&secret,
|
&secret,
|
||||||
&old_secret[..],
|
&old_secret[..],
|
||||||
luks_settings.kdf_time.or(Some(10)),
|
luks_mod.kdf_time.or(Some(10)),
|
||||||
)?;
|
)?;
|
||||||
if *exclusive {
|
if *exclusive {
|
||||||
let destroyed = luks::remove_keyslots(&device, &[added_slot])?;
|
let destroyed = luks::remove_keyslots(&luks.device, &[added_slot])?;
|
||||||
println!(
|
println!(
|
||||||
"Added to key to device {}, slot: {}\nRemoved {} old keys",
|
"Added to key to device {}, slot: {}\nRemoved {} old keys",
|
||||||
device.display(),
|
luks.device.display(),
|
||||||
added_slot,
|
added_slot,
|
||||||
destroyed
|
destroyed
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
"Added to key to device {}, slot: {}",
|
"Added to key to device {}, slot: {}",
|
||||||
device.display(),
|
luks.device.display(),
|
||||||
added_slot
|
added_slot
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Command::ReplaceKey {
|
Command::ReplaceKey {
|
||||||
device,
|
luks,
|
||||||
|
authenticator,
|
||||||
|
secret,
|
||||||
add_password,
|
add_password,
|
||||||
replacement,
|
replacement,
|
||||||
ref secret_gen,
|
luks_mod,
|
||||||
luks_settings,
|
|
||||||
} => {
|
} => {
|
||||||
let secret_gen = secret_gen.patch(&args, Some(false));
|
let salt = |q: &str, verify: bool| -> Fido2LuksResult<[u8; 32]> {
|
||||||
let secret = secret_gen.obtain_secret("Password")?;
|
if interactive || secret.password_helper == PasswordHelper::Stdin {
|
||||||
let new_secret = replacement.obtain(&secret_gen, true, "Replacement password")?;
|
util::read_password_hashed(q, verify)
|
||||||
|
} else {
|
||||||
|
secret.salt.obtain(&secret.password_helper)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let replacement_secret = match replacement {
|
||||||
|
OtherSecret {
|
||||||
|
keyfile: Some(file),
|
||||||
|
..
|
||||||
|
} => util::read_keyfile(file)?,
|
||||||
|
OtherSecret {
|
||||||
|
fido_device: true, ..
|
||||||
|
} => derive_secret(
|
||||||
|
&authenticator.credential_ids.0,
|
||||||
|
&salt("Replacement password", true)?,
|
||||||
|
authenticator.await_time,
|
||||||
|
)?[..]
|
||||||
|
.to_vec(),
|
||||||
|
_ => util::read_password("Replacement password", true)?
|
||||||
|
.as_bytes()
|
||||||
|
.to_vec(),
|
||||||
|
};
|
||||||
|
let existing_secret = derive_secret(
|
||||||
|
&authenticator.credential_ids.0,
|
||||||
|
&salt("Password", false)?,
|
||||||
|
authenticator.await_time,
|
||||||
|
)?;
|
||||||
let slot = if *add_password {
|
let slot = if *add_password {
|
||||||
luks::add_key(device, &new_secret[..], &secret, luks_settings.kdf_time)
|
luks::add_key(
|
||||||
|
&luks.device,
|
||||||
|
&replacement_secret[..],
|
||||||
|
&existing_secret,
|
||||||
|
luks_mod.kdf_time,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
luks::replace_key(device, &new_secret[..], &secret, luks_settings.kdf_time)
|
luks::replace_key(
|
||||||
|
&luks.device,
|
||||||
|
&replacement_secret[..],
|
||||||
|
&existing_secret,
|
||||||
|
luks_mod.kdf_time,
|
||||||
|
)
|
||||||
}?;
|
}?;
|
||||||
println!(
|
println!(
|
||||||
"Added to password to device {}, slot: {}",
|
"Added to password to device {}, slot: {}",
|
||||||
device.display(),
|
luks.device.display(),
|
||||||
slot
|
slot
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Command::Open {
|
Command::Open {
|
||||||
device,
|
luks,
|
||||||
|
authenticator,
|
||||||
|
secret,
|
||||||
name,
|
name,
|
||||||
retries,
|
retries,
|
||||||
ref secret_gen,
|
|
||||||
} => {
|
} => {
|
||||||
|
let salt = |q: &str, verify: bool| -> Fido2LuksResult<[u8; 32]> {
|
||||||
|
if interactive || secret.password_helper == PasswordHelper::Stdin {
|
||||||
|
util::read_password_hashed(q, verify)
|
||||||
|
} else {
|
||||||
|
secret.salt.obtain(&secret.password_helper)
|
||||||
|
}
|
||||||
|
};
|
||||||
let mut retries = *retries;
|
let mut retries = *retries;
|
||||||
loop {
|
loop {
|
||||||
match secret_gen
|
match derive_secret(
|
||||||
.patch(&args, Some(false))
|
&authenticator.credential_ids.0,
|
||||||
.obtain_secret("Password")
|
&salt("Password", false)?,
|
||||||
.and_then(|secret| luks::open_container(&device, &name, &secret))
|
authenticator.await_time,
|
||||||
|
)
|
||||||
|
.and_then(|secret| luks::open_container(&luks.device, &name, &secret))
|
||||||
{
|
{
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
match e {
|
match e {
|
||||||
|
@ -84,7 +84,7 @@ impl InputSalt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum PasswordHelper {
|
pub enum PasswordHelper {
|
||||||
Script(String),
|
Script(String),
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
21
src/main.rs
21
src/main.rs
@ -16,10 +16,6 @@ mod error;
|
|||||||
mod luks;
|
mod luks;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
fn assemble_secret(hmac_result: &[u8], salt: &[u8]) -> [u8; 32] {
|
|
||||||
util::sha256(&[salt, hmac_result])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Fido2LuksResult<()> {
|
fn main() -> Fido2LuksResult<()> {
|
||||||
match run_cli() {
|
match run_cli() {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -32,20 +28,3 @@ fn main() -> Fido2LuksResult<()> {
|
|||||||
_ => exit(0),
|
_ => exit(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_assemble_secret() {
|
|
||||||
assert_eq!(
|
|
||||||
assemble_secret(b"abc", b"def"),
|
|
||||||
[
|
|
||||||
46, 82, 82, 140, 142, 159, 249, 196, 227, 160, 142, 72, 151, 77, 59, 62, 180, 36,
|
|
||||||
33, 47, 241, 94, 17, 232, 133, 103, 247, 32, 152, 253, 43, 19
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -29,6 +29,10 @@ pub fn read_password(q: &str, verify: bool) -> Fido2LuksResult<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_password_hashed(q: &str, verify: bool) -> Fido2LuksResult<[u8; 32]> {
|
||||||
|
read_password(q, verify).map(|pass| sha256(&[pass.as_bytes()]))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_keyfile<P: Into<PathBuf>>(path: P) -> Fido2LuksResult<Vec<u8>> {
|
pub fn read_keyfile<P: Into<PathBuf>>(path: P) -> Fido2LuksResult<Vec<u8>> {
|
||||||
let mut file = File::open(path.into())?;
|
let mut file = File::open(path.into())?;
|
||||||
let mut key = Vec::new();
|
let mut key = Vec::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user