open token

This commit is contained in:
shimun 2020-04-28 14:27:14 +02:00
parent 65e1dead8b
commit 2ec8679c47
Signed by: shimun
GPG Key ID: E81D8382DC2F971B
6 changed files with 193 additions and 68 deletions

92
Cargo.lock generated
View File

@ -55,9 +55,9 @@ dependencies = [
[[package]]
name = "backtrace-sys"
version = "0.1.35"
version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118"
checksum = "78848718ee1255a2485d1309ad9cdecfc2e7d0362dd11c6829364c6b35ae1bc7"
dependencies = [
"cc",
"libc",
@ -111,9 +111,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.50"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
[[package]]
name = "cexpr"
@ -287,7 +287,7 @@ dependencies = [
"proc-macro2 1.0.10",
"quote 1.0.3",
"strsim 0.9.3",
"syn 1.0.17",
"syn 1.0.18",
]
[[package]]
@ -298,7 +298,7 @@ checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
dependencies = [
"darling_core",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
]
[[package]]
@ -311,7 +311,7 @@ dependencies = [
"derive_builder_core",
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
]
[[package]]
@ -323,7 +323,7 @@ dependencies = [
"darling",
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
]
[[package]]
@ -363,13 +363,13 @@ checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231"
dependencies = [
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
"synstructure",
]
[[package]]
name = "fido2luks"
version = "0.2.7"
version = "0.2.8"
dependencies = [
"ctap_hmac",
"failure",
@ -418,9 +418,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.10"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4"
dependencies = [
"libc",
]
@ -466,20 +466,20 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
[[package]]
name = "libc"
version = "0.2.68"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
[[package]]
name = "libcryptsetup-rs"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0177fd0ec022a5adb247e13e3238309913c28102a811227ad5de6a55697f152"
version = "0.3.0"
source = "git+https://github.com/shimunn/libcryptsetup-rs.git?branch=luks2_token_set#3578c05e5d2e23bb19ff8cb0932a778061281844"
dependencies = [
"either",
"libc",
"libcryptsetup-rs-sys",
"pkg-config",
"semver",
"serde_json",
"uuid",
]
@ -487,8 +487,7 @@ dependencies = [
[[package]]
name = "libcryptsetup-rs-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c605998e81e2a99c1f4c5d0be45ea1df6f1dc45dc64f5ca2847b0dbebf49ae7"
source = "git+https://github.com/shimunn/libcryptsetup-rs.git?branch=luks2_token_set#3578c05e5d2e23bb19ff8cb0932a778061281844"
dependencies = [
"bindgen",
"cc",
@ -580,26 +579,26 @@ checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
[[package]]
name = "proc-macro-error"
version = "0.4.12"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678"
dependencies = [
"proc-macro-error-attr",
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "0.4.12"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53"
dependencies = [
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
"syn-mid",
"version_check",
]
@ -784,17 +783,11 @@ dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]]
name = "regex"
version = "1.3.6"
version = "1.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3"
checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
dependencies = [
"aho-corasick",
"memchr",
@ -863,9 +856,9 @@ checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
[[package]]
name = "ryu"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
[[package]]
name = "scopeguard"
@ -902,7 +895,7 @@ checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
dependencies = [
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
]
[[package]]
@ -936,9 +929,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "structopt"
version = "0.3.12"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d"
checksum = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef"
dependencies = [
"clap",
"lazy_static",
@ -947,15 +940,15 @@ dependencies = [
[[package]]
name = "structopt-derive"
version = "0.4.5"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430"
checksum = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
]
[[package]]
@ -971,9 +964,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.17"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213"
dependencies = [
"proc-macro2 1.0.10",
"quote 1.0.3",
@ -988,7 +981,7 @@ checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
dependencies = [
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
]
[[package]]
@ -999,7 +992,7 @@ checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
dependencies = [
"proc-macro2 1.0.10",
"quote 1.0.3",
"syn 1.0.17",
"syn 1.0.18",
"unicode-xid 0.2.0",
]
@ -1032,12 +1025,11 @@ dependencies = [
[[package]]
name = "time"
version = "0.1.42"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
"redox_syscall",
"winapi",
]
@ -1119,9 +1111,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]

View File

@ -1,6 +1,6 @@
[package]
name = "fido2luks"
version = "0.2.7"
version = "0.2.8"
authors = ["shimunn <shimun@shimun.net>"]
edition = "2018"
@ -20,7 +20,8 @@ ring = "0.13.5"
failure = "0.1.5"
rpassword = "4.0.1"
structopt = "0.3.2"
libcryptsetup-rs = "0.2.0"
#libcryptsetup-rs = "0.3.0"
libcryptsetup-rs = { git = "https://github.com/shimunn/libcryptsetup-rs.git", branch = "luks2_token_set" }
serde_json = "1.0.51"
serde_derive = "1.0.106"
serde = "1.0.106"

View File

@ -267,6 +267,15 @@ pub enum Command {
#[structopt(flatten)]
secret_gen: SecretGeneration,
},
/// Open the LUKS device using information embedded into the LUKS 2 header
#[structopt(name = "open-token")]
OpenToken {
#[structopt(env = "FIDO2LUKS_DEVICE")]
device: PathBuf,
#[structopt(env = "FIDO2LUKS_MAPPER_NAME")]
name: String,
salt: String,
},
/// Generate a new FIDO credential
#[structopt(name = "credential")]
Credential {
@ -404,6 +413,26 @@ pub fn run_cli() -> Fido2LuksResult<()> {
}
}
}
Command::OpenToken { device, name, salt } => luks::open_container_token(
device,
&name[..],
Box::new(|mut creds| {
let secret = SecretGeneration {
credential_ids: CommaSeparated(
creds
.iter()
.map(|c| HexEncoded::from_str(&c[..]).unwrap())
.collect(),
),
salt: InputSalt::String("".into()),
password_helper: Default::default(),
await_authenticator: 100,
verify_password: None,
}
.obtain_secret("Password");
secret.map(|s| s.to_vec().into_boxed_slice())
}),
),
Command::Connected => match get_devices() {
Ok(ref devs) if !devs.is_empty() => {
println!("Found {} devices", devs.len());

View File

@ -54,6 +54,8 @@ pub enum LuksError {
Luks2Required,
#[fail(display = "Invalid token: {}", _0)]
InvalidToken(String),
#[fail(display = "No token found")]
NoToken,
}
use libcryptsetup_rs::LibcryptErr;

View File

@ -1,13 +1,22 @@
use crate::error::*;
use failure::{Fail, ResultExt};
use libcryptsetup_rs::{CryptActivateFlags, CryptDevice, CryptInit, CryptTokenInfo, EncryptionFormat, KeyslotInfo, CryptLuks2Token, LibcryptErr};
use libcryptsetup_rs::{
size_t, CryptActivateFlags, CryptDevice, CryptInit, CryptLuks2Token, CryptTokenInfo,
EncryptionFormat, KeyslotInfo, LibcryptErr,
};
use std::path::Path;
use std::result::Result;
fn load_device_handle<P: AsRef<Path>>(path: P) -> Fido2LuksResult<CryptDevice> {
let mut device = CryptInit::init(path.as_ref())?;
//TODO: determine luks version some way other way than just trying
let mut load = |format| device.context_handle().load::<()>(Some(format), None).map(|_| ());
let mut load = |format| {
device
.context_handle()
.load::<()>(Some(format), None)
.map(|_| ())
};
vec![EncryptionFormat::Luks2, EncryptionFormat::Luks1]
.into_iter()
.fold(None, |res, format| match res {
@ -40,7 +49,7 @@ struct Fido2LuksToken {
impl Fido2LuksToken {
fn new(credential_id: impl AsRef<[u8]>, slot: u32) -> Self {
Self {
type_: "fido2luks".into(),
type_: "fido2luks\0".into(),
credential: vec![hex::encode(credential_id)],
keyslots: vec![slot.to_string()],
}
@ -56,15 +65,105 @@ pub fn open_container<P: AsRef<Path>>(path: P, name: &str, secret: &[u8]) -> Fid
.map_err(|_e| Fido2LuksError::WrongSecret)
}
/*pub fn open_container_token<P: AsRef<Path>>(path: P, name: &str, secret: &[u8]) -> Fido2LuksResult<()> {
pub fn open_container_token<P: AsRef<Path>>(
path: P,
name: &str,
mut secret: Box<Fn(Vec<String>) -> Fido2LuksResult<Box<[u8]>>>,
) -> Fido2LuksResult<()> {
let mut device = load_device_handle(path)?;
check_luks2(&mut device)?;
fn open_token(mut device: CryptDevice, token: u32, ptr: &()) -> Result<Box<[u8]>, LibcryptErr> {
/*
// 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) {
}
CryptLuks2Token::register("fido2luks", c_token_handler_open!(ext_open_token,(), open_token),)
unimplemented!()
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 {
let (status, type_) = device.token_handle().status(i)?;
if status == CryptTokenInfo::Inactive {
break;
}
if let Some(s) = type_ {
if &s != "fido2luks" {
continue;
}
} else {
continue;
}
let json = device.token_handle().json_get(i)?;
let info: Fido2LuksToken =
serde_json::from_value(json.clone()).map_err(|_| Fido2LuksError::LuksError {
cause: LuksError::InvalidToken(json.to_string()),
})?;
creds.extend_from_slice(&info.credential[..]);
}
device
.activate_handle()
.activate_by_passphrase(
Some(name),
None,
secret(dbg!(creds))?.as_ref(),
CryptActivateFlags::empty(),
)
.map(|_slot| ())
.map_err(|_e| Fido2LuksError::WrongSecret)
}
pub fn add_key<P: AsRef<Path>>(
path: P,

View File

@ -3,6 +3,8 @@ extern crate failure;
extern crate ctap_hmac as ctap;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate libcryptsetup_rs;
use crate::cli::*;
use crate::config::*;
use crate::device::*;