hint slots
This commit is contained in:
parent
2ec8679c47
commit
0b19760175
@ -417,7 +417,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
device,
|
device,
|
||||||
&name[..],
|
&name[..],
|
||||||
Box::new(|mut creds| {
|
Box::new(|mut creds| {
|
||||||
let secret = SecretGeneration {
|
let (secret, cred) = SecretGeneration {
|
||||||
credential_ids: CommaSeparated(
|
credential_ids: CommaSeparated(
|
||||||
creds
|
creds
|
||||||
.iter()
|
.iter()
|
||||||
@ -429,8 +429,8 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
|||||||
await_authenticator: 100,
|
await_authenticator: 100,
|
||||||
verify_password: None,
|
verify_password: None,
|
||||||
}
|
}
|
||||||
.obtain_secret("Password");
|
.obtain_secret_and_credential("Password")?;
|
||||||
secret.map(|s| s.to_vec().into_boxed_slice())
|
Ok((secret, hex::encode(cred.id)))
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
Command::Connected => match get_devices() {
|
Command::Connected => match get_devices() {
|
||||||
|
18
src/error.rs
18
src/error.rs
@ -56,9 +56,27 @@ pub enum LuksError {
|
|||||||
InvalidToken(String),
|
InvalidToken(String),
|
||||||
#[fail(display = "No token found")]
|
#[fail(display = "No token found")]
|
||||||
NoToken,
|
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 libcryptsetup_rs::LibcryptErr;
|
||||||
|
use std::io::ErrorKind;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
use Fido2LuksError::*;
|
use Fido2LuksError::*;
|
||||||
|
|
||||||
|
109
src/luks.rs
109
src/luks.rs
@ -5,6 +5,7 @@ use libcryptsetup_rs::{
|
|||||||
size_t, CryptActivateFlags, CryptDevice, CryptInit, CryptLuks2Token, CryptTokenInfo,
|
size_t, CryptActivateFlags, CryptDevice, CryptInit, CryptLuks2Token, CryptTokenInfo,
|
||||||
EncryptionFormat, KeyslotInfo, LibcryptErr,
|
EncryptionFormat, KeyslotInfo, LibcryptErr,
|
||||||
};
|
};
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ struct Fido2LuksToken {
|
|||||||
impl Fido2LuksToken {
|
impl Fido2LuksToken {
|
||||||
fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self {
|
fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
type_: "fido2luks\0".into(),
|
type_: "fido2luks\0".into(), // Doubles as c style string
|
||||||
credential: vec![hex::encode(credential_id)],
|
credential: vec![hex::encode(credential_id)],
|
||||||
keyslots: vec![slot.to_string()],
|
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>>(
|
pub fn open_container_token<P: AsRef<Path>>(
|
||||||
path: P,
|
path: P,
|
||||||
name: &str,
|
name: &str,
|
||||||
mut secret: Box<Fn(Vec<String>) -> Fido2LuksResult<Box<[u8]>>>,
|
mut secret: Box<Fn(Vec<String>) -> Fido2LuksResult<([u8; 32], String)>>,
|
||||||
) -> Fido2LuksResult<()> {
|
) -> Fido2LuksResult<()> {
|
||||||
let mut device = load_device_handle(path)?;
|
let mut device = load_device_handle(path)?;
|
||||||
check_luks2(&mut device)?;
|
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(
|
let mut creds = HashMap::new();
|
||||||
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();
|
|
||||||
for i in 0..256 {
|
for i in 0..256 {
|
||||||
let (status, type_) = device.token_handle().status(i)?;
|
let (status, type_) = device.token_handle().status(i)?;
|
||||||
if status == CryptTokenInfo::Inactive {
|
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 {
|
serde_json::from_value(json.clone()).map_err(|_| Fido2LuksError::LuksError {
|
||||||
cause: LuksError::InvalidToken(json.to_string()),
|
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()))?;
|
||||||
.activate_handle()
|
|
||||||
.activate_by_passphrase(
|
let slots = creds.get(&credential).unwrap();
|
||||||
Some(name),
|
let mut slots = slots
|
||||||
None,
|
.iter()
|
||||||
secret(dbg!(creds))?.as_ref(),
|
.cloned()
|
||||||
CryptActivateFlags::empty(),
|
.map(Option::Some)
|
||||||
)
|
.chain(std::iter::once(None).take(slots.is_empty() as usize));
|
||||||
.map(|_slot| ())
|
for slot in slots {
|
||||||
.map_err(|_e| Fido2LuksError::WrongSecret)
|
match device
|
||||||
|
.activate_handle()
|
||||||
|
.activate_by_passphrase(Some(name), slot, &secret, CryptActivateFlags::empty())
|
||||||
|
.map(|_slot| ())
|
||||||
|
.map_err(LuksError::activate)
|
||||||
|
{
|
||||||
|
Err(Fido2LuksError::WrongSecret) => (),
|
||||||
|
res => return res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(Fido2LuksError::WrongSecret)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_key<P: AsRef<Path>>(
|
pub fn add_key<P: AsRef<Path>>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user