hint slots
This commit is contained in:
parent
2ec8679c47
commit
0b19760175
@ -417,7 +417,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
||||
device,
|
||||
&name[..],
|
||||
Box::new(|mut creds| {
|
||||
let secret = SecretGeneration {
|
||||
let (secret, cred) = SecretGeneration {
|
||||
credential_ids: CommaSeparated(
|
||||
creds
|
||||
.iter()
|
||||
@ -429,8 +429,8 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
||||
await_authenticator: 100,
|
||||
verify_password: None,
|
||||
}
|
||||
.obtain_secret("Password");
|
||||
secret.map(|s| s.to_vec().into_boxed_slice())
|
||||
.obtain_secret_and_credential("Password")?;
|
||||
Ok((secret, hex::encode(cred.id)))
|
||||
}),
|
||||
),
|
||||
Command::Connected => match get_devices() {
|
||||
|
18
src/error.rs
18
src/error.rs
@ -56,9 +56,27 @@ pub enum LuksError {
|
||||
InvalidToken(String),
|
||||
#[fail(display = "No token found")]
|
||||
NoToken,
|
||||
#[fail(display = "The device already exists")]
|
||||
DeviceExists,
|
||||
}
|
||||
|
||||
impl LuksError {
|
||||
pub fn activate(e: LibcryptErr) -> Fido2LuksError {
|
||||
match e {
|
||||
LibcryptErr::IOError(ref io) => match io.raw_os_error() {
|
||||
Some(1) if io.kind() == ErrorKind::PermissionDenied => Fido2LuksError::WrongSecret,
|
||||
Some(17) => Fido2LuksError::LuksError {
|
||||
cause: LuksError::DeviceExists,
|
||||
},
|
||||
_ => return Fido2LuksError::CryptsetupError { cause: e },
|
||||
},
|
||||
_ => Fido2LuksError::CryptsetupError { cause: e },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use libcryptsetup_rs::LibcryptErr;
|
||||
use std::io::ErrorKind;
|
||||
use std::string::FromUtf8Error;
|
||||
use Fido2LuksError::*;
|
||||
|
||||
|
105
src/luks.rs
105
src/luks.rs
@ -5,6 +5,7 @@ use libcryptsetup_rs::{
|
||||
size_t, CryptActivateFlags, CryptDevice, CryptInit, CryptLuks2Token, CryptTokenInfo,
|
||||
EncryptionFormat, KeyslotInfo, LibcryptErr,
|
||||
};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::Path;
|
||||
use std::result::Result;
|
||||
|
||||
@ -49,7 +50,7 @@ struct Fido2LuksToken {
|
||||
impl Fido2LuksToken {
|
||||
fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self {
|
||||
Self {
|
||||
type_: "fido2luks\0".into(),
|
||||
type_: "fido2luks\0".into(), // Doubles as c style string
|
||||
credential: vec![hex::encode(credential_id)],
|
||||
keyslots: vec![slot.to_string()],
|
||||
}
|
||||
@ -68,72 +69,12 @@ pub fn open_container<P: AsRef<Path>>(path: P, name: &str, secret: &[u8]) -> Fid
|
||||
pub fn open_container_token<P: AsRef<Path>>(
|
||||
path: P,
|
||||
name: &str,
|
||||
mut secret: Box<Fn(Vec<String>) -> Fido2LuksResult<Box<[u8]>>>,
|
||||
mut secret: Box<Fn(Vec<String>) -> Fido2LuksResult<([u8; 32], String)>>,
|
||||
) -> Fido2LuksResult<()> {
|
||||
let mut device = load_device_handle(path)?;
|
||||
check_luks2(&mut device)?;
|
||||
/*
|
||||
// https://gitlab.com/cryptsetup/cryptsetup/-/blob/0b38128e21175b24f8dd1ad06257754af3d4437f/lib/libcryptsetup.h#L2096
|
||||
let mut token_data: Option<Fido2LuksToken> = None;
|
||||
fn open_token(
|
||||
mut device: CryptDevice,
|
||||
id: i32,
|
||||
data: Option<&mut Box<Fn(Vec<String>) -> Fido2LuksResult<Box<[u8]>>>>,
|
||||
) -> Result<Box<[u8]>, LibcryptErr> {
|
||||
dbg!("handler");
|
||||
let token: Fido2LuksToken = serde_json::from_value( device.token_handle().json_get(id as u32)?).map_err(|e| LibcryptErr::Other(e.to_string()))?;
|
||||
if let Some(secret_gen) = data {
|
||||
secret_gen(token.credential).map_err(|e| LibcryptErr::Other(dbg!(e).to_string()))
|
||||
} else {
|
||||
Err(LibcryptErr::Other("No secret_gen".into()))
|
||||
}
|
||||
}
|
||||
//c_token_handler_open!(ext_open_token, Fido2LuksToken, open_token);
|
||||
extern "C" fn ext_open_token(
|
||||
cd: *mut libcryptsetup_rs_sys::crypt_device,
|
||||
token_id: std::os::raw::c_int,
|
||||
buffer: *mut *mut std::os::raw::c_char,
|
||||
buffer_len: *mut size_t,
|
||||
usrptr: *mut std::os::raw::c_void,
|
||||
) -> std::os::raw::c_int {
|
||||
let device = CryptDevice::from_ptr(cd);
|
||||
let generic_ptr = usrptr as *mut Box<Fn(Vec<String>) -> Fido2LuksResult<Box<[u8]>>>;
|
||||
let generic_ref = unsafe { generic_ptr.as_mut() };
|
||||
match open_token(device, token_id, generic_ref) {
|
||||
Ok(secret) => unsafe {
|
||||
*buffer = Box::into_raw(secret) as *mut std::os::raw::c_char;
|
||||
0
|
||||
},
|
||||
Err(_) => -1,
|
||||
}
|
||||
}
|
||||
fn free_token(boxed: Box<[u8]>) {}
|
||||
c_token_handler_free!(ext_free_token, free_token);
|
||||
|
||||
fn validate_token(
|
||||
device: &mut CryptDevice,
|
||||
json: serde_json::value::Value,
|
||||
) -> Result<(), LibcryptErr> {
|
||||
Ok(())
|
||||
}
|
||||
c_token_handler_validate!(ext_validate_token, validate_token);
|
||||
|
||||
|
||||
fn dump_token(device: &mut CryptDevice, json: serde_json::value::Value) {
|
||||
|
||||
}
|
||||
c_token_handler_dump!(ext_dump_token, dump_token);*/
|
||||
/*CryptLuks2Token::register("fido2luks\0", Some(ext_open_token), None, None, None)?;
|
||||
dbg!("here");
|
||||
//let mut salt = salt.to_vec().into_boxed_slice();
|
||||
match device.token_handle().activate_by_token(Some(&name),None, Some(&mut secret), CryptActivateFlags::empty()) {
|
||||
Err(e) => match e {
|
||||
LibcryptErr::IOError(_) => Err(Fido2LuksError::LuksError { cause: LuksError::NoToken}),
|
||||
_ => Err(e)?
|
||||
},
|
||||
ok => Ok(ok?)
|
||||
}*/
|
||||
let mut creds = Vec::new();
|
||||
let mut creds = HashMap::new();
|
||||
for i in 0..256 {
|
||||
let (status, type_) = device.token_handle().status(i)?;
|
||||
if status == CryptTokenInfo::Inactive {
|
||||
@ -151,18 +92,38 @@ pub fn open_container_token<P: AsRef<Path>>(
|
||||
serde_json::from_value(json.clone()).map_err(|_| Fido2LuksError::LuksError {
|
||||
cause: LuksError::InvalidToken(json.to_string()),
|
||||
})?;
|
||||
creds.extend_from_slice(&info.credential[..]);
|
||||
let slots = || {
|
||||
info.keyslots
|
||||
.iter()
|
||||
.filter_map(|slot| slot.parse::<u32>().ok())
|
||||
};
|
||||
for cred in info.credential.iter().cloned() {
|
||||
creds
|
||||
.entry(cred)
|
||||
.or_insert_with(|| slots().collect::<HashSet<u32>>())
|
||||
.extend(slots());
|
||||
}
|
||||
device
|
||||
}
|
||||
let (secret, credential) = secret(dbg!(creds.keys().cloned().collect()))?;
|
||||
|
||||
let slots = creds.get(&credential).unwrap();
|
||||
let mut slots = slots
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(Option::Some)
|
||||
.chain(std::iter::once(None).take(slots.is_empty() as usize));
|
||||
for slot in slots {
|
||||
match device
|
||||
.activate_handle()
|
||||
.activate_by_passphrase(
|
||||
Some(name),
|
||||
None,
|
||||
secret(dbg!(creds))?.as_ref(),
|
||||
CryptActivateFlags::empty(),
|
||||
)
|
||||
.activate_by_passphrase(Some(name), slot, &secret, CryptActivateFlags::empty())
|
||||
.map(|_slot| ())
|
||||
.map_err(|_e| Fido2LuksError::WrongSecret)
|
||||
.map_err(LuksError::activate)
|
||||
{
|
||||
Err(Fido2LuksError::WrongSecret) => (),
|
||||
res => return res,
|
||||
}
|
||||
}
|
||||
Err(Fido2LuksError::WrongSecret)
|
||||
}
|
||||
|
||||
pub fn add_key<P: AsRef<Path>>(
|
||||
|
Loading…
x
Reference in New Issue
Block a user