diff --git a/Cargo.lock b/Cargo.lock index 293acd0..5c5ba47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,6 +25,11 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bitflags" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "1.1.0" @@ -101,6 +106,16 @@ dependencies = [ "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "errno" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "errno" version = "0.2.4" @@ -148,6 +163,7 @@ dependencies = [ "ctap 0.1.0 (git+https://git.shimun.net/shimun/ctap.git?branch=hmac_ext)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "keyutils 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", @@ -174,6 +190,25 @@ name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "keyutils" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "errno 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -514,6 +549,11 @@ dependencies = [ "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.3.8" @@ -523,6 +563,11 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -537,6 +582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" "checksum backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2" "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" +"checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum blkid-rs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9bc207ca2ccb5bdf3b3e43be52a4afa0eca780851fb80733d28bd3688bead5c6" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" @@ -546,6 +592,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cryptsetup-rs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9da293bc97d0ccf0f53e440537dc2dd945eaa79642997685a1c0664062ef0a29" "checksum ctap 0.1.0 (git+https://git.shimun.net/shimun/ctap.git?branch=hmac_ext)" = "" +"checksum errno 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1e2b2decb0484e15560df3210cf0d78654bb0864b2c138977c07e377a1bae0e2" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" "checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" @@ -554,6 +601,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum keyutils 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbdbe7849bedbbb4f1437a790f6029372d8c400d1ca2d9ead8fb2d3057ccb2cc" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum libcryptsetup-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "321aea95b53514a18b523f544cdb7bc785adec1f0a7e207df611677f9b934ddd" @@ -595,6 +644,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index ab5daa8..ea75323 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,10 @@ failure = "0.1.5" serde_derive = "1.0.100" serde = "1.0.100" serde_json = "1.0.40" +keyutils = "0.2.1" [profile.release] lto = true opt-level = 'z' +panic = 'abort' diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..645beb1 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,92 @@ +use crate::error::*; +use crate::*; + +use cryptsetup_rs as luks; +use cryptsetup_rs::api::{CryptDeviceHandle, CryptDeviceOpenBuilder, Luks1Params}; +use cryptsetup_rs::Luks1CryptDevice; +use ctap; +use ctap::extensions::hmac::{FidoHmacCredential, HmacExtension}; +use ctap::FidoDevice; + +use std::fs::File; +use std::io::{self, Read, Seek, Write}; +use std::path::Path; + +pub fn setup() -> Fido2LuksResult<()> { + let mut config = Config::default(); + + let save_config = |c: &Config| { + File::create("fido2luks.json") + .expect("Failed to save config") + .write_all(serde_json::to_string_pretty(c).unwrap().as_bytes()) + .expect("Failed to save config"); + }; + + fn ask_bool(q: &str) -> bool { + ask_str(&format!("{} (y/n)", q)).expect("Failed to read from stdin") == "y" + } + + println!("1. Generating a credential"); + let mut ccred: Option = None; + for di in ctap::get_devices().expect("Failed to query USB for 2fa devices") { + let mut dev = FidoDevice::new(&di).expect("Failed to open 2fa device"); + match dev.make_hmac_credential() { + Ok(cred) => { + ccred = Some(cred); + break; + } + Err(_e) => println!("Failed to to obtain credential trying next device(if applicable)"), + } + } + config.credential_id = hex::encode(ccred.expect("No credential could be obtained").id); + save_config(&config); + + loop { + let device = ask_str("Path to your luks device: ").expect("Failed to read from stdin");; + if Path::new(&device).exists() + || ask_bool(&format!("{} does not exist, save anyway?", device)) + { + config.device = device.into(); + break; + } + } + + save_config(&config); + + config.mapper_name = ask_str("Name for decrypted disk: ").expect("Failed to read from stdin");; + + save_config(&config); + + println!("Config saved to: fido2luks.json"); + Ok(()) +} + +pub fn add_key_to_luks(conf: &Config) -> Fido2LuksResult { + fn offer_format( + _dev: CryptDeviceOpenBuilder, + ) -> Fido2LuksResult> { + unimplemented!() + } + let dev = || -> luks::device::Result { + luks::open(&conf.device.canonicalize()?) + }; + let mut handle = match dev()?.luks1() { + Ok(handle) => handle, + Err(luks::device::Error::BlkidError(_)) => offer_format(dev()?)?, + Err(luks::device::Error::CryptsetupError(errno)) => { + //if i32::from(errno) == 555 + dbg!(errno); + offer_format(dev()?)? + } //TODO: find correct errorno and offer to format as luks + err => err?, + }; + + let secret = { + let salt = conf.input_salt.obtain(&conf.password_helper)?; + + assemble_secret(&perform_challenge(&conf.credential_id, &salt)?, &salt) + }; + dbg!("Adding key"); + let slot = handle.add_keyslot(&secret, None, None)?; + Ok(slot) +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..47c6ebc --- /dev/null +++ b/src/config.rs @@ -0,0 +1,133 @@ +use crate::error::*; +use crate::*; +use crypto::digest::Digest; +use crypto::sha2::Sha256; + +use serde_derive::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::env; +use std::fs::File; +use std::io::Read; +use std::path::PathBuf; +use std::process::Command; + +#[derive(Debug, Deserialize, Serialize)] +pub struct Config { + pub credential_id: String, + pub input_salt: InputSalt, + pub device: PathBuf, + pub mapper_name: String, + pub password_helper: PasswordHelper, +} + +impl Config { + pub fn load_default_location() -> Fido2LuksResult { + Self::load_config( + &mut File::open( + env::vars() + .collect::>() + .get("FIDO2LUKS_CONFIG") + .unwrap_or(&"/etc/fido2luks.json".to_owned()), + ) + .or(File::open("fido2luks.json"))?, + ) + } + + pub fn load_config(reader: &mut dyn Read) -> Fido2LuksResult { + let mut conf_str = String::new(); + reader.read_to_string(&mut conf_str)?; + + Ok(serde_json::from_str(&conf_str)?) + } +} + +impl Default for Config { + fn default() -> Self { + Config { + credential_id: "".into(), + input_salt: Default::default(), + device: "/dev/some-vg/".into(), + mapper_name: "2fa-secured-luks".into(), + password_helper: PasswordHelper::default(), + } + } +} + +#[derive(Debug, Deserialize, Serialize)] +pub enum InputSalt { + AskPassword, + File { path: PathBuf }, + Both { path: PathBuf }, +} + +impl Default for InputSalt { + fn default() -> Self { + InputSalt::AskPassword + } +} + +impl InputSalt { + pub fn obtain(&self, password_helper: &PasswordHelper) -> Fido2LuksResult<[u8; 32]> { + let mut digest = Sha256::new(); + match self { + InputSalt::File { path } => { + let mut do_io = || { + let mut reader = File::open(path)?; + let mut buf = [0u8; 512]; + loop { + let red = reader.read(&mut buf)?; + digest.input(&buf[0..red]); + if red == 0 { + break; + } + } + Ok(()) + }; + do_io().map_err(|cause| Fido2LuksError::KeyfileError { cause })?; + } + InputSalt::AskPassword => { + digest.input(password_helper.obtain()?.as_bytes()); + } + InputSalt::Both { path } => { + digest.input(&InputSalt::AskPassword.obtain(password_helper)?); + digest.input(&InputSalt::File { path: path.clone() }.obtain(password_helper)?) + } + } + let mut salt = [0u8; 32]; + digest.result(&mut salt); + Ok(salt) + } +} + +#[derive(Debug, Deserialize, Serialize)] +pub enum PasswordHelper { + Script(String), + Systemd, + Stdin, +} + +impl Default for PasswordHelper { + fn default() -> Self { + PasswordHelper::Script("plymouth ask-for-password".into()) + } +} + +impl PasswordHelper { + pub fn obtain(&self) -> Fido2LuksResult { + use PasswordHelper::*; + match self { + Systemd => unimplemented!(), + Stdin => Ok(ask_str("Password: ")?), + Script(password_helper) => { + let mut helper_parts = password_helper.split(" "); + + let password = Command::new((&mut helper_parts).next().unwrap()) + .args(helper_parts) + .output() + .map_err(|e| Fido2LuksError::AskPassError { cause: e })? + .stdout; + Ok(String::from_utf8(password)?) + } + } + } +} diff --git a/src/error.rs b/src/error.rs index c93c4f6..9d7cf7d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,8 +21,11 @@ pub enum Fido2LuksError { ConfigurationError { cause: serde_json::error::Error }, #[fail(display = "the submitted secret is not applicable to this luks device")] WrongSecret, + #[fail(display = "not an utf8 string")] + StringEncodingError { cause: FromUtf8Error }, } +use std::string::FromUtf8Error; use Fido2LuksError::*; impl From for Fido2LuksError { @@ -48,3 +51,9 @@ impl From for Fido2LuksError { ConfigurationError { cause: e } } } + +impl From for Fido2LuksError { + fn from(e: FromUtf8Error) -> Self { + StringEncodingError { cause: e } + } +} diff --git a/src/keystore.rs b/src/keystore.rs new file mode 100644 index 0000000..0b2d124 --- /dev/null +++ b/src/keystore.rs @@ -0,0 +1,17 @@ +use keyutils::Keyring; + +fn get_passphrase() -> Vec { + Keyring::request("user") + .unwrap() + .request_key("fido2luks") + .unwrap() + .read() + .unwrap() +} + +fn add_secret(secret: &[u8]) { + Keyring::request("session") + .unwrap() + .add_key("cryptsetup", secret) + .unwrap(); +} diff --git a/src/main.rs b/src/main.rs index e73e06c..7aefaa0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,120 +2,29 @@ extern crate failure; #[macro_use] extern crate serde_derive; +use crate::cli::*; +use crate::config::*; use crate::error::*; use crypto::digest::Digest; use crypto::sha2::Sha256; use cryptsetup_rs as luks; -use cryptsetup_rs::api::{CryptDeviceHandle, CryptDeviceOpenBuilder, Luks1Params}; + use cryptsetup_rs::Luks1CryptDevice; use ctap; use ctap::extensions::hmac::{FidoHmacCredential, HmacExtension}; use ctap::FidoDevice; use luks::device::Error::CryptsetupError; -use serde_derive::{Deserialize, Serialize}; + use std::collections::HashMap; use std::env; -use std::fs::File; -use std::io::{Read, Write}; -use std::path::{Path, PathBuf}; -use std::process::Command; +use std::io::{self, Read, Seek, Write}; +use std::path::PathBuf; + +mod cli; +mod config; mod error; - -#[derive(Debug, Deserialize, Serialize)] -pub struct Config { - pub credential_id: String, - pub input_salt: InputSalt, - pub device: PathBuf, - pub mapper_name: String, - pub password_helper: String, -} - -impl Config { - pub fn load_default_location() -> Fido2LuksResult { - Self::load_config( - &mut File::open( - env::vars() - .collect::>() - .get("FIDO2LUKS_CONFIG") - .unwrap_or(&"/etc/fido2luks.json".to_owned()), - ) - .or(File::open("fido2luks.json"))?, - ) - } - - pub fn load_config(reader: &mut dyn Read) -> Fido2LuksResult { - let mut conf_str = String::new(); - reader.read_to_string(&mut conf_str)?; - - Ok(serde_json::from_str(&conf_str)?) - } -} - -impl Default for Config { - fn default() -> Self { - Config { - credential_id: "generate using solo key make-credential".into(), - input_salt: Default::default(), - device: "/dev/some-vg/my-volume".into(), - mapper_name: "2fa-secured-luks".into(), - password_helper: "/usr/bin/systemd-ask-password --no-tty --no-output --id='fido2luks' --keyname='fido2luks' 'Please enter second factor for LUKS disk encryption!'".into(), - } - } -} - -#[derive(Debug, Deserialize, Serialize)] -pub enum InputSalt { - AskPassword, - File { path: PathBuf }, - Both { path: PathBuf }, -} - -impl Default for InputSalt { - fn default() -> Self { - InputSalt::AskPassword - } -} - -impl InputSalt { - fn obtain(&self, password_helper: &str) -> Fido2LuksResult<[u8; 32]> { - let mut digest = Sha256::new(); - match self { - InputSalt::File { path } => { - let mut do_io = || { - let mut reader = File::open(path)?; - let mut buf = [0u8; 512]; - loop { - let red = reader.read(&mut buf)?; - digest.input(&buf[0..red]); - if red == 0 { - break; - } - } - Ok(()) - }; - do_io().map_err(|cause| Fido2LuksError::KeyfileError { cause })?; - } - InputSalt::AskPassword => { - let mut helper_parts = password_helper.split(" "); - - let password = Command::new((&mut helper_parts).next().unwrap()) - .args(helper_parts) - .output() - .map_err(|e| Fido2LuksError::AskPassError { cause: e })? - .stdout; - digest.input(&password); - } - InputSalt::Both { path } => { - digest.input(&InputSalt::AskPassword.obtain(password_helper)?); - digest.input(&InputSalt::File { path: path.clone() }.obtain(password_helper)?) - } - } - let mut salt = [0u8; 32]; - digest.result(&mut salt); - Ok(salt) - } -} +mod keystore; fn open_container(device: &PathBuf, name: &str, secret: &[u8; 32]) -> Fido2LuksResult<()> { let mut handle = luks::open(device.canonicalize()?)?.luks1()?; @@ -151,107 +60,16 @@ fn assemble_secret(hmac_result: &[u8], salt: &[u8]) -> [u8; 32] { digest.result(&mut secret); secret } - -fn setup() -> Fido2LuksResult<()> { - let mut config = Config::default(); - - let save_config = |c: &Config| { - File::create("fido2luks.json") - .expect("Failed to save config") - .write_all(serde_json::to_string_pretty(c).unwrap().as_bytes()) - .expect("Failed to save config"); - }; - - fn ask_str(q: &str) -> String { - let stdin = std::io::stdin(); - let mut s = String::new(); - print!("{}", q); - std::io::stdout() - .flush() - .ok() - .expect("Could not flush stdout"); - stdin.read_line(&mut s).expect("Failed to read rom stdin"); - s.trim().to_owned() - } - - fn ask_bool(q: &str) -> bool { - ask_str(&format!("{} (y/n)", q)) == "y" - } - - println!("1. Generating a credential"); - let mut ccred: Option = None; - for di in ctap::get_devices().expect("Failed to query USB for 2fa devices") { - let mut dev = FidoDevice::new(&di).expect("Failed to open 2fa device"); - match dev.make_hmac_credential() { - Ok(cred) => { - ccred = Some(cred); - break; - } - Err(_e) => println!("Failed to to obtain credential trying next device(if applicable)"), - } - } - config.credential_id = hex::encode(ccred.expect("No credential could be obtained").id); - save_config(&config); - - loop { - let device = ask_str("Path to your luks device: "); - if Path::new(&device).exists() - || ask_bool(&format!("{} does not exist, save anyway?", device)) - { - config.device = device.into(); - break; - } - } - - save_config(&config); - - config.mapper_name = ask_str("Name for decrypted disk: "); - - save_config(&config); - - println!("Config saved to: fido2luks.json"); - Ok(()) +fn ask_str(q: &str) -> Fido2LuksResult { + let stdin = io::stdin(); + let mut s = String::new(); + print!("{}", q); + io::stdout().flush()?; + stdin.read_line(&mut s)?; + Ok(s.trim().to_owned()) } -fn add_key_to_luks(conf: &Config) -> Fido2LuksResult { - fn offer_format( - _dev: CryptDeviceOpenBuilder, - ) -> Fido2LuksResult> { - unimplemented!() - } - let dev = || -> luks::device::Result { - luks::open(&conf.device.canonicalize()?) - }; - let mut handle = match dev()?.luks1() { - Ok(handle) => handle, - Err(luks::device::Error::BlkidError(_)) => offer_format(dev()?)?, - Err(luks::device::Error::CryptsetupError(errno)) => { - //if i32::from(errno) == 555 - dbg!(errno); - offer_format(dev()?)? - } //TODO: find correct errorno and offer to format as luks - err => err?, - }; - - let secret = { - let salt = conf.input_salt.obtain(&conf.password_helper)?; - - assemble_secret(&perform_challenge(&conf.credential_id, &salt)?, &salt) - }; - dbg!("Adding key"); - let slot = handle.add_keyslot(&secret, None, None)?; - Ok(slot) -} - -fn open() -> Fido2LuksResult<()> { - let conf = Config::load_default_location()?; - let salt = conf.input_salt.obtain(&conf.password_helper)?; - dbg!(hex::encode(&salt)); - let secret = { - let salt = conf.input_salt.obtain(&conf.password_helper)?; - - assemble_secret(&perform_challenge(&conf.credential_id, &salt)?, &salt) - }; +fn open(conf: &Config, secret: &[u8; 32]) -> Fido2LuksResult<()> { dbg!(hex::encode(&secret)); match open_container(&conf.device, &conf.mapper_name, &secret) { Err(Fido2LuksError::LuksError { @@ -262,10 +80,45 @@ fn open() -> Fido2LuksResult<()> { Ok(()) } +/*fn package_self() -> Fido2LuksResult<()> { + let conf = Config::load_default_location()?; + let binary_path: PathBuf = env::args().next().unwrap().into(); + let mut me = File::open(binary_path)?; + + me.seek(io::SeekFrom::End(("config".as_bytes().len() * -1) as i64 - 4))?; + + let conf_len = me.read_u32()?; + + let mut buf = vec![0u8; 512]; + + me.read(&mut buf[0..6])?; + + if String::from_utf8((&buf[0..6]).iter().collect()).map(|s| &s == "config").unwrap_or(false) { + + } + + Ok(()) +}*/ + fn main() -> Fido2LuksResult<()> { let args: Vec<_> = env::args().skip(1).collect(); //Ignore program name -> Vec + let env = env::vars().collect::>(); if args.is_empty() { - open() + let conf = Config::load_default_location()?; + let salt = conf.input_salt.obtain(&conf.password_helper)?; + dbg!(hex::encode(&salt)); + let secret = { + let salt = conf.input_salt.obtain(&conf.password_helper)?; + + assemble_secret(&perform_challenge(&conf.credential_id, &salt)?, &salt) + }; + if env.contains_key("CRYPTTAB_NAME") { + //Indicates that this script is being run as keyscript + open(&conf, &secret) + } else { + io::stdout().write(&secret)?; + Ok(io::stdout().flush()?) + } } else { match args.first().map(|s| s.as_ref()).unwrap() { "addkey" => add_key_to_luks(&Config::load_default_location()?).map(|_| ()), @@ -273,7 +126,7 @@ fn main() -> Fido2LuksResult<()> { _ => { eprintln!("Usage: setup | addkey"); Ok(()) - } + } //"selfcontain" => package_self() } } }