update to 0.2.2
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is failing

This commit is contained in:
shimun 2020-01-10 21:44:33 +01:00
commit 659fafdfb4
Signed by: shimun
GPG Key ID: E81D8382DC2F971B
7 changed files with 93 additions and 28 deletions

34
Cargo.lock generated
View File

@ -115,15 +115,25 @@ dependencies = [
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "csv-core"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "ctap_hmac" name = "ctap_hmac"
version = "0.1.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cbor-codec 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "cbor-codec 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -173,10 +183,10 @@ dependencies = [
[[package]] [[package]]
name = "fido2luks" name = "fido2luks"
version = "0.2.1" version = "0.2.2"
dependencies = [ dependencies = [
"cryptsetup-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cryptsetup-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ctap_hmac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "ctap_hmac 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libcryptsetup-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libcryptsetup-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -208,6 +218,11 @@ name = "hex"
version = "0.3.2" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hex"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -235,6 +250,14 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "memchr"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-derive" name = "num-derive"
version = "0.2.5" version = "0.2.5"
@ -619,7 +642,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cryptsetup-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8b1eb6abff80fdc7b52c37b3e58f5a4cbda78bffc01ac7b02c1296552a07028a" "checksum cryptsetup-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8b1eb6abff80fdc7b52c37b3e58f5a4cbda78bffc01ac7b02c1296552a07028a"
"checksum ctap_hmac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f91b9400ac9c99e3280065f5bfd6eb7f0a9bb737a7fd166fda4153338e115e3" "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
"checksum ctap_hmac 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d57004228e303ed0d161f081020240d969ce18b623c3f4503645e1a06b42ae7"
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" "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 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" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
@ -628,10 +652,12 @@ 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 gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
"checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "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 libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"checksum libcryptsetup-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cab37dfc7316ea263a42ffa51b4b75c9022538576350d7a416de697384f596" "checksum libcryptsetup-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cab37dfc7316ea263a42ffa51b4b75c9022538576350d7a416de697384f596"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" "checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea" "checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "fido2luks" name = "fido2luks"
version = "0.2.1" version = "0.2.2"
authors = ["shimunn <shimun@shimun.net>"] authors = ["shimunn <shimun@shimun.net>"]
edition = "2018" edition = "2018"
@ -15,7 +15,7 @@ license-file = "LICENSE"
[dependencies] [dependencies]
#ctap = "0.1.0" #ctap = "0.1.0"
ctap_hmac = "0.1.1" ctap_hmac = "0.2.1"
cryptsetup-rs = "0.2.1" cryptsetup-rs = "0.2.1"
libcryptsetup-sys = "0.1.2" libcryptsetup-sys = "0.1.2"

View File

@ -2,7 +2,7 @@
This will allow you to unlock your luks encrypted disk with an fido2 compatible key This will allow you to unlock your luks encrypted disk with an fido2 compatible key
Note: This has only been tested under Fedora 30 using a Solo Key Note: This has only been tested under Fedora 31 using a Solo Key, Trezor Model T
## Setup ## Setup

View File

@ -70,10 +70,6 @@ pub fn add_password_to_luks(
Ok(slot) Ok(slot)
} }
pub fn authenticator_connected() -> Fido2LuksResult<bool> {
Ok(!device::get_devices()?.is_empty())
}
#[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
@ -181,7 +177,11 @@ pub enum Command {
}, },
/// Generate a new FIDO credential /// Generate a new FIDO credential
#[structopt(name = "credential")] #[structopt(name = "credential")]
Credential, Credential {
/// Name to be displayed on the authenticator if it has a display
#[structopt(env = "FIDO2LUKS_CREDENTIAL_NAME")]
name: Option<String>,
},
/// Check if an authenticator is connected /// Check if an authenticator is connected
#[structopt(name = "connected")] #[structopt(name = "connected")]
Connected, Connected,
@ -195,8 +195,8 @@ pub fn run_cli() -> Fido2LuksResult<()> {
let mut stdout = io::stdout(); let mut stdout = io::stdout();
let args = parse_cmdline(); let args = parse_cmdline();
match &args.command { match &args.command {
Command::Credential => { Command::Credential { name } => {
let cred = make_credential_id()?; let cred = make_credential_id(name.as_ref().map(|n| n.as_ref()))?;
println!("{}", hex::encode(&cred.id)); println!("{}", hex::encode(&cred.id));
Ok(()) Ok(())
} }

View File

@ -1,19 +1,53 @@
use crate::error::*; use crate::error::*;
use crate::util::sha256;
use ctap::{ use ctap::{
self, self,
extensions::hmac::{FidoHmacCredential, HmacExtension}, extensions::hmac::{FidoHmacCredential, HmacExtension},
FidoDevice, FidoError, FidoErrorKind, AuthenticatorOptions, FidoDevice, FidoError, FidoErrorKind, PublicKeyCredentialRpEntity,
PublicKeyCredentialUserEntity,
}; };
pub fn make_credential_id() -> Fido2LuksResult<FidoHmacCredential> { const RP_ID: &'static str = "fido2luks";
fn authenticator_options() -> Option<AuthenticatorOptions> {
Some(AuthenticatorOptions {
uv: false, //TODO: should get this from config
rk: true,
})
}
fn authenticator_rp() -> PublicKeyCredentialRpEntity<'static> {
PublicKeyCredentialRpEntity {
id: RP_ID,
name: None,
icon: None,
}
}
fn authenticator_user(name: Option<&str>) -> PublicKeyCredentialUserEntity {
PublicKeyCredentialUserEntity {
id: &[0u8],
name: name.unwrap_or(""),
icon: None,
display_name: name,
}
}
pub fn make_credential_id(name: Option<&str>) -> Fido2LuksResult<FidoHmacCredential> {
let mut errs = Vec::new(); let mut errs = Vec::new();
match get_devices()? { match get_devices()? {
ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?, ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?,
devs => { devs => {
for mut dev in devs.into_iter() { for mut dev in devs.into_iter() {
match dev match dev
.make_credential("fido2luks", &[0u8], "", &[0u8; 32]) .make_hmac_credential_full(
authenticator_rp(),
authenticator_user(name),
&[0u8; 32],
&[],
authenticator_options(),
)
.map(|cred| cred.into()) .map(|cred| cred.into())
{ {
//TODO: make credentials device specific //TODO: make credentials device specific
@ -33,16 +67,16 @@ pub fn make_credential_id() -> Fido2LuksResult<FidoHmacCredential> {
pub fn perform_challenge(credential_id: &str, salt: &[u8; 32]) -> Fido2LuksResult<[u8; 32]> { pub fn perform_challenge(credential_id: &str, salt: &[u8; 32]) -> Fido2LuksResult<[u8; 32]> {
let cred = FidoHmacCredential { let cred = FidoHmacCredential {
id: hex::decode(credential_id).unwrap(), id: hex::decode(credential_id).unwrap(),
rp_id: "fido2luks".to_string(), rp_id: RP_ID.to_string(),
}; };
let mut errs = Vec::new(); let mut errs = Vec::new();
match get_devices()? { match get_devices()? {
ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?, ref devs if devs.is_empty() => Err(Fido2LuksError::NoAuthenticatorError)?,
devs => { devs => {
for mut dev in devs.into_iter() { for mut dev in devs.into_iter() {
match dev.hmac_challange(&cred, &salt[..]) { match dev.get_hmac_assertion(&cred, &sha256(&[&salt[..]]), None, None) {
Ok(secret) => { Ok(secret) => {
return Ok(secret); return Ok(secret.0);
} }
Err(e) => { Err(e) => {
errs.push(e); errs.push(e);

View File

@ -7,9 +7,8 @@ use crate::device::*;
use crate::error::*; use crate::error::*;
use cryptsetup_rs as luks; use cryptsetup_rs as luks;
use cryptsetup_rs::Luks1CryptDevice; use cryptsetup_rs::Luks1CryptDevice;
use ring::digest;
use std::io::{self}; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::exit; use std::process::exit;
@ -26,12 +25,7 @@ fn open_container(device: &PathBuf, name: &str, secret: &[u8; 32]) -> Fido2LuksR
} }
fn assemble_secret(hmac_result: &[u8], salt: &[u8]) -> [u8; 32] { fn assemble_secret(hmac_result: &[u8], salt: &[u8]) -> [u8; 32] {
let mut digest = digest::Context::new(&digest::SHA256); util::sha256(&[salt, hmac_result])
digest.update(salt);
digest.update(hmac_result);
let mut secret = [0u8; 32];
secret.as_mut().copy_from_slice(digest.finish().as_ref());
secret
} }
fn main() -> Fido2LuksResult<()> { fn main() -> Fido2LuksResult<()> {

View File

@ -1,8 +1,19 @@
use crate::error::*; use crate::error::*;
use ring::digest;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
pub fn sha256<'a>(messages: &[&[u8]]) -> [u8; 32] {
let mut digest = digest::Context::new(&digest::SHA256);
for m in messages.iter() {
digest.update(m);
}
let mut secret = [0u8; 32];
secret.as_mut().copy_from_slice(digest.finish().as_ref());
secret
}
pub fn read_password(q: &str, verify: bool) -> Fido2LuksResult<String> { pub fn read_password(q: &str, verify: bool) -> Fido2LuksResult<String> {
match rpassword::read_password_from_tty(Some(&[q, ": "].join("")))? { match rpassword::read_password_from_tty(Some(&[q, ": "].join("")))? {
ref pass ref pass